From ced936627cc1561b2f9f387a7f937323cd11acf1 Mon Sep 17 00:00:00 2001 From: Daniel Schuette Date: Mon, 25 Oct 2021 23:00:09 +0200 Subject: [PATCH] update ale, add complete elm configuration for ale and coc --- vim-config/configs.vim | 26 +- vim-config/plugins/ale/.netrwhist | 12 - vim-config/plugins/ale/Dockerfile | 28 + vim-config/plugins/ale/LICENSE | 2 +- vim-config/plugins/ale/README.md | 959 ++++++ .../plugins/ale/ale_linters/ada/adals.vim | 26 + .../plugins/ale/ale_linters/ada/gcc.vim | 8 +- .../ale/ale_linters/ansible/ansible_lint.vim | 100 +- .../ale/ale_linters/apiblueprint/drafter.vim | 0 .../ale_linters/apkbuild/apkbuild_lint.vim | 12 + .../ale_linters/apkbuild/secfixes_check.vim | 12 + .../plugins/ale/ale_linters/asciidoc/alex.vim | 9 +- .../ale/ale_linters/asciidoc/languagetool.vim | 5 + .../ale/ale_linters/asciidoc/proselint.vim | 0 .../ale/ale_linters/asciidoc/redpen.vim | 0 .../ale/ale_linters/asciidoc/textlint.vim | 4 +- .../plugins/ale/ale_linters/asciidoc/vale.vim | 0 .../ale/ale_linters/asciidoc/writegood.vim | 0 .../plugins/ale/ale_linters/asm/gcc.vim | 11 +- .../plugins/ale/ale_linters/awk/gawk.vim | 4 +- .../ale/ale_linters/bats/shellcheck.vim | 4 + .../plugins/ale/ale_linters/bib/bibclean.vim | 64 +- vim-config/plugins/ale/ale_linters/c/cc.vim | 53 + vim-config/plugins/ale/ale_linters/c/ccls.vim | 7 +- .../plugins/ale/ale_linters/c/clang.vim | 27 - .../plugins/ale/ale_linters/c/clangd.vim | 19 +- .../plugins/ale/ale_linters/c/clangtidy.vim | 24 +- .../plugins/ale/ale_linters/c/cppcheck.vim | 29 +- .../plugins/ale/ale_linters/c/cquery.vim | 16 +- .../plugins/ale/ale_linters/c/flawfinder.vim | 16 +- vim-config/plugins/ale/ale_linters/c/gcc.vim | 27 - .../ale/ale_linters/chef/cookstyle.vim | 54 + .../ale/ale_linters/chef/foodcritic.vim | 4 +- .../ale/ale_linters/clojure/clj_kondo.vim | 46 + .../plugins/ale/ale_linters/clojure/joker.vim | 2 +- .../cloudformation/cfn_python_lint.vim | 1 + .../ale/ale_linters/cmake/cmakelint.vim | 4 +- .../plugins/ale/ale_linters/coffee/coffee.vim | 4 +- .../ale/ale_linters/coffee/coffeelint.vim | 4 +- vim-config/plugins/ale/ale_linters/cpp/cc.vim | 53 + .../plugins/ale/ale_linters/cpp/ccls.vim | 7 +- .../plugins/ale/ale_linters/cpp/clang.vim | 27 - .../ale/ale_linters/cpp/clangcheck.vim | 9 +- .../plugins/ale/ale_linters/cpp/clangd.vim | 19 +- .../plugins/ale/ale_linters/cpp/clangtidy.vim | 31 +- .../plugins/ale/ale_linters/cpp/clazy.vim | 4 +- .../plugins/ale/ale_linters/cpp/cppcheck.vim | 29 +- .../plugins/ale/ale_linters/cpp/cpplint.vim | 4 +- .../plugins/ale/ale_linters/cpp/cquery.vim | 16 +- .../ale/ale_linters/cpp/flawfinder.vim | 16 +- .../plugins/ale/ale_linters/cpp/gcc.vim | 28 - .../plugins/ale/ale_linters/crystal/ameba.vim | 57 + .../ale/ale_linters/crystal/crystal.vim | 6 +- vim-config/plugins/ale/ale_linters/cs/csc.vim | 90 + vim-config/plugins/ale/ale_linters/cs/mcs.vim | 2 +- .../plugins/ale/ale_linters/cs/mcsc.vim | 54 +- .../plugins/ale/ale_linters/css/csslint.vim | 2 +- .../plugins/ale/ale_linters/css/fecs.vim | 9 + .../plugins/ale/ale_linters/css/stylelint.vim | 6 +- .../ale/ale_linters/cucumber/cucumber.vim | 2 +- .../plugins/ale/ale_linters/cuda/clangd.vim | 23 + .../plugins/ale/ale_linters/cuda/nvcc.vim | 7 +- .../ale/ale_linters/cypher/cypher_lint.vim | 26 + vim-config/plugins/ale/ale_linters/d/dls.vim | 6 +- vim-config/plugins/ale/ale_linters/d/dmd.vim | 101 +- .../plugins/ale/ale_linters/dafny/dafny.vim | 19 +- .../ale/ale_linters/dart/analysis_server.vim | 29 + .../ale/ale_linters/dart/dart_analyze.vim | 28 + .../ale/ale_linters/dart/dartanalyzer.vim | 4 +- .../ale/ale_linters/dart/language_server.vim | 4 +- .../desktop/desktop_file_validate.vim | 31 + .../dockerfile/dockerfile_lint.vim | 21 +- .../ale/ale_linters/dockerfile/hadolint.vim | 45 +- .../plugins/ale/ale_linters/elixir/credo.vim | 29 +- .../ale/ale_linters/elixir/dialyxir.vim | 11 +- .../plugins/ale/ale_linters/elixir/dogma.vim | 10 +- .../ale/ale_linters/elixir/elixir_ls.vim | 10 +- .../plugins/ale/ale_linters/elixir/mix.vim | 15 +- .../plugins/ale/ale_linters/elm/elm_ls.vim | 40 + .../plugins/ale/ale_linters/elm/make.vim | 40 +- .../ale/ale_linters/erlang/dialyzer.vim | 97 + .../plugins/ale/ale_linters/erlang/elvis.vim | 39 + .../plugins/ale/ale_linters/erlang/erlc.vim | 26 +- .../ale/ale_linters/erlang/syntaxerl.vim | 19 +- .../plugins/ale/ale_linters/eruby/erb.vim | 2 +- .../plugins/ale/ale_linters/eruby/erblint.vim | 51 + .../plugins/ale/ale_linters/eruby/erubi.vim | 17 +- .../plugins/ale/ale_linters/eruby/erubis.vim | 2 +- .../plugins/ale/ale_linters/eruby/ruumba.vim | 8 +- .../plugins/ale/ale_linters/fish/fish.vim | 0 .../plugins/ale/ale_linters/fortran/gcc.vim | 4 +- .../ale_linters/fortran/language_server.vim | 4 +- .../ale/ale_linters/fountain/proselint.vim | 0 .../ale/ale_linters/fuse/fusionlint.vim | 4 +- .../ale/ale_linters/gitcommit/gitlint.vim | 4 +- .../plugins/ale/ale_linters/glsl/glslang.vim | 4 +- .../plugins/ale/ale_linters/glsl/glslls.vim | 6 +- .../plugins/ale/ale_linters/go/bingo.vim | 12 +- .../plugins/ale/ale_linters/go/gobuild.vim | 7 +- .../plugins/ale/ale_linters/go/gofmt.vim | 7 +- .../ale/ale_linters/go/golangci_lint.vim | 10 +- .../plugins/ale/ale_linters/go/golint.vim | 6 +- .../ale/ale_linters/go/gometalinter.vim | 9 +- .../plugins/ale/ale_linters/go/gopls.vim | 39 + .../plugins/ale/ale_linters/go/gosimple.vim | 7 +- .../plugins/ale/ale_linters/go/gotype.vim | 13 +- .../plugins/ale/ale_linters/go/govet.vim | 7 +- .../plugins/ale/ale_linters/go/langserver.vim | 13 +- .../plugins/ale/ale_linters/go/revive.vim | 21 + .../ale/ale_linters/go/staticcheck.vim | 23 +- .../ale/ale_linters/graphql/eslint.vim | 7 +- .../ale/ale_linters/graphql/gqlint.vim | 9 +- .../plugins/ale/ale_linters/hack/hack.vim | 4 +- .../plugins/ale/ale_linters/hack/hhast.vim | 8 +- .../plugins/ale/ale_linters/haml/hamllint.vim | 6 +- .../handlebars/embertemplatelint.vim | 31 +- .../ale/ale_linters/haskell/cabal_ghc.vim | 3 +- .../plugins/ale/ale_linters/haskell/ghc.vim | 2 +- .../ale/ale_linters/haskell/ghc_mod.vim | 4 +- .../ale/ale_linters/haskell/hdevtools.vim | 4 +- .../plugins/ale/ale_linters/haskell/hie.vim | 32 +- .../plugins/ale/ale_linters/haskell/hlint.vim | 4 +- .../plugins/ale/ale_linters/haskell/hls.vim | 63 + .../ale/ale_linters/haskell/stack_build.vim | 4 +- .../ale/ale_linters/haskell/stack_ghc.vim | 14 +- .../plugins/ale/ale_linters/help/alex.vim | 9 +- .../ale/ale_linters/help/proselint.vim | 0 .../ale/ale_linters/help/writegood.vim | 0 .../plugins/ale/ale_linters/html/alex.vim | 9 +- .../plugins/ale/ale_linters/html/angular.vim | 52 + .../plugins/ale/ale_linters/html/fecs.vim | 9 + .../plugins/ale/ale_linters/html/htmlhint.vim | 6 +- .../ale/ale_linters/html/proselint.vim | 0 .../ale/ale_linters/html/stylelint.vim | 6 +- .../plugins/ale/ale_linters/html/tidy.vim | 4 +- .../ale/ale_linters/html/writegood.vim | 0 .../plugins/ale/ale_linters/idris/idris.vim | 12 +- vim-config/plugins/ale/ale_linters/ink/ls.vim | 35 + .../plugins/ale/ale_linters/inko/inko.vim | 33 + .../plugins/ale/ale_linters/ispc/ispc.vim | 4 +- .../ale/ale_linters/java/checkstyle.vim | 41 +- .../ale/ale_linters/java/eclipselsp.vim | 195 ++ .../plugins/ale/ale_linters/java/javac.vim | 96 +- .../plugins/ale/ale_linters/java/javalsp.vim | 44 +- .../plugins/ale/ale_linters/java/pmd.vim | 2 +- .../ale/ale_linters/javascript/deno.vim | 11 + .../ale/ale_linters/javascript/eslint.vim | 7 +- .../ale/ale_linters/javascript/fecs.vim | 10 + .../ale/ale_linters/javascript/flow.vim | 43 +- .../ale/ale_linters/javascript/flow_ls.vim | 6 +- .../ale/ale_linters/javascript/jscs.vim | 6 +- .../ale/ale_linters/javascript/jshint.vim | 6 +- .../ale/ale_linters/javascript/standard.vim | 8 +- .../ale/ale_linters/javascript/tsserver.vim | 6 +- .../plugins/ale/ale_linters/javascript/xo.vim | 23 +- .../plugins/ale/ale_linters/json/eslint.vim | 16 + .../plugins/ale/ale_linters/json/jq.vim | 24 + .../plugins/ale/ale_linters/json/jsonlint.vim | 23 +- .../plugins/ale/ale_linters/json/spectral.vim | 14 + .../plugins/ale/ale_linters/json5/eslint.vim | 16 + .../plugins/ale/ale_linters/jsonc/eslint.vim | 16 + .../ale/ale_linters/jsonnet/jsonnet_lint.vim | 59 + .../ale/ale_linters/jsonnet/jsonnetfmt.vim | 52 + .../ale/ale_linters/julia/languageserver.vim | 10 +- .../ale/ale_linters/kotlin/kotlinc.vim | 44 +- .../plugins/ale/ale_linters/kotlin/ktlint.vim | 50 +- .../ale/ale_linters/kotlin/languageserver.vim | 4 +- .../plugins/ale/ale_linters/less/lessc.vim | 6 +- .../ale/ale_linters/less/stylelint.vim | 6 +- .../plugins/ale/ale_linters/llvm/llc.vim | 4 +- .../plugins/ale/ale_linters/lua/luac.vim | 2 +- .../plugins/ale/ale_linters/lua/luacheck.vim | 4 +- .../plugins/ale/ale_linters/mail/alex.vim | 11 +- .../ale/ale_linters/mail/languagetool.vim | 5 + .../ale/ale_linters/mail/proselint.vim | 0 .../plugins/ale/ale_linters/mail/vale.vim | 0 .../ale/ale_linters/make/checkmake.vim | 0 .../plugins/ale/ale_linters/markdown/alex.vim | 9 +- .../ale/ale_linters/markdown/languagetool.vim | 5 + .../ale/ale_linters/markdown/markdownlint.vim | 25 +- .../plugins/ale/ale_linters/markdown/mdl.vim | 15 +- .../ale/ale_linters/markdown/proselint.vim | 0 .../ale/ale_linters/markdown/redpen.vim | 0 .../ale/ale_linters/markdown/remark_lint.vim | 6 +- .../ale/ale_linters/markdown/textlint.vim | 4 +- .../plugins/ale/ale_linters/markdown/vale.vim | 19 +- .../ale/ale_linters/markdown/writegood.vim | 0 .../plugins/ale/ale_linters/matlab/mlint.vim | 2 +- .../plugins/ale/ale_linters/mercury/mmc.vim | 12 +- .../plugins/ale/ale_linters/nasm/nasm.vim | 7 +- .../plugins/ale/ale_linters/nim/nimcheck.vim | 16 +- .../plugins/ale/ale_linters/nim/nimlsp.vim | 33 + .../plugins/ale/ale_linters/nix/nix.vim | 57 +- .../plugins/ale/ale_linters/nix/rnix_lsp.vim | 16 + .../plugins/ale/ale_linters/nroff/alex.vim | 9 +- .../ale/ale_linters/nroff/proselint.vim | 0 .../ale/ale_linters/nroff/writegood.vim | 0 .../plugins/ale/ale_linters/objc/ccls.vim | 7 +- .../plugins/ale/ale_linters/objc/clang.vim | 4 +- .../plugins/ale/ale_linters/objc/clangd.vim | 12 +- .../plugins/ale/ale_linters/objcpp/clang.vim | 4 +- .../plugins/ale/ale_linters/objcpp/clangd.vim | 12 +- .../plugins/ale/ale_linters/ocaml/merlin.vim | 0 .../ale/ale_linters/ocaml/ocamllsp.vim | 13 + .../plugins/ale/ale_linters/ocaml/ols.vim | 8 +- .../ale/ale_linters/ocamlinterface/merlin.vim | 17 + .../ale_linters/ocamlinterface/ocamllsp.vim | 13 + .../ale/ale_linters/openapi/ibm_validator.vim | 58 + .../ale/ale_linters/openapi/yamllint.vim | 9 + .../plugins/ale/ale_linters/perl/perl.vim | 4 +- .../ale/ale_linters/perl/perlcritic.vim | 4 +- .../plugins/ale/ale_linters/perl6/perl6.vim | 24 +- .../ale/ale_linters/php/intelephense.vim | 32 + .../ale/ale_linters/php/langserver.vim | 12 +- .../plugins/ale/ale_linters/php/phan.vim | 12 +- .../plugins/ale/ale_linters/php/php.vim | 2 +- .../plugins/ale/ale_linters/php/phpcs.vim | 17 +- .../plugins/ale/ale_linters/php/phpmd.vim | 4 +- .../plugins/ale/ale_linters/php/phpstan.vim | 90 +- .../plugins/ale/ale_linters/php/psalm.vim | 19 +- .../plugins/ale/ale_linters/php/tlint.vim | 80 + .../plugins/ale/ale_linters/po/alex.vim | 9 +- .../plugins/ale/ale_linters/po/msgfmt.vim | 0 .../plugins/ale/ale_linters/po/proselint.vim | 0 .../plugins/ale/ale_linters/po/writegood.vim | 0 .../plugins/ale/ale_linters/pod/alex.vim | 9 +- .../plugins/ale/ale_linters/pod/proselint.vim | 0 .../plugins/ale/ale_linters/pod/writegood.vim | 0 .../plugins/ale/ale_linters/pony/ponyc.vim | 4 +- .../ale/ale_linters/powershell/powershell.vim | 100 + .../powershell/psscriptanalyzer.vim | 76 + .../plugins/ale/ale_linters/prolog/swipl.vim | 24 +- .../ale/ale_linters/proto/protoc_gen_lint.vim | 2 +- .../ale/ale_linters/proto/protolint.vim | 24 + .../plugins/ale/ale_linters/pug/puglint.vim | 22 +- .../ale/ale_linters/puppet/languageserver.vim | 4 +- .../plugins/ale/ale_linters/puppet/puppet.vim | 12 +- .../ale/ale_linters/puppet/puppetlint.vim | 4 +- .../plugins/ale/ale_linters/purescript/ls.vim | 49 + .../plugins/ale/ale_linters/pyrex/cython.vim | 8 +- .../plugins/ale/ale_linters/python/bandit.vim | 76 + .../plugins/ale/ale_linters/python/flake8.vim | 83 +- .../ale/ale_linters/python/flakehell.vim | 175 ++ .../plugins/ale/ale_linters/python/jedils.vim | 34 + .../plugins/ale/ale_linters/python/mypy.vim | 52 +- .../ale/ale_linters/python/prospector.vim | 12 +- .../ale/ale_linters/python/pycodestyle.vim | 12 +- .../ale/ale_linters/python/pydocstyle.vim | 25 +- .../ale/ale_linters/python/pyflakes.vim | 12 +- .../plugins/ale/ale_linters/python/pylama.vim | 99 + .../plugins/ale/ale_linters/python/pylint.vim | 79 +- .../plugins/ale/ale_linters/python/pyls.vim | 36 - .../plugins/ale/ale_linters/python/pylsp.vim | 43 + .../plugins/ale/ale_linters/python/pyre.vim | 24 +- .../ale/ale_linters/python/pyright.vim | 43 + .../ale/ale_linters/python/vulture.vim | 40 +- .../plugins/ale/ale_linters/qml/qmlfmt.vim | 2 +- .../plugins/ale/ale_linters/qml/qmllint.vim | 0 .../ale/ale_linters/r/languageserver.vim | 27 + .../plugins/ale/ale_linters/r/lintr.vim | 10 +- .../ale/ale_linters/racket/langserver.vim | 7 + .../plugins/ale/ale_linters/racket/raco.vim | 1 + .../plugins/ale/ale_linters/reason/ls.vim | 23 + .../plugins/ale/ale_linters/reason/merlin.vim | 0 .../plugins/ale/ale_linters/reason/ols.vim | 8 +- .../plugins/ale/ale_linters/review/redpen.vim | 0 .../plugins/ale/ale_linters/robot/rflint.vim | 46 + .../plugins/ale/ale_linters/rst/alex.vim | 9 +- .../plugins/ale/ale_linters/rst/proselint.vim | 0 .../plugins/ale/ale_linters/rst/redpen.vim | 0 .../plugins/ale/ale_linters/rst/rstcheck.vim | 11 +- .../plugins/ale/ale_linters/rst/textlint.vim | 4 +- .../plugins/ale/ale_linters/rst/vale.vim | 0 .../plugins/ale/ale_linters/rst/writegood.vim | 0 .../plugins/ale/ale_linters/ruby/brakeman.vim | 6 +- .../plugins/ale/ale_linters/ruby/debride.vim | 42 + .../ale_linters/ruby/rails_best_practices.vim | 10 +- .../plugins/ale/ale_linters/ruby/reek.vim | 33 +- .../plugins/ale/ale_linters/ruby/rubocop.vim | 8 +- .../plugins/ale/ale_linters/ruby/ruby.vim | 4 +- .../ale/ale_linters/ruby/solargraph.vim | 8 +- .../plugins/ale/ale_linters/ruby/sorbet.vim | 26 + .../ale/ale_linters/ruby/standardrb.vim | 8 +- .../plugins/ale/ale_linters/rust/analyzer.vim | 24 + .../plugins/ale/ale_linters/rust/cargo.vim | 78 +- .../plugins/ale/ale_linters/rust/rls.vim | 10 +- .../plugins/ale/ale_linters/rust/rustc.vim | 2 +- .../ale/ale_linters/salt/salt_lint.vim | 33 + .../plugins/ale/ale_linters/sass/sasslint.vim | 6 +- .../ale/ale_linters/sass/stylelint.vim | 4 +- .../plugins/ale/ale_linters/scala/fsc.vim | 2 +- .../plugins/ale/ale_linters/scala/metals.vim | 50 + .../ale/ale_linters/scala/sbtserver.vim | 4 +- .../plugins/ale/ale_linters/scala/scalac.vim | 2 +- .../ale/ale_linters/scala/scalastyle.vim | 2 +- .../plugins/ale/ale_linters/scss/sasslint.vim | 6 +- .../plugins/ale/ale_linters/scss/scsslint.vim | 0 .../ale/ale_linters/scss/stylelint.vim | 6 +- .../plugins/ale/ale_linters/sh/bashate.vim | 43 + .../ale/ale_linters/sh/language_server.vim | 8 +- .../plugins/ale/ale_linters/sh/shell.vim | 10 +- .../plugins/ale/ale_linters/sh/shellcheck.vim | 112 +- .../plugins/ale/ale_linters/slim/slimlint.vim | 12 +- .../plugins/ale/ale_linters/sml/smlnj.vim | 2 +- .../plugins/ale/ale_linters/sml/smlnj_cm.vim | 4 +- .../plugins/ale/ale_linters/solidity/solc.vim | 53 + .../ale/ale_linters/solidity/solhint.vim | 31 +- .../ale/ale_linters/solidity/solium.vim | 0 .../plugins/ale/ale_linters/spec/rpmlint.vim | 20 +- .../plugins/ale/ale_linters/sql/sqlint.vim | 0 .../plugins/ale/ale_linters/sql/sqllint.vim | 33 + .../ale/ale_linters/stylus/stylelint.vim | 6 +- .../ale/ale_linters/sugarss/stylelint.vim | 21 + .../ale/ale_linters/svelte/svelteserver.vim | 21 + .../ale_linters/swift/appleswiftformat.vim | 43 + .../ale/ale_linters/swift/sourcekitlsp.vim | 13 + .../ale/ale_linters/swift/swiftlint.vim | 24 +- .../ale_linters/systemd/systemd_analyze.vim | 18 + .../plugins/ale/ale_linters/tcl/nagelfar.vim | 4 +- .../ale/ale_linters/terraform/terraform.vim | 63 + .../ale_linters/terraform/terraform_ls.vim | 38 + .../ale_linters/terraform/terraform_lsp.vim | 25 + .../ale/ale_linters/terraform/tflint.vim | 85 +- .../ale/ale_linters/testft/testlinter.vim | 0 .../plugins/ale/ale_linters/tex/alex.vim | 9 +- .../plugins/ale/ale_linters/tex/chktex.vim | 2 +- .../plugins/ale/ale_linters/tex/lacheck.vim | 2 +- .../plugins/ale/ale_linters/tex/proselint.vim | 0 .../plugins/ale/ale_linters/tex/redpen.vim | 0 .../plugins/ale/ale_linters/tex/texlab.vim | 24 + .../plugins/ale/ale_linters/tex/textlint.vim | 9 + .../plugins/ale/ale_linters/tex/vale.vim | 0 .../plugins/ale/ale_linters/tex/writegood.vim | 0 .../plugins/ale/ale_linters/texinfo/alex.vim | 9 +- .../ale/ale_linters/texinfo/proselint.vim | 0 .../ale/ale_linters/texinfo/writegood.vim | 0 .../plugins/ale/ale_linters/text/alex.vim | 9 +- .../ale/ale_linters/text/languagetool.vim | 4 + .../ale/ale_linters/text/proselint.vim | 0 .../plugins/ale/ale_linters/text/redpen.vim | 0 .../plugins/ale/ale_linters/text/textlint.vim | 4 +- .../plugins/ale/ale_linters/text/vale.vim | 0 .../ale/ale_linters/text/writegood.vim | 0 .../plugins/ale/ale_linters/thrift/thrift.vim | 7 +- .../ale/ale_linters/thrift/thriftcheck.vim | 46 + .../ale/ale_linters/typescript/deno.vim | 12 + .../ale/ale_linters/typescript/eslint.vim | 7 +- .../ale/ale_linters/typescript/standard.vim | 31 + .../ale/ale_linters/typescript/tslint.vim | 8 +- .../ale/ale_linters/typescript/tsserver.vim | 7 +- .../ale/ale_linters/typescript/typecheck.vim | 0 .../plugins/ale/ale_linters/typescript/xo.vim | 6 + vim-config/plugins/ale/ale_linters/v/v.vim | 82 + .../ale/ale_linters/vala/vala_lint.vim | 66 + .../ale/ale_linters/verilog/hdl_checker.vim | 5 + .../ale/ale_linters/verilog/iverilog.vim | 2 +- .../ale/ale_linters/verilog/verilator.vim | 43 +- .../plugins/ale/ale_linters/verilog/vlog.vim | 52 + .../plugins/ale/ale_linters/verilog/xvlog.vim | 35 + .../plugins/ale/ale_linters/verilog/yosys.vim | 42 + .../plugins/ale/ale_linters/vhdl/ghdl.vim | 37 + .../ale/ale_linters/vhdl/hdl_checker.vim | 5 + .../plugins/ale/ale_linters/vhdl/vcom.vim | 38 + .../plugins/ale/ale_linters/vhdl/xvhdl.vim | 37 + .../vim/ale_custom_linting_rules.vim | 17 +- .../plugins/ale/ale_linters/vim/vimls.vim | 61 + .../plugins/ale/ale_linters/vim/vint.vim | 45 +- .../plugins/ale/ale_linters/vue/vls.vim | 6 +- .../plugins/ale/ale_linters/xhtml/alex.vim | 9 +- .../ale/ale_linters/xhtml/proselint.vim | 0 .../ale/ale_linters/xhtml/writegood.vim | 0 .../plugins/ale/ale_linters/xml/xmllint.vim | 28 +- .../plugins/ale/ale_linters/yaml/circleci.vim | 35 + .../plugins/ale/ale_linters/yaml/spectral.vim | 14 + .../plugins/ale/ale_linters/yaml/swaglint.vim | 4 +- .../plugins/ale/ale_linters/yaml/yamllint.vim | 45 +- .../plugins/ale/ale_linters/yang/yang_lsp.vim | 4 +- .../plugins/ale/ale_linters/zeek/zeek.vim | 22 + .../plugins/ale/ale_linters/zig/zls.vim | 20 + vim-config/plugins/ale/autoload/ale.vim | 64 +- vim-config/plugins/ale/autoload/ale/ant.vim | 45 + vim-config/plugins/ale/autoload/ale/args.vim | 43 + .../plugins/ale/autoload/ale/assert.vim | 341 +- .../plugins/ale/autoload/ale/balloon.vim | 32 +- vim-config/plugins/ale/autoload/ale/c.vim | 475 ++- .../plugins/ale/autoload/ale/code_action.vim | 411 +++ .../plugins/ale/autoload/ale/codefix.vim | 497 +++ .../plugins/ale/autoload/ale/command.vim | 423 ++- .../plugins/ale/autoload/ale/completion.vim | 727 ++++- .../ale/autoload/ale/completion/python.vim | 0 .../plugins/ale/autoload/ale/cursor.vim | 32 +- vim-config/plugins/ale/autoload/ale/d.vim | 0 .../plugins/ale/autoload/ale/debugging.vim | 36 +- .../plugins/ale/autoload/ale/definition.vim | 123 +- vim-config/plugins/ale/autoload/ale/dhall.vim | 24 + .../plugins/ale/autoload/ale/engine.vim | 662 ++-- .../ale/autoload/ale/engine/ignore.vim | 6 +- .../plugins/ale/autoload/ale/events.vim | 12 +- .../ale/autoload/ale/filename_mapping.vim | 22 + .../plugins/ale/autoload/ale/filetypes.vim | 4 +- vim-config/plugins/ale/autoload/ale/fix.vim | 458 ++- .../plugins/ale/autoload/ale/fix/registry.vim | 254 +- .../autoload/ale/fixers/appleswiftformat.vim | 16 + .../ale/autoload/ale/fixers/astyle.vim | 59 + .../ale/autoload/ale/fixers/autoflake.vim | 28 + .../ale/autoload/ale/fixers/autoimport.vim | 27 + .../ale/autoload/ale/fixers/autopep8.vim | 0 .../ale/autoload/ale/fixers/bibclean.vim | 0 .../plugins/ale/autoload/ale/fixers/black.vim | 36 +- .../ale/autoload/ale/fixers/brittany.vim | 0 .../ale/autoload/ale/fixers/buildifier.vim | 26 + .../ale/autoload/ale/fixers/clangformat.vim | 35 +- .../ale/autoload/ale/fixers/clangtidy.vim | 52 + .../ale/autoload/ale/fixers/cmakeformat.vim | 16 + .../ale/autoload/ale/fixers/dart_format.vim | 18 + .../ale/autoload/ale/fixers/dartfmt.vim | 0 .../plugins/ale/autoload/ale/fixers/deno.vim | 17 + .../plugins/ale/autoload/ale/fixers/dfmt.vim | 18 + .../ale/autoload/ale/fixers/dhall_format.vim | 11 + .../ale/autoload/ale/fixers/dhall_freeze.vim | 14 + .../ale/autoload/ale/fixers/dhall_lint.vim | 11 + .../ale/autoload/ale/fixers/dotnet_format.vim | 18 + .../ale/autoload/ale/fixers/elm_format.vim | 2 +- .../ale/autoload/ale/fixers/erblint.vim | 40 + .../ale/autoload/ale/fixers/erlfmt.vim | 21 + .../ale/autoload/ale/fixers/eslint.vim | 43 +- .../plugins/ale/autoload/ale/fixers/fecs.vim | 17 + .../ale/autoload/ale/fixers/fish_indent.vim | 19 + .../ale/autoload/ale/fixers/fixjson.vim | 2 +- .../ale/autoload/ale/fixers/floskell.vim | 20 + .../ale/autoload/ale/fixers/generic.vim | 4 +- .../autoload/ale/fixers/generic_python.vim | 4 +- .../ale/autoload/ale/fixers/gnatpp.vim | 17 + .../plugins/ale/autoload/ale/fixers/gofmt.vim | 6 +- .../ale/autoload/ale/fixers/goimports.vim | 3 +- .../ale/autoload/ale/fixers/golines.vim | 21 + .../plugins/ale/autoload/ale/fixers/gomod.vim | 3 +- .../ale/fixers/google_java_format.vim | 0 .../ale/autoload/ale/fixers/hackfmt.vim | 0 .../plugins/ale/autoload/ale/fixers/help.vim | 2 +- .../plugins/ale/autoload/ale/fixers/hfmt.vim | 0 .../ale/autoload/ale/fixers/hindent.vim | 20 + .../plugins/ale/autoload/ale/fixers/hlint.vim | 0 .../ale/autoload/ale/fixers/html_beautify.vim | 21 + .../ale/autoload/ale/fixers/importjs.vim | 0 .../plugins/ale/autoload/ale/fixers/isort.vim | 70 +- .../plugins/ale/autoload/ale/fixers/jq.vim | 20 +- .../ale/autoload/ale/fixers/jsonnetfmt.vim | 18 + .../ale/autoload/ale/fixers/ktlint.vim | 8 + .../ale/autoload/ale/fixers/latexindent.vim | 16 + .../ale/autoload/ale/fixers/lua_format.vim | 16 + .../ale/autoload/ale/fixers/luafmt.vim | 13 + .../ale/autoload/ale/fixers/mix_format.vim | 0 .../ale/autoload/ale/fixers/nimpretty.vim | 15 + .../ale/autoload/ale/fixers/nixfmt.vim | 15 + .../ale/autoload/ale/fixers/nixpkgsfmt.vim | 12 + .../ale/autoload/ale/fixers/ocamlformat.vim | 3 +- .../ale/autoload/ale/fixers/ocp_indent.vim | 18 + .../ale/autoload/ale/fixers/ormolu.vim | 12 + .../ale/autoload/ale/fixers/pandoc.vim | 16 + .../ale/autoload/ale/fixers/perltidy.vim | 0 .../ale/autoload/ale/fixers/pgformatter.vim | 12 + .../ale/autoload/ale/fixers/php_cs_fixer.vim | 2 +- .../ale/autoload/ale/fixers/phpcbf.vim | 5 +- .../ale/autoload/ale/fixers/prettier.vim | 57 +- .../autoload/ale/fixers/prettier_eslint.vim | 40 +- .../autoload/ale/fixers/prettier_standard.vim | 6 +- .../ale/autoload/ale/fixers/protolint.vim | 26 + .../plugins/ale/autoload/ale/fixers/ptop.vim | 17 + .../ale/autoload/ale/fixers/puppetlint.vim | 0 .../ale/autoload/ale/fixers/purs_tidy.vim | 24 + .../plugins/ale/autoload/ale/fixers/purty.vim | 22 + .../ale/autoload/ale/fixers/qmlfmt.vim | 6 +- .../plugins/ale/autoload/ale/fixers/refmt.vim | 0 .../ale/autoload/ale/fixers/remark_lint.vim | 24 + .../ale/fixers/reorder_python_imports.vim | 25 + .../ale/autoload/ale/fixers/rubocop.vim | 28 +- .../plugins/ale/autoload/ale/fixers/rufo.vim | 0 .../ale/autoload/ale/fixers/rustfmt.vim | 0 .../ale/autoload/ale/fixers/scalafmt.vim | 0 .../plugins/ale/autoload/ale/fixers/shfmt.vim | 0 .../ale/autoload/ale/fixers/sorbet.vim | 19 + .../ale/autoload/ale/fixers/sqlfmt.vim | 0 .../ale/autoload/ale/fixers/sqlformat.vim | 16 + .../ale/autoload/ale/fixers/standard.vim | 14 +- .../ale/autoload/ale/fixers/standardrb.vim | 6 +- .../ale/autoload/ale/fixers/stylelint.vim | 17 +- .../ale/autoload/ale/fixers/styler.vim | 16 + .../autoload/ale/fixers/stylish_haskell.vim | 0 .../ale/autoload/ale/fixers/stylua.vim | 14 + .../ale/autoload/ale/fixers/swiftformat.vim | 2 +- .../ale/autoload/ale/fixers/terraform.vim | 0 .../ale/autoload/ale/fixers/textlint.vim | 0 .../plugins/ale/autoload/ale/fixers/tidy.vim | 2 +- .../ale/autoload/ale/fixers/tslint.vim | 2 +- .../ale/autoload/ale/fixers/uncrustify.vim | 0 .../plugins/ale/autoload/ale/fixers/vfmt.vim | 13 + .../ale/autoload/ale/fixers/xmllint.vim | 0 .../plugins/ale/autoload/ale/fixers/xo.vim | 37 +- .../ale/autoload/ale/fixers/yamlfix.vim | 25 + .../plugins/ale/autoload/ale/fixers/yapf.vim | 0 .../ale/autoload/ale/floating_preview.vim | 203 ++ vim-config/plugins/ale/autoload/ale/go.vim | 43 +- .../plugins/ale/autoload/ale/gradle.vim | 25 +- .../ale/autoload/ale/gradle/init.gradle | 0 .../ale/autoload/ale/handlers/alex.vim | 34 +- .../ale/autoload/ale/handlers/atools.vim | 41 + .../ale/autoload/ale/handlers/ccls.vim | 21 +- .../ale/autoload/ale/handlers/cppcheck.vim | 59 +- .../ale/autoload/ale/handlers/cpplint.vim | 0 .../plugins/ale/autoload/ale/handlers/css.vim | 0 .../ale/autoload/ale/handlers/deno.vim | 74 + .../ale/autoload/ale/handlers/elixir.vim | 0 .../ale/autoload/ale/handlers/eslint.vim | 182 +- .../ale/autoload/ale/handlers/fecs.vim | 52 + .../ale/autoload/ale/handlers/flawfinder.vim | 3 +- .../ale/autoload/ale/handlers/gawk.vim | 0 .../plugins/ale/autoload/ale/handlers/gcc.vim | 43 +- .../plugins/ale/autoload/ale/handlers/go.vim | 5 +- .../ale/autoload/ale/handlers/haskell.vim | 8 +- .../autoload/ale/handlers/haskell_stack.vim | 0 .../ale/autoload/ale/handlers/hdl_checker.vim | 73 + .../ale/autoload/ale/handlers/hlint.vim | 0 .../ale/autoload/ale/handlers/inko.vim | 37 + .../ale/autoload/ale/handlers/ktlint.vim | 45 + .../autoload/ale/handlers/languagetool.vim | 77 + .../autoload/ale/handlers/markdownlint.vim | 19 +- .../ale/autoload/ale/handlers/ocamllsp.vim | 30 + .../plugins/ale/autoload/ale/handlers/ols.vim | 2 +- .../ale/autoload/ale/handlers/pony.vim | 0 .../ale/autoload/ale/handlers/redpen.vim | 4 +- .../ale/autoload/ale/handlers/ruby.vim | 8 - .../ale/autoload/ale/handlers/rust.vim | 12 +- .../ale/autoload/ale/handlers/scala.vim | 0 .../plugins/ale/autoload/ale/handlers/sh.vim | 37 +- .../ale/autoload/ale/handlers/shellcheck.vim | 123 + .../plugins/ale/autoload/ale/handlers/sml.vim | 36 +- .../ale/autoload/ale/handlers/solhint.vim | 98 + .../ale/autoload/ale/handlers/spectral.vim | 31 + .../ale/autoload/ale/handlers/textlint.vim | 2 +- .../ale/autoload/ale/handlers/tslint.vim | 2 +- .../ale/autoload/ale/handlers/tsserver.vim | 8 + .../ale/autoload/ale/handlers/unix.vim | 0 .../ale/autoload/ale/handlers/vale.vim | 0 .../ale/autoload/ale/handlers/writegood.vim | 6 +- .../plugins/ale/autoload/ale/handlers/xo.vim | 44 + .../ale/autoload/ale/handlers/yamllint.vim | 39 + .../plugins/ale/autoload/ale/highlight.vim | 113 +- .../plugins/ale/autoload/ale/history.vim | 0 vim-config/plugins/ale/autoload/ale/hover.vim | 255 +- vim-config/plugins/ale/autoload/ale/java.vim | 6 + vim-config/plugins/ale/autoload/ale/job.vim | 44 +- vim-config/plugins/ale/autoload/ale/julia.vim | 0 .../plugins/ale/autoload/ale/linter.vim | 249 +- vim-config/plugins/ale/autoload/ale/list.vim | 120 +- .../ale/autoload/ale/loclist_jumping.vim | 102 +- vim-config/plugins/ale/autoload/ale/lsp.vim | 267 +- .../plugins/ale/autoload/ale/lsp/message.vim | 56 +- .../plugins/ale/autoload/ale/lsp/reset.vim | 0 .../plugins/ale/autoload/ale/lsp/response.vim | 21 +- .../ale/autoload/ale/lsp/tsserver_message.vim | 72 +- .../plugins/ale/autoload/ale/lsp_linter.vim | 412 ++- .../plugins/ale/autoload/ale/lsp_window.vim | 58 + vim-config/plugins/ale/autoload/ale/maven.vim | 57 + vim-config/plugins/ale/autoload/ale/node.vim | 27 +- .../ale/autoload/ale/organize_imports.vim | 62 + .../plugins/ale/autoload/ale/other_source.vim | 0 vim-config/plugins/ale/autoload/ale/path.vim | 83 +- .../ale/autoload/ale/pattern_options.vim | 0 .../plugins/ale/autoload/ale/powershell.vim | 32 + .../plugins/ale/autoload/ale/preview.vim | 69 +- .../plugins/ale/autoload/ale/python.vim | 55 +- .../plugins/ale/autoload/ale/racket.vim | 12 + .../plugins/ale/autoload/ale/references.vim | 82 +- .../plugins/ale/autoload/ale/rename.vim | 208 ++ vim-config/plugins/ale/autoload/ale/ruby.vim | 11 +- .../plugins/ale/autoload/ale/semver.vim | 49 +- vim-config/plugins/ale/autoload/ale/sign.vim | 159 +- .../plugins/ale/autoload/ale/socket.vim | 5 +- .../plugins/ale/autoload/ale/statusline.vim | 75 +- vim-config/plugins/ale/autoload/ale/swift.vim | 70 + .../plugins/ale/autoload/ale/symbol.vim | 37 +- vim-config/plugins/ale/autoload/ale/test.vim | 123 +- .../plugins/ale/autoload/ale/toggle.vim | 4 + vim-config/plugins/ale/autoload/ale/uri.vim | 15 +- vim-config/plugins/ale/autoload/ale/util.vim | 103 +- .../plugins/ale/autoload/ale/virtualtext.vim | 47 +- .../ale/autoload/asyncomplete/sources/ale.vim | 26 + vim-config/plugins/ale/doc/ale-ada.txt | 41 + vim-config/plugins/ale/doc/ale-ansible.txt | 0 vim-config/plugins/ale/doc/ale-apkbuild.txt | 30 + vim-config/plugins/ale/doc/ale-asciidoc.txt | 0 vim-config/plugins/ale/doc/ale-asm.txt | 0 vim-config/plugins/ale/doc/ale-awk.txt | 0 vim-config/plugins/ale/doc/ale-bats.txt | 13 + vim-config/plugins/ale/doc/ale-bazel.txt | 28 + vim-config/plugins/ale/doc/ale-bib.txt | 0 vim-config/plugins/ale/doc/ale-c.txt | 234 +- vim-config/plugins/ale/doc/ale-chef.txt | 20 + vim-config/plugins/ale/doc/ale-clojure.txt | 15 + .../plugins/ale/doc/ale-cloudformation.txt | 36 +- vim-config/plugins/ale/doc/ale-cmake.txt | 18 + vim-config/plugins/ale/doc/ale-cpp.txt | 169 +- vim-config/plugins/ale/doc/ale-cs.txt | 122 +- vim-config/plugins/ale/doc/ale-css.txt | 8 + vim-config/plugins/ale/doc/ale-cuda.txt | 25 + vim-config/plugins/ale/doc/ale-d.txt | 9 + vim-config/plugins/ale/doc/ale-dafny.txt | 16 + vim-config/plugins/ale/doc/ale-dart.txt | 86 + vim-config/plugins/ale/doc/ale-desktop.txt | 21 + .../plugins/ale/doc/ale-development.txt | 171 +- vim-config/plugins/ale/doc/ale-dhall.txt | 52 + vim-config/plugins/ale/doc/ale-dockerfile.txt | 0 vim-config/plugins/ale/doc/ale-elixir.txt | 21 +- vim-config/plugins/ale/doc/ale-elm.txt | 50 + vim-config/plugins/ale/doc/ale-erlang.txt | 77 + vim-config/plugins/ale/doc/ale-eruby.txt | 21 + vim-config/plugins/ale/doc/ale-fish.txt | 17 + vim-config/plugins/ale/doc/ale-fortran.txt | 0 vim-config/plugins/ale/doc/ale-fountain.txt | 0 vim-config/plugins/ale/doc/ale-fuse.txt | 0 vim-config/plugins/ale/doc/ale-gitcommit.txt | 0 vim-config/plugins/ale/doc/ale-glsl.txt | 0 vim-config/plugins/ale/doc/ale-go.txt | 257 +- vim-config/plugins/ale/doc/ale-graphql.txt | 0 vim-config/plugins/ale/doc/ale-hack.txt | 0 vim-config/plugins/ale/doc/ale-handlebars.txt | 13 +- vim-config/plugins/ale/doc/ale-haskell.txt | 75 + vim-config/plugins/ale/doc/ale-hcl.txt | 2 +- vim-config/plugins/ale/doc/ale-html.txt | 113 +- vim-config/plugins/ale/doc/ale-idris.txt | 0 vim-config/plugins/ale/doc/ale-ink.txt | 40 + vim-config/plugins/ale/doc/ale-inko.txt | 22 + vim-config/plugins/ale/doc/ale-ispc.txt | 0 vim-config/plugins/ale/doc/ale-java.txt | 190 +- vim-config/plugins/ale/doc/ale-javascript.txt | 34 +- vim-config/plugins/ale/doc/ale-json.txt | 57 +- vim-config/plugins/ale/doc/ale-json5.txt | 15 + vim-config/plugins/ale/doc/ale-jsonc.txt | 15 + vim-config/plugins/ale/doc/ale-jsonnet.txt | 43 + vim-config/plugins/ale/doc/ale-julia.txt | 0 vim-config/plugins/ale/doc/ale-kotlin.txt | 10 +- vim-config/plugins/ale/doc/ale-latex.txt | 6 + vim-config/plugins/ale/doc/ale-less.txt | 0 vim-config/plugins/ale/doc/ale-llvm.txt | 0 vim-config/plugins/ale/doc/ale-lua.txt | 54 + vim-config/plugins/ale/doc/ale-markdown.txt | 30 + vim-config/plugins/ale/doc/ale-mercury.txt | 0 vim-config/plugins/ale/doc/ale-nasm.txt | 0 vim-config/plugins/ale/doc/ale-nim.txt | 45 + vim-config/plugins/ale/doc/ale-nix.txt | 42 + vim-config/plugins/ale/doc/ale-nroff.txt | 0 vim-config/plugins/ale/doc/ale-objc.txt | 0 vim-config/plugins/ale/doc/ale-objcpp.txt | 0 vim-config/plugins/ale/doc/ale-ocaml.txt | 43 + vim-config/plugins/ale/doc/ale-openapi.txt | 74 + vim-config/plugins/ale/doc/ale-pascal.txt | 24 + vim-config/plugins/ale/doc/ale-pawn.txt | 0 vim-config/plugins/ale/doc/ale-perl.txt | 0 vim-config/plugins/ale/doc/ale-perl6.txt | 0 vim-config/plugins/ale/doc/ale-php.txt | 139 +- vim-config/plugins/ale/doc/ale-po.txt | 0 vim-config/plugins/ale/doc/ale-pod.txt | 0 vim-config/plugins/ale/doc/ale-pony.txt | 0 vim-config/plugins/ale/doc/ale-powershell.txt | 70 + vim-config/plugins/ale/doc/ale-prolog.txt | 0 vim-config/plugins/ale/doc/ale-proto.txt | 37 +- vim-config/plugins/ale/doc/ale-pug.txt | 0 vim-config/plugins/ale/doc/ale-puppet.txt | 0 vim-config/plugins/ale/doc/ale-purescript.txt | 69 + vim-config/plugins/ale/doc/ale-pyrex.txt | 0 vim-config/plugins/ale/doc/ale-python.txt | 591 +++- vim-config/plugins/ale/doc/ale-qml.txt | 0 vim-config/plugins/ale/doc/ale-r.txt | 41 +- vim-config/plugins/ale/doc/ale-reasonml.txt | 38 +- .../plugins/ale/doc/ale-restructuredtext.txt | 0 vim-config/plugins/ale/doc/ale-robot.txt | 16 + vim-config/plugins/ale/doc/ale-ruby.txt | 71 +- vim-config/plugins/ale/doc/ale-rust.txt | 83 +- vim-config/plugins/ale/doc/ale-salt.tmt | 43 + vim-config/plugins/ale/doc/ale-sass.txt | 2 +- vim-config/plugins/ale/doc/ale-scala.txt | 26 + vim-config/plugins/ale/doc/ale-scss.txt | 0 vim-config/plugins/ale/doc/ale-sh.txt | 47 + vim-config/plugins/ale/doc/ale-sml.txt | 0 vim-config/plugins/ale/doc/ale-solidity.txt | 19 +- vim-config/plugins/ale/doc/ale-spec.txt | 0 vim-config/plugins/ale/doc/ale-sql.txt | 36 + vim-config/plugins/ale/doc/ale-stylus.txt | 0 vim-config/plugins/ale/doc/ale-sugarss.txt | 31 + .../doc/ale-supported-languages-and-tools.txt | 610 ++++ vim-config/plugins/ale/doc/ale-svelte.txt | 31 + vim-config/plugins/ale/doc/ale-swift.txt | 60 + vim-config/plugins/ale/doc/ale-systemd.txt | 14 + vim-config/plugins/ale/doc/ale-tcl.txt | 0 vim-config/plugins/ale/doc/ale-terraform.txt | 55 +- vim-config/plugins/ale/doc/ale-tex.txt | 41 + vim-config/plugins/ale/doc/ale-texinfo.txt | 0 vim-config/plugins/ale/doc/ale-text.txt | 0 vim-config/plugins/ale/doc/ale-thrift.txt | 19 + vim-config/plugins/ale/doc/ale-typescript.txt | 93 + vim-config/plugins/ale/doc/ale-v.txt | 45 + vim-config/plugins/ale/doc/ale-vala.txt | 21 + vim-config/plugins/ale/doc/ale-verilog.txt | 101 +- vim-config/plugins/ale/doc/ale-vhdl.txt | 157 + vim-config/plugins/ale/doc/ale-vim-help.txt | 0 vim-config/plugins/ale/doc/ale-vim.txt | 55 + vim-config/plugins/ale/doc/ale-vue.txt | 0 vim-config/plugins/ale/doc/ale-xhtml.txt | 0 vim-config/plugins/ale/doc/ale-xml.txt | 0 vim-config/plugins/ale/doc/ale-yaml.txt | 96 +- vim-config/plugins/ale/doc/ale-yang.txt | 0 vim-config/plugins/ale/doc/ale-zeek.txt | 23 + vim-config/plugins/ale/doc/ale-zig.txt | 33 + vim-config/plugins/ale/doc/ale.txt | 2766 ++++++++++++----- vim-config/plugins/ale/doc/tags | 873 +++++- .../plugins/ale/ftplugin/ale-fix-suggest.vim | 0 .../ale/ftplugin/ale-preview-selection.vim | 2 +- .../plugins/ale/ftplugin/ale-preview.vim | 0 vim-config/plugins/ale/plugin/ale.vim | 126 +- .../rplugin/python3/deoplete/sources/ale.py | 61 + vim-config/plugins/ale/run-tests | 289 ++ vim-config/plugins/ale/run-tests.bat | 30 + vim-config/plugins/ale/supported-tools.md | 616 ++++ .../plugins/ale/syntax/ale-fix-suggest.vim | 0 .../ale/syntax/ale-preview-selection.vim | 0 .../completion/test_ale_import_command.vader | 562 ++++ .../completion/test_complete_events.vader | 35 + .../completion/test_completion_events.vader | 486 +++ .../test_completion_filtering.vader | 142 + .../completion/test_completion_prefixes.vader | 65 + .../test_lsp_completion_messages.vader | 307 ++ .../test_lsp_completion_parsing.vader | 704 +++++ .../completion/test_omnifunc_completion.vader | 60 + .../test_public_completion_api.vader | 47 + .../test_tsserver_completion_parsing.vader | 309 ++ .../plugins/ale/test/fix/test_ale_fix.vader | 884 ++++++ .../ale/test/fix/test_ale_fix_aliases.vader | 5 + .../test/fix/test_ale_fix_completion.vader | 23 + .../fix/test_ale_fix_completion_filter.vader | 14 + .../ale/test/fix/test_ale_fix_ignore.vader | 110 + .../ale/test/fix/test_ale_fix_suggest.vader | 102 + ...test_appleswiftformat_fixer_callback.vader | 47 + .../fixers/test_astyle_fixer_callback.vader | 96 + .../test_autoflake_fixer_callback.vader | 49 + .../test_autoimport_fixer_callback.vader | 47 + .../fixers/test_autopep8_fixer_callback.vader | 37 + .../fixers/test_bibclean_fixer_callback.vader | 30 + .../fixers/test_black_fixer_callback.vader | 67 + ...est_break_up_long_lines_python_fixer.vader | 39 + .../fixers/test_brittany_fixer_callback.vader | 24 + .../test_buildifier_fixer_callback.vader | 29 + .../test_clangformat_fixer_callback.vader | 64 + .../test_clangtidy_fixer_callback.vader | 47 + .../test_cmakeformat_fixer_callback.vader | 36 + .../test_dart_format_fixer_callback.vader | 40 + .../fixers/test_dartfmt_fixer_callback.vader | 40 + .../fixers/test_dfmt_fixer_callback.vader | 40 + .../test_dhall_format_fixer_callback.vader | 22 + .../test_dhall_freeze_fixer_callback.vader | 22 + .../test_dhall_lint_fixer_callback.vader | 20 + .../test_dotnet_format_fixer_callback.vader | 41 + .../test_elm_format_fixer_callback.vader | 74 + .../fixers/test_erblint_fixer_callback.vader | 55 + .../fixers/test_erlfmt_fixer_callback.vader | 25 + .../fixers/test_eslint_fixer_callback.vader | 339 ++ .../fixers/test_fecs_fixer_callback.vader | 24 + .../test_fish_indent_fixer_callback.vader | 40 + .../fixers/test_fixjson_fixer_callback.vader | 50 + .../fixers/test_floskell_fixer_callback.vader | 23 + .../fixers/test_gnatpp_fixer_callback.vader | 28 + .../fixers/test_gofmt_fixer_callback.vader | 50 + .../test_goimports_fixer_callback.vader | 57 + .../fixers/test_golines_fixer_callback.vader | 54 + .../fixers/test_gomod_fixer_callback.vader | 41 + ...st_goofle_java_format_fixer_callback.vader | 27 + .../fixers/test_hackfmt_fixer_callback.vader | 37 + .../fixers/test_hfmt_fixer_callback.vader | 24 + .../fixers/test_hindent_fixer_callback.vader | 18 + .../fixers/test_hlint_fixer_callback.vader | 20 + .../test_html_beautify_fixer_callback.vader | 12 + .../fixers/test_importjs_fixer_callback.vader | 35 + .../fixers/test_isort_fixer_callback.vader | 70 + .../test/fixers/test_jq_fixer_callback.vader | 26 + .../test_jsonnetfmt_fixer_callback.vader | 38 + .../fixers/test_ktlint_fixer_callback.vader | 42 + .../test_latexindent_fixer_callback.vader | 36 + .../test_lua_format_fixer_callback.vader | 35 + .../fixers/test_luafmt_fixer_callback.vader | 35 + .../test_mix_format_fixer_callback.vader | 36 + .../test_nimpretty_fixer_callback.vader | 23 + .../fixers/test_nixfmt_fixer_callback.vader | 24 + .../test_nixpkgsfmt_fixer_callback.vader | 24 + .../test_ocamlformat_fixer_callback.vader | 36 + .../test_ocp_indent_fixer_callback.vader | 34 + .../fixers/test_ormolu_fixer_callback.vader | 24 + .../fixers/test_pandoc_fixer_callback.vader | 23 + .../fixers/test_perltidy_fixer_callback.vader | 40 + .../test_pgformatter_fixer_callback.vader | 24 + .../ale/test/fixers/test_php_cs_fixer.vader | 62 + .../fixers/test_phpcbf_fixer_callback.vader | 117 + .../test_prettier_eslint_fixer.callback.vader | 97 + .../fixers/test_prettier_fixer_callback.vader | 337 ++ .../test_prettier_standard_callback.vader | 15 + .../test_protolint_fixer_callback.vader | 28 + .../fixers/test_ptop_fixer_callback.vader | 38 + .../test_puppetlint_fixer_callback.vader | 24 + .../test_purs_tidy_fixer_callback.vader | 20 + .../fixers/test_purty_fixer_callback.vader | 24 + .../test_python_add_blank_lines_fixer.vader | 167 + .../fixers/test_qmlfmt_fixer_callback.vader | 12 + .../fixers/test_refmt_fixer_callback.vader | 41 + .../test_remark_lint_fixer_callback.vader | 24 + ...eorder_python_imports_fixer_callback.vader | 46 + .../fixers/test_rubocop_fixer_callback.vader | 89 + .../fixers/test_rufo_fixer_callback.vader | 30 + .../fixers/test_rustfmt_fixer_callback.vader | 16 + .../fixers/test_scalafmt_fixer_callback.vader | 66 + .../fixers/test_shfmt_fixer_callback.vader | 59 + .../fixers/test_sorbet_fixer_callback.vader | 38 + .../fixers/test_sqlfmt_fixer_callback.vader | 26 + .../test_sqlformat_fixer_callback.vader | 24 + .../fixers/test_standard_fixer_callback.vader | 31 + .../test_standardrb_fixer_callback.vader | 51 + .../test_stylelint_fixer_callback.vader | 34 + .../fixers/test_styler_fixer_callback.vader | 21 + .../test_stylish_haskell_fixer_callback.vader | 24 + .../fixers/test_stylua_fixer_callback.vader | 19 + .../test_swiftformat_fixer_callback.vader | 35 + .../test_terraform_fmt_fixer_callback.vader | 34 + .../fixers/test_textlint_fixer_callback.vader | 42 + .../fixers/test_tidy_fixer_callback.vader | 25 + .../test/fixers/test_trim_whitespace.vader | 28 + .../fixers/test_tslint_fixer_callback.vader | 42 + .../test_uncrustify_fixer_callback.vader | 33 + .../fixers/test_vfmt_fixer_callback.vader | 44 + .../test_vim_help_tags_alignment_fixer.vader | 19 + .../fixers/test_xmllint_fixer_callback.vader | 46 + .../test/fixers/test_xo_fixer_callback.vader | 45 + .../fixers/test_xots_fixer_callback.vader | 45 + .../fixers/test_yamlfix_fixer_callback.vader | 33 + .../fixers/test_yapf_fixer_callback.vader | 39 + .../test/handler/test_ada_gcc_handler.vader | 36 + .../ale/test/handler/test_alex_handler.vader | 54 + .../ale/test/handler/test_ameba_handler.vader | 44 + .../handler/test_ansible_lint_handler.vader | 95 + .../test_appleswiftformat_handler.vader | 28 + .../ale/test/handler/test_asm_handler.vader | 26 + .../test/handler/test_atools_handler.vader | 85 + .../test/handler/test_bandit_handler.vader | 42 + .../test/handler/test_bashate_handler.vader | 36 + .../test/handler/test_bibclean_handler.vader | 88 + .../test/handler/test_brakeman_handler.vader | 83 + .../test_cfn_python_lint_handler.vader | 33 + .../test/handler/test_checkmake_handler.vader | 23 + .../handler/test_checkstyle_handler.vader | 53 + .../test/handler/test_circleci_handler.vader | 39 + .../ale/test/handler/test_clang_handler.vader | 30 + .../test_clojure_clj_kondo_handler.vader | 89 + .../handler/test_clojure_joker_handler.vader | 75 + .../handler/test_coffeelint_handler.vader | 20 + .../test/handler/test_common_handlers.vader | 181 ++ .../test/handler/test_cookstyle_handler.vader | 22 + .../test/handler/test_cppcheck_handler.vader | 76 + .../test/handler/test_cpplint_handler.vader | 29 + .../ale/test/handler/test_credo_handler.vader | 53 + .../test/handler/test_crystal_handler.vader | 28 + .../ale/test/handler/test_csc_handler.vader | 98 + .../test/handler/test_cucumber_handler.vader | 18 + .../test/handler/test_cuda_nvcc_handler.vader | 41 + .../handler/test_cypher_lint_handler.vader | 21 + .../ale/test/handler/test_dafny_handler.vader | 36 + .../handler/test_dart_analyze_handler.vader | 28 + .../handler/test_dartanalyzer_handler.vader | 28 + .../test/handler/test_debride_handler.vader | 27 + .../test_desktop_file_validate_handler.vader | 26 + .../ale/test/handler/test_dmd_handler.vader | 41 + .../test_dockerfile_lint_handler.vader | 112 + .../ale/test/handler/test_dogma_handler.vader | 30 + .../test/handler/test_drafter_handler.vader | 37 + .../test/handler/test_elmmake_handler.vader | 299 ++ .../test_embertemplatelint_handler.vader | 81 + .../test/handler/test_erblint_handler.vader | 70 + .../test_erlang_dialyzer_handler.vader | 27 + .../handler/test_erlang_elvis_handler.vader | 37 + .../test/handler/test_eslint_handler.vader | 438 +++ .../handler/test_eslint_json_handler.vader | 376 +++ .../ale/test/handler/test_fecs_handler.vader | 35 + .../ale/test/handler/test_fish_handler.vader | 61 + .../test/handler/test_flake8_handler.vader | 276 ++ .../test/handler/test_flakehell_handler.vader | 276 ++ .../handler/test_flawfinder_handler.vader | 57 + .../ale/test/handler/test_flow_handler.vader | 507 +++ .../handler/test_foodcritic_handler.vader | 44 + .../test/handler/test_fortran_handler.vader | 95 + .../ale/test/handler/test_gawk_handler.vader | 39 + .../ale/test/handler/test_gcc_handler.vader | 316 ++ .../ale/test/handler/test_ghc_handler.vader | 132 + .../test/handler/test_ghc_mod_handler.vader | 37 + .../ale/test/handler/test_ghdl_handler.vader | 26 + .../test/handler/test_gitlint_handler.vader | 89 + .../test/handler/test_glslang_handler.vader | 24 + .../handler/test_go_generic_handler.vader | 38 + .../test/handler/test_gobuild_handler.vader | 45 + .../handler/test_golangci_lint_handler.vader | 55 + .../handler/test_gometalinter_handler.vader | 57 + .../ale/test/handler/test_hadolint.vader | 59 + .../handler/test_haskell_stack_handler.vader | 7 + .../ale/test/handler/test_hlint_handler.vader | 80 + .../test_ibm_openapi_validator_handler.vader | 49 + .../ale/test/handler/test_idris_handler.vader | 66 + .../ale/test/handler/test_inko_handler.vader | 54 + .../test/handler/test_ispc_ispc_handler.vader | 90 + .../ale/test/handler/test_javac_handler.vader | 97 + .../ale/test/handler/test_jscs_handler.vader | 39 + .../test/handler/test_ktlint_handler.vader | 21 + .../test/handler/test_lacheck_handler.vader | 34 + .../handler/test_languagetool_handler.vader | 62 + .../ale/test/handler/test_lessc_handler.vader | 69 + .../ale/test/handler/test_llc_handler.vader | 58 + .../ale/test/handler/test_luac_handler.vader | 36 + .../test/handler/test_luacheck_handler.vader | 62 + .../handler/test_markdownlint_handler.vader | 91 + .../ale/test/handler/test_mcs_handler.vader | 37 + .../ale/test/handler/test_mcsc_handler.vader | 88 + .../ale/test/handler/test_mdl_handler.vader | 25 + .../handler/test_mercury_mmc_handler.vader | 58 + .../ale/test/handler/test_mix_handler.vader | 21 + .../ale/test/handler/test_msgfmt_hander.vader | 24 + .../ale/test/handler/test_mypy_handler.vader | 141 + .../test/handler/test_nagelfar_handler.vader | 174 ++ .../ale/test/handler/test_nasm_handler.vader | 30 + .../ale/test/handler/test_nim_handler.vader | 80 + .../ale/test/handler/test_nix_handler.vader | 51 + .../ale/test/handler/test_perl6_handler.vader | 277 ++ .../ale/test/handler/test_perl_handler.vader | 109 + .../handler/test_perlcritic_handler.vader | 20 + .../ale/test/handler/test_php_handler.vader | 93 + .../test/handler/test_php_phan_handler.vader | 26 + .../test/handler/test_php_phpmd_handler.vader | 24 + .../ale/test/handler/test_phpcs_handler.vader | 28 + .../test/handler/test_phpstan_handler.vader | 51 + .../ale/test/handler/test_pmd_handler.vader | 42 + .../ale/test/handler/test_pony_handler.vader | 21 + .../handler/test_powershell_handler.vader | 109 + .../handler/test_prospector_handler.vader | 163 + .../test_psscriptanalyzer_handler.vader | 42 + .../test/handler/test_puglint_handler.vader | 45 + .../test/handler/test_puppet_handler.vader | 77 + .../handler/test_pycodestyle_handler.vader | 154 + .../handler/test_pydocstyle_handler.vader | 116 + .../test/handler/test_pyflakes_handler.vader | 24 + .../test/handler/test_pylama_handler.vader | 193 ++ .../test/handler/test_pylint_handler.vader | 135 + .../handler/test_pyrex_cython_handler.vader | 26 + .../test/handler/test_qmlfmt_handler.vader | 19 + .../test/handler/test_qmllint_handler.vader | 19 + .../ale/test/handler/test_raco_handler.vader | 27 + .../test_rails_best_practices_handler.vader | 52 + .../test/handler/test_redpen_handler.vader | 98 + .../ale/test/handler/test_reek_handler.vader | 81 + .../handler/test_remark_lint_handler.vader | 39 + .../test/handler/test_rflint_handler.vader | 33 + .../test/handler/test_rpmlint_handler.vader | 33 + .../handler/test_rstcheck_lint_handler.vader | 42 + .../test/handler/test_rubocop_handler.vader | 76 + .../ale/test/handler/test_ruby_handler.vader | 38 + .../ale/test/handler/test_rust_handler.vader | 483 +++ .../test/handler/test_salt_salt_lint.vader | 34 + .../ale/test/handler/test_scala_handler.vader | 32 + .../handler/test_scalastyle_handler.vader | 53 + .../ale/test/handler/test_shell_handler.vader | 177 ++ .../handler/test_shellcheck_handler.vader | 43 + .../ale/test/handler/test_slim_handler.vader | 34 + .../ale/test/handler/test_sml_handler.vader | 87 + .../ale/test/handler/test_solc_handler.vader | 34 + .../test/handler/test_solhint_handler.vader | 84 + .../test/handler/test_spectral_handler.vader | 52 + .../test/handler/test_sqlint_handler.vader | 34 + .../test/handler/test_sqllint_handler.vader | 23 + .../test/handler/test_standard_handler.vader | 37 + .../test/handler/test_stylelint_handler.vader | 43 + .../test/handler/test_swaglint_handler.vader | 68 + .../test/handler/test_swiftlint_handler.vader | 30 + .../ale/test/handler/test_swipl_handler.vader | 155 + .../test/handler/test_syntaxerl_handler.vader | 24 + .../test_systemd_analyze_handler.vader | 19 + .../test/handler/test_terraform_handler.vader | 99 + .../test/handler/test_textlint_handler.vader | 41 + .../test/handler/test_tflint_handler.vader | 99 + .../test/handler/test_thrift_handler.vader | 63 + .../handler/test_thriftcheck_handler.vader | 28 + .../ale/test/handler/test_tlint_handler.vader | 34 + .../test/handler/test_tslint_handler.vader | 315 ++ .../test/handler/test_typecheck_handler.vader | 24 + .../ale/test/handler/test_v_handler.vader | 54 + .../test/handler/test_vala_lint_handler.vader | 54 + .../ale/test/handler/test_vale_handler.vader | 88 + .../ale/test/handler/test_vcom_handler.vader | 36 + .../test/handler/test_verilator_handler.vader | 52 + .../ale/test/handler/test_vint_handler.vader | 65 + .../ale/test/handler/test_vlog_handler.vader | 47 + .../test/handler/test_vulture_handler.vader | 92 + .../handler/test_write_good_handler.vader | 37 + .../test/handler/test_xmllint_handler.vader | 30 + .../ale/test/handler/test_xvhdl_handler.vader | 24 + .../ale/test/handler/test_xvlog_handler.vader | 18 + .../test/handler/test_yamllint_handler.vader | 59 + .../ale/test/handler/test_yosys_handler.vader | 27 + .../ale/test/handler/test_zeek_handler.vader | 17 + .../ale/test/jsonnet_files/testfile.jsonnet | 1 + .../ale/test/linter/test_ada_gcc.vader | 42 + .../plugins/ale/test/linter/test_adals.vader | 17 + .../plugins/ale/test/linter/test_alex.vader | 34 + .../plugins/ale/test/linter/test_ameba.vader | 20 + .../ale/test/linter/test_angular.vader | 44 + .../ale/test/linter/test_ansible_lint.vader | 22 + .../test/linter/test_asciidoc_textlint.vader | 65 + .../ale/test/linter/test_asm_gcc.vader | 19 + .../plugins/ale/test/linter/test_bandit.vader | 90 + .../ale/test/linter/test_bashate.vader | 15 + .../ale/test/linter/test_bib_bibclean.vader | 24 + .../plugins/ale/test/linter/test_bingo.vader | 74 + .../ale/test/linter/test_brakeman.vader | 37 + .../plugins/ale/test/linter/test_c_cc.vader | 55 + .../plugins/ale/test/linter/test_c_ccls.vader | 69 + .../ale/test/linter/test_c_clang_tidy.vader | 77 + .../ale/test/linter/test_c_clangd.vader | 47 + .../ale/test/linter/test_c_cppcheck.vader | 46 + .../ale/test/linter/test_c_cquery.vader | 37 + .../ale/test/linter/test_c_flawfinder.vader | 24 + .../ale/test/linter/test_c_import_paths.vader | 162 + .../plugins/ale/test/linter/test_cargo.vader | 222 ++ .../ale/test/linter/test_checkstyle.vader | 72 + .../ale/test/linter/test_circleci.vader | 13 + .../ale/test/linter/test_clang_tidy.vader | 84 + .../ale/test/linter/test_clj_kondo.vader | 15 + .../ale/test/linter/test_cookstyle.vader | 19 + .../plugins/ale/test/linter/test_cpp_cc.vader | 55 + .../ale/test/linter/test_cpp_ccls.vader | 69 + .../ale/test/linter/test_cpp_clangcheck.vader | 35 + .../ale/test/linter/test_cpp_clazy.vader | 56 + .../ale/test/linter/test_cpp_cppcheck.vader | 66 + .../ale/test/linter/test_cpp_cquery.vader | 40 + .../ale/test/linter/test_cpp_flawfinder.vader | 26 + .../ale/test/linter/test_cpplint.vader | 17 + .../plugins/ale/test/linter/test_cs_csc.vader | 42 + .../plugins/ale/test/linter/test_cs_mcs.vader | 13 + .../ale/test/linter/test_cs_mcsc.vader | 42 + .../ale/test/linter/test_cucumber.vader | 18 + .../ale/test/linter/test_cuda_nvcc.vader | 20 + .../test/linter/test_cypher_cypher_lint.vader | 8 + .../plugins/ale/test/linter/test_d_dls.vader | 19 + .../linter/test_dart_analysis_server.vader | 15 + .../linter/test_dart_language_server.vader | 8 + .../ale/test/linter/test_dartanalyzer.vader | 20 + .../linter/test_desktop_file_validate.vader | 15 + .../ale/test/linter/test_dialyxir.vader | 16 + .../test/linter/test_dmd_commandline.vader | 96 + .../test/linter/test_dockerfile_lint.vader | 19 + .../plugins/ale/test/linter/test_dogma.vader | 16 + .../ale/test/linter/test_eclipselsp.vader | 111 + .../ale/test/linter/test_elixir_credo.vader | 43 + .../ale/test/linter/test_elixir_ls.vader | 34 + .../ale/test/linter/test_elixir_mix.vader | 19 + .../plugins/ale/test/linter/test_elm_ls.vader | 29 + .../ale/test/linter/test_elm_make.vader | 63 + .../test/linter/test_embertemplatelint.vader | 17 + .../plugins/ale/test/linter/test_erb.vader | 16 + .../ale/test/linter/test_erblint.vader | 26 + .../test/linter/test_erlang_dialyzer.vader | 45 + .../ale/test/linter/test_erlang_elvis.vader | 16 + .../ale/test/linter/test_erlang_erlc.vader | 62 + .../test/linter/test_erlang_syntaxerl.vader | 45 + .../plugins/ale/test/linter/test_erubi.vader | 32 + .../plugins/ale/test/linter/test_erubis.vader | 16 + .../plugins/ale/test/linter/test_eslint.vader | 85 + .../plugins/ale/test/linter/test_fecs.vader | 9 + .../plugins/ale/test/linter/test_flake8.vader | 217 ++ .../ale/test/linter/test_flakehell.vader | 202 ++ .../plugins/ale/test/linter/test_flow.vader | 42 + .../ale/test/linter/test_foodcritic.vader | 18 + .../ale/test/linter/test_fortran_fortls.vader | 18 + .../plugins/ale/test/linter/test_fsc.vader | 13 + .../ale/test/linter/test_fusionlint.vader | 19 + .../plugins/ale/test/linter/test_gawk.vader | 25 + .../ale/test/linter/test_gfortran.vader | 24 + .../plugins/ale/test/linter/test_ghdl.vader | 19 + .../ale/test/linter/test_gitlint.vader | 43 + .../ale/test/linter/test_glslang.vader | 19 + .../plugins/ale/test/linter/test_glslls.vader | 19 + .../ale/test/linter/test_gobuild.vader | 33 + .../plugins/ale/test/linter/test_gofmt.vader | 26 + .../ale/test/linter/test_golangci_lint.vader | 50 + .../ale/test/linter/test_golangserver.vader | 76 + .../plugins/ale/test/linter/test_golint.vader | 30 + .../ale/test/linter/test_gometalinter.vader | 49 + .../plugins/ale/test/linter/test_gopls.vader | 96 + .../ale/test/linter/test_gosimple.vader | 19 + .../plugins/ale/test/linter/test_gotype.vader | 24 + .../plugins/ale/test/linter/test_govet.vader | 32 + .../ale/test/linter/test_graphql_gqlint.vader | 9 + .../ale/test/linter/test_haml_hamllint.vader | 41 + .../test/linter/test_haskell_cabal_ghc.vader | 13 + .../ale/test/linter/test_haskell_ghc.vader | 12 + .../test/linter/test_haskell_ghc_mod.vader | 10 + .../test/linter/test_haskell_hdevtools.vader | 16 + .../ale/test/linter/test_haskell_hie.vader | 27 + .../ale/test/linter/test_haskell_hlint.vader | 17 + .../ale/test/linter/test_haskell_hls.vader | 27 + .../linter/test_haskell_stack_build.vader | 13 + .../test/linter/test_haskell_stack_ghc.vader | 18 + .../linter/test_hdl_checker_options.vader | 86 + .../ale/test/linter/test_html_stylelint.vader | 60 + .../ale/test/linter/test_htmlhint.vader | 51 + .../linter/test_ibm_openapi_validator.vader | 15 + .../plugins/ale/test/linter/test_idris.vader | 21 + .../plugins/ale/test/linter/test_ink_ls.vader | 22 + .../ale/test/linter/test_inko_inko.vader | 20 + .../ale/test/linter/test_ispc_ispc.vader | 20 + .../ale/test/linter/test_iverilog.vader | 14 + .../plugins/ale/test/linter/test_javac.vader | 326 ++ .../ale/test/linter/test_javalsp.vader | 80 + .../linter/test_javascript_deno_lsp.vader | 79 + .../linter/test_javascript_tsserver.vader | 16 + .../plugins/ale/test/linter/test_jq.vader | 8 + .../plugins/ale/test/linter/test_jscs.vader | 15 + .../plugins/ale/test/linter/test_jshint.vader | 17 + .../ale/test/linter/test_jsonnet_lint.vader | 19 + .../ale/test/linter/test_jsonnetfmt.vader | 19 + .../linter/test_julia_languageserver.vader | 30 + .../linter/test_kotlin_languageserver.vader | 23 + .../ale/test/linter/test_kotlinc.vader | 9 + .../ale/test/linter/test_languagetool.vader | 22 + .../ale/test/linter/test_less_stylelint.vader | 31 + .../plugins/ale/test/linter/test_lessc.vader | 46 + .../plugins/ale/test/linter/test_lintr.vader | 34 + .../plugins/ale/test/linter/test_llc.vader | 21 + .../plugins/ale/test/linter/test_luac.vader | 13 + .../ale/test/linter/test_luacheck.vader | 23 + .../linter/test_markdown_markdownlint.vader | 13 + .../ale/test/linter/test_markdown_mdl.vader | 19 + .../ale/test/linter/test_markdown_vale.vader | 32 + .../ale/test/linter/test_mercury_mmc.vader | 22 + .../plugins/ale/test/linter/test_mypy.vader | 106 + .../ale/test/linter/test_nagelfar.vader | 19 + .../ale/test/linter/test_nasm_nasm.vader | 32 + .../plugins/ale/test/linter/test_nimlsp.vader | 12 + .../ale/test/linter/test_objc_ccls.vader | 66 + .../ale/test/linter/test_ocaml_ocamllsp.vader | 29 + .../ale/test/linter/test_ocaml_ols.vader | 40 + .../linter/test_ocamlinterface_ocamllsp.vader | 29 + .../plugins/ale/test/linter/test_perl.vader | 14 + .../plugins/ale/test/linter/test_perl6.vader | 14 + .../ale/test/linter/test_perlcritic.vader | 36 + .../plugins/ale/test/linter/test_php.vader | 15 + .../test/linter/test_php_intelephense.vader | 26 + .../ale/test/linter/test_php_langserver.vader | 30 + .../plugins/ale/test/linter/test_phpcs.vader | 42 + .../plugins/ale/test/linter/test_phpmd.vader | 12 + .../ale/test/linter/test_phpstan.vader | 115 + .../ale/test/linter/test_pony_ponyc.vader | 12 + .../ale/test/linter/test_prospector.vader | 35 + .../plugins/ale/test/linter/test_proto.vader | 16 + .../ale/test/linter/test_protolint.vader | 24 + .../plugins/ale/test/linter/test_psalm.vader | 38 + .../ale/test/linter/test_puglint.vader | 48 + .../ale/test/linter/test_purescript_ls.vader | 31 + .../ale/test/linter/test_pycodestyle.vader | 46 + .../ale/test/linter/test_pydocstyle.vader | 45 + .../ale/test/linter/test_pyflakes.vader | 59 + .../plugins/ale/test/linter/test_pylama.vader | 88 + .../plugins/ale/test/linter/test_pylint.vader | 96 + .../plugins/ale/test/linter/test_pylsp.vader | 69 + .../plugins/ale/test/linter/test_pyre.vader | 66 + .../ale/test/linter/test_pyrex_cython.vader | 30 + .../ale/test/linter/test_pyright.vader | 116 + .../plugins/ale/test/linter/test_qmlfmt.vader | 13 + .../test/linter/test_r_languageserver.vader | 22 + .../test/linter/test_racket_langserver.vader | 45 + .../ale/test/linter/test_racket_raco.vader | 10 + .../linter/test_rails_best_practices.vader | 42 + .../ale/test/linter/test_reason_ls.vader | 21 + .../ale/test/linter/test_reason_ols.vader | 41 + .../plugins/ale/test/linter/test_reek.vader | 49 + .../ale/test/linter/test_remark_lint.vader | 37 + .../plugins/ale/test/linter/test_revive.vader | 30 + .../plugins/ale/test/linter/test_rflint.vader | 20 + .../plugins/ale/test/linter/test_rnix.vader | 12 + .../ale/test/linter/test_rst_textlint.vader | 65 + .../ale/test/linter/test_rubocop.vader | 26 + .../plugins/ale/test/linter/test_ruby.vader | 13 + .../ale/test/linter/test_ruby_debride.vader | 8 + .../test/linter/test_ruby_solargraph.vader | 43 + .../ale/test/linter/test_rust_analyzer.vader | 20 + .../ale/test/linter/test_rust_rls.vader | 30 + .../plugins/ale/test/linter/test_rustc.vader | 21 + .../plugins/ale/test/linter/test_ruumba.vader | 26 + .../ale/test/linter/test_sass_sasslint.vader | 43 + .../ale/test/linter/test_scala_metals.vader | 21 + .../test/linter/test_scala_sbtserver.vader | 23 + .../plugins/ale/test/linter/test_scalac.vader | 13 + .../ale/test/linter/test_scalastyle.vader | 34 + .../ale/test/linter/test_scss_sasslint.vader | 43 + .../ale/test/linter/test_scss_stylelint.vader | 31 + .../ale/test/linter/test_shellcheck.vader | 106 + .../ale/test/linter/test_slimlint.vader | 19 + .../plugins/ale/test/linter/test_solc.vader | 13 + .../ale/test/linter/test_solc_commit.vader | 14 + .../ale/test/linter/test_solhint.vader | 28 + .../plugins/ale/test/linter/test_sorbet.vader | 34 + .../ale/test/linter/test_spectral.vader | 31 + .../ale/test/linter/test_sqllint.vader | 12 + .../ale/test/linter/test_standard.vader | 43 + .../ale/test/linter/test_standardrb.vader | 26 + .../ale/test/linter/test_standardts.vader | 43 + .../ale/test/linter/test_staticcheck.vader | 49 + .../test/linter/test_sugarss_stylelint.vader | 31 + .../ale/test/linter/test_svelteserver.vader | 8 + .../ale/test/linter/test_swaglint.vader | 29 + .../linter/test_swift_appleswiftformat.vader | 42 + .../test/linter/test_swift_sourcekitlsp.vader | 21 + .../ale/test/linter/test_swiftlint.vader | 43 + .../test/linter/test_systemd_analyze.vader | 9 + .../ale/test/linter/test_terraform_ls.vader | 61 + .../ale/test/linter/test_terraform_lsp.vader | 48 + .../linter/test_terraform_terraform.vader | 15 + .../test/linter/test_terraform_tflint.vader | 28 + .../ale/test/linter/test_tex_lacheck.vader | 13 + .../ale/test/linter/test_tex_textlint.vader | 65 + .../plugins/ale/test/linter/test_texlab.vader | 30 + .../ale/test/linter/test_textlint.vader | 65 + .../plugins/ale/test/linter/test_thrift.vader | 53 + .../ale/test/linter/test_thriftcheck.vader | 21 + .../plugins/ale/test/linter/test_tslint.vader | 23 + .../linter/test_typescript_deno_lsp.vader | 79 + .../linter/test_typescript_tsserver.vader | 8 + .../test/linter/test_v_command_callback.vader | 25 + .../plugins/ale/test/linter/test_vcom.vader | 19 + .../ale/test/linter/test_verilator.vader | 14 + .../ale/test/linter/test_vim_vimls.vader | 76 + .../plugins/ale/test/linter/test_vint.vader | 34 + .../plugins/ale/test/linter/test_vlog.vader | 19 + .../ale/test/linter/test_vulture.vader | 62 + .../ale/test/linter/test_write_good.vader | 55 + .../ale/test/linter/test_xmllint.vader | 20 + .../plugins/ale/test/linter/test_xo.vader | 23 + .../plugins/ale/test/linter/test_xots.vader | 23 + .../plugins/ale/test/linter/test_xvhdl.vader | 19 + .../plugins/ale/test/linter/test_xvlog.vader | 19 + .../ale/test/linter/test_yang_lsp.vader | 12 + .../plugins/ale/test/linter/test_zeek.vader | 17 + .../ale/test/linter/test_zig_zls.vader | 15 + .../ale/test/lsp/test_closing_documents.vader | 176 ++ .../ale/test/lsp/test_did_save_event.vader | 147 + .../test_engine_lsp_response_handling.vader | 428 +++ .../lsp/test_handling_window_requests.vader | 94 + .../test/lsp/test_lsp_client_messages.vader | 362 +++ .../lsp/test_lsp_command_formatting.vader | 44 + .../ale/test/lsp/test_lsp_connections.vader | 227 ++ .../test/lsp/test_lsp_custom_request.vader | 158 + .../ale/test/lsp/test_lsp_error_parsing.vader | 74 + .../test/lsp/test_lsp_root_detection.vader | 90 + .../ale/test/lsp/test_lsp_startup.vader | 483 +++ ...st_other_initialize_message_handling.vader | 214 ++ .../test/lsp/test_read_lsp_diagnostics.vader | 257 ++ .../plugins/ale/test/lsp/test_reset_lsp.vader | 98 + .../ale/test/lsp/test_update_config.vader | 21 + .../ale/test/python/test_deoplete_source.py | 120 + .../ale/test/script/block-padding-checker | 145 + .../ale/test/script/check-duplicate-tags | 5 + .../test/script/check-supported-tools-tables | 60 + .../ale/test/script/check-tag-alignment | 11 + .../ale/test/script/check-tag-references | 22 + vim-config/plugins/ale/test/script/check-toc | 90 + .../plugins/ale/test/script/custom-checks | 80 + .../ale/test/script/custom-linting-rules | 155 + .../ale/test/script/dumb_named_pipe_server.py | 42 + .../ale/test/script/dumb_tcp_client.py | 33 + .../ale/test/script/dumb_tcp_server.py | 40 + .../plugins/ale/test/script/run-vader-tests | 151 + vim-config/plugins/ale/test/script/run-vint | 20 + .../test/sign/test_linting_sets_signs.vader | 76 + .../sign/test_sign_column_highlighting.vader | 68 + .../ale/test/sign/test_sign_limits.vader | 57 + .../ale/test/sign/test_sign_parsing.vader | 88 + .../ale/test/sign/test_sign_placement.vader | 315 ++ vim-config/plugins/ale/test/smoke_test.vader | 181 ++ .../ale/test/test-files/.circleci/config.yml | 0 .../plugins/ale/test/test-files/.gitignore | 2 + .../ale/test/test-files/ada/testfile.adb | 0 .../node-modules-2/node_modules/alex/cli.js | 0 .../alex/node-modules/node_modules/.bin/alex | 0 .../@angular/language-server/bin/ngserver | 0 .../@angular/language-service/dummy | 0 .../test/test-files/ant/ant-project/build.xml | 0 .../plugins/ale/test/test-files/ant/bin/ant | 0 .../ale/test/test-files/ant/bin/ant.exe | 0 .../plugins/ale/test/test-files/bazel/BUILD | 0 .../ale/test/test-files/bazel/WORKSPACE | 0 .../ale/test/test-files/bazel/defs.bzl | 0 .../plugins/ale/test/test-files/bib/dummy.bib | 0 .../build/bad_folder_to_test_priority | 0 .../build/compile_commands.json | 0 .../test-files/c/configure_project/Makefile | 0 .../test-files/c/configure_project/configure | 0 .../c/configure_project/include/test.h | 0 .../c/configure_project/subdir/Makefile | 0 .../plugins/ale/test/test-files/c/dummy.c | 0 .../c/git_and_nested_makefiles/include/test.h | 0 .../c/git_and_nested_makefiles/src/Makefile | 0 .../c/gnumakefile_project/GNUmakefile | 0 .../test-files/c/gnumakefile_project/file.c | 0 .../test/test-files/c/h_file_project/Makefile | 0 .../test-files/c/h_file_project/subdir/dummy | 0 .../test/test-files/c/h_file_project/test.h | 0 .../test-files/c/hpp_file_project/Makefile | 0 .../c/hpp_file_project/subdir/dummy | 0 .../test-files/c/hpp_file_project/test.hpp | 0 .../json_project/build/compile_commands.json | 0 .../test-files/c/json_project/include/test.h | 0 .../test-files/c/json_project/subdir/dummy | 0 .../test-files/c/makefile_project/Makefile | 0 .../test-files/c/makefile_project/_astylerc | 0 .../test/test-files/c/makefile_project/args | 3 + .../c/makefile_project/include/test.h | 0 .../test-files/c/makefile_project/subdir/args | 1 + .../c/makefile_project/subdir/dummy | 0 .../c/makefile_project/subdir/file.c | 0 .../ale/test/test-files/cargo/Cargo.toml | 0 .../cargo/workspace_paths/Cargo.toml | 0 .../cargo/workspace_paths/subpath/Cargo.toml | 0 .../compile_commands.json | 0 .../test-files/ccls/with_ccls-root/.ccls-root | 0 .../ale/test/test-files/ccls/with_ccls/.ccls | 0 .../compile_commands.json | 0 .../test-files/checkstyle/other_config.xml | 0 .../compile_commands.json | 0 .../compile_commands.json | 0 .../with_clangformat/.clang-format | 0 .../plugins/ale/test/test-files/cpp/.astylerc | 0 .../plugins/ale/test/test-files/cpp/dummy.cpp | 0 .../cppcheck/one/compile_commands.json | 0 .../test-files/cppcheck/one/two/three/file.c | 0 .../cppcheck/one/two/three/file.cpp | 0 .../build/compile_commands.json | 0 .../cquery/build/compile_commands.json | 0 .../test-files/cquery/with_cquery/.cquery | 0 .../test-files/csslint/other-app/testfile.css | 0 .../test-files/csslint/some-app/.csslintrc | 0 .../csslint/some-app/subdir/testfile.css | 0 .../test-files/cucumber/features/cuke.feature | 0 .../features/step_definitions/base_steps.rb | 0 .../plugins/ale/test/test-files/d/test.d | 0 .../ale/test/test-files/dart/.packages | 0 .../ale/test/test-files/dart/testfile.dart | 0 .../test-files/elixir/mix_project/lib/app.ex | 0 .../test-files/elixir/mix_project/mix.exs | 3 + .../ale/test/test-files/elixir/testfile.ex | 0 .../umbrella_project/apps/app1/lib/app.ex | 0 .../elixir/umbrella_project/apps/app1/mix.exs | 0 .../umbrella_project/apps/app2/lib/app.ex | 0 .../elixir/umbrella_project/apps/app2/mix.exs | 0 .../elixir/umbrella_project/mix.exs | 0 .../test-files/elm/newapp-notests/elm.json | 0 .../elm/newapp-notests/node_modules/.bin/elm | 0 .../elm/newapp-notests/tests/TestMain.elm | 0 .../ale/test/test-files/elm/newapp/elm.json | 0 .../elm/newapp/node_modules/.bin/elm | 0 .../elm/newapp/node_modules/.bin/elm-test | 0 .../test/test-files/elm/newapp/src/Main.elm | 0 .../test-files/elm/newapp/tests/TestSuite.elm | 0 .../elm/node_modules/.bin/elm-format | 0 .../test-files/elm/oldapp/elm-package.json | 0 .../elm/oldapp/node_modules/.bin/elm | 0 .../elm/oldapp/node_modules/.bin/elm-test | 0 .../test/test-files/elm/oldapp/src/Main.elm | 0 .../test-files/elm/oldapp/tests/TestSuite.elm | 0 .../test-files/elm/src/subdir/testfile.elm | 0 .../ale/test/test-files/eruby/dummy.html.erb | 0 .../node_modules/.bin/eslint_d | 0 .../eslint/node_modules/.bin/eslint | 0 .../eslint/other-app/subdir/testfile.js | 0 .../ale/test/test-files/eslint/package.json | 0 .../test-files/eslint/react-app/.eslintrc.js | 0 .../node_modules/eslint/bin/eslint.js | 0 .../node_modules/standard/bin/cmd.js | 0 .../node_modules/stylelint/bin/stylelint.js | 0 .../eslint/react-app/node_modules/xo/cli.js | 0 .../react-app/subdir-with-config/.eslintrc | 0 .../node_modules/.gitkeep | 0 .../subdir-with-package-json/package.json | 0 .../eslint/react-app/subdir/testfile.css | 0 .../eslint/react-app/subdir/testfile.js | 0 .../eslint/react-app/subdir/testfile.ts | 0 .../yarn2-app/.yarn/sdks/eslint/bin/eslint.js | 0 .../eslint/yarn2-app/subdir/testfile.js | 0 .../plugins/ale/test/test-files/fecs/fecs | 0 .../plugins/ale/test/test-files/fecs/fecs.exe | 0 .../ale/test/test-files/fish/testfile.fish | 0 .../ale/test/test-files/flow/a/.flowconfig | 0 .../ale/test/test-files/flow/a/sub/dummy | 0 .../ale/test/test-files/flow/b/sub/dummy | 0 .../test/test-files/fortls-project/.fortls | 2 + .../plugins/ale/test/test-files/go/go.mod | 1 + .../ale/test/test-files/go/go1/prj1/file.go | 0 .../ale/test/test-files/go/go2/prj2/file.go | 0 .../ale/test/test-files/go/gopath/bin/gopls | 0 .../test/test-files/go/gopath/bin/staticcheck | 0 .../ale/test/test-files/go/testfile.go | 0 .../ale/test/test-files/go/testfile2.go | 0 .../gradle/build-gradle-project/build.gradle | 0 .../src/main/kotlin/dummy.kt | 0 .../plugins/ale/test/test-files/gradle/gradle | 0 .../src/main/kotlin/dummy.kt | 0 .../settings-gradle-project/settings.gradle | 0 .../src/main/kotlin/dummy.kt | 0 .../gradle/unwrapped-project/build.gradle | 0 .../gradle/unwrapped-project/settings.gradle | 0 .../src/main/kotlin/dummy.kt | 0 .../gradle/wrapped-project/build.gradle | 0 .../test-files/gradle/wrapped-project/gradlew | 0 .../gradle/wrapped-project/settings.gradle | 0 .../wrapped-project/src/main/kotlin/dummy.kt | 0 .../haml-lint-and-rubocop/.haml-lint.yml | 0 .../haml-lint-and-rubocop/.rubocop.yml | 0 .../haml-lint-and-rubocop/subdir/file.haml | 0 .../hamllint/haml-lint-yml/.haml-lint.yml | 0 .../hamllint/haml-lint-yml/subdir/file.haml | 0 .../hamllint/rubocop-yml/.rubocop.yml | 0 .../hamllint/rubocop-yml/subdir/file.haml | 0 .../ale/test/test-files/hdl_server/foo.vhd | 0 .../with_config_file/.hdl_checker.config | 0 .../with_config_file/_hdl_checker.config | 0 .../hdl_server/with_config_file/foo.vhd | 0 .../hdl_server/with_git/files/foo.vhd | 1 + .../test-files/html_beautify/html-beautify | 0 .../test/test-files/html_beautify/test.html | 0 .../htmlhint/node_modules/.bin/htmlhint | 0 .../htmlhint/with_config/.htmlhintrc | 0 .../ale/test/test-files/ink/story/main.ink | 0 .../ale/test/test-files/inko/test.inko | 0 .../test-files/inko/tests/test/test_foo.inko | 0 .../no_main/src/test/java/com/something/dummy | 0 .../src/main/java/com/something/dummy | 0 .../src/main/jaxb/com/something/dummy | 0 .../build/gen/main/java/com/something/dummy | 0 .../build/gen2/main/java/com/something/dummy | 0 .../src/main/java/com/something/dummy | 0 .../src/test/java/com/something/dummy | 0 .../ale/test/test-files/javascript/test.js | 0 .../javascript_deno/custom_import_map.json | 3 + .../javascript_deno/import_map.json | 3 + .../test/test-files/javascript_deno/main.js | 1 + .../test-files/javascript_deno/tsconfig.json | 16 + .../ale/test/test-files/json/testfile.json | 1 + .../app-without-jsonlint/src/app.json | 0 .../jsonlint/app/node_modules/.bin/jsonlint | 0 .../test/test-files/jsonlint/app/src/app.json | 0 .../jsonlint/node_modules/jsonlint/lib/cli.js | 0 .../plugins/ale/test/test-files/julia/REQUIRE | 0 .../plugins/ale/test/test-files/julia/test.jl | 0 .../ale/test/test-files/kotlin/testfile.kt | 0 .../test-files/lessc/node_modules/.bin/lessc | 0 .../ale/test/test-files/long-line/setup.cfg | 2 + .../ale/test/test-files/lua/testfile.lua | 0 .../ale/test/test-files/markdown/testfile.md | 0 .../maven/maven-java-project/module1/mvnw | 0 .../maven/maven-java-project/module1/mvnw.cmd | 0 .../maven/maven-java-project/module1/pom.xml | 1 + .../module1/src/main/java/dummy1.java | 0 .../maven/maven-java-project/module2/pom.xml | 1 + .../module2/src/main/java/dummy2.java | 0 .../maven/maven-kotlin-project/pom.xml | 1 + .../src/main/kotlin/dummy.kt | 1 + .../plugins/ale/test/test-files/maven/mvn | 0 .../src/main/java/dummy.java | 0 .../test-files/nim/with-git/src/source.nim | 0 .../ale/test/test-files/ocaml/testfile.ml | 0 .../ale/test/test-files/ocamllsp/dune-project | 0 .../plugins/ale/test/test-files/ols/.merlin | 0 .../node_modules/.bin/ocaml-language-server | 0 .../ale/test/test-files/pascal/test.pas | 0 .../php/project-with-php-cs-fixer/test.php | 0 .../vendor/bin/php-cs-fixer | 0 .../php/project-with-phpcbf/foo/test.php | 0 .../php/project-with-phpcbf/vendor/bin/phpcbf | 0 .../php/project-without-php-cs-fixer/test.php | 0 .../php/project-without-phpcbf/foo/test.php | 0 .../php/vendor/bin/php-language-server.php | 0 .../php/with-composer/composer.json | 0 .../vendor/bin/php-language-server.php | 0 .../vendor/bin/php-language-server.php | 0 .../phpcs/project-with-phpcs/foo/test.php | 0 .../phpcs/project-with-phpcs/vendor/bin/phpcs | 0 .../phpcs/project-without-phpcs/foo/test.php | 0 .../ale/test/test-files/prettier/testfile | 0 .../ale/test/test-files/prettier/testfile.css | 0 .../ale/test/test-files/prettier/testfile.js | 0 .../test/test-files/prettier/testfile.json | 0 .../test/test-files/prettier/testfile.scss | 0 .../ale/test/test-files/prettier/testfile.ts | 0 .../prettier/with_config/.prettierrc | 0 .../prettier/with_config/testfile.js | 0 .../with_prettierignore/.prettierignore | 0 .../with_prettierignore/src/testfile.js | 0 .../test/test-files/psalm/vendor/bin/psalm | 0 .../puglint/node_modules/.bin/pug-lint | 0 .../ale/test/test-files/puglint/package.json | 0 .../puglint/puglint_rc_dir/.pug-lintrc | 0 .../puglint/puglint_rc_js_dir/.pug-lintrc.js | 0 .../puglint_rc_json_dir/.pug-lintrc.json | 0 .../ale/test/test-files/puppet/dummy.pp | 0 .../lib/puppet/types/exampletype.rb | 0 .../puppet/new-style-module/metadata.json | 0 .../new-style-module/template/template.epp | 0 .../puppet/old-style-module/manifests/init.pp | 0 .../old-style-module/templates/template.epp | 0 .../test/test-files/purescript/bower/Foo.purs | 0 .../test-files/purescript/bower/bower.json | 0 .../purescript/psc-package/Foo.purs | 0 .../purescript/psc-package/psc-package.json | 0 .../test/test-files/purescript/spago/Foo.purs | 0 .../test-files/purescript/spago/spago.dhall | 0 .../namespace_package_manifest/MANIFEST.in | 3 + .../namespace/foo/__init__.py | 0 .../namespace/foo/bar.py | 0 .../namespace/foo/__init__.py | 0 .../namespace/foo/bar.py | 0 .../namespace_package_pytest/pytest.ini | 2 + .../namespace/foo/__init__.py | 0 .../namespace/foo/bar.py | 0 .../python/namespace_package_setup/setup.cfg | 2 + .../namespace/foo/__init__.py | 0 .../namespace/foo/bar.py | 0 .../python/namespace_package_tox/tox.ini | 3 + .../no_virtualenv/subdir/foo/COMMIT_EDITMSG | 0 .../no_virtualenv/subdir/foo/__init__.py | 0 .../python/no_virtualenv/subdir/foo/bar.py | 0 .../test-files/python/pipenv/Pipfile.lock | 0 .../test/test-files/python/poetry/poetry.lock | 0 .../.pyre_configuration.local | 0 .../pyre_configuration_dir/foo/__init__.py | 0 .../python/pyre_configuration_dir/foo/bar.py | 0 .../python/python-package-project/.flake8 | 0 .../package-name/module.py | 0 .../test-files/python/with_bandit/.bandit | 0 .../with_bandit/namespace/foo/__init__.py | 0 .../python/with_bandit/namespace/foo/bar.py | 0 .../with_mypy_ini_and_pytest_ini/mypy.ini | 0 .../tests/pytest.ini | 0 .../tests/testsubfolder/my_tests.py | 0 .../dir_with_yapf_config/.style.yapf | 0 .../with_virtualenv/env/Scripts/activate | 0 .../with_virtualenv/env/Scripts/autoflake.exe | 0 .../env/Scripts/autoimport.exe | 0 .../with_virtualenv/env/Scripts/autopep8.exe | 0 .../with_virtualenv/env/Scripts/black.exe | 0 .../with_virtualenv/env/Scripts/flake8.exe | 0 .../with_virtualenv/env/Scripts/flakehell.exe | 0 .../with_virtualenv/env/Scripts/gitlint.exe | 0 .../with_virtualenv/env/Scripts/isort.exe | 0 .../with_virtualenv/env/Scripts/mypy.exe | 0 .../with_virtualenv/env/Scripts/pyflakes.exe | 0 .../with_virtualenv/env/Scripts/pylama.exe | 0 .../with_virtualenv/env/Scripts/pylint.exe | 0 .../with_virtualenv/env/Scripts/pylsp.exe | 0 .../with_virtualenv/env/Scripts/pyre.exe | 0 .../env/Scripts/reorder-python-imports.exe | 0 .../with_virtualenv/env/Scripts/vulture.exe | 0 .../with_virtualenv/env/Scripts/yamlfix.exe | 0 .../with_virtualenv/env/Scripts/yapf.exe | 0 .../python/with_virtualenv/env/bin/activate | 0 .../python/with_virtualenv/env/bin/autoflake | 0 .../python/with_virtualenv/env/bin/autoimport | 0 .../python/with_virtualenv/env/bin/autopep8 | 0 .../python/with_virtualenv/env/bin/black | 0 .../python/with_virtualenv/env/bin/flake8 | 0 .../python/with_virtualenv/env/bin/flakehell | 0 .../python/with_virtualenv/env/bin/gitlint | 0 .../python/with_virtualenv/env/bin/isort | 0 .../python/with_virtualenv/env/bin/mypy | 0 .../python/with_virtualenv/env/bin/pyflakes | 0 .../python/with_virtualenv/env/bin/pylama | 0 .../python/with_virtualenv/env/bin/pylint | 0 .../python/with_virtualenv/env/bin/pylsp | 0 .../python/with_virtualenv/env/bin/pyre | 0 .../env/bin/reorder-python-imports | 0 .../python/with_virtualenv/env/bin/vulture | 0 .../python/with_virtualenv/env/bin/yamlfix | 0 .../python/with_virtualenv/env/bin/yapf | 0 .../with_virtualenv/subdir/foo/COMMIT_EDITMSG | 0 .../with_virtualenv/subdir/foo/__init__.py | 0 .../python/with_virtualenv/subdir/foo/bar.py | 0 .../python/with_virtualenv/subdir/foo/bar.pyi | 0 .../plugins/ale/test/test-files/r/.Rprofile | 0 .../racket/many-inits/a/b/c/foo.rkt | 3 + .../racket/many-inits/a/b/c/init.rkt | 1 + .../test-files/racket/many-inits/a/b/foo.rkt | 3 + .../test-files/racket/many-inits/a/b/init.rkt | 1 + .../test-files/racket/many-inits/a/foo.rkt | 3 + .../test-files/racket/many-inits/a/init.rkt | 1 + .../test/test-files/racket/many-inits/foo.rkt | 3 + .../test-files/racket/many-inits/init.rkt | 1 + .../test-files/racket/simple-script/foo.rkt | 3 + .../test/test-files/reasonml/bsconfig.json | 0 .../ale/test/test-files/reasonml/testfile.re | 0 .../with_bin_path/node_modules/.bin/remark | 0 .../plugins/ale/test/test-files/ruby/dummy.rb | 0 .../test-files/ruby/not_a_rails_app/file.rb | 0 .../ruby/valid_rails_app/app/dummy.rb | 0 .../ruby/valid_rails_app/app/models/thing.rb | 0 .../app/views/my_great_view.html.erb | 0 .../ruby/valid_rails_app/config/dummy.rb | 0 .../ruby/valid_rails_app/db/dummy.rb | 0 .../test-files/ruby/valid_ruby_app1/Rakefile | 0 .../ruby/valid_ruby_app1/lib/file.rb | 0 .../test-files/ruby/valid_ruby_app2/Gemfile | 0 .../ruby/valid_ruby_app2/lib/file.rb | 0 .../ruby/valid_ruby_app3/.solargraph.yml | 0 .../ruby/valid_ruby_app3/lib/file.rb | 0 .../test-files/ruby/with_config/.rubocop.yml | 0 .../test-files/ruby/with_config/.standard.yml | 0 .../ale/test/test-files/rust/Cargo.toml | 0 .../ale/test/test-files/rust/testfile.rs | 0 .../with-bin/node_modules/.bin/sass-lint | 0 .../node_modules/sass-lint/bin/sass-lint.js | 0 .../ale/test/test-files/scala/dummy.scala | 0 .../scala/invalid_sbt_project/Main.scala | 0 .../scala/valid_sbt_project/Main.scala | 0 .../scala/valid_sbt_project/build.sbt | 0 .../ale/test/test-files/slimlint/.rubocop.yml | 0 .../test/test-files/slimlint/subdir/file.slim | 0 .../ale/test/test-files/smlnj/cm/foo.sml | 0 .../test/test-files/smlnj/cm/path/to/bar.sml | 0 .../ale/test/test-files/smlnj/cm/sources.cm | 0 .../ale/test/test-files/smlnj/file/qux.sml | 0 .../ale/test/test-files/solhint/Contract.sol | 0 .../solhint/node_modules/.bin/solhint | 0 .../solhint/node_modules/solhint/index.js | 0 .../ale/test/test-files/solhint/package.json | 0 .../spectral/node_modules/.bin/spectral | 0 .../ale/test/test-files/spectral/openapi.yaml | 0 .../ale/test/test-files/stack/stack.yaml | 0 .../with-bin/node_modules/.bin/standard | 0 .../with-cmd/node_modules/standard/bin/cmd.js | 0 .../stylelint/node_modules/.bin/stylelint | 0 .../test-files/swaglint/docs/swagger.yaml | 0 .../swaglint/node_modules/.bin/swaglint | 0 .../ale/test/test-files/swift/dummy.swift | 0 .../src/folder/dummy.swift | 0 .../.swift-format | 10 + .../Package.swift | 0 .../src/folder/dummy.swift | 0 .../swift/swift-package-project/Package.swift | 0 .../src/folder/dummy.swift | 0 .../Pods/SwiftLint/swiftlint | 0 .../ios/Pods/SwiftLint/swiftlint | 0 .../cocoapods/Pods/SwiftLint/swiftlint | 0 .../react-native/ios/Pods/SwiftLint/swiftlint | 0 .../ale/test/test-files/terraform/main.tf | 0 .../ale/test/test-files/tex/sample1.tex | 0 .../ale/test/test-files/tex/sample2.tex | 0 .../ale/test/test-files/tex/testfile.tex | 0 .../with_bin_path/node_modules/.bin/textlint | 0 .../node_modules/textlint/bin/textlint.js | 0 .../test/test-files/tflint/foo/.tflint.hcl | 0 .../ale/test/test-files/tflint/foo/bar.tf | 0 .../plugins/ale/test/test-files/tidy/.tidyrc | 0 .../ale/test/test-files/tidy/test.html | 0 .../plugins/ale/test/test-files/tidy/tidy | 0 .../plugins/ale/test/test-files/tidy/tidy.exe | 0 .../empty-file | 0 .../ale/test/test-files/top/example.ini | 0 .../test-files/top/middle/bottom/dummy.txt | 0 .../ale/test/test-files/tsserver/src/file1.ts | 0 .../test-files/tsserver/src/level-1/file2.ts | 0 .../tsserver/src/level-1/level-2/file3.ts | 0 .../tsserver/src/level-1/tsconfig.json | 0 .../test/test-files/tsserver/tsconfig.json | 0 .../typescript/custom_import_map.json | 0 .../test-files/typescript/import_map.json | 0 .../ale/test/test-files/typescript/test.ts | 0 .../test/test-files/typescript/tsconfig.json | 0 .../vim/invalid_vim_project/test.vim | 0 .../vim/node_modules/.bin/vim-language-server | 0 .../vim/path_with_autoload/autoload/test.vim | 0 .../vim/path_with_autoload/test.vim | 0 .../test-files/vim/path_with_initvim/init.vim | 0 .../vim/path_with_plugin/plugin/test.vim | 0 .../test-files/vim/path_with_plugin/test.vim | 0 .../test-files/vim/path_with_vimrc/.vimrc | 0 .../node_modules/write-good/bin/write-good.js | 0 .../node-modules/node_modules/.bin/write-good | 0 .../xo/monorepo/node_modules/xo/cli.js | 0 .../test/test-files/xo/monorepo/package.json | 0 .../xo/monorepo/packages/a/index.js | 0 .../xo/monorepo/packages/a/index.ts | 0 .../xo/monorepo/packages/a/package.json | 0 .../plugins/ale/test/test-files/zig/build.zig | 0 .../plugins/ale/test/test_ale_has.vader | 12 + .../plugins/ale/test/test_ale_info.vader | 777 +++++ .../ale/test/test_ale_info_to_clipboard.vader | 15 + .../ale/test/test_ale_lint_command.vader | 77 + .../ale/test/test_ale_lint_stop_command.vader | 27 + .../plugins/ale/test/test_ale_toggle.vader | 444 +++ .../plugins/ale/test/test_ale_var.vader | 24 + .../ale/test/test_alejobstarted_autocmd.vader | 46 + .../ale/test/test_alelint_autocmd.vader | 40 + .../test_ant_build_classpath_command.vader | 27 + .../ale/test/test_ant_find_project_root.vader | 35 + .../ale/test/test_autocmd_commands.vader | 238 ++ .../test/test_backwards_compatibility.vader | 19 + .../ale/test/test_balloon_messages.vader | 87 + .../ale/test/test_c_flag_parsing.vader | 689 ++++ .../test/test_checkingbuffer_autocmd.vader | 57 + .../plugins/ale/test/test_cleanup.vader | 14 + .../plugins/ale/test/test_code_action.vader | 408 +++ .../test/test_code_action_corner_cases.vader | 179 ++ .../ale/test/test_code_action_python.vader | 59 + .../plugins/ale/test/test_codefix.vader | 549 ++++ .../test/test_computed_lint_file_values.vader | 150 + .../test/test_csslint_config_detection.vader | 29 + .../ale/test/test_cursor_warnings.vader | 256 ++ .../test/test_deferred_command_string.vader | 50 + .../test_deferred_executable_string.vader | 46 + .../test/test_deno_executable_detection.vader | 20 + .../plugins/ale/test/test_disabling_ale.vader | 119 + .../test_dockerfile_hadolint_linter.vader | 90 + .../plugins/ale/test/test_env_function.vader | 8 + ...rrors_removed_after_filetype_changed.vader | 78 + .../ale/test/test_filename_mapping.vader | 62 + .../test/test_filetype_linter_defaults.vader | 79 + .../ale/test/test_filetype_mapping.vader | 29 + .../test/test_find_nearest_directory.vader | 17 + .../ale/test/test_find_references.vader | 392 +++ .../ale/test/test_floating_preview.vader | 92 + .../ale/test/test_format_command.vader | 186 ++ .../test_format_temporary_file_creation.vader | 63 + .../ale/test/test_function_arg_count.vader | 45 + .../ale/test/test_fuzzy_json_decode.vader | 29 + .../plugins/ale/test/test_get_abspath.vader | 29 + .../plugins/ale/test/test_get_loclist.vader | 31 + .../plugins/ale/test/test_getmatches.vader | 163 + .../ale/test/test_go_to_definition.vader | 593 ++++ .../test_gradle_build_classpath_command.vader | 52 + .../test/test_gradle_find_executable.vader | 37 + .../test/test_gradle_find_project_root.vader | 35 + .../ale/test/test_highlight_placement.vader | 448 +++ .../test_highlight_position_chunking.vader | 76 + .../ale/test/test_history_saving.vader | 177 ++ vim-config/plugins/ale/test/test_hover.vader | 272 ++ .../plugins/ale/test/test_hover_parsing.vader | 173 ++ .../ale/test/test_ignoring_linters.vader | 403 +++ .../plugins/ale/test/test_jq_linter.vader | 18 + .../test_jsonlint_executable_detection.vader | 45 + .../plugins/ale/test/test_line_join.vader | 84 + .../ale/test/test_lint_file_linters.vader | 317 ++ ...test_lint_on_enter_when_file_changed.vader | 84 + .../test/test_lint_on_filetype_changed.vader | 77 + .../test_linter_defintion_processing.vader | 501 +++ .../ale/test/test_linter_retrieval.vader | 190 ++ .../ale/test/test_linter_type_mapping.vader | 120 + .../ale/test/test_linting_blacklist.vader | 16 + .../test/test_linting_updates_loclist.vader | 96 + .../ale/test/test_list_formatting.vader | 188 ++ .../plugins/ale/test/test_list_opening.vader | 262 ++ .../plugins/ale/test/test_list_titles.vader | 77 + .../ale/test/test_load_all_linters.vader | 6 + .../ale/test/test_loclist_binary_search.vader | 66 + .../ale/test/test_loclist_corrections.vader | 468 +++ .../ale/test/test_loclist_jumping.vader | 121 + .../ale/test/test_loclist_sorting.vader | 43 + .../test_maven_build_classpath_command.vader | 53 + .../ale/test/test_maven_find_executable.vader | 46 + .../test/test_maven_find_project_root.vader | 28 + .../ale/test/test_nearest_file_search.vader | 15 + .../ale/test/test_nimlsp_project_root.vader | 19 + .../test/test_no_linting_on_write_quit.vader | 118 + .../ale/test/test_organize_imports.vader | 172 + .../plugins/ale/test/test_other_sources.vader | 153 + .../ale/test/test_parse_command_args.vader | 52 + .../plugins/ale/test/test_path_dirname.vader | 13 + .../plugins/ale/test/test_path_equality.vader | 82 + .../plugins/ale/test/test_path_upwards.vader | 48 + .../plugins/ale/test/test_path_uri.vader | 73 + .../ale/test/test_pattern_options.vader | 107 + .../ale/test/test_prepare_command.vader | 75 + .../ale/test/test_puppet_path_detection.vader | 22 + .../test/test_python_find_project_root.vader | 11 + .../plugins/ale/test/test_python_pipenv.vader | 19 + .../plugins/ale/test/test_python_poetry.vader | 19 + .../ale/test/test_python_traceback.vader | 79 + .../ale/test/test_python_virtualenv.vader | 12 + .../test/test_quickfix_deduplication.vader | 50 + .../ale/test/test_quitting_variable.vader | 39 + ...redundant_tsserver_rendering_avoided.vader | 178 ++ .../ale/test/test_regex_escaping.vader | 4 + vim-config/plugins/ale/test/test_rename.vader | 504 +++ .../ale/test/test_resolve_local_path.vader | 17 + ...lts_not_cleared_when_opening_loclist.vader | 30 + .../ale/test/test_sandbox_execution.vader | 103 + .../plugins/ale/test/test_semver_utils.vader | 43 + .../ale/test/test_set_list_timers.vader | 29 + ..._setting_loclist_from_another_buffer.vader | 26 + ...g_problems_found_in_previous_buffers.vader | 98 + .../ale/test/test_shell_detection.vader | 177 ++ .../test_should_do_nothing_conditions.vader | 88 + .../plugins/ale/test/test_sml_command.vader | 45 + .../ale/test/test_socket_connections.vader | 139 + .../plugins/ale/test/test_statusline.vader | 157 + .../test/test_swift_find_project_root.vader | 18 + .../plugins/ale/test/test_symbol_search.vader | 189 ++ .../test/test_temporary_file_management.vader | 146 + .../ale/test/test_tmpdir_wrapper.vader | 32 + .../test/test_vim8_processid_parsing.vader | 5 + .../ale/test/test_windows_escaping.vader | 42 + .../plugins/ale/test/test_wrap_comand.vader | 48 + .../ale/test/test_writefile_function.vader | 117 + .../test/util/test_cd_string_commands.vader | 20 + .../plugins/ale/test/v_files/testfile.v | 0 vim-config/plugins/ale/test/vimrc | 42 + 1822 files changed, 73531 insertions(+), 4962 deletions(-) delete mode 100644 vim-config/plugins/ale/.netrwhist create mode 100644 vim-config/plugins/ale/Dockerfile create mode 100644 vim-config/plugins/ale/README.md create mode 100644 vim-config/plugins/ale/ale_linters/ada/adals.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ada/gcc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ansible/ansible_lint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/apiblueprint/drafter.vim create mode 100644 vim-config/plugins/ale/ale_linters/apkbuild/apkbuild_lint.vim create mode 100644 vim-config/plugins/ale/ale_linters/apkbuild/secfixes_check.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/asciidoc/alex.vim create mode 100644 vim-config/plugins/ale/ale_linters/asciidoc/languagetool.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/asciidoc/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/asciidoc/redpen.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/asciidoc/textlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/asciidoc/vale.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/asciidoc/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/asm/gcc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/awk/gawk.vim create mode 100644 vim-config/plugins/ale/ale_linters/bats/shellcheck.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/bib/bibclean.vim create mode 100644 vim-config/plugins/ale/ale_linters/c/cc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/c/ccls.vim delete mode 100755 vim-config/plugins/ale/ale_linters/c/clang.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/c/clangd.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/c/clangtidy.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/c/cppcheck.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/c/cquery.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/c/flawfinder.vim delete mode 100755 vim-config/plugins/ale/ale_linters/c/gcc.vim create mode 100644 vim-config/plugins/ale/ale_linters/chef/cookstyle.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/chef/foodcritic.vim create mode 100644 vim-config/plugins/ale/ale_linters/clojure/clj_kondo.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/clojure/joker.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cloudformation/cfn_python_lint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cmake/cmakelint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/coffee/coffee.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/coffee/coffeelint.vim create mode 100644 vim-config/plugins/ale/ale_linters/cpp/cc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cpp/ccls.vim delete mode 100755 vim-config/plugins/ale/ale_linters/cpp/clang.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cpp/clangcheck.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cpp/clangd.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cpp/clangtidy.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cpp/clazy.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cpp/cppcheck.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cpp/cpplint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cpp/cquery.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cpp/flawfinder.vim delete mode 100755 vim-config/plugins/ale/ale_linters/cpp/gcc.vim create mode 100644 vim-config/plugins/ale/ale_linters/crystal/ameba.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/crystal/crystal.vim create mode 100644 vim-config/plugins/ale/ale_linters/cs/csc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cs/mcs.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cs/mcsc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/css/csslint.vim create mode 100644 vim-config/plugins/ale/ale_linters/css/fecs.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/css/stylelint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cucumber/cucumber.vim create mode 100644 vim-config/plugins/ale/ale_linters/cuda/clangd.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/cuda/nvcc.vim create mode 100644 vim-config/plugins/ale/ale_linters/cypher/cypher_lint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/d/dls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/d/dmd.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/dafny/dafny.vim create mode 100644 vim-config/plugins/ale/ale_linters/dart/analysis_server.vim create mode 100644 vim-config/plugins/ale/ale_linters/dart/dart_analyze.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/dart/dartanalyzer.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/dart/language_server.vim create mode 100644 vim-config/plugins/ale/ale_linters/desktop/desktop_file_validate.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/dockerfile/dockerfile_lint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/dockerfile/hadolint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/elixir/credo.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/elixir/dialyxir.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/elixir/dogma.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/elixir/elixir_ls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/elixir/mix.vim create mode 100644 vim-config/plugins/ale/ale_linters/elm/elm_ls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/elm/make.vim create mode 100644 vim-config/plugins/ale/ale_linters/erlang/dialyzer.vim create mode 100644 vim-config/plugins/ale/ale_linters/erlang/elvis.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/erlang/erlc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/erlang/syntaxerl.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/eruby/erb.vim create mode 100644 vim-config/plugins/ale/ale_linters/eruby/erblint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/eruby/erubi.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/eruby/erubis.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/eruby/ruumba.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/fish/fish.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/fortran/gcc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/fortran/language_server.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/fountain/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/fuse/fusionlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/gitcommit/gitlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/glsl/glslang.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/glsl/glslls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/bingo.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/gobuild.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/gofmt.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/golangci_lint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/golint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/gometalinter.vim create mode 100644 vim-config/plugins/ale/ale_linters/go/gopls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/gosimple.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/gotype.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/govet.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/langserver.vim create mode 100644 vim-config/plugins/ale/ale_linters/go/revive.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/go/staticcheck.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/graphql/eslint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/graphql/gqlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/hack/hack.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/hack/hhast.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/haml/hamllint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/handlebars/embertemplatelint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/haskell/cabal_ghc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/haskell/ghc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/haskell/ghc_mod.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/haskell/hdevtools.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/haskell/hie.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/haskell/hlint.vim create mode 100644 vim-config/plugins/ale/ale_linters/haskell/hls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/haskell/stack_build.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/haskell/stack_ghc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/help/alex.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/help/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/help/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/html/alex.vim create mode 100644 vim-config/plugins/ale/ale_linters/html/angular.vim create mode 100644 vim-config/plugins/ale/ale_linters/html/fecs.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/html/htmlhint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/html/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/html/stylelint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/html/tidy.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/html/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/idris/idris.vim create mode 100644 vim-config/plugins/ale/ale_linters/ink/ls.vim create mode 100644 vim-config/plugins/ale/ale_linters/inko/inko.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ispc/ispc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/java/checkstyle.vim create mode 100644 vim-config/plugins/ale/ale_linters/java/eclipselsp.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/java/javac.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/java/javalsp.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/java/pmd.vim create mode 100644 vim-config/plugins/ale/ale_linters/javascript/deno.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/javascript/eslint.vim create mode 100644 vim-config/plugins/ale/ale_linters/javascript/fecs.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/javascript/flow.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/javascript/flow_ls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/javascript/jscs.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/javascript/jshint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/javascript/standard.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/javascript/tsserver.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/javascript/xo.vim create mode 100644 vim-config/plugins/ale/ale_linters/json/eslint.vim create mode 100644 vim-config/plugins/ale/ale_linters/json/jq.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/json/jsonlint.vim create mode 100644 vim-config/plugins/ale/ale_linters/json/spectral.vim create mode 100644 vim-config/plugins/ale/ale_linters/json5/eslint.vim create mode 100644 vim-config/plugins/ale/ale_linters/jsonc/eslint.vim create mode 100644 vim-config/plugins/ale/ale_linters/jsonnet/jsonnet_lint.vim create mode 100644 vim-config/plugins/ale/ale_linters/jsonnet/jsonnetfmt.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/julia/languageserver.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/kotlin/kotlinc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/kotlin/ktlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/kotlin/languageserver.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/less/lessc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/less/stylelint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/llvm/llc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/lua/luac.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/lua/luacheck.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/mail/alex.vim create mode 100644 vim-config/plugins/ale/ale_linters/mail/languagetool.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/mail/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/mail/vale.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/make/checkmake.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/markdown/alex.vim create mode 100644 vim-config/plugins/ale/ale_linters/markdown/languagetool.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/markdown/markdownlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/markdown/mdl.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/markdown/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/markdown/redpen.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/markdown/remark_lint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/markdown/textlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/markdown/vale.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/markdown/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/matlab/mlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/mercury/mmc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/nasm/nasm.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/nim/nimcheck.vim create mode 100644 vim-config/plugins/ale/ale_linters/nim/nimlsp.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/nix/nix.vim create mode 100644 vim-config/plugins/ale/ale_linters/nix/rnix_lsp.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/nroff/alex.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/nroff/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/nroff/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/objc/ccls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/objc/clang.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/objc/clangd.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/objcpp/clang.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/objcpp/clangd.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ocaml/merlin.vim create mode 100644 vim-config/plugins/ale/ale_linters/ocaml/ocamllsp.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ocaml/ols.vim create mode 100644 vim-config/plugins/ale/ale_linters/ocamlinterface/merlin.vim create mode 100644 vim-config/plugins/ale/ale_linters/ocamlinterface/ocamllsp.vim create mode 100644 vim-config/plugins/ale/ale_linters/openapi/ibm_validator.vim create mode 100644 vim-config/plugins/ale/ale_linters/openapi/yamllint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/perl/perl.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/perl/perlcritic.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/perl6/perl6.vim create mode 100755 vim-config/plugins/ale/ale_linters/php/intelephense.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/php/langserver.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/php/phan.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/php/php.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/php/phpcs.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/php/phpmd.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/php/phpstan.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/php/psalm.vim create mode 100644 vim-config/plugins/ale/ale_linters/php/tlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/po/alex.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/po/msgfmt.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/po/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/po/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/pod/alex.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/pod/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/pod/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/pony/ponyc.vim create mode 100644 vim-config/plugins/ale/ale_linters/powershell/powershell.vim create mode 100644 vim-config/plugins/ale/ale_linters/powershell/psscriptanalyzer.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/prolog/swipl.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/proto/protoc_gen_lint.vim create mode 100644 vim-config/plugins/ale/ale_linters/proto/protolint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/pug/puglint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/puppet/languageserver.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/puppet/puppet.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/puppet/puppetlint.vim create mode 100644 vim-config/plugins/ale/ale_linters/purescript/ls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/pyrex/cython.vim create mode 100644 vim-config/plugins/ale/ale_linters/python/bandit.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/python/flake8.vim create mode 100644 vim-config/plugins/ale/ale_linters/python/flakehell.vim create mode 100644 vim-config/plugins/ale/ale_linters/python/jedils.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/python/mypy.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/python/prospector.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/python/pycodestyle.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/python/pydocstyle.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/python/pyflakes.vim create mode 100644 vim-config/plugins/ale/ale_linters/python/pylama.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/python/pylint.vim delete mode 100755 vim-config/plugins/ale/ale_linters/python/pyls.vim create mode 100644 vim-config/plugins/ale/ale_linters/python/pylsp.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/python/pyre.vim create mode 100644 vim-config/plugins/ale/ale_linters/python/pyright.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/python/vulture.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/qml/qmlfmt.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/qml/qmllint.vim create mode 100644 vim-config/plugins/ale/ale_linters/r/languageserver.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/r/lintr.vim create mode 100644 vim-config/plugins/ale/ale_linters/racket/langserver.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/racket/raco.vim create mode 100644 vim-config/plugins/ale/ale_linters/reason/ls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/reason/merlin.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/reason/ols.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/review/redpen.vim create mode 100644 vim-config/plugins/ale/ale_linters/robot/rflint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rst/alex.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rst/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rst/redpen.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rst/rstcheck.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rst/textlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rst/vale.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rst/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ruby/brakeman.vim create mode 100644 vim-config/plugins/ale/ale_linters/ruby/debride.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ruby/rails_best_practices.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ruby/reek.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ruby/rubocop.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ruby/ruby.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ruby/solargraph.vim create mode 100644 vim-config/plugins/ale/ale_linters/ruby/sorbet.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/ruby/standardrb.vim create mode 100644 vim-config/plugins/ale/ale_linters/rust/analyzer.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rust/cargo.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rust/rls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/rust/rustc.vim create mode 100644 vim-config/plugins/ale/ale_linters/salt/salt_lint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/sass/sasslint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/sass/stylelint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/scala/fsc.vim create mode 100644 vim-config/plugins/ale/ale_linters/scala/metals.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/scala/sbtserver.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/scala/scalac.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/scala/scalastyle.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/scss/sasslint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/scss/scsslint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/scss/stylelint.vim create mode 100644 vim-config/plugins/ale/ale_linters/sh/bashate.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/sh/language_server.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/sh/shell.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/sh/shellcheck.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/slim/slimlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/sml/smlnj.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/sml/smlnj_cm.vim create mode 100644 vim-config/plugins/ale/ale_linters/solidity/solc.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/solidity/solhint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/solidity/solium.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/spec/rpmlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/sql/sqlint.vim create mode 100644 vim-config/plugins/ale/ale_linters/sql/sqllint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/stylus/stylelint.vim create mode 100644 vim-config/plugins/ale/ale_linters/sugarss/stylelint.vim create mode 100644 vim-config/plugins/ale/ale_linters/svelte/svelteserver.vim create mode 100644 vim-config/plugins/ale/ale_linters/swift/appleswiftformat.vim create mode 100644 vim-config/plugins/ale/ale_linters/swift/sourcekitlsp.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/swift/swiftlint.vim create mode 100644 vim-config/plugins/ale/ale_linters/systemd/systemd_analyze.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/tcl/nagelfar.vim create mode 100644 vim-config/plugins/ale/ale_linters/terraform/terraform.vim create mode 100644 vim-config/plugins/ale/ale_linters/terraform/terraform_ls.vim create mode 100644 vim-config/plugins/ale/ale_linters/terraform/terraform_lsp.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/terraform/tflint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/testft/testlinter.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/tex/alex.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/tex/chktex.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/tex/lacheck.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/tex/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/tex/redpen.vim create mode 100644 vim-config/plugins/ale/ale_linters/tex/texlab.vim create mode 100644 vim-config/plugins/ale/ale_linters/tex/textlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/tex/vale.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/tex/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/texinfo/alex.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/texinfo/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/texinfo/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/text/alex.vim create mode 100644 vim-config/plugins/ale/ale_linters/text/languagetool.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/text/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/text/redpen.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/text/textlint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/text/vale.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/text/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/thrift/thrift.vim create mode 100644 vim-config/plugins/ale/ale_linters/thrift/thriftcheck.vim create mode 100644 vim-config/plugins/ale/ale_linters/typescript/deno.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/typescript/eslint.vim create mode 100644 vim-config/plugins/ale/ale_linters/typescript/standard.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/typescript/tslint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/typescript/tsserver.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/typescript/typecheck.vim create mode 100644 vim-config/plugins/ale/ale_linters/typescript/xo.vim create mode 100644 vim-config/plugins/ale/ale_linters/v/v.vim create mode 100644 vim-config/plugins/ale/ale_linters/vala/vala_lint.vim create mode 100644 vim-config/plugins/ale/ale_linters/verilog/hdl_checker.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/verilog/iverilog.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/verilog/verilator.vim create mode 100644 vim-config/plugins/ale/ale_linters/verilog/vlog.vim create mode 100644 vim-config/plugins/ale/ale_linters/verilog/xvlog.vim create mode 100644 vim-config/plugins/ale/ale_linters/verilog/yosys.vim create mode 100644 vim-config/plugins/ale/ale_linters/vhdl/ghdl.vim create mode 100644 vim-config/plugins/ale/ale_linters/vhdl/hdl_checker.vim create mode 100644 vim-config/plugins/ale/ale_linters/vhdl/vcom.vim create mode 100644 vim-config/plugins/ale/ale_linters/vhdl/xvhdl.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/vim/ale_custom_linting_rules.vim create mode 100644 vim-config/plugins/ale/ale_linters/vim/vimls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/vim/vint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/vue/vls.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/xhtml/alex.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/xhtml/proselint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/xhtml/writegood.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/xml/xmllint.vim create mode 100644 vim-config/plugins/ale/ale_linters/yaml/circleci.vim create mode 100644 vim-config/plugins/ale/ale_linters/yaml/spectral.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/yaml/swaglint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/yaml/yamllint.vim mode change 100755 => 100644 vim-config/plugins/ale/ale_linters/yang/yang_lsp.vim create mode 100644 vim-config/plugins/ale/ale_linters/zeek/zeek.vim create mode 100644 vim-config/plugins/ale/ale_linters/zig/zls.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale.vim create mode 100644 vim-config/plugins/ale/autoload/ale/ant.vim create mode 100644 vim-config/plugins/ale/autoload/ale/args.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/assert.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/balloon.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/c.vim create mode 100644 vim-config/plugins/ale/autoload/ale/code_action.vim create mode 100644 vim-config/plugins/ale/autoload/ale/codefix.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/command.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/completion.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/completion/python.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/cursor.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/d.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/debugging.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/definition.vim create mode 100644 vim-config/plugins/ale/autoload/ale/dhall.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/engine.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/engine/ignore.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/events.vim create mode 100644 vim-config/plugins/ale/autoload/ale/filename_mapping.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/filetypes.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fix.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fix/registry.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/appleswiftformat.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/astyle.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/autoflake.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/autoimport.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/autopep8.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/bibclean.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/black.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/brittany.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/buildifier.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/clangformat.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/clangtidy.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/cmakeformat.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/dart_format.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/dartfmt.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/deno.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/dfmt.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/dhall_format.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/dhall_freeze.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/dhall_lint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/dotnet_format.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/elm_format.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/erblint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/erlfmt.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/eslint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/fecs.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/fish_indent.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/fixjson.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/floskell.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/generic.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/generic_python.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/gnatpp.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/gofmt.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/goimports.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/golines.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/gomod.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/google_java_format.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/hackfmt.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/help.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/hfmt.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/hindent.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/hlint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/html_beautify.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/importjs.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/isort.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/jq.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/jsonnetfmt.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/ktlint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/latexindent.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/lua_format.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/luafmt.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/mix_format.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/nimpretty.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/nixfmt.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/nixpkgsfmt.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/ocamlformat.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/ocp_indent.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/ormolu.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/pandoc.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/perltidy.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/pgformatter.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/php_cs_fixer.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/phpcbf.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/prettier.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/prettier_eslint.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/prettier_standard.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/protolint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/ptop.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/puppetlint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/purs_tidy.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/purty.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/qmlfmt.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/refmt.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/remark_lint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/reorder_python_imports.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/rubocop.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/rufo.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/rustfmt.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/scalafmt.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/shfmt.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/sorbet.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/sqlfmt.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/sqlformat.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/standard.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/standardrb.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/stylelint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/styler.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/stylish_haskell.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/stylua.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/swiftformat.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/terraform.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/textlint.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/tidy.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/tslint.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/uncrustify.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/vfmt.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/xmllint.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/xo.vim create mode 100644 vim-config/plugins/ale/autoload/ale/fixers/yamlfix.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/fixers/yapf.vim create mode 100644 vim-config/plugins/ale/autoload/ale/floating_preview.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/go.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/gradle.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/gradle/init.gradle mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/alex.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/atools.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/ccls.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/cppcheck.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/cpplint.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/css.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/deno.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/elixir.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/eslint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/fecs.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/flawfinder.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/gawk.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/gcc.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/go.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/haskell.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/haskell_stack.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/hdl_checker.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/hlint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/inko.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/ktlint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/languagetool.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/markdownlint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/ocamllsp.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/ols.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/pony.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/redpen.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/ruby.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/rust.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/scala.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/sh.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/shellcheck.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/sml.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/solhint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/spectral.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/textlint.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/tslint.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/tsserver.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/unix.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/vale.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/handlers/writegood.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/xo.vim create mode 100644 vim-config/plugins/ale/autoload/ale/handlers/yamllint.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/highlight.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/history.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/hover.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/java.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/job.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/julia.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/linter.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/list.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/loclist_jumping.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/lsp.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/lsp/message.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/lsp/reset.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/lsp/response.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/lsp/tsserver_message.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/lsp_linter.vim create mode 100644 vim-config/plugins/ale/autoload/ale/lsp_window.vim create mode 100644 vim-config/plugins/ale/autoload/ale/maven.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/node.vim create mode 100644 vim-config/plugins/ale/autoload/ale/organize_imports.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/other_source.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/path.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/pattern_options.vim create mode 100644 vim-config/plugins/ale/autoload/ale/powershell.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/preview.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/python.vim create mode 100644 vim-config/plugins/ale/autoload/ale/racket.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/references.vim create mode 100644 vim-config/plugins/ale/autoload/ale/rename.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/ruby.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/semver.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/sign.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/socket.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/statusline.vim create mode 100644 vim-config/plugins/ale/autoload/ale/swift.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/symbol.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/test.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/toggle.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/uri.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/util.vim mode change 100755 => 100644 vim-config/plugins/ale/autoload/ale/virtualtext.vim create mode 100644 vim-config/plugins/ale/autoload/asyncomplete/sources/ale.vim mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-ada.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-ansible.txt create mode 100644 vim-config/plugins/ale/doc/ale-apkbuild.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-asciidoc.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-asm.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-awk.txt create mode 100644 vim-config/plugins/ale/doc/ale-bats.txt create mode 100644 vim-config/plugins/ale/doc/ale-bazel.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-bib.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-c.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-chef.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-clojure.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-cloudformation.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-cmake.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-cpp.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-cs.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-css.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-cuda.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-d.txt create mode 100644 vim-config/plugins/ale/doc/ale-dafny.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-dart.txt create mode 100644 vim-config/plugins/ale/doc/ale-desktop.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-development.txt create mode 100644 vim-config/plugins/ale/doc/ale-dhall.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-dockerfile.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-elixir.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-elm.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-erlang.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-eruby.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-fish.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-fortran.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-fountain.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-fuse.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-gitcommit.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-glsl.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-go.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-graphql.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-hack.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-handlebars.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-haskell.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-hcl.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-html.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-idris.txt create mode 100644 vim-config/plugins/ale/doc/ale-ink.txt create mode 100644 vim-config/plugins/ale/doc/ale-inko.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-ispc.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-java.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-javascript.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-json.txt create mode 100644 vim-config/plugins/ale/doc/ale-json5.txt create mode 100644 vim-config/plugins/ale/doc/ale-jsonc.txt create mode 100644 vim-config/plugins/ale/doc/ale-jsonnet.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-julia.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-kotlin.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-latex.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-less.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-llvm.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-lua.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-markdown.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-mercury.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-nasm.txt create mode 100644 vim-config/plugins/ale/doc/ale-nim.txt create mode 100644 vim-config/plugins/ale/doc/ale-nix.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-nroff.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-objc.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-objcpp.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-ocaml.txt create mode 100644 vim-config/plugins/ale/doc/ale-openapi.txt create mode 100644 vim-config/plugins/ale/doc/ale-pascal.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-pawn.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-perl.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-perl6.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-php.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-po.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-pod.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-pony.txt create mode 100644 vim-config/plugins/ale/doc/ale-powershell.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-prolog.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-proto.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-pug.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-puppet.txt create mode 100644 vim-config/plugins/ale/doc/ale-purescript.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-pyrex.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-python.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-qml.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-r.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-reasonml.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-restructuredtext.txt create mode 100644 vim-config/plugins/ale/doc/ale-robot.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-ruby.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-rust.txt create mode 100644 vim-config/plugins/ale/doc/ale-salt.tmt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-sass.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-scala.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-scss.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-sh.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-sml.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-solidity.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-spec.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-sql.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-stylus.txt create mode 100644 vim-config/plugins/ale/doc/ale-sugarss.txt create mode 100644 vim-config/plugins/ale/doc/ale-supported-languages-and-tools.txt create mode 100644 vim-config/plugins/ale/doc/ale-svelte.txt create mode 100644 vim-config/plugins/ale/doc/ale-swift.txt create mode 100644 vim-config/plugins/ale/doc/ale-systemd.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-tcl.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-terraform.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-tex.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-texinfo.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-text.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-thrift.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-typescript.txt create mode 100644 vim-config/plugins/ale/doc/ale-v.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-vala.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-verilog.txt create mode 100644 vim-config/plugins/ale/doc/ale-vhdl.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-vim-help.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-vim.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-vue.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-xhtml.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-xml.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-yaml.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale-yang.txt create mode 100644 vim-config/plugins/ale/doc/ale-zeek.txt create mode 100644 vim-config/plugins/ale/doc/ale-zig.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/ale.txt mode change 100755 => 100644 vim-config/plugins/ale/doc/tags mode change 100755 => 100644 vim-config/plugins/ale/ftplugin/ale-fix-suggest.vim mode change 100755 => 100644 vim-config/plugins/ale/ftplugin/ale-preview-selection.vim mode change 100755 => 100644 vim-config/plugins/ale/ftplugin/ale-preview.vim mode change 100755 => 100644 vim-config/plugins/ale/plugin/ale.vim create mode 100644 vim-config/plugins/ale/rplugin/python3/deoplete/sources/ale.py create mode 100755 vim-config/plugins/ale/run-tests create mode 100644 vim-config/plugins/ale/run-tests.bat create mode 100644 vim-config/plugins/ale/supported-tools.md mode change 100755 => 100644 vim-config/plugins/ale/syntax/ale-fix-suggest.vim mode change 100755 => 100644 vim-config/plugins/ale/syntax/ale-preview-selection.vim create mode 100644 vim-config/plugins/ale/test/completion/test_ale_import_command.vader create mode 100644 vim-config/plugins/ale/test/completion/test_complete_events.vader create mode 100644 vim-config/plugins/ale/test/completion/test_completion_events.vader create mode 100644 vim-config/plugins/ale/test/completion/test_completion_filtering.vader create mode 100644 vim-config/plugins/ale/test/completion/test_completion_prefixes.vader create mode 100644 vim-config/plugins/ale/test/completion/test_lsp_completion_messages.vader create mode 100644 vim-config/plugins/ale/test/completion/test_lsp_completion_parsing.vader create mode 100644 vim-config/plugins/ale/test/completion/test_omnifunc_completion.vader create mode 100644 vim-config/plugins/ale/test/completion/test_public_completion_api.vader create mode 100644 vim-config/plugins/ale/test/completion/test_tsserver_completion_parsing.vader create mode 100644 vim-config/plugins/ale/test/fix/test_ale_fix.vader create mode 100644 vim-config/plugins/ale/test/fix/test_ale_fix_aliases.vader create mode 100644 vim-config/plugins/ale/test/fix/test_ale_fix_completion.vader create mode 100644 vim-config/plugins/ale/test/fix/test_ale_fix_completion_filter.vader create mode 100644 vim-config/plugins/ale/test/fix/test_ale_fix_ignore.vader create mode 100644 vim-config/plugins/ale/test/fix/test_ale_fix_suggest.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_appleswiftformat_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_astyle_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_autoflake_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_autoimport_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_autopep8_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_bibclean_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_black_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_break_up_long_lines_python_fixer.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_brittany_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_buildifier_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_clangformat_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_clangtidy_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_cmakeformat_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_dart_format_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_dartfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_dfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_dhall_format_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_dhall_freeze_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_dhall_lint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_dotnet_format_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_elm_format_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_erblint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_erlfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_eslint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_fecs_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_fish_indent_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_fixjson_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_floskell_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_gnatpp_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_gofmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_goimports_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_golines_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_gomod_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_goofle_java_format_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_hackfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_hfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_hindent_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_hlint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_html_beautify_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_importjs_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_isort_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_jq_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_jsonnetfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_ktlint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_latexindent_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_lua_format_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_luafmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_mix_format_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_nimpretty_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_nixfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_nixpkgsfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_ocamlformat_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_ocp_indent_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_ormolu_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_pandoc_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_perltidy_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_pgformatter_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_php_cs_fixer.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_phpcbf_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_prettier_eslint_fixer.callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_prettier_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_prettier_standard_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_protolint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_ptop_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_puppetlint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_purs_tidy_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_purty_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_python_add_blank_lines_fixer.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_qmlfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_refmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_remark_lint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_reorder_python_imports_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_rubocop_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_rufo_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_rustfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_scalafmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_shfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_sorbet_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_sqlfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_sqlformat_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_standard_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_standardrb_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_stylelint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_styler_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_stylish_haskell_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_stylua_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_swiftformat_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_terraform_fmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_textlint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_tidy_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_trim_whitespace.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_tslint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_uncrustify_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_vfmt_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_vim_help_tags_alignment_fixer.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_xmllint_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_xo_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_xots_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_yamlfix_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/fixers/test_yapf_fixer_callback.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ada_gcc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_alex_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ameba_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ansible_lint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_appleswiftformat_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_asm_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_atools_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_bandit_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_bashate_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_bibclean_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_brakeman_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_cfn_python_lint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_checkmake_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_checkstyle_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_circleci_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_clang_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_clojure_clj_kondo_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_clojure_joker_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_coffeelint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_common_handlers.vader create mode 100644 vim-config/plugins/ale/test/handler/test_cookstyle_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_cppcheck_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_cpplint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_credo_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_crystal_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_csc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_cucumber_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_cuda_nvcc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_cypher_lint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_dafny_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_dart_analyze_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_dartanalyzer_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_debride_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_desktop_file_validate_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_dmd_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_dockerfile_lint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_dogma_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_drafter_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_elmmake_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_embertemplatelint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_erblint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_erlang_dialyzer_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_erlang_elvis_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_eslint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_eslint_json_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_fecs_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_fish_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_flake8_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_flakehell_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_flawfinder_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_flow_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_foodcritic_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_fortran_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_gawk_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_gcc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ghc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ghc_mod_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ghdl_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_gitlint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_glslang_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_go_generic_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_gobuild_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_golangci_lint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_gometalinter_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_hadolint.vader create mode 100644 vim-config/plugins/ale/test/handler/test_haskell_stack_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_hlint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ibm_openapi_validator_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_idris_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_inko_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ispc_ispc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_javac_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_jscs_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ktlint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_lacheck_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_languagetool_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_lessc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_llc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_luac_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_luacheck_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_markdownlint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_mcs_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_mcsc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_mdl_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_mercury_mmc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_mix_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_msgfmt_hander.vader create mode 100644 vim-config/plugins/ale/test/handler/test_mypy_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_nagelfar_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_nasm_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_nim_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_nix_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_perl6_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_perl_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_perlcritic_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_php_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_php_phan_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_php_phpmd_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_phpcs_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_phpstan_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_pmd_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_pony_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_powershell_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_prospector_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_psscriptanalyzer_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_puglint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_puppet_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_pycodestyle_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_pydocstyle_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_pyflakes_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_pylama_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_pylint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_pyrex_cython_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_qmlfmt_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_qmllint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_raco_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_rails_best_practices_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_redpen_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_reek_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_remark_lint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_rflint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_rpmlint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_rstcheck_lint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_rubocop_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_ruby_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_rust_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_salt_salt_lint.vader create mode 100644 vim-config/plugins/ale/test/handler/test_scala_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_scalastyle_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_shell_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_shellcheck_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_slim_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_sml_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_solc_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_solhint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_spectral_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_sqlint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_sqllint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_standard_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_stylelint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_swaglint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_swiftlint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_swipl_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_syntaxerl_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_systemd_analyze_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_terraform_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_textlint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_tflint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_thrift_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_thriftcheck_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_tlint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_tslint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_typecheck_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_v_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_vala_lint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_vale_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_vcom_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_verilator_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_vint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_vlog_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_vulture_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_write_good_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_xmllint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_xvhdl_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_xvlog_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_yamllint_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_yosys_handler.vader create mode 100644 vim-config/plugins/ale/test/handler/test_zeek_handler.vader create mode 100644 vim-config/plugins/ale/test/jsonnet_files/testfile.jsonnet create mode 100644 vim-config/plugins/ale/test/linter/test_ada_gcc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_adals.vader create mode 100644 vim-config/plugins/ale/test/linter/test_alex.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ameba.vader create mode 100644 vim-config/plugins/ale/test/linter/test_angular.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ansible_lint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_asciidoc_textlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_asm_gcc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_bandit.vader create mode 100644 vim-config/plugins/ale/test/linter/test_bashate.vader create mode 100644 vim-config/plugins/ale/test/linter/test_bib_bibclean.vader create mode 100644 vim-config/plugins/ale/test/linter/test_bingo.vader create mode 100644 vim-config/plugins/ale/test/linter/test_brakeman.vader create mode 100644 vim-config/plugins/ale/test/linter/test_c_cc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_c_ccls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_c_clang_tidy.vader create mode 100644 vim-config/plugins/ale/test/linter/test_c_clangd.vader create mode 100644 vim-config/plugins/ale/test/linter/test_c_cppcheck.vader create mode 100644 vim-config/plugins/ale/test/linter/test_c_cquery.vader create mode 100644 vim-config/plugins/ale/test/linter/test_c_flawfinder.vader create mode 100644 vim-config/plugins/ale/test/linter/test_c_import_paths.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cargo.vader create mode 100644 vim-config/plugins/ale/test/linter/test_checkstyle.vader create mode 100644 vim-config/plugins/ale/test/linter/test_circleci.vader create mode 100644 vim-config/plugins/ale/test/linter/test_clang_tidy.vader create mode 100644 vim-config/plugins/ale/test/linter/test_clj_kondo.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cookstyle.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cpp_cc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cpp_ccls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cpp_clangcheck.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cpp_clazy.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cpp_cppcheck.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cpp_cquery.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cpp_flawfinder.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cpplint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cs_csc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cs_mcs.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cs_mcsc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cucumber.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cuda_nvcc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_cypher_cypher_lint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_d_dls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_dart_analysis_server.vader create mode 100644 vim-config/plugins/ale/test/linter/test_dart_language_server.vader create mode 100644 vim-config/plugins/ale/test/linter/test_dartanalyzer.vader create mode 100644 vim-config/plugins/ale/test/linter/test_desktop_file_validate.vader create mode 100644 vim-config/plugins/ale/test/linter/test_dialyxir.vader create mode 100644 vim-config/plugins/ale/test/linter/test_dmd_commandline.vader create mode 100644 vim-config/plugins/ale/test/linter/test_dockerfile_lint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_dogma.vader create mode 100644 vim-config/plugins/ale/test/linter/test_eclipselsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_elixir_credo.vader create mode 100644 vim-config/plugins/ale/test/linter/test_elixir_ls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_elixir_mix.vader create mode 100644 vim-config/plugins/ale/test/linter/test_elm_ls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_elm_make.vader create mode 100644 vim-config/plugins/ale/test/linter/test_embertemplatelint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_erb.vader create mode 100644 vim-config/plugins/ale/test/linter/test_erblint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_erlang_dialyzer.vader create mode 100644 vim-config/plugins/ale/test/linter/test_erlang_elvis.vader create mode 100644 vim-config/plugins/ale/test/linter/test_erlang_erlc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_erlang_syntaxerl.vader create mode 100644 vim-config/plugins/ale/test/linter/test_erubi.vader create mode 100644 vim-config/plugins/ale/test/linter/test_erubis.vader create mode 100644 vim-config/plugins/ale/test/linter/test_eslint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_fecs.vader create mode 100644 vim-config/plugins/ale/test/linter/test_flake8.vader create mode 100644 vim-config/plugins/ale/test/linter/test_flakehell.vader create mode 100644 vim-config/plugins/ale/test/linter/test_flow.vader create mode 100644 vim-config/plugins/ale/test/linter/test_foodcritic.vader create mode 100644 vim-config/plugins/ale/test/linter/test_fortran_fortls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_fsc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_fusionlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_gawk.vader create mode 100644 vim-config/plugins/ale/test/linter/test_gfortran.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ghdl.vader create mode 100644 vim-config/plugins/ale/test/linter/test_gitlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_glslang.vader create mode 100644 vim-config/plugins/ale/test/linter/test_glslls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_gobuild.vader create mode 100644 vim-config/plugins/ale/test/linter/test_gofmt.vader create mode 100644 vim-config/plugins/ale/test/linter/test_golangci_lint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_golangserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_golint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_gometalinter.vader create mode 100644 vim-config/plugins/ale/test/linter/test_gopls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_gosimple.vader create mode 100644 vim-config/plugins/ale/test/linter/test_gotype.vader create mode 100644 vim-config/plugins/ale/test/linter/test_govet.vader create mode 100644 vim-config/plugins/ale/test/linter/test_graphql_gqlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haml_hamllint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haskell_cabal_ghc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haskell_ghc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haskell_ghc_mod.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haskell_hdevtools.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haskell_hie.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haskell_hlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haskell_hls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haskell_stack_build.vader create mode 100644 vim-config/plugins/ale/test/linter/test_haskell_stack_ghc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_hdl_checker_options.vader create mode 100644 vim-config/plugins/ale/test/linter/test_html_stylelint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_htmlhint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ibm_openapi_validator.vader create mode 100644 vim-config/plugins/ale/test/linter/test_idris.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ink_ls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_inko_inko.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ispc_ispc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_iverilog.vader create mode 100644 vim-config/plugins/ale/test/linter/test_javac.vader create mode 100644 vim-config/plugins/ale/test/linter/test_javalsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_javascript_deno_lsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_javascript_tsserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_jq.vader create mode 100644 vim-config/plugins/ale/test/linter/test_jscs.vader create mode 100644 vim-config/plugins/ale/test/linter/test_jshint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_jsonnet_lint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_jsonnetfmt.vader create mode 100644 vim-config/plugins/ale/test/linter/test_julia_languageserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_kotlin_languageserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_kotlinc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_languagetool.vader create mode 100644 vim-config/plugins/ale/test/linter/test_less_stylelint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_lessc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_lintr.vader create mode 100644 vim-config/plugins/ale/test/linter/test_llc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_luac.vader create mode 100644 vim-config/plugins/ale/test/linter/test_luacheck.vader create mode 100644 vim-config/plugins/ale/test/linter/test_markdown_markdownlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_markdown_mdl.vader create mode 100644 vim-config/plugins/ale/test/linter/test_markdown_vale.vader create mode 100644 vim-config/plugins/ale/test/linter/test_mercury_mmc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_mypy.vader create mode 100644 vim-config/plugins/ale/test/linter/test_nagelfar.vader create mode 100644 vim-config/plugins/ale/test/linter/test_nasm_nasm.vader create mode 100644 vim-config/plugins/ale/test/linter/test_nimlsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_objc_ccls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ocaml_ocamllsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ocaml_ols.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ocamlinterface_ocamllsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_perl.vader create mode 100644 vim-config/plugins/ale/test/linter/test_perl6.vader create mode 100644 vim-config/plugins/ale/test/linter/test_perlcritic.vader create mode 100644 vim-config/plugins/ale/test/linter/test_php.vader create mode 100644 vim-config/plugins/ale/test/linter/test_php_intelephense.vader create mode 100644 vim-config/plugins/ale/test/linter/test_php_langserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_phpcs.vader create mode 100644 vim-config/plugins/ale/test/linter/test_phpmd.vader create mode 100644 vim-config/plugins/ale/test/linter/test_phpstan.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pony_ponyc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_prospector.vader create mode 100644 vim-config/plugins/ale/test/linter/test_proto.vader create mode 100644 vim-config/plugins/ale/test/linter/test_protolint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_psalm.vader create mode 100644 vim-config/plugins/ale/test/linter/test_puglint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_purescript_ls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pycodestyle.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pydocstyle.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pyflakes.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pylama.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pylint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pylsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pyre.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pyrex_cython.vader create mode 100644 vim-config/plugins/ale/test/linter/test_pyright.vader create mode 100644 vim-config/plugins/ale/test/linter/test_qmlfmt.vader create mode 100644 vim-config/plugins/ale/test/linter/test_r_languageserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_racket_langserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_racket_raco.vader create mode 100644 vim-config/plugins/ale/test/linter/test_rails_best_practices.vader create mode 100644 vim-config/plugins/ale/test/linter/test_reason_ls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_reason_ols.vader create mode 100644 vim-config/plugins/ale/test/linter/test_reek.vader create mode 100644 vim-config/plugins/ale/test/linter/test_remark_lint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_revive.vader create mode 100644 vim-config/plugins/ale/test/linter/test_rflint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_rnix.vader create mode 100644 vim-config/plugins/ale/test/linter/test_rst_textlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_rubocop.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ruby.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ruby_debride.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ruby_solargraph.vader create mode 100644 vim-config/plugins/ale/test/linter/test_rust_analyzer.vader create mode 100644 vim-config/plugins/ale/test/linter/test_rust_rls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_rustc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_ruumba.vader create mode 100644 vim-config/plugins/ale/test/linter/test_sass_sasslint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_scala_metals.vader create mode 100644 vim-config/plugins/ale/test/linter/test_scala_sbtserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_scalac.vader create mode 100644 vim-config/plugins/ale/test/linter/test_scalastyle.vader create mode 100644 vim-config/plugins/ale/test/linter/test_scss_sasslint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_scss_stylelint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_shellcheck.vader create mode 100644 vim-config/plugins/ale/test/linter/test_slimlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_solc.vader create mode 100644 vim-config/plugins/ale/test/linter/test_solc_commit.vader create mode 100644 vim-config/plugins/ale/test/linter/test_solhint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_sorbet.vader create mode 100644 vim-config/plugins/ale/test/linter/test_spectral.vader create mode 100644 vim-config/plugins/ale/test/linter/test_sqllint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_standard.vader create mode 100644 vim-config/plugins/ale/test/linter/test_standardrb.vader create mode 100644 vim-config/plugins/ale/test/linter/test_standardts.vader create mode 100644 vim-config/plugins/ale/test/linter/test_staticcheck.vader create mode 100644 vim-config/plugins/ale/test/linter/test_sugarss_stylelint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_svelteserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_swaglint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_swift_appleswiftformat.vader create mode 100644 vim-config/plugins/ale/test/linter/test_swift_sourcekitlsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_swiftlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_systemd_analyze.vader create mode 100644 vim-config/plugins/ale/test/linter/test_terraform_ls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_terraform_lsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_terraform_terraform.vader create mode 100644 vim-config/plugins/ale/test/linter/test_terraform_tflint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_tex_lacheck.vader create mode 100644 vim-config/plugins/ale/test/linter/test_tex_textlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_texlab.vader create mode 100644 vim-config/plugins/ale/test/linter/test_textlint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_thrift.vader create mode 100644 vim-config/plugins/ale/test/linter/test_thriftcheck.vader create mode 100644 vim-config/plugins/ale/test/linter/test_tslint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_typescript_deno_lsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_typescript_tsserver.vader create mode 100644 vim-config/plugins/ale/test/linter/test_v_command_callback.vader create mode 100644 vim-config/plugins/ale/test/linter/test_vcom.vader create mode 100644 vim-config/plugins/ale/test/linter/test_verilator.vader create mode 100644 vim-config/plugins/ale/test/linter/test_vim_vimls.vader create mode 100644 vim-config/plugins/ale/test/linter/test_vint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_vlog.vader create mode 100644 vim-config/plugins/ale/test/linter/test_vulture.vader create mode 100644 vim-config/plugins/ale/test/linter/test_write_good.vader create mode 100644 vim-config/plugins/ale/test/linter/test_xmllint.vader create mode 100644 vim-config/plugins/ale/test/linter/test_xo.vader create mode 100644 vim-config/plugins/ale/test/linter/test_xots.vader create mode 100644 vim-config/plugins/ale/test/linter/test_xvhdl.vader create mode 100644 vim-config/plugins/ale/test/linter/test_xvlog.vader create mode 100644 vim-config/plugins/ale/test/linter/test_yang_lsp.vader create mode 100644 vim-config/plugins/ale/test/linter/test_zeek.vader create mode 100644 vim-config/plugins/ale/test/linter/test_zig_zls.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_closing_documents.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_did_save_event.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_engine_lsp_response_handling.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_handling_window_requests.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_lsp_client_messages.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_lsp_command_formatting.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_lsp_connections.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_lsp_custom_request.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_lsp_error_parsing.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_lsp_root_detection.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_lsp_startup.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_other_initialize_message_handling.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_read_lsp_diagnostics.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_reset_lsp.vader create mode 100644 vim-config/plugins/ale/test/lsp/test_update_config.vader create mode 100644 vim-config/plugins/ale/test/python/test_deoplete_source.py create mode 100755 vim-config/plugins/ale/test/script/block-padding-checker create mode 100755 vim-config/plugins/ale/test/script/check-duplicate-tags create mode 100755 vim-config/plugins/ale/test/script/check-supported-tools-tables create mode 100755 vim-config/plugins/ale/test/script/check-tag-alignment create mode 100755 vim-config/plugins/ale/test/script/check-tag-references create mode 100755 vim-config/plugins/ale/test/script/check-toc create mode 100755 vim-config/plugins/ale/test/script/custom-checks create mode 100755 vim-config/plugins/ale/test/script/custom-linting-rules create mode 100644 vim-config/plugins/ale/test/script/dumb_named_pipe_server.py create mode 100644 vim-config/plugins/ale/test/script/dumb_tcp_client.py create mode 100644 vim-config/plugins/ale/test/script/dumb_tcp_server.py create mode 100755 vim-config/plugins/ale/test/script/run-vader-tests create mode 100755 vim-config/plugins/ale/test/script/run-vint create mode 100644 vim-config/plugins/ale/test/sign/test_linting_sets_signs.vader create mode 100644 vim-config/plugins/ale/test/sign/test_sign_column_highlighting.vader create mode 100644 vim-config/plugins/ale/test/sign/test_sign_limits.vader create mode 100644 vim-config/plugins/ale/test/sign/test_sign_parsing.vader create mode 100644 vim-config/plugins/ale/test/sign/test_sign_placement.vader create mode 100644 vim-config/plugins/ale/test/smoke_test.vader create mode 100644 vim-config/plugins/ale/test/test-files/.circleci/config.yml create mode 100644 vim-config/plugins/ale/test/test-files/.gitignore create mode 100644 vim-config/plugins/ale/test/test-files/ada/testfile.adb create mode 100644 vim-config/plugins/ale/test/test-files/alex/node-modules-2/node_modules/alex/cli.js create mode 100644 vim-config/plugins/ale/test/test-files/alex/node-modules/node_modules/.bin/alex create mode 100644 vim-config/plugins/ale/test/test-files/angular/node_modules/@angular/language-server/bin/ngserver create mode 100644 vim-config/plugins/ale/test/test-files/angular/node_modules/@angular/language-service/dummy create mode 100644 vim-config/plugins/ale/test/test-files/ant/ant-project/build.xml create mode 100755 vim-config/plugins/ale/test/test-files/ant/bin/ant create mode 100755 vim-config/plugins/ale/test/test-files/ant/bin/ant.exe create mode 100644 vim-config/plugins/ale/test/test-files/bazel/BUILD create mode 100644 vim-config/plugins/ale/test/test-files/bazel/WORKSPACE create mode 100644 vim-config/plugins/ale/test/test-files/bazel/defs.bzl create mode 100644 vim-config/plugins/ale/test/test-files/bib/dummy.bib create mode 100644 vim-config/plugins/ale/test/test-files/c/build_compile_commands_project/build/bad_folder_to_test_priority create mode 100644 vim-config/plugins/ale/test/test-files/c/build_compile_commands_project/build/compile_commands.json create mode 100644 vim-config/plugins/ale/test/test-files/c/configure_project/Makefile create mode 100644 vim-config/plugins/ale/test/test-files/c/configure_project/configure create mode 100644 vim-config/plugins/ale/test/test-files/c/configure_project/include/test.h create mode 100644 vim-config/plugins/ale/test/test-files/c/configure_project/subdir/Makefile create mode 100644 vim-config/plugins/ale/test/test-files/c/dummy.c create mode 100644 vim-config/plugins/ale/test/test-files/c/git_and_nested_makefiles/include/test.h create mode 100644 vim-config/plugins/ale/test/test-files/c/git_and_nested_makefiles/src/Makefile create mode 100644 vim-config/plugins/ale/test/test-files/c/gnumakefile_project/GNUmakefile create mode 100644 vim-config/plugins/ale/test/test-files/c/gnumakefile_project/file.c create mode 100644 vim-config/plugins/ale/test/test-files/c/h_file_project/Makefile create mode 100644 vim-config/plugins/ale/test/test-files/c/h_file_project/subdir/dummy create mode 100644 vim-config/plugins/ale/test/test-files/c/h_file_project/test.h create mode 100644 vim-config/plugins/ale/test/test-files/c/hpp_file_project/Makefile create mode 100644 vim-config/plugins/ale/test/test-files/c/hpp_file_project/subdir/dummy create mode 100644 vim-config/plugins/ale/test/test-files/c/hpp_file_project/test.hpp create mode 100644 vim-config/plugins/ale/test/test-files/c/json_project/build/compile_commands.json create mode 100644 vim-config/plugins/ale/test/test-files/c/json_project/include/test.h create mode 100644 vim-config/plugins/ale/test/test-files/c/json_project/subdir/dummy create mode 100644 vim-config/plugins/ale/test/test-files/c/makefile_project/Makefile create mode 100644 vim-config/plugins/ale/test/test-files/c/makefile_project/_astylerc create mode 100644 vim-config/plugins/ale/test/test-files/c/makefile_project/args create mode 100644 vim-config/plugins/ale/test/test-files/c/makefile_project/include/test.h create mode 100644 vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/args create mode 100644 vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/dummy create mode 100644 vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/file.c create mode 100644 vim-config/plugins/ale/test/test-files/cargo/Cargo.toml create mode 100644 vim-config/plugins/ale/test/test-files/cargo/workspace_paths/Cargo.toml create mode 100644 vim-config/plugins/ale/test/test-files/cargo/workspace_paths/subpath/Cargo.toml create mode 100644 vim-config/plugins/ale/test/test-files/ccls/with_build_dir/unusual_build_dir_name/compile_commands.json create mode 100644 vim-config/plugins/ale/test/test-files/ccls/with_ccls-root/.ccls-root create mode 100644 vim-config/plugins/ale/test/test-files/ccls/with_ccls/.ccls create mode 100644 vim-config/plugins/ale/test/test-files/ccls/with_compile_commands_json/compile_commands.json create mode 100644 vim-config/plugins/ale/test/test-files/checkstyle/other_config.xml create mode 100644 vim-config/plugins/ale/test/test-files/clangd/with_build_dir/unusual_build_dir_name/compile_commands.json create mode 100644 vim-config/plugins/ale/test/test-files/clangd/with_compile_commands/compile_commands.json create mode 100644 vim-config/plugins/ale/test/test-files/clangformat/with_clangformat/.clang-format create mode 100644 vim-config/plugins/ale/test/test-files/cpp/.astylerc create mode 100644 vim-config/plugins/ale/test/test-files/cpp/dummy.cpp create mode 100644 vim-config/plugins/ale/test/test-files/cppcheck/one/compile_commands.json create mode 100644 vim-config/plugins/ale/test/test-files/cppcheck/one/two/three/file.c create mode 100644 vim-config/plugins/ale/test/test-files/cppcheck/one/two/three/file.cpp create mode 100644 vim-config/plugins/ale/test/test-files/cppcheck/with_build_dir/build/compile_commands.json create mode 100644 vim-config/plugins/ale/test/test-files/cquery/build/compile_commands.json create mode 100644 vim-config/plugins/ale/test/test-files/cquery/with_cquery/.cquery create mode 100644 vim-config/plugins/ale/test/test-files/csslint/other-app/testfile.css create mode 100644 vim-config/plugins/ale/test/test-files/csslint/some-app/.csslintrc create mode 100644 vim-config/plugins/ale/test/test-files/csslint/some-app/subdir/testfile.css create mode 100644 vim-config/plugins/ale/test/test-files/cucumber/features/cuke.feature create mode 100644 vim-config/plugins/ale/test/test-files/cucumber/features/step_definitions/base_steps.rb create mode 100644 vim-config/plugins/ale/test/test-files/d/test.d create mode 100644 vim-config/plugins/ale/test/test-files/dart/.packages create mode 100644 vim-config/plugins/ale/test/test-files/dart/testfile.dart create mode 100644 vim-config/plugins/ale/test/test-files/elixir/mix_project/lib/app.ex create mode 100644 vim-config/plugins/ale/test/test-files/elixir/mix_project/mix.exs create mode 100644 vim-config/plugins/ale/test/test-files/elixir/testfile.ex create mode 100644 vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app1/lib/app.ex create mode 100644 vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app1/mix.exs create mode 100644 vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app2/lib/app.ex create mode 100644 vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app2/mix.exs create mode 100644 vim-config/plugins/ale/test/test-files/elixir/umbrella_project/mix.exs create mode 100644 vim-config/plugins/ale/test/test-files/elm/newapp-notests/elm.json create mode 100644 vim-config/plugins/ale/test/test-files/elm/newapp-notests/node_modules/.bin/elm create mode 100644 vim-config/plugins/ale/test/test-files/elm/newapp-notests/tests/TestMain.elm create mode 100644 vim-config/plugins/ale/test/test-files/elm/newapp/elm.json create mode 100644 vim-config/plugins/ale/test/test-files/elm/newapp/node_modules/.bin/elm create mode 100644 vim-config/plugins/ale/test/test-files/elm/newapp/node_modules/.bin/elm-test create mode 100644 vim-config/plugins/ale/test/test-files/elm/newapp/src/Main.elm create mode 100644 vim-config/plugins/ale/test/test-files/elm/newapp/tests/TestSuite.elm create mode 100644 vim-config/plugins/ale/test/test-files/elm/node_modules/.bin/elm-format create mode 100644 vim-config/plugins/ale/test/test-files/elm/oldapp/elm-package.json create mode 100644 vim-config/plugins/ale/test/test-files/elm/oldapp/node_modules/.bin/elm create mode 100644 vim-config/plugins/ale/test/test-files/elm/oldapp/node_modules/.bin/elm-test create mode 100644 vim-config/plugins/ale/test/test-files/elm/oldapp/src/Main.elm create mode 100644 vim-config/plugins/ale/test/test-files/elm/oldapp/tests/TestSuite.elm create mode 100644 vim-config/plugins/ale/test/test-files/elm/src/subdir/testfile.elm create mode 100644 vim-config/plugins/ale/test/test-files/eruby/dummy.html.erb create mode 100644 vim-config/plugins/ale/test/test-files/eslint/app-with-eslint-d/node_modules/.bin/eslint_d create mode 100644 vim-config/plugins/ale/test/test-files/eslint/node_modules/.bin/eslint create mode 100644 vim-config/plugins/ale/test/test-files/eslint/other-app/subdir/testfile.js create mode 100644 vim-config/plugins/ale/test/test-files/eslint/package.json create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/.eslintrc.js create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/eslint/bin/eslint.js create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/standard/bin/cmd.js create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/stylelint/bin/stylelint.js create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/xo/cli.js create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/subdir-with-config/.eslintrc create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/subdir-with-package-json/node_modules/.gitkeep create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/subdir-with-package-json/package.json create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/subdir/testfile.css create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/subdir/testfile.js create mode 100644 vim-config/plugins/ale/test/test-files/eslint/react-app/subdir/testfile.ts create mode 100644 vim-config/plugins/ale/test/test-files/eslint/yarn2-app/.yarn/sdks/eslint/bin/eslint.js create mode 100644 vim-config/plugins/ale/test/test-files/eslint/yarn2-app/subdir/testfile.js create mode 100755 vim-config/plugins/ale/test/test-files/fecs/fecs create mode 100755 vim-config/plugins/ale/test/test-files/fecs/fecs.exe create mode 100644 vim-config/plugins/ale/test/test-files/fish/testfile.fish create mode 100644 vim-config/plugins/ale/test/test-files/flow/a/.flowconfig create mode 100644 vim-config/plugins/ale/test/test-files/flow/a/sub/dummy create mode 100644 vim-config/plugins/ale/test/test-files/flow/b/sub/dummy create mode 100644 vim-config/plugins/ale/test/test-files/fortls-project/.fortls create mode 100644 vim-config/plugins/ale/test/test-files/go/go.mod create mode 100644 vim-config/plugins/ale/test/test-files/go/go1/prj1/file.go create mode 100644 vim-config/plugins/ale/test/test-files/go/go2/prj2/file.go create mode 100644 vim-config/plugins/ale/test/test-files/go/gopath/bin/gopls create mode 100644 vim-config/plugins/ale/test/test-files/go/gopath/bin/staticcheck create mode 100644 vim-config/plugins/ale/test/test-files/go/testfile.go create mode 100644 vim-config/plugins/ale/test/test-files/go/testfile2.go create mode 100644 vim-config/plugins/ale/test/test-files/gradle/build-gradle-project/build.gradle create mode 100644 vim-config/plugins/ale/test/test-files/gradle/build-gradle-project/src/main/kotlin/dummy.kt create mode 100755 vim-config/plugins/ale/test/test-files/gradle/gradle create mode 100644 vim-config/plugins/ale/test/test-files/gradle/non-gradle-project/src/main/kotlin/dummy.kt create mode 100644 vim-config/plugins/ale/test/test-files/gradle/settings-gradle-project/settings.gradle create mode 100644 vim-config/plugins/ale/test/test-files/gradle/settings-gradle-project/src/main/kotlin/dummy.kt create mode 100644 vim-config/plugins/ale/test/test-files/gradle/unwrapped-project/build.gradle create mode 100644 vim-config/plugins/ale/test/test-files/gradle/unwrapped-project/settings.gradle create mode 100644 vim-config/plugins/ale/test/test-files/gradle/unwrapped-project/src/main/kotlin/dummy.kt create mode 100644 vim-config/plugins/ale/test/test-files/gradle/wrapped-project/build.gradle create mode 100644 vim-config/plugins/ale/test/test-files/gradle/wrapped-project/gradlew create mode 100644 vim-config/plugins/ale/test/test-files/gradle/wrapped-project/settings.gradle create mode 100644 vim-config/plugins/ale/test/test-files/gradle/wrapped-project/src/main/kotlin/dummy.kt create mode 100644 vim-config/plugins/ale/test/test-files/hamllint/haml-lint-and-rubocop/.haml-lint.yml create mode 100644 vim-config/plugins/ale/test/test-files/hamllint/haml-lint-and-rubocop/.rubocop.yml create mode 100644 vim-config/plugins/ale/test/test-files/hamllint/haml-lint-and-rubocop/subdir/file.haml create mode 100644 vim-config/plugins/ale/test/test-files/hamllint/haml-lint-yml/.haml-lint.yml create mode 100644 vim-config/plugins/ale/test/test-files/hamllint/haml-lint-yml/subdir/file.haml create mode 100644 vim-config/plugins/ale/test/test-files/hamllint/rubocop-yml/.rubocop.yml create mode 100644 vim-config/plugins/ale/test/test-files/hamllint/rubocop-yml/subdir/file.haml create mode 100644 vim-config/plugins/ale/test/test-files/hdl_server/foo.vhd create mode 100644 vim-config/plugins/ale/test/test-files/hdl_server/with_config_file/.hdl_checker.config create mode 100644 vim-config/plugins/ale/test/test-files/hdl_server/with_config_file/_hdl_checker.config create mode 100644 vim-config/plugins/ale/test/test-files/hdl_server/with_config_file/foo.vhd create mode 100644 vim-config/plugins/ale/test/test-files/hdl_server/with_git/files/foo.vhd create mode 100755 vim-config/plugins/ale/test/test-files/html_beautify/html-beautify create mode 100644 vim-config/plugins/ale/test/test-files/html_beautify/test.html create mode 100755 vim-config/plugins/ale/test/test-files/htmlhint/node_modules/.bin/htmlhint create mode 100644 vim-config/plugins/ale/test/test-files/htmlhint/with_config/.htmlhintrc create mode 100644 vim-config/plugins/ale/test/test-files/ink/story/main.ink create mode 100644 vim-config/plugins/ale/test/test-files/inko/test.inko create mode 100644 vim-config/plugins/ale/test/test-files/inko/tests/test/test_foo.inko create mode 100644 vim-config/plugins/ale/test/test-files/java/no_main/src/test/java/com/something/dummy create mode 100644 vim-config/plugins/ale/test/test-files/java/with_jaxb/src/main/java/com/something/dummy create mode 100644 vim-config/plugins/ale/test/test-files/java/with_jaxb/src/main/jaxb/com/something/dummy create mode 100644 vim-config/plugins/ale/test/test-files/java/with_main/build/gen/main/java/com/something/dummy create mode 100644 vim-config/plugins/ale/test/test-files/java/with_main/build/gen2/main/java/com/something/dummy create mode 100644 vim-config/plugins/ale/test/test-files/java/with_main/src/main/java/com/something/dummy create mode 100644 vim-config/plugins/ale/test/test-files/java/with_main/src/test/java/com/something/dummy create mode 100644 vim-config/plugins/ale/test/test-files/javascript/test.js create mode 100644 vim-config/plugins/ale/test/test-files/javascript_deno/custom_import_map.json create mode 100644 vim-config/plugins/ale/test/test-files/javascript_deno/import_map.json create mode 100644 vim-config/plugins/ale/test/test-files/javascript_deno/main.js create mode 100644 vim-config/plugins/ale/test/test-files/javascript_deno/tsconfig.json create mode 100644 vim-config/plugins/ale/test/test-files/json/testfile.json create mode 100644 vim-config/plugins/ale/test/test-files/jsonlint/app-without-jsonlint/src/app.json create mode 100644 vim-config/plugins/ale/test/test-files/jsonlint/app/node_modules/.bin/jsonlint create mode 100644 vim-config/plugins/ale/test/test-files/jsonlint/app/src/app.json create mode 100644 vim-config/plugins/ale/test/test-files/jsonlint/node_modules/jsonlint/lib/cli.js create mode 100644 vim-config/plugins/ale/test/test-files/julia/REQUIRE create mode 100644 vim-config/plugins/ale/test/test-files/julia/test.jl create mode 100644 vim-config/plugins/ale/test/test-files/kotlin/testfile.kt create mode 100755 vim-config/plugins/ale/test/test-files/lessc/node_modules/.bin/lessc create mode 100644 vim-config/plugins/ale/test/test-files/long-line/setup.cfg create mode 100644 vim-config/plugins/ale/test/test-files/lua/testfile.lua create mode 100644 vim-config/plugins/ale/test/test-files/markdown/testfile.md create mode 100755 vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/mvnw create mode 100755 vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/mvnw.cmd create mode 100644 vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/pom.xml create mode 100644 vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/src/main/java/dummy1.java create mode 100644 vim-config/plugins/ale/test/test-files/maven/maven-java-project/module2/pom.xml create mode 100644 vim-config/plugins/ale/test/test-files/maven/maven-java-project/module2/src/main/java/dummy2.java create mode 100644 vim-config/plugins/ale/test/test-files/maven/maven-kotlin-project/pom.xml create mode 100644 vim-config/plugins/ale/test/test-files/maven/maven-kotlin-project/src/main/kotlin/dummy.kt create mode 100755 vim-config/plugins/ale/test/test-files/maven/mvn create mode 100644 vim-config/plugins/ale/test/test-files/maven/non-maven-project/src/main/java/dummy.java create mode 100644 vim-config/plugins/ale/test/test-files/nim/with-git/src/source.nim create mode 100644 vim-config/plugins/ale/test/test-files/ocaml/testfile.ml create mode 100644 vim-config/plugins/ale/test/test-files/ocamllsp/dune-project create mode 100644 vim-config/plugins/ale/test/test-files/ols/.merlin create mode 100644 vim-config/plugins/ale/test/test-files/ols/node_modules/.bin/ocaml-language-server create mode 100644 vim-config/plugins/ale/test/test-files/pascal/test.pas create mode 100644 vim-config/plugins/ale/test/test-files/php/project-with-php-cs-fixer/test.php create mode 100644 vim-config/plugins/ale/test/test-files/php/project-with-php-cs-fixer/vendor/bin/php-cs-fixer create mode 100644 vim-config/plugins/ale/test/test-files/php/project-with-phpcbf/foo/test.php create mode 100644 vim-config/plugins/ale/test/test-files/php/project-with-phpcbf/vendor/bin/phpcbf create mode 100644 vim-config/plugins/ale/test/test-files/php/project-without-php-cs-fixer/test.php create mode 100644 vim-config/plugins/ale/test/test-files/php/project-without-phpcbf/foo/test.php create mode 100755 vim-config/plugins/ale/test/test-files/php/vendor/bin/php-language-server.php create mode 100644 vim-config/plugins/ale/test/test-files/php/with-composer/composer.json create mode 100755 vim-config/plugins/ale/test/test-files/php/with-composer/vendor/bin/php-language-server.php create mode 100755 vim-config/plugins/ale/test/test-files/php/with-git/vendor/bin/php-language-server.php create mode 100644 vim-config/plugins/ale/test/test-files/phpcs/project-with-phpcs/foo/test.php create mode 100644 vim-config/plugins/ale/test/test-files/phpcs/project-with-phpcs/vendor/bin/phpcs create mode 100644 vim-config/plugins/ale/test/test-files/phpcs/project-without-phpcs/foo/test.php create mode 100644 vim-config/plugins/ale/test/test-files/prettier/testfile create mode 100644 vim-config/plugins/ale/test/test-files/prettier/testfile.css create mode 100644 vim-config/plugins/ale/test/test-files/prettier/testfile.js create mode 100644 vim-config/plugins/ale/test/test-files/prettier/testfile.json create mode 100644 vim-config/plugins/ale/test/test-files/prettier/testfile.scss create mode 100644 vim-config/plugins/ale/test/test-files/prettier/testfile.ts create mode 100644 vim-config/plugins/ale/test/test-files/prettier/with_config/.prettierrc create mode 100644 vim-config/plugins/ale/test/test-files/prettier/with_config/testfile.js create mode 100644 vim-config/plugins/ale/test/test-files/prettier/with_prettierignore/.prettierignore create mode 100644 vim-config/plugins/ale/test/test-files/prettier/with_prettierignore/src/testfile.js create mode 100755 vim-config/plugins/ale/test/test-files/psalm/vendor/bin/psalm create mode 100644 vim-config/plugins/ale/test/test-files/puglint/node_modules/.bin/pug-lint create mode 100644 vim-config/plugins/ale/test/test-files/puglint/package.json create mode 100644 vim-config/plugins/ale/test/test-files/puglint/puglint_rc_dir/.pug-lintrc create mode 100644 vim-config/plugins/ale/test/test-files/puglint/puglint_rc_js_dir/.pug-lintrc.js create mode 100644 vim-config/plugins/ale/test/test-files/puglint/puglint_rc_json_dir/.pug-lintrc.json create mode 100644 vim-config/plugins/ale/test/test-files/puppet/dummy.pp create mode 100644 vim-config/plugins/ale/test/test-files/puppet/new-style-module/lib/puppet/types/exampletype.rb create mode 100644 vim-config/plugins/ale/test/test-files/puppet/new-style-module/metadata.json create mode 100644 vim-config/plugins/ale/test/test-files/puppet/new-style-module/template/template.epp create mode 100644 vim-config/plugins/ale/test/test-files/puppet/old-style-module/manifests/init.pp create mode 100644 vim-config/plugins/ale/test/test-files/puppet/old-style-module/templates/template.epp create mode 100644 vim-config/plugins/ale/test/test-files/purescript/bower/Foo.purs create mode 100644 vim-config/plugins/ale/test/test-files/purescript/bower/bower.json create mode 100644 vim-config/plugins/ale/test/test-files/purescript/psc-package/Foo.purs create mode 100644 vim-config/plugins/ale/test/test-files/purescript/psc-package/psc-package.json create mode 100644 vim-config/plugins/ale/test/test-files/purescript/spago/Foo.purs create mode 100644 vim-config/plugins/ale/test/test-files/purescript/spago/spago.dhall create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/MANIFEST.in create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/namespace/foo/__init__.py create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/namespace/foo/bar.py create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/namespace/foo/__init__.py create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/namespace/foo/bar.py create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/pytest.ini create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_setup/namespace/foo/__init__.py create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_setup/namespace/foo/bar.py create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_setup/setup.cfg create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_tox/namespace/foo/__init__.py create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_tox/namespace/foo/bar.py create mode 100644 vim-config/plugins/ale/test/test-files/python/namespace_package_tox/tox.ini create mode 100644 vim-config/plugins/ale/test/test-files/python/no_virtualenv/subdir/foo/COMMIT_EDITMSG create mode 100644 vim-config/plugins/ale/test/test-files/python/no_virtualenv/subdir/foo/__init__.py create mode 100644 vim-config/plugins/ale/test/test-files/python/no_virtualenv/subdir/foo/bar.py create mode 100644 vim-config/plugins/ale/test/test-files/python/pipenv/Pipfile.lock create mode 100644 vim-config/plugins/ale/test/test-files/python/poetry/poetry.lock create mode 100644 vim-config/plugins/ale/test/test-files/python/pyre_configuration_dir/.pyre_configuration.local create mode 100644 vim-config/plugins/ale/test/test-files/python/pyre_configuration_dir/foo/__init__.py create mode 100644 vim-config/plugins/ale/test/test-files/python/pyre_configuration_dir/foo/bar.py create mode 100644 vim-config/plugins/ale/test/test-files/python/python-package-project/.flake8 create mode 100644 vim-config/plugins/ale/test/test-files/python/python-package-project/package-name/module.py create mode 100644 vim-config/plugins/ale/test/test-files/python/with_bandit/.bandit create mode 100644 vim-config/plugins/ale/test/test-files/python/with_bandit/namespace/foo/__init__.py create mode 100644 vim-config/plugins/ale/test/test-files/python/with_bandit/namespace/foo/bar.py create mode 100644 vim-config/plugins/ale/test/test-files/python/with_mypy_ini_and_pytest_ini/mypy.ini create mode 100644 vim-config/plugins/ale/test/test-files/python/with_mypy_ini_and_pytest_ini/tests/pytest.ini create mode 100644 vim-config/plugins/ale/test/test-files/python/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py create mode 100644 vim-config/plugins/ale/test/test-files/python/with_virtualenv/dir_with_yapf_config/.style.yapf create mode 100644 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/activate create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/autoflake.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/autoimport.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/autopep8.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/black.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/flake8.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/flakehell.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/gitlint.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/isort.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/mypy.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pyflakes.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pylama.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pylint.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pylsp.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pyre.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/reorder-python-imports.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/vulture.exe create mode 100644 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/yamlfix.exe create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/yapf.exe create mode 100644 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/activate create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/autoflake create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/autoimport create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/autopep8 create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/black create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/flake8 create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/flakehell create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/gitlint create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/isort create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/mypy create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pyflakes create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pylama create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pylint create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pylsp create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pyre create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/reorder-python-imports create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/vulture create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/yamlfix create mode 100755 vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/yapf create mode 100644 vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/COMMIT_EDITMSG create mode 100644 vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/__init__.py create mode 100644 vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/bar.py create mode 100644 vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/bar.pyi create mode 100644 vim-config/plugins/ale/test/test-files/r/.Rprofile create mode 100644 vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/c/foo.rkt create mode 100644 vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/c/init.rkt create mode 100644 vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/foo.rkt create mode 100644 vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/init.rkt create mode 100644 vim-config/plugins/ale/test/test-files/racket/many-inits/a/foo.rkt create mode 100644 vim-config/plugins/ale/test/test-files/racket/many-inits/a/init.rkt create mode 100644 vim-config/plugins/ale/test/test-files/racket/many-inits/foo.rkt create mode 100644 vim-config/plugins/ale/test/test-files/racket/many-inits/init.rkt create mode 100644 vim-config/plugins/ale/test/test-files/racket/simple-script/foo.rkt create mode 100644 vim-config/plugins/ale/test/test-files/reasonml/bsconfig.json create mode 100644 vim-config/plugins/ale/test/test-files/reasonml/testfile.re create mode 100755 vim-config/plugins/ale/test/test-files/remark_lint/with_bin_path/node_modules/.bin/remark create mode 100644 vim-config/plugins/ale/test/test-files/ruby/dummy.rb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/not_a_rails_app/file.rb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/app/dummy.rb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/app/models/thing.rb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/app/views/my_great_view.html.erb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/config/dummy.rb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/db/dummy.rb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app1/Rakefile create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app1/lib/file.rb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app2/Gemfile create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app2/lib/file.rb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app3/.solargraph.yml create mode 100644 vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app3/lib/file.rb create mode 100644 vim-config/plugins/ale/test/test-files/ruby/with_config/.rubocop.yml create mode 100644 vim-config/plugins/ale/test/test-files/ruby/with_config/.standard.yml create mode 100644 vim-config/plugins/ale/test/test-files/rust/Cargo.toml create mode 100644 vim-config/plugins/ale/test/test-files/rust/testfile.rs create mode 100755 vim-config/plugins/ale/test/test-files/sasslint/with-bin/node_modules/.bin/sass-lint create mode 100755 vim-config/plugins/ale/test/test-files/sasslint/with-source/node_modules/sass-lint/bin/sass-lint.js create mode 100644 vim-config/plugins/ale/test/test-files/scala/dummy.scala create mode 100644 vim-config/plugins/ale/test/test-files/scala/invalid_sbt_project/Main.scala create mode 100644 vim-config/plugins/ale/test/test-files/scala/valid_sbt_project/Main.scala create mode 100644 vim-config/plugins/ale/test/test-files/scala/valid_sbt_project/build.sbt create mode 100644 vim-config/plugins/ale/test/test-files/slimlint/.rubocop.yml create mode 100644 vim-config/plugins/ale/test/test-files/slimlint/subdir/file.slim create mode 100644 vim-config/plugins/ale/test/test-files/smlnj/cm/foo.sml create mode 100644 vim-config/plugins/ale/test/test-files/smlnj/cm/path/to/bar.sml create mode 100644 vim-config/plugins/ale/test/test-files/smlnj/cm/sources.cm create mode 100644 vim-config/plugins/ale/test/test-files/smlnj/file/qux.sml create mode 100644 vim-config/plugins/ale/test/test-files/solhint/Contract.sol create mode 100644 vim-config/plugins/ale/test/test-files/solhint/node_modules/.bin/solhint create mode 100644 vim-config/plugins/ale/test/test-files/solhint/node_modules/solhint/index.js create mode 100644 vim-config/plugins/ale/test/test-files/solhint/package.json create mode 100644 vim-config/plugins/ale/test/test-files/spectral/node_modules/.bin/spectral create mode 100644 vim-config/plugins/ale/test/test-files/spectral/openapi.yaml create mode 100644 vim-config/plugins/ale/test/test-files/stack/stack.yaml create mode 100755 vim-config/plugins/ale/test/test-files/standard/with-bin/node_modules/.bin/standard create mode 100755 vim-config/plugins/ale/test/test-files/standard/with-cmd/node_modules/standard/bin/cmd.js create mode 100755 vim-config/plugins/ale/test/test-files/stylelint/node_modules/.bin/stylelint create mode 100644 vim-config/plugins/ale/test/test-files/swaglint/docs/swagger.yaml create mode 100644 vim-config/plugins/ale/test/test-files/swaglint/node_modules/.bin/swaglint create mode 100644 vim-config/plugins/ale/test/test-files/swift/dummy.swift create mode 100644 vim-config/plugins/ale/test/test-files/swift/non-swift-package-project/src/folder/dummy.swift create mode 100644 vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/.swift-format create mode 100644 vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/Package.swift create mode 100644 vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/src/folder/dummy.swift create mode 100644 vim-config/plugins/ale/test/test-files/swift/swift-package-project/Package.swift create mode 100644 vim-config/plugins/ale/test/test-files/swift/swift-package-project/src/folder/dummy.swift create mode 100644 vim-config/plugins/ale/test/test-files/swiftlint/cocoapods-and-react-native/Pods/SwiftLint/swiftlint create mode 100644 vim-config/plugins/ale/test/test-files/swiftlint/cocoapods-and-react-native/ios/Pods/SwiftLint/swiftlint create mode 100644 vim-config/plugins/ale/test/test-files/swiftlint/cocoapods/Pods/SwiftLint/swiftlint create mode 100644 vim-config/plugins/ale/test/test-files/swiftlint/react-native/ios/Pods/SwiftLint/swiftlint create mode 100644 vim-config/plugins/ale/test/test-files/terraform/main.tf create mode 100644 vim-config/plugins/ale/test/test-files/tex/sample1.tex create mode 100644 vim-config/plugins/ale/test/test-files/tex/sample2.tex create mode 100644 vim-config/plugins/ale/test/test-files/tex/testfile.tex create mode 100755 vim-config/plugins/ale/test/test-files/textlint/with_bin_path/node_modules/.bin/textlint create mode 100755 vim-config/plugins/ale/test/test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js create mode 100644 vim-config/plugins/ale/test/test-files/tflint/foo/.tflint.hcl create mode 100644 vim-config/plugins/ale/test/test-files/tflint/foo/bar.tf create mode 100644 vim-config/plugins/ale/test/test-files/tidy/.tidyrc create mode 100644 vim-config/plugins/ale/test/test-files/tidy/test.html create mode 100755 vim-config/plugins/ale/test/test-files/tidy/tidy create mode 100755 vim-config/plugins/ale/test/test-files/tidy/tidy.exe create mode 100644 vim-config/plugins/ale/test/test-files/top/ale-special-directory-name-dont-use-this-please/empty-file create mode 100644 vim-config/plugins/ale/test/test-files/top/example.ini create mode 100644 vim-config/plugins/ale/test/test-files/top/middle/bottom/dummy.txt create mode 100644 vim-config/plugins/ale/test/test-files/tsserver/src/file1.ts create mode 100644 vim-config/plugins/ale/test/test-files/tsserver/src/level-1/file2.ts create mode 100644 vim-config/plugins/ale/test/test-files/tsserver/src/level-1/level-2/file3.ts create mode 100644 vim-config/plugins/ale/test/test-files/tsserver/src/level-1/tsconfig.json create mode 100644 vim-config/plugins/ale/test/test-files/tsserver/tsconfig.json create mode 100644 vim-config/plugins/ale/test/test-files/typescript/custom_import_map.json create mode 100644 vim-config/plugins/ale/test/test-files/typescript/import_map.json create mode 100644 vim-config/plugins/ale/test/test-files/typescript/test.ts create mode 100644 vim-config/plugins/ale/test/test-files/typescript/tsconfig.json create mode 100644 vim-config/plugins/ale/test/test-files/vim/invalid_vim_project/test.vim create mode 100644 vim-config/plugins/ale/test/test-files/vim/node_modules/.bin/vim-language-server create mode 100644 vim-config/plugins/ale/test/test-files/vim/path_with_autoload/autoload/test.vim create mode 100644 vim-config/plugins/ale/test/test-files/vim/path_with_autoload/test.vim create mode 100644 vim-config/plugins/ale/test/test-files/vim/path_with_initvim/init.vim create mode 100644 vim-config/plugins/ale/test/test-files/vim/path_with_plugin/plugin/test.vim create mode 100644 vim-config/plugins/ale/test/test-files/vim/path_with_plugin/test.vim create mode 100644 vim-config/plugins/ale/test/test-files/vim/path_with_vimrc/.vimrc create mode 100644 vim-config/plugins/ale/test/test-files/write-good/node-modules-2/node_modules/write-good/bin/write-good.js create mode 100644 vim-config/plugins/ale/test/test-files/write-good/node-modules/node_modules/.bin/write-good create mode 100644 vim-config/plugins/ale/test/test-files/xo/monorepo/node_modules/xo/cli.js create mode 100644 vim-config/plugins/ale/test/test-files/xo/monorepo/package.json create mode 100644 vim-config/plugins/ale/test/test-files/xo/monorepo/packages/a/index.js create mode 100644 vim-config/plugins/ale/test/test-files/xo/monorepo/packages/a/index.ts create mode 100644 vim-config/plugins/ale/test/test-files/xo/monorepo/packages/a/package.json create mode 100644 vim-config/plugins/ale/test/test-files/zig/build.zig create mode 100644 vim-config/plugins/ale/test/test_ale_has.vader create mode 100644 vim-config/plugins/ale/test/test_ale_info.vader create mode 100644 vim-config/plugins/ale/test/test_ale_info_to_clipboard.vader create mode 100644 vim-config/plugins/ale/test/test_ale_lint_command.vader create mode 100644 vim-config/plugins/ale/test/test_ale_lint_stop_command.vader create mode 100644 vim-config/plugins/ale/test/test_ale_toggle.vader create mode 100644 vim-config/plugins/ale/test/test_ale_var.vader create mode 100644 vim-config/plugins/ale/test/test_alejobstarted_autocmd.vader create mode 100644 vim-config/plugins/ale/test/test_alelint_autocmd.vader create mode 100644 vim-config/plugins/ale/test/test_ant_build_classpath_command.vader create mode 100644 vim-config/plugins/ale/test/test_ant_find_project_root.vader create mode 100644 vim-config/plugins/ale/test/test_autocmd_commands.vader create mode 100644 vim-config/plugins/ale/test/test_backwards_compatibility.vader create mode 100644 vim-config/plugins/ale/test/test_balloon_messages.vader create mode 100644 vim-config/plugins/ale/test/test_c_flag_parsing.vader create mode 100644 vim-config/plugins/ale/test/test_checkingbuffer_autocmd.vader create mode 100644 vim-config/plugins/ale/test/test_cleanup.vader create mode 100644 vim-config/plugins/ale/test/test_code_action.vader create mode 100644 vim-config/plugins/ale/test/test_code_action_corner_cases.vader create mode 100644 vim-config/plugins/ale/test/test_code_action_python.vader create mode 100644 vim-config/plugins/ale/test/test_codefix.vader create mode 100644 vim-config/plugins/ale/test/test_computed_lint_file_values.vader create mode 100644 vim-config/plugins/ale/test/test_csslint_config_detection.vader create mode 100644 vim-config/plugins/ale/test/test_cursor_warnings.vader create mode 100644 vim-config/plugins/ale/test/test_deferred_command_string.vader create mode 100644 vim-config/plugins/ale/test/test_deferred_executable_string.vader create mode 100644 vim-config/plugins/ale/test/test_deno_executable_detection.vader create mode 100644 vim-config/plugins/ale/test/test_disabling_ale.vader create mode 100644 vim-config/plugins/ale/test/test_dockerfile_hadolint_linter.vader create mode 100644 vim-config/plugins/ale/test/test_env_function.vader create mode 100644 vim-config/plugins/ale/test/test_errors_removed_after_filetype_changed.vader create mode 100644 vim-config/plugins/ale/test/test_filename_mapping.vader create mode 100644 vim-config/plugins/ale/test/test_filetype_linter_defaults.vader create mode 100644 vim-config/plugins/ale/test/test_filetype_mapping.vader create mode 100644 vim-config/plugins/ale/test/test_find_nearest_directory.vader create mode 100644 vim-config/plugins/ale/test/test_find_references.vader create mode 100644 vim-config/plugins/ale/test/test_floating_preview.vader create mode 100644 vim-config/plugins/ale/test/test_format_command.vader create mode 100644 vim-config/plugins/ale/test/test_format_temporary_file_creation.vader create mode 100644 vim-config/plugins/ale/test/test_function_arg_count.vader create mode 100644 vim-config/plugins/ale/test/test_fuzzy_json_decode.vader create mode 100644 vim-config/plugins/ale/test/test_get_abspath.vader create mode 100644 vim-config/plugins/ale/test/test_get_loclist.vader create mode 100644 vim-config/plugins/ale/test/test_getmatches.vader create mode 100644 vim-config/plugins/ale/test/test_go_to_definition.vader create mode 100644 vim-config/plugins/ale/test/test_gradle_build_classpath_command.vader create mode 100644 vim-config/plugins/ale/test/test_gradle_find_executable.vader create mode 100644 vim-config/plugins/ale/test/test_gradle_find_project_root.vader create mode 100644 vim-config/plugins/ale/test/test_highlight_placement.vader create mode 100644 vim-config/plugins/ale/test/test_highlight_position_chunking.vader create mode 100644 vim-config/plugins/ale/test/test_history_saving.vader create mode 100644 vim-config/plugins/ale/test/test_hover.vader create mode 100644 vim-config/plugins/ale/test/test_hover_parsing.vader create mode 100644 vim-config/plugins/ale/test/test_ignoring_linters.vader create mode 100644 vim-config/plugins/ale/test/test_jq_linter.vader create mode 100644 vim-config/plugins/ale/test/test_jsonlint_executable_detection.vader create mode 100644 vim-config/plugins/ale/test/test_line_join.vader create mode 100644 vim-config/plugins/ale/test/test_lint_file_linters.vader create mode 100644 vim-config/plugins/ale/test/test_lint_on_enter_when_file_changed.vader create mode 100644 vim-config/plugins/ale/test/test_lint_on_filetype_changed.vader create mode 100644 vim-config/plugins/ale/test/test_linter_defintion_processing.vader create mode 100644 vim-config/plugins/ale/test/test_linter_retrieval.vader create mode 100644 vim-config/plugins/ale/test/test_linter_type_mapping.vader create mode 100644 vim-config/plugins/ale/test/test_linting_blacklist.vader create mode 100644 vim-config/plugins/ale/test/test_linting_updates_loclist.vader create mode 100644 vim-config/plugins/ale/test/test_list_formatting.vader create mode 100644 vim-config/plugins/ale/test/test_list_opening.vader create mode 100644 vim-config/plugins/ale/test/test_list_titles.vader create mode 100644 vim-config/plugins/ale/test/test_load_all_linters.vader create mode 100644 vim-config/plugins/ale/test/test_loclist_binary_search.vader create mode 100644 vim-config/plugins/ale/test/test_loclist_corrections.vader create mode 100644 vim-config/plugins/ale/test/test_loclist_jumping.vader create mode 100644 vim-config/plugins/ale/test/test_loclist_sorting.vader create mode 100644 vim-config/plugins/ale/test/test_maven_build_classpath_command.vader create mode 100644 vim-config/plugins/ale/test/test_maven_find_executable.vader create mode 100644 vim-config/plugins/ale/test/test_maven_find_project_root.vader create mode 100644 vim-config/plugins/ale/test/test_nearest_file_search.vader create mode 100644 vim-config/plugins/ale/test/test_nimlsp_project_root.vader create mode 100644 vim-config/plugins/ale/test/test_no_linting_on_write_quit.vader create mode 100644 vim-config/plugins/ale/test/test_organize_imports.vader create mode 100644 vim-config/plugins/ale/test/test_other_sources.vader create mode 100644 vim-config/plugins/ale/test/test_parse_command_args.vader create mode 100644 vim-config/plugins/ale/test/test_path_dirname.vader create mode 100644 vim-config/plugins/ale/test/test_path_equality.vader create mode 100644 vim-config/plugins/ale/test/test_path_upwards.vader create mode 100644 vim-config/plugins/ale/test/test_path_uri.vader create mode 100644 vim-config/plugins/ale/test/test_pattern_options.vader create mode 100644 vim-config/plugins/ale/test/test_prepare_command.vader create mode 100644 vim-config/plugins/ale/test/test_puppet_path_detection.vader create mode 100644 vim-config/plugins/ale/test/test_python_find_project_root.vader create mode 100644 vim-config/plugins/ale/test/test_python_pipenv.vader create mode 100644 vim-config/plugins/ale/test/test_python_poetry.vader create mode 100644 vim-config/plugins/ale/test/test_python_traceback.vader create mode 100644 vim-config/plugins/ale/test/test_python_virtualenv.vader create mode 100644 vim-config/plugins/ale/test/test_quickfix_deduplication.vader create mode 100644 vim-config/plugins/ale/test/test_quitting_variable.vader create mode 100644 vim-config/plugins/ale/test/test_redundant_tsserver_rendering_avoided.vader create mode 100644 vim-config/plugins/ale/test/test_regex_escaping.vader create mode 100644 vim-config/plugins/ale/test/test_rename.vader create mode 100644 vim-config/plugins/ale/test/test_resolve_local_path.vader create mode 100644 vim-config/plugins/ale/test/test_results_not_cleared_when_opening_loclist.vader create mode 100644 vim-config/plugins/ale/test/test_sandbox_execution.vader create mode 100644 vim-config/plugins/ale/test/test_semver_utils.vader create mode 100644 vim-config/plugins/ale/test/test_set_list_timers.vader create mode 100644 vim-config/plugins/ale/test/test_setting_loclist_from_another_buffer.vader create mode 100644 vim-config/plugins/ale/test/test_setting_problems_found_in_previous_buffers.vader create mode 100644 vim-config/plugins/ale/test/test_shell_detection.vader create mode 100644 vim-config/plugins/ale/test/test_should_do_nothing_conditions.vader create mode 100644 vim-config/plugins/ale/test/test_sml_command.vader create mode 100644 vim-config/plugins/ale/test/test_socket_connections.vader create mode 100644 vim-config/plugins/ale/test/test_statusline.vader create mode 100644 vim-config/plugins/ale/test/test_swift_find_project_root.vader create mode 100644 vim-config/plugins/ale/test/test_symbol_search.vader create mode 100644 vim-config/plugins/ale/test/test_temporary_file_management.vader create mode 100644 vim-config/plugins/ale/test/test_tmpdir_wrapper.vader create mode 100644 vim-config/plugins/ale/test/test_vim8_processid_parsing.vader create mode 100644 vim-config/plugins/ale/test/test_windows_escaping.vader create mode 100644 vim-config/plugins/ale/test/test_wrap_comand.vader create mode 100644 vim-config/plugins/ale/test/test_writefile_function.vader create mode 100644 vim-config/plugins/ale/test/util/test_cd_string_commands.vader create mode 100644 vim-config/plugins/ale/test/v_files/testfile.v create mode 100644 vim-config/plugins/ale/test/vimrc diff --git a/vim-config/configs.vim b/vim-config/configs.vim index 67883700..8734f371 100644 --- a/vim-config/configs.vim +++ b/vim-config/configs.vim @@ -232,6 +232,7 @@ augroup END "** Plugin Configs **" "********************" " Ctags +" ----- " Vim supports ctags natively, but some of the keybindings are awkward by " default. They are redefined here. Tagbar must be installed separately. set tags=./tags,tags; " where to look for tags file @@ -239,6 +240,21 @@ nnoremap ct nnoremap cT nnoremap tb :TagbarToggle +" Tagbar +" ------ +let g:tagbar_type_elm = { + \ 'kinds' : [ + \ 'f:function:0:0', + \ 'm:modules:0:0', + \ 'i:imports:1:0', + \ 't:types:1:0', + \ 'a:type aliases:0:0', + \ 'c:type constructors:0:0', + \ 'p:ports:0:0', + \ 's:functions:0:0', + \ ] + \} + " Vim-Markdown Configs " -------------------- " disable automatic folding @@ -452,7 +468,7 @@ let g:ale_echo_msg_format = '[%linter%] %s' let g:ale_lint_on_text_changed = 'never' let g:ale_lint_on_enter = 1 let g:ale_fix_on_save = 1 -let g:ale_completion_enabled = 1 +let g:ale_completion_enabled = 0 " we _do not_ want completion with ale but CoC " enable auto-completion using github.com/maralla/completor.vim let g:completor_gocode_binary = '~/code/go_src/src/github.com/nsf/gocode/' @@ -488,11 +504,11 @@ let g:ale_c_clangtidy_options = '-Wall -Wextra -std=c11 -x c' let g:ale_c_clangcheck_options = '-- -Wall -Wextra -std=c11 -x c' let g:ale_elm_ls_use_global = 1 -let g:ale_elm_ls_executable = '/usr/local/bin/elm-language-server' +let g:ale_elm_ls_executable = '/usr/bin/elm-language-server' let g:ale_elm_ls_elm_analyse_trigger = 'change' -let g:ale_elm_ls_elm_path = '/usr/local/bin/elm' -let g:ale_elm_ls_elm_format_path = '/home/daniel/.local/bin/elm-format' -let g:ale_elm_ls_elm_test_path = '/home/daniel/.local/bin/elm-test' +let g:ale_elm_ls_elm_path = '/usr/bin/elm' +let g:ale_elm_ls_elm_format_path = '/usr/bin/elm-format' +let g:ale_elm_ls_elm_test_path = '/usr/bin/elm-test' let g:ale_glsl_glslang_executable = '/usr/bin/glslangValidator' diff --git a/vim-config/plugins/ale/.netrwhist b/vim-config/plugins/ale/.netrwhist deleted file mode 100644 index b8333b82..00000000 --- a/vim-config/plugins/ale/.netrwhist +++ /dev/null @@ -1,12 +0,0 @@ -let g:netrw_dirhistmax =10 -let g:netrw_dirhistcnt =7 -let g:netrw_dirhist_7='/home/daniel/code/cc_src/opengl/tut4/src' -let g:netrw_dirhist_6='/home/daniel/code/cc_src/opengl/tut4/src/json' -let g:netrw_dirhist_5='/home/daniel/code/cc_src/sjp/.git' -let g:netrw_dirhist_4='/home/daniel/code/cc_src/sjp/.git/hooks' -let g:netrw_dirhist_3='/home/daniel/code/cc_src/sjp/.git' -let g:netrw_dirhist_2='/home/daniel/code/js_src/webgl2/webgl_ts/dist' -let g:netrw_dirhist_1='/home/daniel/dotfiles/vim-config/plugins/gruvbox/colors' -let g:netrw_dirhist_0='/home/daniel/code/cc_src/opengl/tut4/assets' -let g:netrw_dirhist_9='/home/daniel/code/cc_src/opengl/tut3' -let g:netrw_dirhist_8='/home/daniel/code/cc_src/opengl/tut4/src' diff --git a/vim-config/plugins/ale/Dockerfile b/vim-config/plugins/ale/Dockerfile new file mode 100644 index 00000000..2b626701 --- /dev/null +++ b/vim-config/plugins/ale/Dockerfile @@ -0,0 +1,28 @@ +FROM testbed/vim:20 + +RUN install_vim -tag v8.0.0027 -build \ + -tag v8.2.2401 -build \ + -tag neovim:v0.2.0 -build \ + -tag neovim:v0.4.4 -build \ + -tag neovim:v0.5.0 -build + +ENV PACKAGES="\ + bash \ + git \ + python2 \ + python3 \ + py3-pip \ + grep \ + sed \ +" +RUN apk --update add $PACKAGES && \ + rm -rf /var/cache/apk/* /tmp/* /var/tmp/* + +RUN pip install vim-vint==0.3.21 + +RUN git clone https://github.com/junegunn/vader.vim vader && \ + cd vader && git checkout c6243dd81c98350df4dec608fa972df98fa2a3af + +ARG GIT_VERSION +LABEL Version=${GIT_VERSION} +LABEL Name=w0rp/ale diff --git a/vim-config/plugins/ale/LICENSE b/vim-config/plugins/ale/LICENSE index 739ccae0..471776e4 100644 --- a/vim-config/plugins/ale/LICENSE +++ b/vim-config/plugins/ale/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2018, w0rp +Copyright (c) 2016-2020, w0rp All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/vim-config/plugins/ale/README.md b/vim-config/plugins/ale/README.md new file mode 100644 index 00000000..697f2d87 --- /dev/null +++ b/vim-config/plugins/ale/README.md @@ -0,0 +1,959 @@ +# Asynchronous Lint Engine [![GitHub Build Status](https://github.com/dense-analysis/ale/workflows/CI/badge.svg)](https://github.com/dense-analysis/ale/actions?query=event%3Apush+workflow%3ACI+branch%3Amaster++) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/dense-analysis/ale) [![Join the chat at https://gitter.im/vim-ale/Lobby](https://badges.gitter.im/vim-ale/Lobby.svg)](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + + +![ALE Logo by Mark Grealish - https://www.bhalash.com/](https://user-images.githubusercontent.com/3518142/59195920-2c339500-8b85-11e9-9c22-f6b7f69637b8.jpg) + +ALE (Asynchronous Lint Engine) is a plugin providing linting (syntax checking +and semantic errors) in NeoVim 0.2.0+ and Vim 8 while you edit your text files, +and acts as a Vim [Language Server Protocol](https://langserver.org/) client. + +A linting example with the darkspectrum color scheme in GVim. + +ALE makes use of NeoVim and Vim 8 job control functions and timers to +run linters on the contents of text buffers and return errors as +text is changed in Vim. This allows for displaying warnings and +errors in files being edited in Vim before files have been saved +back to a filesystem. + +In other words, this plugin allows you to lint while you type. + +ALE offers support for fixing code with command line tools in a non-blocking +manner with the `:ALEFix` feature, supporting tools in many languages, like +`prettier`, `eslint`, `autopep8`, and more. + +ALE acts as a "language client" to support a variety of Language Server Protocol +features, including: + +* Diagnostics (via Language Server Protocol linters) +* Go To Definition (`:ALEGoToDefinition`) +* Completion (Built in completion support, or with Deoplete) +* Finding references (`:ALEFindReferences`) +* Hover information (`:ALEHover`) +* Symbol search (`:ALESymbolSearch`) + +If you don't care about Language Server Protocol, ALE won't load any of the code +for working with it unless needed. One of ALE's general missions is that you +won't pay for the features that you don't use. + +**Help Wanted:** If you would like to help maintain this plugin by managing the +many issues and pull requests that are submitted, please send the author an +email at [dev@w0rp.com](mailto:dev@w0rp.com?subject=Helping%20with%20ALE). + +If you enjoy this plugin, feel free to contribute or check out the author's +other content at [w0rp.com](https://w0rp.com). + +## Table of Contents + +1. [Supported Languages and Tools](#supported-languages) +2. [Usage](#usage) + 1. [Linting](#usage-linting) + 2. [Fixing](#usage-fixing) + 3. [Completion](#usage-completion) + 4. [Go To Definition](#usage-go-to-definition) + 5. [Find References](#usage-find-references) + 6. [Hovering](#usage-hover) + 7. [Symbol Search](#usage-symbol-search) + 8. [Refactoring: Rename, Actions](#usage-refactoring) +3. [Installation](#installation) + 1. [Installation with Vim package management](#standard-installation) + 2. [Installation with Pathogen](#installation-with-pathogen) + 3. [Installation with Vundle](#installation-with-vundle) + 4. [Installation with Vim-Plug](#installation-with-vim-plug) +4. [Contributing](#contributing) +5. [FAQ](#faq) + 1. [How do I disable particular linters?](#faq-disable-linters) + 2. [How can I see what ALE has configured for the current file?](#faq-get-info) + 3. [How can I use ALE and coc.nvim together?](#faq-coc-nvim) + 4. [How can I keep the sign gutter open?](#faq-keep-signs) + 5. [How can I change the signs ALE uses?](#faq-change-signs) + 6. [How can I change or disable the highlights ALE uses?](#faq-change-highlights) + 7. [How can I show errors or warnings in my statusline?](#faq-statusline) + 8. [How can I show errors or warnings in my lightline?](#faq-lightline) + 9. [How can I change the format for echo messages?](#faq-echo-format) + 10. [How can I execute some code when ALE starts or stops linting?](#faq-autocmd) + 11. [How can I navigate between errors quickly?](#faq-navigation) + 12. [How can I run linters only when I save files?](#faq-lint-on-save) + 13. [How can I use the quickfix list instead of the loclist?](#faq-quickfix) + 14. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint) + 15. [How can I check Vue files with ESLint?](#faq-vue-eslint) + 16. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad) + 17. [How can I configure my C or C++ project?](#faq-c-configuration) + 18. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration) + 19. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height) + 20. [How can I run linters or fixers via Docker or a VM?](#faq-vm) + 21. [How can I change the borders for floating preview windows?](#faq-window-borders) + 22. [How can I use ALE and vim-lsp together?](#faq-vim-lsp) + + + +## 1. Supported Languages and Tools + +ALE supports a wide variety of languages and tools. See the +[full list](supported-tools.md) in the +[Supported Languages and Tools](supported-tools.md) page. + + + +## 2. Usage + + + +### 2.i Linting + +Once this plugin is installed, while editing your files in supported +languages and tools which have been correctly installed, +this plugin will send the contents of your text buffers to a variety of +programs for checking the syntax and semantics of your programs. By default, +linters will be re-run in the background to check your syntax when you open +new buffers or as you make edits to your files. + +The behavior of linting can be configured with a variety of options, +documented in [the Vim help file](doc/ale.txt). For more information on the +options ALE offers, consult `:help ale-options` for global options and `:help +ale-integration-options` for options specified to particular linters. + + + +### 2.ii Fixing + +ALE can fix files with the `ALEFix` command. Functions need to be configured +either in each buffer with a `b:ale_fixers`, or globally with `g:ale_fixers`. + +The recommended way to configure fixers is to define a List in an ftplugin file. + +```vim +" In ~/.vim/ftplugin/javascript.vim, or somewhere similar. + +" Fix files with prettier, and then ESLint. +let b:ale_fixers = ['prettier', 'eslint'] +" Equivalent to the above. +let b:ale_fixers = {'javascript': ['prettier', 'eslint']} +``` + +You can also configure your fixers from vimrc using `g:ale_fixers`, before or +after ALE has been loaded. + +A `*` in place of the filetype will apply a List of fixers to all files which +do not match some filetype in the Dictionary. + +Note that using a plain List for `g:ale_fixers` is not supported. + +```vim +" In ~/.vim/vimrc, or somewhere similar. +let g:ale_fixers = { +\ '*': ['remove_trailing_lines', 'trim_whitespace'], +\ 'javascript': ['eslint'], +\} +``` + +If you want to automatically fix files when you save them, you need to turn +a setting on in vimrc. + +```vim +" Set this variable to 1 to fix files when you save them. +let g:ale_fix_on_save = 1 +``` + +The `:ALEFixSuggest` command will suggest some supported tools for fixing code. +Both `g:ale_fixers` and `b:ale_fixers` can also accept functions, including +lambda functions, as fixers, for fixing files with custom tools. + +See `:help ale-fix` for complete information on how to fix files with ALE. + + + +### 2.iii Completion + +ALE offers some support for completion via hijacking of omnicompletion while you +type. All of ALE's completion information must come from Language Server +Protocol linters, or from `tsserver` for TypeScript. + +ALE integrates with [Deoplete](https://github.com/Shougo/deoplete.nvim) as a +completion source, named `'ale'`. You can configure Deoplete to only use ALE as +the source of completion information, or mix it with other sources. + +```vim +" Use ALE and also some plugin 'foobar' as completion sources for all code. +call deoplete#custom#option('sources', { +\ '_': ['ale', 'foobar'], +\}) +``` + +ALE also offers its own automatic completion support, which does not require any +other plugins, and can be enabled by changing a setting before ALE is loaded. + +```vim +" Enable completion where available. +" This setting must be set before ALE is loaded. +" +" You should not turn this setting on if you wish to use ALE as a completion +" source for other completion plugins, like Deoplete. +let g:ale_completion_enabled = 1 +``` + +ALE provides an omni-completion function you can use for triggering +completion manually with ``. + +```vim +set omnifunc=ale#completion#OmniFunc +``` + +ALE supports automatic imports from external modules. This behavior is disabled +by default and can be enabled by setting: + +```vim +let g:ale_completion_autoimport = 1 +``` + +See `:help ale-completion` for more information. + + + +### 2.iv Go To Definition + +ALE supports jumping to the definition of words under your cursor with the +`:ALEGoToDefinition` command using any enabled Language Server Protocol linters +and `tsserver`. + +See `:help ale-go-to-definition` for more information. + + + +### 2.v Find References + +ALE supports finding references for words under your cursor with the +`:ALEFindReferences` command using any enabled Language Server Protocol linters +and `tsserver`. + +See `:help ale-find-references` for more information. + + + +### 2.vi Hovering + +ALE supports "hover" information for printing brief information about symbols at +the cursor taken from Language Server Protocol linters and `tsserver` with the +`ALEHover` command. + +Truncated information will be displayed when the cursor rests on a symbol by +default, as long as there are no problems on the same line. + +The information can be displayed in a `balloon` tooltip in Vim or GVim by +hovering your mouse over symbols. Mouse hovering is enabled by default in GVim, +and needs to be configured for Vim 8.1+ in terminals. + +See `:help ale-hover` for more information. + + + +### 2.vii Symbol Search + +ALE supports searching for workspace symbols via Language Server Protocol +linters with the `ALESymbolSearch` command. + +Search queries can be performed to find functions, types, and more which are +similar to a given query string. + +See `:help ale-symbol-search` for more information. + + + +### 2.viii Refactoring: Rename, Actions + +ALE supports renaming symbols in symbols in code such as variables or class +names with the `ALERename` command. + +`ALECodeAction` will execute actions on the cursor or applied to a visual +range selection, such as automatically fixing errors. + +See `:help ale-refactor` for more information. + + + +## 3. Installation + +To install this plugin, you should use one of the following methods. +For Windows users, replace usage of the Unix `~/.vim` directory with +`%USERPROFILE%\vimfiles`, or another directory if you have configured +Vim differently. On Windows, your `~/.vimrc` file will be similarly +stored in `%USERPROFILE%\_vimrc`. + + + +### 3.i. Installation with Vim package management + +In Vim 8 and NeoVim, you can install plugins easily without needing to use +any other tools. Simply clone the plugin into your `pack` directory. + +#### Vim 8 on Unix + +```bash +mkdir -p ~/.vim/pack/git-plugins/start +git clone --depth 1 https://github.com/dense-analysis/ale.git ~/.vim/pack/git-plugins/start/ale +``` + +#### NeoVim on Unix + +```bash +mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start +git clone --depth 1 https://github.com/dense-analysis/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale +``` + +#### Vim 8 on Windows + +```bash +# Run these commands in the "Git for Windows" Bash terminal +mkdir -p ~/vimfiles/pack/git-plugins/start +git clone --depth 1 https://github.com/dense-analysis/ale.git ~/vimfiles/pack/git-plugins/start/ale +``` + +#### Generating Vim help files + +You can add the following line to your vimrc files to generate documentation +tags automatically, if you don't have something similar already, so you can use +the `:help` command to consult ALE's online documentation: + +```vim +" Put these lines at the very end of your vimrc file. + +" Load all plugins now. +" Plugins need to be added to runtimepath before helptags can be generated. +packloadall +" Load all of the helptags now, after plugins have been loaded. +" All messages and errors will be ignored. +silent! helptags ALL +``` + + + +### 3.ii. Installation with Pathogen + +To install this module with [Pathogen](https://github.com/tpope/vim-pathogen), +you should clone this repository to your bundle directory, and ensure +you have the line `execute pathogen#infect()` in your `~/.vimrc` file. +You can run the following commands in your terminal to do so: + +```bash +cd ~/.vim/bundle +git clone https://github.com/dense-analysis/ale.git +``` + + + +### 3.iii. Installation with Vundle + +You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.vim) +by adding the GitHub path for this repository to your `~/.vimrc`: + +```vim +Plugin 'dense-analysis/ale' +``` + +Then run the command `:PluginInstall` in Vim. + +See the Vundle documentation for more information. + + + +### 3.iiii. Installation with Vim-Plug + +You can install this plugin using [Vim-Plug](https://github.com/junegunn/vim-plug) +by adding the GitHub path for this repository to your `~/.vimrc`: + +```vim +Plug 'dense-analysis/ale' +``` + +Then run the command `:PlugInstall` in Vim. + +See the Vim-Plug documentation for more information. + + + +## 4. Contributing + +If you would like to see support for more languages and tools, please +[create an issue](https://github.com/dense-analysis/ale/issues) +or [create a pull request](https://github.com/dense-analysis/ale/pulls). +If your tool can read from stdin or you have code to suggest which is good, +support can be happily added for it. + +If you are interested in the general direction of the project, check out the +[wiki home page](https://github.com/dense-analysis/ale/wiki). The wiki includes +a Roadmap for the future, and more. + +If you'd liked to discuss the project more directly, check out the `#vim-ale` channel +on Freenode. Web chat is available [here](https://webchat.freenode.net/?channels=vim-ale). + + + +## 5. FAQ + + + +### 5.i. How do I disable particular linters? + +By default, all available tools for all supported languages will be run. If you +want to only select a subset of the tools, you can define `b:ale_linters` for a +single buffer, or `g:ale_linters` globally. + +The recommended way to configure linters is to define a List in an ftplugin +file. + +```vim +" In ~/.vim/ftplugin/javascript.vim, or somewhere similar. + +" Enable ESLint only for JavaScript. +let b:ale_linters = ['eslint'] + +" Equivalent to the above. +let b:ale_linters = {'javascript': ['eslint']} +``` + +You can also declare which linters you want to run in your vimrc file, before or +after ALE has been loaded. + +```vim +" In ~/.vim/vimrc, or somewhere similar. +let g:ale_linters = { +\ 'javascript': ['eslint'], +\} +``` + +For all languages unspecified in the dictionary, all possible linters will +be run for those languages, just as when the dictionary is not defined. +Running many linters should not typically obstruct editing in Vim, +as they will all be executed in separate processes simultaneously. + +If you don't want ALE to run anything other than what you've explicitly asked +for, you can set `g:ale_linters_explicit` to `1`. + +```vim +" Only run linters named in ale_linters settings. +let g:ale_linters_explicit = 1 +``` + +This plugin will look for linters in the [`ale_linters`](ale_linters) directory. +Each directory within corresponds to a particular filetype in Vim, and each file +in each directory corresponds to the name of a particular linter. + + + +### 5.ii. How can I see what ALE has configured for the current file? + +Run the following to see what is currently configured: + +```vim +:ALEInfo +``` + + + +### 5.iii. How can I use ALE and coc.nvim together? + +[coc.nvim](https://github.com/neoclide/coc.nvim) is a popular Vim plugin written +in TypeScript and dependent on the [npm](https://www.npmjs.com/) ecosystem for +providing full IDE features to Vim. Both ALE and coc.nvim implement +[Language Server Protocol](https://microsoft.github.io/language-server-protocol/) +(LSP) clients for supporting diagnostics (linting with a live server), and other +features like auto-completion, and others listed above. + +ALE is primarily focused on integrating with external programs through virtually +any means, provided the plugin remains almost entirely written in Vim script. +coc.nvim is primarily focused on bringing IDE features to Vim. If you want to +run external programs on your files to check for errors, and also use the most +advanced IDE features, you might want to use both plugins at the same time. + +The easiest way to get both plugins to work together is to configure coc.nvim to +send diagnostics to ALE, so ALE controls how all problems are presented to you, +and to disable all LSP features in ALE, so ALE doesn't try to provide LSP +features already provided by coc.nvim, such as auto-completion. + +1. Open your coc.nvim configuration file with `:CocConfig` and add + `"diagnostic.displayByAle": true` to your settings. +2. Add `let g:ale_disable_lsp = 1` to your vimrc file, before plugins are + loaded. + +You can also use `b:ale_disable_lsp` in your ftplugin files to enable or disable +LSP features in ALE for different filetypes. After you configure coc.nvim and +ALE this way, you can further configure how problems appear to you by using all +of the settings mentioned in ALE's help file, including how often diagnostics +are requested. See `:help ale-lint`. + +The integration between ALE and coc.nvim works using an API ALE offers for +letting any other plugin integrate with ALE. If you are interested in writing a +similar integration, see `:help ale-lint-other-sources`. + + + +### 5.iv. How can I keep the sign gutter open? + +You can keep the sign gutter open at all times by setting the +`g:ale_sign_column_always` to 1 + +```vim +let g:ale_sign_column_always = 1 +``` + + + +### 5.v. How can I change the signs ALE uses? + +Use these options to specify what text should be used for signs: + +```vim +let g:ale_sign_error = '>>' +let g:ale_sign_warning = '--' +``` + +ALE sets some background colors automatically for warnings and errors +in the sign gutter, with the names `ALEErrorSign` and `ALEWarningSign`. +These colors can be customised, or even removed completely: + +```vim +highlight clear ALEErrorSign +highlight clear ALEWarningSign +``` + + + +### 5.vi. How can I change or disable the highlights ALE uses? + +ALE's highlights problems with highlight groups which link to `SpellBad`, +`SpellCap`, `error`, and `todo` groups by default. The characters that are +highlighted depend on the linters being used, and the information provided to +ALE. + +Highlighting can be disabled completely by setting `g:ale_set_highlights` to +`0`. + +```vim +" Set this in your vimrc file to disabling highlighting +let g:ale_set_highlights = 0 +``` + +You can control all of the highlights ALE uses, say if you are using a different +color scheme which produces ugly highlights. For example: + +```vim +highlight ALEWarning ctermbg=DarkMagenta +``` + +See `:help ale-highlights` for more information. + + + +### 5.vii. How can I show errors or warnings in my statusline? + +[vim-airline](https://github.com/vim-airline/vim-airline) integrates with ALE +for displaying error information in the status bar. If you want to see the +status for ALE in a nice format, it is recommended to use vim-airline with ALE. +The airline extension can be enabled by adding the following to your vimrc: + +```vim +" Set this. Airline will handle the rest. +let g:airline#extensions#ale#enabled = 1 +``` + +If you don't want to use vim-airline, you can implement your own statusline +function without adding any other plugins. ALE provides some functions to +assist in this endeavour, including: + +* `ale#statusline#Count`: Which returns the number of problems found by ALE + for a specified buffer. +* `ale#statusline#FirstProblem`: Which returns a dictionary containing the + full loclist details of the first problem of a specified type found by ALE + in a buffer. (e.g. The first style warning in the current buffer.) + This can be useful for displaying more detailed information such as the + line number of the first problem in a file. + +Say you want to display all errors as one figure, and all non-errors as another +figure. You can do the following: + +```vim +function! LinterStatus() abort + let l:counts = ale#statusline#Count(bufnr('')) + + let l:all_errors = l:counts.error + l:counts.style_error + let l:all_non_errors = l:counts.total - l:all_errors + + return l:counts.total == 0 ? 'OK' : printf( + \ '%dW %dE', + \ all_non_errors, + \ all_errors + \) +endfunction + +set statusline=%{LinterStatus()} +``` + +See `:help ale#statusline#Count()` or `:help ale#statusline#FirstProblem()` +for more information. + + + +### 5.viii. How can I show errors or warnings in my lightline? + +[lightline](https://github.com/itchyny/lightline.vim) does not have built-in +support for ALE, nevertheless there is a plugin that adds this functionality: [maximbaz/lightline-ale](https://github.com/maximbaz/lightline-ale). + +For more information, check out the sources of that plugin, `:help ale#statusline#Count()` and [lightline documentation](https://github.com/itchyny/lightline.vim#advanced-configuration). + + + +### 5.ix. How can I change the format for echo messages? + +There are 3 global options that allow customizing the echoed message. + +- `g:ale_echo_msg_format` where: + * `%s` is the error message itself + * `%...code...%` is an optional error code, and most characters can be + written between the `%` characters. + * `%linter%` is the linter name + * `%severity%` is the severity type +- `g:ale_echo_msg_error_str` is the string used for error severity. +- `g:ale_echo_msg_warning_str` is the string used for warning severity. + +So for example this: + +```vim +let g:ale_echo_msg_error_str = 'E' +let g:ale_echo_msg_warning_str = 'W' +let g:ale_echo_msg_format = '[%linter%] %s [%severity%]' +``` + +Will give you: + +![Echoed message](https://user-images.githubusercontent.com/3518142/59195927-348bd000-8b85-11e9-88b6-508a094f1548.png) + +See `:help g:ale_echo_msg_format` for more information. + + + +### 5.x. How can I execute some code when ALE starts or stops linting? + +ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html) +events when a lint or fix cycle are started and stopped. There is also an event +that runs when a linter job has been successfully started. These events can be +used to call arbitrary functions during these respective parts of the ALE's +operation. + +```vim +augroup YourGroup + autocmd! + autocmd User ALELintPre call YourFunction() + autocmd User ALELintPost call YourFunction() + + autocmd User ALEJobStarted call YourFunction() + + autocmd User ALEFixPre call YourFunction() + autocmd User ALEFixPost call YourFunction() +augroup END +``` + + + +### 5.xi. How can I navigate between errors quickly? + +ALE offers some commands with `` keybinds for moving between warnings and +errors quickly. You can map the keys Ctrl+j and Ctrl+k to moving between errors +for example: + +```vim +nmap (ale_previous_wrap) +nmap (ale_next_wrap) +``` + +For more information, consult the online documentation with +`:help ale-navigation-commands`. + + + +### 5.xii. How can I run linters only when I save files? + +ALE offers an option `g:ale_lint_on_save` for enabling running the linters +when files are saved. This option is enabled by default. If you only +wish to run linters when files are saved, you can turn the other +options off. + +```vim +" Write this in your vimrc file +let g:ale_lint_on_text_changed = 'never' +let g:ale_lint_on_insert_leave = 0 +" You can disable this option too +" if you don't want linters to run on opening a file +let g:ale_lint_on_enter = 0 +``` + +If for whatever reason you don't wish to run linters again when you save +files, you can set `g:ale_lint_on_save` to `0`. + + + +### 5.xiii. How can I use the quickfix list instead of the loclist? + +The quickfix list can be enabled by turning the `g:ale_set_quickfix` +option on. If you wish to also disable the loclist, you can disable +the `g:ale_set_loclist` option. + +```vim +" Write this in your vimrc file +let g:ale_set_loclist = 0 +let g:ale_set_quickfix = 1 +``` + +If you wish to show Vim windows for the loclist or quickfix items +when a file contains warnings or errors, `g:ale_open_list` can be +set to `1`. `g:ale_keep_list_window_open` can be set to `1` +if you wish to keep the window open even after errors disappear. + +```vim +let g:ale_open_list = 1 +" Set this if you want to. +" This can be useful if you are combining ALE with +" some other plugin which sets quickfix errors, etc. +let g:ale_keep_list_window_open = 1 +``` + +You can also set `let g:ale_list_vertical = 1` to open the windows vertically +instead of the default horizontally. + + + +### 5.xiv. How can I check JSX files with both stylelint and eslint? + +If you configure ALE options correctly in your vimrc file, and install +the right tools, you can check JSX files with stylelint and eslint. + +First, install eslint and install stylelint with +[stylelint-processor-styled-components](https://github.com/styled-components/stylelint-processor-styled-components). + +Supposing you have installed both tools correctly, configure your .jsx files so +`jsx` is included in the filetype. You can use an `autocmd` for this. + +```vim +augroup FiletypeGroup + autocmd! + au BufNewFile,BufRead *.jsx set filetype=javascript.jsx +augroup END +``` + +Supposing the filetype has been set correctly, you can set the following +options in a jsx.vim ftplugin file. + +```vim +" In ~/.vim/ftplugin/jsx.vim, or somewhere similar. +let b:ale_linter_aliases = ['css', 'javascript'] +let b:ale_linters = ['stylelint', 'eslint'] +``` + +Or if you want, you can configure the linters from your vimrc file. + +```vim +" In ~/.vim/vimrc, or somewhere similar. +let g:ale_linter_aliases = {'jsx': ['css', 'javascript']} +let g:ale_linters = {'jsx': ['stylelint', 'eslint']} +``` + +ALE will alias the `jsx` filetype so it uses the `css` filetype linters, and +use the original Array of selected linters for `jsx` from the `g:ale_linters` +object. All available linters will be used for the filetype `javascript`, and +no linter will be run twice for the same file. + + + +### 5.xv. How can I check Vue files with ESLint? + +To check Vue files with ESLint, your ESLint project configuration file must be +configured to use the [Vue plugin](https://github.com/vuejs/eslint-plugin-vue). +After that, you need to configure ALE so it will run the JavaScript ESLint +linter on your files. The settings you need are similar to the settings needed +for checking JSX code with both stylelint and ESLint, in the previous section. + +```vim +" In ~/.vim/ftplugin/vue.vim, or somewhere similar. + +" Run both javascript and vue linters for vue files. +let b:ale_linter_aliases = ['javascript', 'vue'] +" Select the eslint and vls linters. +let b:ale_linters = ['eslint', 'vls'] +``` + +Run `:ALEInfo` to see which linters are available after telling ALE to run +JavaScript linters on Vue files. Not all linters support checking Vue files. + +If you don't want to configure your linters in ftplugin files for some reason, +you can configure them from your vimrc file instead. + +```vim +" In ~/.vim/vimrc, or somewhere similar. +let g:ale_linter_aliases = {'vue': ['vue', 'javascript']} +let g:ale_linters = {'vue': ['eslint', 'vls']} +``` + + + +### 5.xvi. Will this plugin eat all of my laptop battery power? + +ALE takes advantage of the power of various tools to check your code. This of +course means that CPU time will be used to continuously check your code. If you +are concerned about the CPU time ALE will spend, which will of course imply +some cost to battery life, you can adjust your settings to make your CPU do +less work. + +First, consider increasing the delay before which ALE will run any linters +while you type. ALE uses a timeout which is cancelled and reset every time you +type, and this delay can be increased so linters are run less often. See +`:help g:ale_lint_delay` for more information. + +If you don't wish to run linters while you type, you can disable that behavior. +Set `g:ale_lint_on_text_changed` to `never`. You won't get as frequent error +checking, but ALE shouldn't block your ability to edit a document after you save +a file, so the asynchronous nature of the plugin will still be an advantage. + +If you are still concerned, you can turn the automatic linting off altogether, +including the option `g:ale_lint_on_enter`, and you can run ALE manually with +`:ALELint`. + + + +### 5.xvii. How can I configure my C or C++ project? + +The structure of C and C++ projects varies wildly from project to project, with +many different build tools being used for building them, and many different +formats for project configuration files. ALE can run compilers easily, but +ALE cannot easily detect which compiler flags to use. + +Some tools and build configurations can generate +[compile_commands.json](https://clang.llvm.org/docs/JSONCompilationDatabase.html) +files. The `cppcheck`, `clangcheck`, `clangtidy` and `cquery` linters can read +these files for automatically determining the appropriate compiler flags to +use. + +For linting with compilers like `gcc` and `clang`, and with other tools, you +will need to tell ALE which compiler flags to use yourself. You can use +different options for different projects with the `g:ale_pattern_options` +setting. Consult the documentation for that setting for more information. +`b:ale_linters` can be used to select which tools you want to run, say if you +want to use only `gcc` for one project, and only `clang` for another. + +ALE will attempt to parse `compile_commands.json` files to discover compiler +flags to use when linting code. See `:help g:ale_c_parse_compile_commands` for +more information. See Clang's documentation for +[compile_commands.json files](https://clang.llvm.org/docs/JSONCompilationDatabase.html). +You should strongly consider generating them in your builds, which is easy to do +with CMake. + +You can also configure ALE to automatically run `make -n` to run dry runs on +`Makefile`s to discover compiler flags. This can execute arbitrary code, so the +option is disabled by default. See `:help g:ale_c_parse_makefile`. + +You may also configure buffer-local settings for linters with project-specific +vimrc files. [local_vimrc](https://github.com/LucHermitte/local_vimrc) can be +used for executing local vimrc files which can be shared in your project. + + + +### 5.xviii. How can I configure ALE differently for different buffers? + +ALE offers various ways to configure which linters or fixers are run, and +other settings. For the majority of ALE's settings, they can either be +configured globally with a `g:` variable prefix, or for a specific buffer +with a `b:` variable prefix. For example, you can configure a Python ftplugin +file like so. + +```vim +" In ~/.vim/ftplugin/python.vim + +" Check Python files with flake8 and pylint. +let b:ale_linters = ['flake8', 'pylint'] +" Fix Python files with autopep8 and yapf. +let b:ale_fixers = ['autopep8', 'yapf'] +" Disable warnings about trailing whitespace for Python files. +let b:ale_warn_about_trailing_whitespace = 0 +``` + +For configuring files based on regular expression patterns matched against the +absolute path to a file, you can use `g:ale_pattern_options`. + +```vim +" Do not lint or fix minified files. +let g:ale_pattern_options = { +\ '\.min\.js$': {'ale_linters': [], 'ale_fixers': []}, +\ '\.min\.css$': {'ale_linters': [], 'ale_fixers': []}, +\} +" If you configure g:ale_pattern_options outside of vimrc, you need this. +let g:ale_pattern_options_enabled = 1 +``` + +Buffer-local variables for settings always override the global settings. + + + +### 5.xix. How can I configure the height of the list in which ALE displays errors? + +To set a default height for the error list, use the `g:ale_list_window_size` variable. + +```vim +" Show 5 lines of errors (default: 10) +let g:ale_list_window_size = 5 +``` + + + +### 5.xx. How can I run linters or fixers via Docker or a VM? + +ALE supports running linters or fixers via Docker, virtual machines, or in +combination with any remote machine with a different file system, so long as the +tools are well-integrated with ALE, and ALE is properly configured to run the +correct commands and map filename paths between different file systems. See +`:help ale-lint-other-machines` for the full documentation on how to configure +ALE to support this. + + + +### 5.xxi. How can I change the borders for floating preview windows? + +Borders for floating preview windows are enabled by default. You can use the +`g:ale_floating_window_border` setting to configure them. + +You could disable the border with an empty list. + +```vim +let g:ale_floating_window_border = [] +``` + +If the terminal supports Unicode, you might try setting the value like below, to +make it look nicer. + +```vim +let g:ale_floating_window_border = ['│', '─', '╭', '╮', '╯', '╰'] +``` + +Since vim's default uses nice unicode characters when possible, you can trick +ale into using that default with + +```vim +let g:ale_floating_window_border = repeat([''], 6) +``` + + + +### 5.xxii. How can I use ALE and vim-lsp together? + +[vim-lsp](https://github.com/prabirshrestha/vim-lsp) is a popular plugin as +implementation of Language Server Protocol (LSP) client for Vim. It provides +all the LSP features including auto completion, diagnostics, go to definitions, +etc. + +ALE also provides LSP support for diagnostics. When you use both ALE and +vim-lsp, one option is disabling ALE's LSP support by +`let g:ale_disable_lsp = 1`. However ALE provides integration of external +programs. Showing errors from language servers by vim-lsp and showing errors +from other external programs by ALE are confusing and problematic. + +[vim-lsp-ale](https://github.com/rhysd/vim-lsp-ale) is a bridge plugin to solve +the problem when using both ALE and vim-lsp. With the plugin, diagnostics are +provided by vim-lsp and ALE can handle all the errors. Please read +[vim-lsp-ale's documentation](https://github.com/rhysd/vim-lsp-ale/blob/master/doc/vim-lsp-ale.txt) +for more details. diff --git a/vim-config/plugins/ale/ale_linters/ada/adals.vim b/vim-config/plugins/ale/ale_linters/ada/adals.vim new file mode 100644 index 00000000..9a41e1df --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/ada/adals.vim @@ -0,0 +1,26 @@ +" Author: Bartek Jasicki http://github.com/thindil +" Description: Support for Ada Language Server + +call ale#Set('ada_adals_executable', 'ada_language_server') +call ale#Set('ada_adals_project', 'default.gpr') +call ale#Set('ada_adals_encoding', 'utf-8') + +function! ale_linters#ada#adals#GetAdaLSConfig(buffer) abort + return { + \ 'ada.projectFile': ale#Var(a:buffer, 'ada_adals_project'), + \ 'ada.defaultCharset': ale#Var(a:buffer, 'ada_adals_encoding') + \} +endfunction + +function! ale_linters#ada#adals#GetRootDirectory(buffer) abort + return fnamemodify(bufname(a:buffer), ':p:h') +endfunction + +call ale#linter#Define('ada', { +\ 'name': 'adals', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'ada_adals_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#ada#adals#GetRootDirectory'), +\ 'lsp_config': function('ale_linters#ada#adals#GetAdaLSConfig') +\}) diff --git a/vim-config/plugins/ale/ale_linters/ada/gcc.vim b/vim-config/plugins/ale/ale_linters/ada/gcc.vim old mode 100755 new mode 100644 index d6f973ae..5afc9ae3 --- a/vim-config/plugins/ale/ale_linters/ada/gcc.vim +++ b/vim-config/plugins/ale/ale_linters/ada/gcc.vim @@ -12,13 +12,13 @@ function! ale_linters#ada#gcc#GetCommand(buffer) abort " 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#engine#CreateDirectory(a:buffer), ':p') + 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')) + \ . ' -I %s:h' \ . ale#Pad(ale#Var(a:buffer, 'ada_gcc_options')) \ . ' %t' endfunction @@ -48,7 +48,7 @@ endfunction call ale#linter#Define('ada', { \ 'name': 'gcc', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('ada_gcc_executable'), -\ 'command_callback': 'ale_linters#ada#gcc#GetCommand', +\ 'executable': {b -> ale#Var(b, 'ada_gcc_executable')}, +\ 'command': function('ale_linters#ada#gcc#GetCommand'), \ 'callback': 'ale_linters#ada#gcc#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/ansible/ansible_lint.vim b/vim-config/plugins/ale/ale_linters/ansible/ansible_lint.vim old mode 100755 new mode 100644 index 99fff6c3..3b443369 --- a/vim-config/plugins/ale/ale_linters/ansible/ansible_lint.vim +++ b/vim-config/plugins/ale/ale_linters/ansible/ansible_lint.vim @@ -1,4 +1,4 @@ -" Author: Bjorn Neergaard +" Authors: Bjorn Neergaard , Vytautas Macionis " Description: ansible-lint for ansible-yaml files call ale#Set('ansible_ansible_lint_executable', 'ansible-lint') @@ -7,7 +7,7 @@ function! ale_linters#ansible#ansible_lint#GetExecutable(buffer) abort return ale#Var(a:buffer, 'ansible_ansible_lint_executable') endfunction -function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort +function! ale_linters#ansible#ansible_lint#Handle(buffer, version, lines) abort for l:line in a:lines[:10] if match(l:line, '^Traceback') >= 0 return [{ @@ -18,39 +18,87 @@ function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort 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:version_group = ale#semver#GTE(a:version, [5, 0, 0]) ? '>=5.0.0' : '<5.0.0' let l:output = [] - for l:match in ale#util#GetMatches(a:lines, l:pattern) - let l:code = l:match[4] + if '>=5.0.0' is# l:version_group + " Matches patterns line the following: + " test.yml:3:148: syntax-check 'var' is not a valid attribute for a Play + " roles/test/tasks/test.yml:8: [package-latest] [VERY_LOW] Package installs should not use latest + " D:\test\tasks\test.yml:8: [package-latest] [VERY_LOW] package installs should not use latest + let l:pattern = '\v^(%([a-zA-Z]:)?[^:]+):(\d+):%((\d+):)? %(\[([-[:alnum:]]+)\]) %(\[([_[:alnum:]]+)\]) (.*)$' + let l:error_codes = { 'VERY_HIGH': 'E', 'HIGH': 'E', 'MEDIUM': 'W', 'LOW': 'W', 'VERY_LOW': 'W', 'INFO': 'I' } - 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 + for l:match in ale#util#GetMatches(a:lines, l:pattern) + if ale#path#IsBufferPath(a:buffer, l:match[1]) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[6], + \ 'code': l:match[4], + \ 'type': l:error_codes[l:match[5]], + \}) + endif + endfor + endif - if 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 + if '<5.0.0' is# l:version_group + " Matches patterns line the following: + " test.yml:35: [EANSIBLE0002] Trailing whitespace + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: \[?([[:alnum:]]+)\]? (.*)$' + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:code = l:match[4] + + if l:code is# 'EANSIBLE0002' + \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + " Skip warnings for trailing whitespace if the option is off. + continue + endif + + if ale#path#IsBufferPath(a:buffer, l:match[1]) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[5], + \ 'code': l:code, + \ 'type': l:code[:0] is# 'E' ? 'E' : 'W', + \}) + endif + endfor + endif return l:output endfunction +function! ale_linters#ansible#ansible_lint#GetCommand(buffer, version) abort + let l:commands = { + \ '>=5.0.0': '%e --nocolor --parseable-severity -x yaml %s', + \ '<5.0.0': '%e --nocolor -p %t' + \} + let l:command = ale#semver#GTE(a:version, [5, 0]) ? l:commands['>=5.0.0'] : l:commands['<5.0.0'] + + return l:command +endfunction + call ale#linter#Define('ansible', { \ 'name': 'ansible_lint', \ 'aliases': ['ansible', 'ansible-lint'], -\ 'executable_callback': 'ale_linters#ansible#ansible_lint#GetExecutable', -\ 'command': '%e -p %t', -\ 'callback': 'ale_linters#ansible#ansible_lint#Handle', +\ 'executable': function('ale_linters#ansible#ansible_lint#GetExecutable'), +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale_linters#ansible#ansible_lint#GetExecutable(buffer), +\ '%e --version', +\ function('ale_linters#ansible#ansible_lint#GetCommand'), +\ )}, +\ 'lint_file': 1, +\ 'callback': {buffer, lines -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale_linters#ansible#ansible_lint#GetExecutable(buffer), +\ '%e --version', +\ {buffer, version -> ale_linters#ansible#ansible_lint#Handle( +\ buffer, +\ l:version, +\ lines)}, +\ )}, \}) diff --git a/vim-config/plugins/ale/ale_linters/apiblueprint/drafter.vim b/vim-config/plugins/ale/ale_linters/apiblueprint/drafter.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/apkbuild/apkbuild_lint.vim b/vim-config/plugins/ale/ale_linters/apkbuild/apkbuild_lint.vim new file mode 100644 index 00000000..285f5534 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/apkbuild/apkbuild_lint.vim @@ -0,0 +1,12 @@ +" Author: Leo +" Description: apkbuild-lint from atools linter for APKBUILDs + +call ale#Set('apkbuild_apkbuild_lint_executable', 'apkbuild-lint') + +call ale#linter#Define('apkbuild', { +\ 'name': 'apkbuild_lint', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'apkbuild_apkbuild_lint_executable')}, +\ 'command': '%e %t', +\ 'callback': 'ale#handlers#atools#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/apkbuild/secfixes_check.vim b/vim-config/plugins/ale/ale_linters/apkbuild/secfixes_check.vim new file mode 100644 index 00000000..c65267fd --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/apkbuild/secfixes_check.vim @@ -0,0 +1,12 @@ +" Author: Leo +" Description: secfixes-check from atools linter for APKBUILDs + +call ale#Set('apkbuild_secfixes_check_executable', 'secfixes-check') + +call ale#linter#Define('apkbuild', { +\ 'name': 'secfixes_check', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'apkbuild_secfixes_check_executable')}, +\ 'command': '%e %t', +\ 'callback': 'ale#handlers#atools#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/asciidoc/alex.vim b/vim-config/plugins/ale/ale_linters/asciidoc/alex.vim old mode 100755 new mode 100644 index 79b04fc3..97976b2c --- a/vim-config/plugins/ale/ale_linters/asciidoc/alex.vim +++ b/vim-config/plugins/ale/ale_linters/asciidoc/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for asciidoc files -call ale#linter#Define('help', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('asciidoc', '--text') diff --git a/vim-config/plugins/ale/ale_linters/asciidoc/languagetool.vim b/vim-config/plugins/ale/ale_linters/asciidoc/languagetool.vim new file mode 100644 index 00000000..8e8de7f3 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/asciidoc/languagetool.vim @@ -0,0 +1,5 @@ +" Author: Horacio Sanson (hsanson [ät] gmail.com) +" Description: languagetool for asciidoc files, copied from markdown. + + +call ale#handlers#languagetool#DefineLinter('asciidoc') diff --git a/vim-config/plugins/ale/ale_linters/asciidoc/proselint.vim b/vim-config/plugins/ale/ale_linters/asciidoc/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/asciidoc/redpen.vim b/vim-config/plugins/ale/ale_linters/asciidoc/redpen.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/asciidoc/textlint.vim b/vim-config/plugins/ale/ale_linters/asciidoc/textlint.vim old mode 100755 new mode 100644 index 757718b9..308a3a29 --- a/vim-config/plugins/ale/ale_linters/asciidoc/textlint.vim +++ b/vim-config/plugins/ale/ale_linters/asciidoc/textlint.vim @@ -3,7 +3,7 @@ call ale#linter#Define('asciidoc', { \ 'name': 'textlint', -\ 'executable_callback': 'ale#handlers#textlint#GetExecutable', -\ 'command_callback': 'ale#handlers#textlint#GetCommand', +\ 'executable': function('ale#handlers#textlint#GetExecutable'), +\ 'command': function('ale#handlers#textlint#GetCommand'), \ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', \}) diff --git a/vim-config/plugins/ale/ale_linters/asciidoc/vale.vim b/vim-config/plugins/ale/ale_linters/asciidoc/vale.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/asciidoc/writegood.vim b/vim-config/plugins/ale/ale_linters/asciidoc/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/asm/gcc.vim b/vim-config/plugins/ale/ale_linters/asm/gcc.vim old mode 100755 new mode 100644 index fdd0ee83..cda38923 --- a/vim-config/plugins/ale/ale_linters/asm/gcc.vim +++ b/vim-config/plugins/ale/ale_linters/asm/gcc.vim @@ -5,8 +5,11 @@ call ale#Set('asm_gcc_executable', 'gcc') call ale#Set('asm_gcc_options', '-Wall') function! ale_linters#asm#gcc#GetCommand(buffer) abort - return '%e -x assembler -fsyntax-only ' - \ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + " `-o /dev/null` or `-o null` is needed to catch all errors, + " -fsyntax-only doesn't catch everything. + return '%e -x assembler' + \ . ' -o ' . g:ale#util#nul_file + \ . '-iquote %s:h' \ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -' endfunction @@ -28,7 +31,7 @@ endfunction call ale#linter#Define('asm', { \ 'name': 'gcc', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('asm_gcc_executable'), -\ 'command_callback': 'ale_linters#asm#gcc#GetCommand', +\ 'executable': {b -> ale#Var(b, 'asm_gcc_executable')}, +\ 'command': function('ale_linters#asm#gcc#GetCommand'), \ 'callback': 'ale_linters#asm#gcc#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/awk/gawk.vim b/vim-config/plugins/ale/ale_linters/awk/gawk.vim old mode 100755 new mode 100644 index eb92e45e..f795c57d --- a/vim-config/plugins/ale/ale_linters/awk/gawk.vim +++ b/vim-config/plugins/ale/ale_linters/awk/gawk.vim @@ -15,8 +15,8 @@ endfunction call ale#linter#Define('awk', { \ 'name': 'gawk', -\ 'executable_callback': ale#VarFunc('awk_gawk_executable'), -\ 'command_callback': 'ale_linters#awk#gawk#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/bats/shellcheck.vim b/vim-config/plugins/ale/ale_linters/bats/shellcheck.vim new file mode 100644 index 00000000..5c2a0ea9 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/bats/shellcheck.vim @@ -0,0 +1,4 @@ +" Author: Ian2020 +" Description: shellcheck linter for bats scripts. + +call ale#handlers#shellcheck#DefineLinter('bats') diff --git a/vim-config/plugins/ale/ale_linters/bib/bibclean.vim b/vim-config/plugins/ale/ale_linters/bib/bibclean.vim old mode 100755 new mode 100644 index 6750f22f..f1610e00 --- a/vim-config/plugins/ale/ale_linters/bib/bibclean.vim +++ b/vim-config/plugins/ale/ale_linters/bib/bibclean.vim @@ -11,14 +11,19 @@ endfunction function! ale_linters#bib#bibclean#get_type(str) abort if a:str is# '??' - return 'E' + return 'E' else - return 'W' + return 'W' endif endfunction function! ale_linters#bib#bibclean#match_msg(line) abort - return matchlist(a:line, '^\(.*\) "stdin", line \(.*\): \(.*\)$') + " Legacy message pattern works for bibclean <= v2.11.4. If empty, try + " the new message pattern for bibtex > v2.11.4 + let l:matches_legacy = matchlist(a:line, '^\(.*\) "stdin", line \(\d\+\): \(.*\)$') + + return ! empty(l:matches_legacy) ? l:matches_legacy + \ : matchlist(a:line, '^\(.*\) stdin:\(\d\+\):\(.*\)$') endfunction function! ale_linters#bib#bibclean#match_entry(line) abort @@ -36,30 +41,31 @@ function! ale_linters#bib#bibclean#Handle(buffer, lines) abort 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 + 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 @@ -67,8 +73,8 @@ endfunction call ale#linter#Define('bib', { \ 'name': 'bibclean', -\ 'executable_callback': ale#VarFunc('bib_bibclean_executable'), -\ 'command_callback': 'ale_linters#bib#bibclean#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/c/cc.vim b/vim-config/plugins/ale/ale_linters/c/cc.vim new file mode 100644 index 00000000..5655fbf7 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/c/cc.vim @@ -0,0 +1,53 @@ +" Author: w0rp +" Description: A C compiler linter for C files with gcc/clang, etc. + +call ale#Set('c_cc_executable', '') +call ale#Set('c_cc_options', '-std=c11 -Wall') + +function! ale_linters#c#cc#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'c_cc_executable') + + " Default to either clang or gcc. + if l:executable is# '' + if ale#engine#IsExecutable(a:buffer, 'clang') + let l:executable = 'clang' + else + let l:executable = 'gcc' + endif + endif + + return l:executable +endfunction + +function! ale_linters#c#cc#GetCommand(buffer, output) abort + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:ale_flags = ale#Var(a:buffer, 'c_cc_options') + + if l:cflags =~# '-std=' + let l:ale_flags = substitute( + \ l:ale_flags, + \ '-std=\(c\|gnu\)[0-9]\{2\}', + \ '', + \ 'g') + endif + + " -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 %s:h' + \ . ale#Pad(l:cflags) + \ . ale#Pad(l:ale_flags) . ' -' +endfunction + +call ale#linter#Define('c', { +\ 'name': 'cc', +\ 'aliases': ['gcc', 'clang'], +\ 'output_stream': 'stderr', +\ 'executable': function('ale_linters#c#cc#GetExecutable'), +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#cc#GetCommand'))}, +\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', +\}) diff --git a/vim-config/plugins/ale/ale_linters/c/ccls.vim b/vim-config/plugins/ale/ale_linters/c/ccls.vim old mode 100755 new mode 100644 index 5dc2339f..9f105712 --- a/vim-config/plugins/ale/ale_linters/c/ccls.vim +++ b/vim-config/plugins/ale/ale_linters/c/ccls.vim @@ -3,12 +3,13 @@ call ale#Set('c_ccls_executable', 'ccls') call ale#Set('c_ccls_init_options', {}) +call ale#Set('c_build_dir', '') call ale#linter#Define('c', { \ 'name': 'ccls', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('c_ccls_executable'), +\ 'executable': {b -> ale#Var(b, 'c_ccls_executable')}, \ 'command': '%e', -\ 'project_root_callback': 'ale#handlers#ccls#GetProjectRoot', -\ 'initialization_options_callback':ale#VarFunc('c_ccls_init_options'), +\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'), +\ 'initialization_options': {b -> ale#handlers#ccls#GetInitOpts(b, 'c_ccls_init_options')}, \}) diff --git a/vim-config/plugins/ale/ale_linters/c/clang.vim b/vim-config/plugins/ale/ale_linters/c/clang.vim deleted file mode 100755 index f1bd675b..00000000 --- a/vim-config/plugins/ale/ale_linters/c/clang.vim +++ /dev/null @@ -1,27 +0,0 @@ -" 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_callback': ale#VarFunc('c_clang_executable'), -\ 'command_chain': [ -\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'}, -\ {'callback': 'ale_linters#c#clang#GetCommand'} -\ ], -\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', -\}) diff --git a/vim-config/plugins/ale/ale_linters/c/clangd.vim b/vim-config/plugins/ale/ale_linters/c/clangd.vim old mode 100755 new mode 100644 index 6cad601a..c42d4497 --- a/vim-config/plugins/ale/ale_linters/c/clangd.vim +++ b/vim-config/plugins/ale/ale_linters/c/clangd.vim @@ -3,21 +3,20 @@ call ale#Set('c_clangd_executable', 'clangd') call ale#Set('c_clangd_options', '') - -function! ale_linters#c#clangd#GetProjectRoot(buffer) abort - let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') - - return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' -endfunction +call ale#Set('c_build_dir', '') function! ale_linters#c#clangd#GetCommand(buffer) abort - return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options')) + let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + + return '%e' + \ . ale#Pad(ale#Var(a:buffer, 'c_clangd_options')) + \ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '') endfunction call ale#linter#Define('c', { \ 'name': 'clangd', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('c_clangd_executable'), -\ 'command_callback': 'ale_linters#c#clangd#GetCommand', -\ 'project_root_callback': 'ale_linters#c#clangd#GetProjectRoot', +\ 'executable': {b -> ale#Var(b, 'c_clangd_executable')}, +\ 'command': function('ale_linters#c#clangd#GetCommand'), +\ 'project_root': function('ale#c#FindProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/c/clangtidy.vim b/vim-config/plugins/ale/ale_linters/c/clangtidy.vim old mode 100755 new mode 100644 index 4f334655..553cc23b --- a/vim-config/plugins/ale/ale_linters/c/clangtidy.vim +++ b/vim-config/plugins/ale/ale_linters/c/clangtidy.vim @@ -11,22 +11,32 @@ call ale#Set('c_clangtidy_executable', 'clang-tidy') " http://clang.llvm.org/extra/clang-tidy/checks/list.html call ale#Set('c_clangtidy_checks', []) -" Set this option to manually set some options for clang-tidy. +" 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 +function! ale_linters#c#clangtidy#GetCommand(buffer, output) abort let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',') let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + let l:options = '' " Get the extra options if we couldn't find a build directory. - let l:options = empty(l:build_dir) - \ ? ale#Var(a:buffer, 'c_clangtidy_options') - \ : '' + if empty(l:build_dir) + let l:options = ale#Var(a:buffer, 'c_clangtidy_options') + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags + endif + + " Get the options to pass directly to clang-tidy + let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options') 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 : '') @@ -35,8 +45,8 @@ endfunction call ale#linter#Define('c', { \ 'name': 'clangtidy', \ 'output_stream': 'stdout', -\ 'executable_callback': ale#VarFunc('c_clangtidy_executable'), -\ 'command_callback': 'ale_linters#c#clangtidy#GetCommand', +\ 'executable': {b -> ale#Var(b, 'c_clangtidy_executable')}, +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clangtidy#GetCommand'))}, \ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/c/cppcheck.vim b/vim-config/plugins/ale/ale_linters/c/cppcheck.vim old mode 100755 new mode 100644 index 5e8c7936..28c2861f --- a/vim-config/plugins/ale/ale_linters/c/cppcheck.vim +++ b/vim-config/plugins/ale/ale_linters/c/cppcheck.vim @@ -5,30 +5,25 @@ call ale#Set('c_cppcheck_executable', 'cppcheck') call ale#Set('c_cppcheck_options', '--enable=style') function! ale_linters#c#cppcheck#GetCommand(buffer) abort - " Search upwards from the file for compile_commands.json. - " - " If we find it, we'll `cd` to where the compile_commands.json file is, - " then use the file to set up import paths, etc. - let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') - - let l:cd_command = !empty(l:compile_commmands_path) - \ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h')) - \ : '' - let l:compile_commands_option = !empty(l:compile_commmands_path) - \ ? '--project=compile_commands.json ' + let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) + let l:buffer_path_include = empty(l:compile_commands_option) + \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ : '' + let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') - return l:cd_command - \ . '%e -q --language=c ' - \ . l:compile_commands_option - \ . ale#Var(a:buffer, 'c_cppcheck_options') + return '%e -q --language=c' + \ . l:template + \ . ale#Pad(l:compile_commands_option) + \ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options')) + \ . l:buffer_path_include \ . ' %t' endfunction call ale#linter#Define('c', { \ 'name': 'cppcheck', \ 'output_stream': 'both', -\ 'executable_callback': ale#VarFunc('c_cppcheck_executable'), -\ 'command_callback': 'ale_linters#c#cppcheck#GetCommand', +\ 'executable': {b -> ale#Var(b, 'c_cppcheck_executable')}, +\ 'cwd': function('ale#handlers#cppcheck#GetCwd'), +\ 'command': function('ale_linters#c#cppcheck#GetCommand'), \ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/c/cquery.vim b/vim-config/plugins/ale/ale_linters/c/cquery.vim old mode 100755 new mode 100644 index a20782a2..ff0f34af --- a/vim-config/plugins/ale/ale_linters/c/cquery.vim +++ b/vim-config/plugins/ale/ale_linters/c/cquery.vim @@ -5,13 +5,15 @@ 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 - let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') + " Try to find cquery configuration files first. + let l:config = ale#path#FindNearestFile(a:buffer, '.cquery') - if empty(l:project_root) - let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery') + if !empty(l:config) + return fnamemodify(l:config, ':h') endif - return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' + " Fall back on default project root detection. + return ale#c#FindProjectRoot(a:buffer) endfunction function! ale_linters#c#cquery#GetInitializationOptions(buffer) abort @@ -21,8 +23,8 @@ endfunction call ale#linter#Define('c', { \ 'name': 'cquery', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('c_cquery_executable'), +\ 'executable': {b -> ale#Var(b, 'c_cquery_executable')}, \ 'command': '%e', -\ 'project_root_callback': 'ale_linters#c#cquery#GetProjectRoot', -\ 'initialization_options_callback': 'ale_linters#c#cquery#GetInitializationOptions', +\ 'project_root': function('ale_linters#c#cquery#GetProjectRoot'), +\ 'initialization_options': function('ale_linters#c#cquery#GetInitializationOptions'), \}) diff --git a/vim-config/plugins/ale/ale_linters/c/flawfinder.vim b/vim-config/plugins/ale/ale_linters/c/flawfinder.vim old mode 100755 new mode 100644 index 7e1f6769..53c36716 --- a/vim-config/plugins/ale/ale_linters/c/flawfinder.vim +++ b/vim-config/plugins/ale/ale_linters/c/flawfinder.vim @@ -7,19 +7,19 @@ 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') + " 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' + 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_callback': ale#VarFunc('c_flawfinder_executable'), -\ 'command_callback': 'ale_linters#c#flawfinder#GetCommand', +\ 'executable': {b -> ale#Var(b, 'c_flawfinder_executable')}, +\ 'command': function('ale_linters#c#flawfinder#GetCommand'), \ 'callback': 'ale#handlers#flawfinder#HandleFlawfinderFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/c/gcc.vim b/vim-config/plugins/ale/ale_linters/c/gcc.vim deleted file mode 100755 index 60ecb712..00000000 --- a/vim-config/plugins/ale/ale_linters/c/gcc.vim +++ /dev/null @@ -1,27 +0,0 @@ -" 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. - return '%e -S -x c -fsyntax-only' - \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) - \ . ale#Pad(l:cflags) - \ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -' -endfunction - -call ale#linter#Define('c', { -\ 'name': 'gcc', -\ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('c_gcc_executable'), -\ 'command_chain': [ -\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'}, -\ {'callback': 'ale_linters#c#gcc#GetCommand'} -\ ], -\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', -\}) diff --git a/vim-config/plugins/ale/ale_linters/chef/cookstyle.vim b/vim-config/plugins/ale/ale_linters/chef/cookstyle.vim new file mode 100644 index 00000000..50bae2aa --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/chef/foodcritic.vim b/vim-config/plugins/ale/ale_linters/chef/foodcritic.vim old mode 100755 new mode 100644 index c86336d6..48beba75 --- a/vim-config/plugins/ale/ale_linters/chef/foodcritic.vim +++ b/vim-config/plugins/ale/ale_linters/chef/foodcritic.vim @@ -34,8 +34,8 @@ endfunction call ale#linter#Define('chef', { \ 'name': 'foodcritic', -\ 'executable_callback': ale#VarFunc('chef_foodcritic_executable'), -\ 'command_callback': 'ale_linters#chef#foodcritic#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/clojure/clj_kondo.vim b/vim-config/plugins/ale/ale_linters/clojure/clj_kondo.vim new file mode 100644 index 00000000..a023f8b6 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/clojure/clj_kondo.vim @@ -0,0 +1,46 @@ +" Author: Masashi Iizuka +" Description: linter for clojure using clj-kondo https://github.com/borkdude/clj-kondo + +call ale#Set('clojure_clj_kondo_options', '--cache') + +function! ale_linters#clojure#clj_kondo#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'clojure_clj_kondo_options') + + let l:command = 'clj-kondo' + \ . ale#Pad(l:options) + \ . ' --lint %t' + + return l:command +endfunction + +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': function('ale_linters#clojure#clj_kondo#GetCommand'), +\ 'callback': 'ale_linters#clojure#clj_kondo#HandleCljKondoFormat', +\}) diff --git a/vim-config/plugins/ale/ale_linters/clojure/joker.vim b/vim-config/plugins/ale/ale_linters/clojure/joker.vim old mode 100755 new mode 100644 index 2f61148b..1f17cd31 --- a/vim-config/plugins/ale/ale_linters/clojure/joker.vim +++ b/vim-config/plugins/ale/ale_linters/clojure/joker.vim @@ -11,7 +11,7 @@ function! ale_linters#clojure#joker#HandleJokerFormat(buffer, lines) abort let l:type = 'E' if l:match[4] is? 'Parse warning' - let l:type = 'W' + let l:type = 'W' endif call add(l:output, { diff --git a/vim-config/plugins/ale/ale_linters/cloudformation/cfn_python_lint.vim b/vim-config/plugins/ale/ale_linters/cloudformation/cfn_python_lint.vim old mode 100755 new mode 100644 index d0ac7b28..16841431 --- a/vim-config/plugins/ale/ale_linters/cloudformation/cfn_python_lint.vim +++ b/vim-config/plugins/ale/ale_linters/cloudformation/cfn_python_lint.vim @@ -29,6 +29,7 @@ endfunction call ale#linter#Define('cloudformation', { \ 'name': 'cloudformation', +\ 'aliases': ['cfn-lint'], \ 'executable': 'cfn-lint', \ 'command': 'cfn-lint --template %t --format parseable', \ 'callback': 'ale_linters#cloudformation#cfn_python_lint#Handle', diff --git a/vim-config/plugins/ale/ale_linters/cmake/cmakelint.vim b/vim-config/plugins/ale/ale_linters/cmake/cmakelint.vim old mode 100755 new mode 100644 index 78676518..d955a265 --- a/vim-config/plugins/ale/ale_linters/cmake/cmakelint.vim +++ b/vim-config/plugins/ale/ale_linters/cmake/cmakelint.vim @@ -18,7 +18,7 @@ endfunction call ale#linter#Define('cmake', { \ 'name': 'cmakelint', -\ 'executable_callback': 'ale_linters#cmake#cmakelint#Executable', -\ 'command_callback': 'ale_linters#cmake#cmakelint#Command', +\ 'executable': function('ale_linters#cmake#cmakelint#Executable'), +\ 'command': function('ale_linters#cmake#cmakelint#Command'), \ 'callback': 'ale#handlers#unix#HandleAsWarning', \}) diff --git a/vim-config/plugins/ale/ale_linters/coffee/coffee.vim b/vim-config/plugins/ale/ale_linters/coffee/coffee.vim old mode 100755 new mode 100644 index f2539281..8e891639 --- a/vim-config/plugins/ale/ale_linters/coffee/coffee.vim +++ b/vim-config/plugins/ale/ale_linters/coffee/coffee.vim @@ -16,8 +16,8 @@ endfunction call ale#linter#Define('coffee', { \ 'name': 'coffee', -\ 'executable_callback': 'ale_linters#coffee#coffee#GetExecutable', -\ 'command_callback': 'ale_linters#coffee#coffee#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/coffee/coffeelint.vim b/vim-config/plugins/ale/ale_linters/coffee/coffeelint.vim old mode 100755 new mode 100644 index 6d3df353..b7c85fa7 --- a/vim-config/plugins/ale/ale_linters/coffee/coffeelint.vim +++ b/vim-config/plugins/ale/ale_linters/coffee/coffeelint.vim @@ -37,7 +37,7 @@ endfunction call ale#linter#Define('coffee', { \ 'name': 'coffeelint', -\ 'executable_callback': 'ale_linters#coffee#coffeelint#GetExecutable', -\ 'command_callback': 'ale_linters#coffee#coffeelint#GetCommand', +\ 'executable': function('ale_linters#coffee#coffeelint#GetExecutable'), +\ 'command': function('ale_linters#coffee#coffeelint#GetCommand'), \ 'callback': 'ale_linters#coffee#coffeelint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/cpp/cc.vim b/vim-config/plugins/ale/ale_linters/cpp/cc.vim new file mode 100644 index 00000000..ffb8f068 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/cpp/cc.vim @@ -0,0 +1,53 @@ +" Author: w0rp +" Description: A C++ compiler linter for C++ files with gcc/clang, etc. + +call ale#Set('cpp_cc_executable', '') +call ale#Set('cpp_cc_options', '-std=c++14 -Wall') + +function! ale_linters#cpp#cc#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'cpp_cc_executable') + + " Default to either clang++ or gcc. + if l:executable is# '' + if ale#engine#IsExecutable(a:buffer, 'clang++') + let l:executable = 'clang++' + else + let l:executable = 'gcc' + endif + endif + + return l:executable +endfunction + +function! ale_linters#cpp#cc#GetCommand(buffer, output) abort + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:ale_flags = ale#Var(a:buffer, 'cpp_cc_options') + + if l:cflags =~# '-std=' + let l:ale_flags = substitute( + \ l:ale_flags, + \ '-std=\(c\|gnu\)++[0-9]\{2\}', + \ '', + \ 'g') + endif + + " -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 %s:h' + \ . ale#Pad(l:cflags) + \ . ale#Pad(l:ale_flags) . ' -' +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'cc', +\ 'aliases': ['gcc', 'clang', 'g++', 'clang++'], +\ 'output_stream': 'stderr', +\ 'executable': function('ale_linters#cpp#cc#GetExecutable'), +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#cc#GetCommand'))}, +\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', +\}) diff --git a/vim-config/plugins/ale/ale_linters/cpp/ccls.vim b/vim-config/plugins/ale/ale_linters/cpp/ccls.vim old mode 100755 new mode 100644 index 501fd685..38f8df9c --- a/vim-config/plugins/ale/ale_linters/cpp/ccls.vim +++ b/vim-config/plugins/ale/ale_linters/cpp/ccls.vim @@ -3,12 +3,13 @@ call ale#Set('cpp_ccls_executable', 'ccls') call ale#Set('cpp_ccls_init_options', {}) +call ale#Set('c_build_dir', '') call ale#linter#Define('cpp', { \ 'name': 'ccls', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('cpp_ccls_executable'), +\ 'executable': {b -> ale#Var(b, 'cpp_ccls_executable')}, \ 'command': '%e', -\ 'project_root_callback': 'ale#handlers#ccls#GetProjectRoot', -\ 'initialization_options_callback': ale#VarFunc('cpp_ccls_init_options'), +\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'), +\ 'initialization_options': {b -> ale#handlers#ccls#GetInitOpts(b, 'cpp_ccls_init_options')}, \}) diff --git a/vim-config/plugins/ale/ale_linters/cpp/clang.vim b/vim-config/plugins/ale/ale_linters/cpp/clang.vim deleted file mode 100755 index 649c5993..00000000 --- a/vim-config/plugins/ale/ale_linters/cpp/clang.vim +++ /dev/null @@ -1,27 +0,0 @@ -" 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_callback': ale#VarFunc('cpp_clang_executable'), -\ 'command_chain': [ -\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'}, -\ {'callback': 'ale_linters#cpp#clang#GetCommand'}, -\ ], -\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', -\}) diff --git a/vim-config/plugins/ale/ale_linters/cpp/clangcheck.vim b/vim-config/plugins/ale/ale_linters/cpp/clangcheck.vim old mode 100755 new mode 100644 index c66d6702..4cb04864 --- a/vim-config/plugins/ale/ale_linters/cpp/clangcheck.vim +++ b/vim-config/plugins/ale/ale_linters/cpp/clangcheck.vim @@ -12,14 +12,15 @@ function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort let l:build_dir = ale#Var(a:buffer, 'c_build_dir') if empty(l:build_dir) - let l:build_dir = ale#path#Dirname(ale#c#FindCompileCommands(a:buffer)) + 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' : '') + \ . (empty(l:build_dir) ? ' --extra-arg=-Xclang --extra-arg=-analyzer-output=text --extra-arg=-fno-color-diagnostics': '') \ . ale#Pad(l:user_options) \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') endfunction @@ -27,8 +28,8 @@ endfunction call ale#linter#Define('cpp', { \ 'name': 'clangcheck', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('cpp_clangcheck_executable'), -\ 'command_callback': 'ale_linters#cpp#clangcheck#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/cpp/clangd.vim b/vim-config/plugins/ale/ale_linters/cpp/clangd.vim old mode 100755 new mode 100644 index 9139f054..14f3fe55 --- a/vim-config/plugins/ale/ale_linters/cpp/clangd.vim +++ b/vim-config/plugins/ale/ale_linters/cpp/clangd.vim @@ -3,21 +3,20 @@ call ale#Set('cpp_clangd_executable', 'clangd') call ale#Set('cpp_clangd_options', '') - -function! ale_linters#cpp#clangd#GetProjectRoot(buffer) abort - let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') - - return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' -endfunction +call ale#Set('c_build_dir', '') function! ale_linters#cpp#clangd#GetCommand(buffer) abort - return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options')) + let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + + return '%e' + \ . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options')) + \ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '') endfunction call ale#linter#Define('cpp', { \ 'name': 'clangd', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('cpp_clangd_executable'), -\ 'command_callback': 'ale_linters#cpp#clangd#GetCommand', -\ 'project_root_callback': 'ale_linters#cpp#clangd#GetProjectRoot', +\ 'executable': {b -> ale#Var(b, 'cpp_clangd_executable')}, +\ 'command': function('ale_linters#cpp#clangd#GetCommand'), +\ 'project_root': function('ale#c#FindProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/cpp/clangtidy.vim b/vim-config/plugins/ale/ale_linters/cpp/clangtidy.vim old mode 100755 new mode 100644 index 9c3da8db..d6944aae --- a/vim-config/plugins/ale/ale_linters/cpp/clangtidy.vim +++ b/vim-config/plugins/ale/ale_linters/cpp/clangtidy.vim @@ -5,22 +5,39 @@ 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. +" 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 +function! ale_linters#cpp#clangtidy#GetCommand(buffer, output) abort let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',') let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + let l:options = '' " Get the extra options if we couldn't find a build directory. - let l:options = empty(l:build_dir) - \ ? ale#Var(a:buffer, 'cpp_clangtidy_options') - \ : '' + if empty(l:build_dir) + let l:options = ale#Var(a:buffer, 'cpp_clangtidy_options') + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags + + " Tell clang-tidy a .h header with a C++ filetype in Vim is a C++ file + " only when compile-commands.json file is not there. Adding these + " flags makes clang-tidy completely ignore compile commmands. + if expand('#' . a:buffer) =~# '\.h$' + let l:options .= !empty(l:options) ? ' -x c++' : '-x c++' + endif + endif + + " Get the options to pass directly to clang-tidy + let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options') 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 : '') @@ -29,8 +46,8 @@ endfunction call ale#linter#Define('cpp', { \ 'name': 'clangtidy', \ 'output_stream': 'stdout', -\ 'executable_callback': ale#VarFunc('cpp_clangtidy_executable'), -\ 'command_callback': 'ale_linters#cpp#clangtidy#GetCommand', +\ 'executable': {b -> ale#Var(b, 'cpp_clangtidy_executable')}, +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clangtidy#GetCommand'))}, \ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/cpp/clazy.vim b/vim-config/plugins/ale/ale_linters/cpp/clazy.vim old mode 100755 new mode 100644 index cbbd0ccf..9b29ac9a --- a/vim-config/plugins/ale/ale_linters/cpp/clazy.vim +++ b/vim-config/plugins/ale/ale_linters/cpp/clazy.vim @@ -25,8 +25,8 @@ endfunction call ale#linter#Define('cpp', { \ 'name': 'clazy', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('cpp_clazy_executable'), -\ 'command_callback': 'ale_linters#cpp#clazy#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/cpp/cppcheck.vim b/vim-config/plugins/ale/ale_linters/cpp/cppcheck.vim old mode 100755 new mode 100644 index 229d6133..eb86adf4 --- a/vim-config/plugins/ale/ale_linters/cpp/cppcheck.vim +++ b/vim-config/plugins/ale/ale_linters/cpp/cppcheck.vim @@ -5,30 +5,25 @@ call ale#Set('cpp_cppcheck_executable', 'cppcheck') call ale#Set('cpp_cppcheck_options', '--enable=style') function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort - " Search upwards from the file for compile_commands.json. - " - " If we find it, we'll `cd` to where the compile_commands.json file is, - " then use the file to set up import paths, etc. - let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') - - let l:cd_command = !empty(l:compile_commmands_path) - \ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h')) - \ : '' - let l:compile_commands_option = !empty(l:compile_commmands_path) - \ ? '--project=compile_commands.json ' + let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) + let l:buffer_path_include = empty(l:compile_commands_option) + \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ : '' + let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') - return l:cd_command - \ . '%e -q --language=c++ ' - \ . l:compile_commands_option - \ . ale#Var(a:buffer, 'cpp_cppcheck_options') + return '%e -q --language=c++' + \ . l:template + \ . ale#Pad(l:compile_commands_option) + \ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options')) + \ . l:buffer_path_include \ . ' %t' endfunction call ale#linter#Define('cpp', { \ 'name': 'cppcheck', \ 'output_stream': 'both', -\ 'executable_callback': ale#VarFunc('cpp_cppcheck_executable'), -\ 'command_callback': 'ale_linters#cpp#cppcheck#GetCommand', +\ 'executable': {b -> ale#Var(b, 'cpp_cppcheck_executable')}, +\ 'cwd': function('ale#handlers#cppcheck#GetCwd'), +\ 'command': function('ale_linters#cpp#cppcheck#GetCommand'), \ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/cpp/cpplint.vim b/vim-config/plugins/ale/ale_linters/cpp/cpplint.vim old mode 100755 new mode 100644 index d135fa79..f1f6ce7f --- a/vim-config/plugins/ale/ale_linters/cpp/cpplint.vim +++ b/vim-config/plugins/ale/ale_linters/cpp/cpplint.vim @@ -13,8 +13,8 @@ endfunction call ale#linter#Define('cpp', { \ 'name': 'cpplint', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('cpp_cpplint_executable'), -\ 'command_callback': 'ale_linters#cpp#cpplint#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/cpp/cquery.vim b/vim-config/plugins/ale/ale_linters/cpp/cquery.vim old mode 100755 new mode 100644 index b1c81989..2971cdcb --- a/vim-config/plugins/ale/ale_linters/cpp/cquery.vim +++ b/vim-config/plugins/ale/ale_linters/cpp/cquery.vim @@ -5,13 +5,15 @@ call ale#Set('cpp_cquery_executable', 'cquery') call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery')) function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort - let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') + " Try to find cquery configuration files first. + let l:config = ale#path#FindNearestFile(a:buffer, '.cquery') - if empty(l:project_root) - let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery') + if !empty(l:config) + return fnamemodify(l:config, ':h') endif - return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' + " Fall back on default project root detection. + return ale#c#FindProjectRoot(a:buffer) endfunction function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort @@ -21,8 +23,8 @@ endfunction call ale#linter#Define('cpp', { \ 'name': 'cquery', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('cpp_cquery_executable'), +\ 'executable': {b -> ale#Var(b, 'cpp_cquery_executable')}, \ 'command': '%e', -\ 'project_root_callback': 'ale_linters#cpp#cquery#GetProjectRoot', -\ 'initialization_options_callback': 'ale_linters#cpp#cquery#GetInitializationOptions', +\ 'project_root': function('ale_linters#cpp#cquery#GetProjectRoot'), +\ 'initialization_options': function('ale_linters#cpp#cquery#GetInitializationOptions'), \}) diff --git a/vim-config/plugins/ale/ale_linters/cpp/flawfinder.vim b/vim-config/plugins/ale/ale_linters/cpp/flawfinder.vim old mode 100755 new mode 100644 index 4f669bff..5bfdea22 --- a/vim-config/plugins/ale/ale_linters/cpp/flawfinder.vim +++ b/vim-config/plugins/ale/ale_linters/cpp/flawfinder.vim @@ -7,19 +7,19 @@ 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') + " 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' + 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_callback': ale#VarFunc('cpp_flawfinder_executable'), -\ 'command_callback': 'ale_linters#cpp#flawfinder#GetCommand', +\ 'executable': {b -> ale#Var(b, 'cpp_flawfinder_executable')}, +\ 'command': function('ale_linters#cpp#flawfinder#GetCommand'), \ 'callback': 'ale#handlers#flawfinder#HandleFlawfinderFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/cpp/gcc.vim b/vim-config/plugins/ale/ale_linters/cpp/gcc.vim deleted file mode 100755 index 9935b0bb..00000000 --- a/vim-config/plugins/ale/ale_linters/cpp/gcc.vim +++ /dev/null @@ -1,28 +0,0 @@ -" 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. - return '%e -S -x c++ -fsyntax-only' - \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) - \ . ale#Pad(l:cflags) - \ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -' -endfunction - -call ale#linter#Define('cpp', { -\ 'name': 'gcc', -\ 'aliases': ['g++'], -\ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('cpp_gcc_executable'), -\ 'command_chain': [ -\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'}, -\ {'callback': 'ale_linters#cpp#gcc#GetCommand'}, -\ ], -\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', -\}) diff --git a/vim-config/plugins/ale/ale_linters/crystal/ameba.vim b/vim-config/plugins/ale/ale_linters/crystal/ameba.vim new file mode 100644 index 00000000..5dfc7f45 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/crystal/crystal.vim b/vim-config/plugins/ale/ale_linters/crystal/crystal.vim old mode 100755 new mode 100644 index 81579d63..8a905b12 --- a/vim-config/plugins/ale/ale_linters/crystal/crystal.vim +++ b/vim-config/plugins/ale/ale_linters/crystal/crystal.vim @@ -5,6 +5,10 @@ function! ale_linters#crystal#crystal#Handle(buffer, lines) abort let l:output = [] for l:error in ale#util#FuzzyJSONDecode(a:lines, []) + if !has_key(l:error, 'file') + continue + endif + call add(l:output, { \ 'lnum': l:error.line + 0, \ 'col': l:error.column + 0, @@ -26,6 +30,6 @@ call ale#linter#Define('crystal', { \ 'executable': 'crystal', \ 'output_stream': 'both', \ 'lint_file': 1, -\ 'command_callback': 'ale_linters#crystal#crystal#GetCommand', +\ 'command': function('ale_linters#crystal#crystal#GetCommand'), \ 'callback': 'ale_linters#crystal#crystal#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/cs/csc.vim b/vim-config/plugins/ale/ale_linters/cs/csc.vim new file mode 100644 index 00000000..5ee3de29 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/cs/csc.vim @@ -0,0 +1,90 @@ +call ale#Set('cs_csc_options', '') +call ale#Set('cs_csc_source', '') +call ale#Set('cs_csc_assembly_path', []) +call ale#Set('cs_csc_assemblies', []) + +function! ale_linters#cs#csc#GetCwd(buffer) abort + let l:cwd = ale#Var(a:buffer, 'cs_csc_source') + + return !empty(l:cwd) ? l:cwd : expand('#' . a:buffer . ':p:h') +endfunction + +function! ale_linters#cs#csc#GetCommand(buffer) abort + " Pass assembly paths via the -lib: parameter. + let l:path_list = ale#Var(a:buffer, 'cs_csc_assembly_path') + + let l:lib_option = !empty(l:path_list) + \ ? '/lib:' . join(map(copy(l:path_list), 'ale#Escape(v:val)'), ',') + \ : '' + + " Pass paths to DLL files via the -r: parameter. + let l:assembly_list = ale#Var(a:buffer, 'cs_csc_assemblies') + + let l:r_option = !empty(l:assembly_list) + \ ? '/r:' . join(map(copy(l:assembly_list), 'ale#Escape(v:val)'), ',') + \ : '' + + " register temporary module target file with ale + " register temporary module target file with ALE. + let l:out = ale#command#CreateFile(a:buffer) + + " The code is compiled as a module and the output is redirected to a + " temporary file. + return 'csc /unsafe' + \ . ale#Pad(ale#Var(a:buffer, 'cs_csc_options')) + \ . ale#Pad(l:lib_option) + \ . ale#Pad(l:r_option) + \ . ' /out:' . l:out + \ . ' /t:module' + \ . ' /recurse:' . ale#Escape('*.cs') +endfunction + +function! ale_linters#cs#csc#Handle(buffer, lines) abort + " Look for lines like the following. + " + " Tests.cs(12,29): error CSXXXX: ; expected + " + " NOTE: pattern also captures file name as linter compiles all + " files within the source tree rooted at the specified source + " path and not just the file loaded in the buffer + let l:patterns = [ + \ '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$', + \ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$', + \] + let l:output = [] + let l:dir = ale_linters#cs#csc#GetCwd(a:buffer) + + for l:match in ale#util#GetMatches(a:lines, l:patterns) + if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS' + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]), + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'type': l:match[4] is# 'error' ? 'E' : 'W', + \ 'code': l:match[5], + \ 'text': l:match[6] , + \}) + elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS' + call add(l:output, { + \ 'filename':'', + \ 'lnum': -1, + \ 'col': -1, + \ 'type': l:match[1] is# 'error' ? 'E' : 'W', + \ 'code': l:match[2], + \ 'text': l:match[3], + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('cs',{ +\ 'name': 'csc', +\ 'output_stream': 'stdout', +\ 'executable': 'csc', +\ 'cwd': function('ale_linters#cs#csc#GetCwd'), +\ 'command': function('ale_linters#cs#csc#GetCommand'), +\ 'callback': 'ale_linters#cs#csc#Handle', +\ 'lint_file': 1 +\}) diff --git a/vim-config/plugins/ale/ale_linters/cs/mcs.vim b/vim-config/plugins/ale/ale_linters/cs/mcs.vim old mode 100755 new mode 100644 index 8738026d..1b373e73 --- a/vim-config/plugins/ale/ale_linters/cs/mcs.vim +++ b/vim-config/plugins/ale/ale_linters/cs/mcs.vim @@ -32,6 +32,6 @@ call ale#linter#Define('cs',{ \ 'name': 'mcs', \ 'output_stream': 'stderr', \ 'executable': 'mcs', -\ 'command_callback': 'ale_linters#cs#mcs#GetCommand', +\ 'command': function('ale_linters#cs#mcs#GetCommand'), \ 'callback': 'ale_linters#cs#mcs#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/cs/mcsc.vim b/vim-config/plugins/ale/ale_linters/cs/mcsc.vim old mode 100755 new mode 100644 index 1561661e..2dd46661 --- a/vim-config/plugins/ale/ale_linters/cs/mcsc.vim +++ b/vim-config/plugins/ale/ale_linters/cs/mcsc.vim @@ -3,14 +3,10 @@ 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') +function! ale_linters#cs#mcsc#GetCwd(buffer) abort + let l:cwd = ale#Var(a:buffer, 'cs_mcsc_source') - if !empty(l:working_directory) - return l:working_directory - endif - - return expand('#' . a:buffer . ':p:h') + return !empty(l:cwd) ? l:cwd : expand('#' . a:buffer . ':p:h') endfunction function! ale_linters#cs#mcsc#GetCommand(buffer) abort @@ -30,12 +26,11 @@ function! ale_linters#cs#mcsc#GetCommand(buffer) abort " register temporary module target file with ale " register temporary module target file with ALE. - let l:out = ale#engine#CreateFile(a:buffer) + 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' + return 'mcs -unsafe' \ . ale#Pad(ale#Var(a:buffer, 'cs_mcsc_options')) \ . ale#Pad(l:lib_option) \ . ale#Pad(l:r_option) @@ -52,20 +47,34 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort " NOTE: pattern also captures file name as linter compiles all " files within the source tree rooted at the specified source " path and not just the file loaded in the buffer - let l:pattern = '^\v(.+\.cs)\((\d+),(\d+)\)\: ([^ ]+) ([^ ]+): (.+)$' + let l:patterns = [ + \ '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$', + \ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$', + \] let l:output = [] - let l:dir = s:GetWorkingDirectory(a:buffer) + let l:dir = ale_linters#cs#mcsc#GetCwd(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], - \}) + for l:match in ale#util#GetMatches(a:lines, l:patterns) + if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS' + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]), + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'type': l:match[4] is# 'error' ? 'E' : 'W', + \ 'code': l:match[5], + \ 'text': l:match[6] , + \}) + elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS' + call add(l:output, { + \ 'filename':'', + \ 'lnum': -1, + \ 'col': -1, + \ 'type': l:match[1] is# 'error' ? 'E' : 'W', + \ 'code': l:match[2], + \ 'text': l:match[3], + \}) + endif endfor return l:output @@ -75,7 +84,8 @@ call ale#linter#Define('cs',{ \ 'name': 'mcsc', \ 'output_stream': 'stderr', \ 'executable': 'mcs', -\ 'command_callback': 'ale_linters#cs#mcsc#GetCommand', +\ 'cwd': function('ale_linters#cs#mcsc#GetCwd'), +\ 'command': function('ale_linters#cs#mcsc#GetCommand'), \ 'callback': 'ale_linters#cs#mcsc#Handle', \ 'lint_file': 1 \}) diff --git a/vim-config/plugins/ale/ale_linters/css/csslint.vim b/vim-config/plugins/ale/ale_linters/css/csslint.vim old mode 100755 new mode 100644 index 98b7fdd4..50c21ce2 --- a/vim-config/plugins/ale/ale_linters/css/csslint.vim +++ b/vim-config/plugins/ale/ale_linters/css/csslint.vim @@ -13,6 +13,6 @@ endfunction call ale#linter#Define('css', { \ 'name': 'csslint', \ 'executable': 'csslint', -\ 'command_callback': 'ale_linters#css#csslint#GetCommand', +\ 'command': function('ale_linters#css#csslint#GetCommand'), \ 'callback': 'ale#handlers#css#HandleCSSLintFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/css/fecs.vim b/vim-config/plugins/ale/ale_linters/css/fecs.vim new file mode 100644 index 00000000..511847c6 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/css/stylelint.vim b/vim-config/plugins/ale/ale_linters/css/stylelint.vim old mode 100755 new mode 100644 index 6f8bef68..e508f392 --- a/vim-config/plugins/ale/ale_linters/css/stylelint.vim +++ b/vim-config/plugins/ale/ale_linters/css/stylelint.vim @@ -11,9 +11,9 @@ endfunction call ale#linter#Define('css', { \ 'name': 'stylelint', -\ 'executable_callback': ale#node#FindExecutableFunc('css_stylelint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'css_stylelint', [ \ 'node_modules/.bin/stylelint', -\ ]), -\ 'command_callback': 'ale_linters#css#stylelint#GetCommand', +\ ])}, +\ 'command': function('ale_linters#css#stylelint#GetCommand'), \ 'callback': 'ale#handlers#css#HandleStyleLintFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/cucumber/cucumber.vim b/vim-config/plugins/ale/ale_linters/cucumber/cucumber.vim old mode 100755 new mode 100644 index e8ae09ff..0cfd815e --- a/vim-config/plugins/ale/ale_linters/cucumber/cucumber.vim +++ b/vim-config/plugins/ale/ale_linters/cucumber/cucumber.vim @@ -41,6 +41,6 @@ endfunction call ale#linter#Define('cucumber', { \ 'name': 'cucumber', \ 'executable': 'cucumber', -\ 'command_callback': 'ale_linters#cucumber#cucumber#GetCommand', +\ 'command': function('ale_linters#cucumber#cucumber#GetCommand'), \ 'callback': 'ale_linters#cucumber#cucumber#Handle' \}) diff --git a/vim-config/plugins/ale/ale_linters/cuda/clangd.vim b/vim-config/plugins/ale/ale_linters/cuda/clangd.vim new file mode 100644 index 00000000..bfda821b --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/cuda/clangd.vim @@ -0,0 +1,23 @@ +" Author: Tommy Chiang +" Description: Clangd language server for CUDA (modified from Andrey +" Melentyev's implementation for C++) + +call ale#Set('cuda_clangd_executable', 'clangd') +call ale#Set('cuda_clangd_options', '') +call ale#Set('c_build_dir', '') + +function! ale_linters#cuda#clangd#GetCommand(buffer) abort + let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + + return '%e' + \ . ale#Pad(ale#Var(a:buffer, 'cuda_clangd_options')) + \ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '') +endfunction + +call ale#linter#Define('cuda', { +\ 'name': 'clangd', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'cuda_clangd_executable')}, +\ 'command': function('ale_linters#cuda#clangd#GetCommand'), +\ 'project_root': function('ale#c#FindProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/cuda/nvcc.vim b/vim-config/plugins/ale/ale_linters/cuda/nvcc.vim old mode 100755 new mode 100644 index f4442cb8..2734f6ec --- a/vim-config/plugins/ale/ale_linters/cuda/nvcc.vim +++ b/vim-config/plugins/ale/ale_linters/cuda/nvcc.vim @@ -5,9 +5,6 @@ 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#engine#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')) @@ -42,8 +39,8 @@ endfunction call ale#linter#Define('cuda', { \ 'name': 'nvcc', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('cuda_nvcc_executable'), -\ 'command_callback': 'ale_linters#cuda#nvcc#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/cypher/cypher_lint.vim b/vim-config/plugins/ale/ale_linters/cypher/cypher_lint.vim new file mode 100644 index 00000000..408ddd6e --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/d/dls.vim b/vim-config/plugins/ale/ale_linters/d/dls.vim old mode 100755 new mode 100644 index 7210d21e..78d1c152 --- a/vim-config/plugins/ale/ale_linters/d/dls.vim +++ b/vim-config/plugins/ale/ale_linters/d/dls.vim @@ -16,7 +16,7 @@ endfunction call ale#linter#Define('d', { \ 'name': 'dls', \ 'lsp': 'stdio', -\ 'executable_callback': 'ale_linters#d#dls#GetExecutable', -\ 'command_callback': 'ale_linters#d#dls#GetExecutable', -\ 'project_root_callback': 'ale_linters#d#dls#FindProjectRoot', +\ '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/vim-config/plugins/ale/ale_linters/d/dmd.vim b/vim-config/plugins/ale/ale_linters/d/dmd.vim old mode 100755 new mode 100644 index c816d592..f38e812c --- a/vim-config/plugins/ale/ale_linters/d/dmd.vim +++ b/vim-config/plugins/ale/ale_linters/d/dmd.vim @@ -1,53 +1,106 @@ " Author: w0rp " Description: "dmd for D files" -function! ale_linters#d#dmd#DUBCommand(buffer) abort +function! s:GetDUBCommand(buffer) abort " If we can't run dub, then skip this command. - if !executable('dub') + if executable('dub') " Returning an empty string skips to the DMD command. - return '' + let l:config = ale#d#FindDUBConfig(a:buffer) + + " To support older dub versions, we just change the directory to the + " directory where we found the dub config, and then run `dub describe` + " from that directory. + if !empty(l:config) + return [fnamemodify(l:config, ':h'), 'dub describe --data-list + \ --data=import-paths + \ --data=string-import-paths + \ --data=versions + \ --data=debug-versions + \'] + endif endif - let l:dub_file = ale#d#FindDUBConfig(a:buffer) + return ['', ''] +endfunction + +function! ale_linters#d#dmd#RunDUBCommand(buffer) abort + let [l:cwd, l:command] = s:GetDUBCommand(a:buffer) - if empty(l:dub_file) - return '' + if empty(l:command) + " If we can't run DUB, just run DMD. + return ale_linters#d#dmd#DMDCommand(a:buffer, [], {}) 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' + return ale#command#Run( + \ a:buffer, + \ l:command, + \ function('ale_linters#d#dmd#DMDCommand'), + \ {'cwd': l:cwd}, + \) endfunction -function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort +function! ale_linters#d#dmd#DMDCommand(buffer, dub_output, meta) abort let l:import_list = [] + let l:str_import_list = [] + let l:versions_list = [] + let l:deb_versions_list = [] + let l:list_ind = 1 + let l:seen_line = 0 - " Build a list of import paths generated from DUB, if available. + " Build a list of options generated from DUB, if available. + " DUB output each path or version on a single line. + " Each list is separated by a blank line. + " Empty list are represented by a blank line (followed and/or + " preceded by a separation blank line) for l:line in a:dub_output + " line still has end of line char on windows + let l:line = substitute(l:line, '[\r\n]*$', '', '') + if !empty(l:line) - " The arguments must be '-Ifilename', not '-I filename' - call add(l:import_list, '-I' . ale#Escape(l:line)) + if l:list_ind == 1 + call add(l:import_list, '-I' . ale#Escape(l:line)) + elseif l:list_ind == 2 + call add(l:str_import_list, '-J' . ale#Escape(l:line)) + elseif l:list_ind == 3 + call add(l:versions_list, '-version=' . ale#Escape(l:line)) + elseif l:list_ind == 4 + call add(l:deb_versions_list, '-debug=' . ale#Escape(l:line)) + endif + + let l:seen_line = 1 + elseif !l:seen_line + " if list is empty must skip one empty line + let l:seen_line = 1 + else + let l:seen_line = 0 + let l:list_ind += 1 endif endfor - return 'dmd '. join(l:import_list) . ' -o- -wi -vcolumns -c %t' + return 'dmd ' . join(l:import_list) . ' ' . + \ join(l:str_import_list) . ' ' . + \ join(l:versions_list) . ' ' . + \ join(l:deb_versions_list) . ' -o- -wi -vcolumns -c %t' 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:pattern = '\v^(\f+)\((\d+)(,(\d+))?\): (\w+): (.+)$' let l:output = [] + let l:dir = expand('#' . a:buffer . ':p:h') for l:match in ale#util#GetMatches(a:lines, l:pattern) + " If dmd was invoked with relative path, match[1] is relative, otherwise it is absolute. + " As we invoke dmd with the buffer path (in /tmp), this will generally be absolute already + let l:fname = ale#path#GetAbsPath(l:dir, l:match[1]) call add(l:output, { - \ 'lnum': l:match[1], - \ 'col': l:match[2], - \ 'type': l:match[3] is# 'Warning' ? 'W' : 'E', - \ 'text': l:match[4], + \ 'filename': l:fname, + \ 'lnum': l:match[2], + \ 'col': l:match[4], + \ 'type': l:match[5] is# 'Warning' || l:match[5] is# 'Deprecation' ? 'W' : 'E', + \ 'text': l:match[6], \}) endfor @@ -57,9 +110,7 @@ endfunction call ale#linter#Define('d', { \ 'name': 'dmd', \ 'executable': 'dmd', -\ 'command_chain': [ -\ {'callback': 'ale_linters#d#dmd#DUBCommand', 'output_stream': 'stdout'}, -\ {'callback': 'ale_linters#d#dmd#DMDCommand', 'output_stream': 'stderr'}, -\ ], +\ 'command': function('ale_linters#d#dmd#RunDUBCommand'), \ 'callback': 'ale_linters#d#dmd#Handle', +\ 'output_stream': 'stderr', \}) diff --git a/vim-config/plugins/ale/ale_linters/dafny/dafny.vim b/vim-config/plugins/ale/ale_linters/dafny/dafny.vim old mode 100755 new mode 100644 index b5b90675..2a9f761a --- a/vim-config/plugins/ale/ale_linters/dafny/dafny.vim +++ b/vim-config/plugins/ale/ale_linters/dafny/dafny.vim @@ -6,7 +6,7 @@ function! ale_linters#dafny#dafny#Handle(buffer, lines) abort for l:match in ale#util#GetMatches(a:lines, l:pattern) call add(l:output, { - \ 'bufnr': a:buffer, + \ 'filename': l:match[1], \ 'col': l:match[3] + 0, \ 'lnum': l:match[2] + 0, \ 'text': l:match[5], @@ -14,13 +14,28 @@ function! ale_linters#dafny#dafny#Handle(buffer, lines) abort \ }) endfor + for l:match in ale#util#GetMatches(a:lines, '\v(.*)\((\d+),(\d+)\): (Verification of .{-} timed out after \d+ seconds)') + call add(l:output, { + \ 'filename': l:match[1], + \ 'col': l:match[3] + 0, + \ 'lnum': l:match[2] + 0, + \ 'text': l:match[4], + \ 'type': 'E', + \ }) + endfor + return l:output endfunction +function! ale_linters#dafny#dafny#GetCommand(buffer) abort + return printf('dafny %%s /compile:0 /timeLimit:%d', ale#Var(a:buffer, 'dafny_dafny_timelimit')) +endfunction + +call ale#Set('dafny_dafny_timelimit', 10) call ale#linter#Define('dafny', { \ 'name': 'dafny', \ 'executable': 'dafny', -\ 'command': 'dafny %s /compile:0', +\ 'command': function('ale_linters#dafny#dafny#GetCommand'), \ 'callback': 'ale_linters#dafny#dafny#Handle', \ 'lint_file': 1, \ }) diff --git a/vim-config/plugins/ale/ale_linters/dart/analysis_server.vim b/vim-config/plugins/ale/ale_linters/dart/analysis_server.vim new file mode 100644 index 00000000..a6870da9 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/dart/analysis_server.vim @@ -0,0 +1,29 @@ +" Author: Nelson Yeung +" Description: Check Dart files with dart analysis server LSP + +call ale#Set('dart_analysis_server_executable', 'dart') + +function! ale_linters#dart#analysis_server#GetProjectRoot(buffer) abort + " Note: pub only looks for pubspec.yaml, there's no point in adding + " support for pubspec.yml + let l:pubspec = ale#path#FindNearestFile(a:buffer, 'pubspec.yaml') + + return !empty(l:pubspec) ? fnamemodify(l:pubspec, ':h:h') : '.' +endfunction + +function! ale_linters#dart#analysis_server#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'dart_analysis_server_executable') + let l:dart = resolve(exepath(l:executable)) + + return '%e ' + \ . fnamemodify(l:dart, ':h') . '/snapshots/analysis_server.dart.snapshot' + \ . ' --lsp' +endfunction + +call ale#linter#Define('dart', { +\ 'name': 'analysis_server', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'dart_analysis_server_executable')}, +\ 'command': function('ale_linters#dart#analysis_server#GetCommand'), +\ 'project_root': function('ale_linters#dart#analysis_server#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/dart/dart_analyze.vim b/vim-config/plugins/ale/ale_linters/dart/dart_analyze.vim new file mode 100644 index 00000000..a00162d8 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/dart/dart_analyze.vim @@ -0,0 +1,28 @@ +" Author: ghsang +" Description: Check Dart files with dart analyze + +call ale#Set('dart_analyze_executable', 'dart') + +function! ale_linters#dart#dart_analyze#Handle(buffer, lines) abort + let l:pattern = '\v^ ([a-z]+) - (.+):(\d+):(\d+) - (.+) - (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'type': l:match[1] is# 'error' ? 'E' : 'W', + \ 'text': l:match[6] . ': ' . l:match[5], + \ 'lnum': str2nr(l:match[3]), + \ 'col': str2nr(l:match[4]), + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('dart', { +\ 'name': 'dart_analyze', +\ 'executable': {b -> ale#Var(b, 'dart_analyze_executable')}, +\ 'command': '%e analyze %s', +\ 'callback': 'ale_linters#dart#dart_analyze#Handle', +\ 'lint_file': 1, +\}) diff --git a/vim-config/plugins/ale/ale_linters/dart/dartanalyzer.vim b/vim-config/plugins/ale/ale_linters/dart/dartanalyzer.vim old mode 100755 new mode 100644 index 26817df5..0a4d9742 --- a/vim-config/plugins/ale/ale_linters/dart/dartanalyzer.vim +++ b/vim-config/plugins/ale/ale_linters/dart/dartanalyzer.vim @@ -29,8 +29,8 @@ endfunction call ale#linter#Define('dart', { \ 'name': 'dartanalyzer', -\ 'executable_callback': ale#VarFunc('dart_dartanalyzer_executable'), -\ 'command_callback': 'ale_linters#dart#dartanalyzer#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/dart/language_server.vim b/vim-config/plugins/ale/ale_linters/dart/language_server.vim old mode 100755 new mode 100644 index 8e0c139b..d0e639c8 --- a/vim-config/plugins/ale/ale_linters/dart/language_server.vim +++ b/vim-config/plugins/ale/ale_linters/dart/language_server.vim @@ -14,7 +14,7 @@ endfunction call ale#linter#Define('dart', { \ 'name': 'language_server', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('dart_language_server_executable'), +\ 'executable': {b -> ale#Var(b, 'dart_language_server_executable')}, \ 'command': '%e', -\ 'project_root_callback': 'ale_linters#dart#language_server#GetProjectRoot', +\ 'project_root': function('ale_linters#dart#language_server#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/desktop/desktop_file_validate.vim b/vim-config/plugins/ale/ale_linters/desktop/desktop_file_validate.vim new file mode 100644 index 00000000..5a97d315 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/desktop/desktop_file_validate.vim @@ -0,0 +1,31 @@ +call ale#Set('desktop_desktop_file_validate_options', '') + +" Example matches for pattern: +" +" foo.desktop: warning: key "TerminalOptions" in group ... +" foo.desktop: error: action "new-private-window" is defined, ... +let s:pattern = '\v^(.+): ([a-z]+): (.+)$' + +function! ale_linters#desktop#desktop_file_validate#Handle(buffer, lines) abort + " The error format doesn't specify lines, so we can just put all of the + " errors on line 1. + return ale#util#MapMatches(a:lines, s:pattern, {match -> { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': match[2] is? 'error' ? 'E' : 'W', + \ 'text': match[3], + \}}) +endfunction + +call ale#linter#Define('desktop', { +\ 'name': 'desktop_file_validate', +\ 'aliases': ['desktop-file-validate'], +\ 'executable': 'desktop-file-validate', +\ 'command': {b -> +\ '%e' +\ . ale#Pad(ale#Var(b, 'desktop_desktop_file_validate_options')) +\ . ' %t' +\ }, +\ 'callback': 'ale_linters#desktop#desktop_file_validate#Handle', +\ 'output_stream': 'both', +\}) diff --git a/vim-config/plugins/ale/ale_linters/dockerfile/dockerfile_lint.vim b/vim-config/plugins/ale/ale_linters/dockerfile/dockerfile_lint.vim old mode 100755 new mode 100644 index a5a846f2..0c0ad533 --- a/vim-config/plugins/ale/ale_linters/dockerfile/dockerfile_lint.vim +++ b/vim-config/plugins/ale/ale_linters/dockerfile/dockerfile_lint.vim @@ -32,14 +32,29 @@ function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort let l:line = get(l:object, 'line', -1) let l:message = l:object['message'] + let l:link = get(l:object, 'reference_url', '') + + if type(l:link) == v:t_list + " Somehow, reference_url is returned as two-part list. + " Anchor markers in that list are sometimes duplicated. + " See https://github.com/projectatomic/dockerfile_lint/issues/134 + let l:link = join(l:link, '') + let l:link = substitute(l:link, '##', '#', '') + endif + + let l:detail = l:message + if get(l:object, 'description', 'None') isnot# 'None' - let l:message = l:message . '. ' . l:object['description'] + let l:detail .= "\n\n" . l:object['description'] endif + let l:detail .= "\n\n" . l:link + call add(l:messages, { \ 'lnum': l:line, \ 'text': l:message, \ 'type': ale_linters#dockerfile#dockerfile_lint#GetType(l:type), + \ 'detail': l:detail, \}) endfor endfor @@ -55,7 +70,7 @@ endfunction call ale#linter#Define('dockerfile', { \ 'name': 'dockerfile_lint', -\ 'executable_callback': ale#VarFunc('dockerfile_dockerfile_lint_executable'), -\ 'command_callback': 'ale_linters#dockerfile#dockerfile_lint#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/dockerfile/hadolint.vim b/vim-config/plugins/ale/ale_linters/dockerfile/hadolint.vim old mode 100755 new mode 100644 index dc0f5b9e..278e9466 --- a/vim-config/plugins/ale/ale_linters/dockerfile/hadolint.vim +++ b/vim-config/plugins/ale/ale_linters/dockerfile/hadolint.vim @@ -7,9 +7,9 @@ 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. + " -:19 DL3001 warning: Pipe chain should start with a raw value. " /dev/stdin:19:3 unexpected thing - let l:pattern = '\v^/dev/stdin:(\d+):?(\d+)? ((DL|SC)(\d+) )?(.+)$' + let l:pattern = '\v^%(/dev/stdin|-):(\d+):?(\d+)? ((DL|SC)(\d+) )?((.+)?: )?(.+)$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) @@ -24,10 +24,22 @@ function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort let l:colnum = l:match[2] + 0 endif - let l:type = 'W' - let l:text = l:match[6] - let l:detail = l:match[6] + " Shellcheck knows a 'style' severity - pin it to info level as well. + if l:match[7] is# 'style' + let l:type = 'I' + elseif l:match[7] is# 'info' + let l:type = 'I' + elseif l:match[7] is# 'warning' + let l:type = 'W' + else + let l:type = 'E' + endif + + let l:text = l:match[8] + let l:detail = l:match[8] let l:domain = 'https://github.com/hadolint/hadolint/wiki/' + let l:code = '' + let l:link = '' if l:match[4] is# 'SC' let l:domain = 'https://github.com/koalaman/shellcheck/wiki/' @@ -36,18 +48,26 @@ function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort if l:match[5] isnot# '' let l:code = l:match[4] . l:match[5] let l:link = ' ( ' . l:domain . l:code . ' )' + let l:text = l:code . ': ' . l:detail let l:detail = l:code . l:link . "\n\n" . l:detail else let l:type = 'E' + let l:detail = 'hadolint could not parse the file because of a syntax error.' endif - call add(l:output, { + let l:line_output = { \ 'lnum': l:lnum, \ 'col': l:colnum, \ 'type': l:type, \ 'text': l:text, \ 'detail': l:detail - \}) + \} + + if l:code isnot# '' + let l:line_output['code'] = l:code + endif + + call add(l:output, l:line_output) endfor return l:output @@ -82,18 +102,21 @@ endfunction function! ale_linters#dockerfile#hadolint#GetCommand(buffer) abort let l:command = ale_linters#dockerfile#hadolint#GetExecutable(a:buffer) + let l:opts = '--no-color -' if l:command is# 'docker' - return 'docker run --rm -i ' . ale#Var(a:buffer, 'dockerfile_hadolint_docker_image') + return printf('docker run --rm -i %s hadolint %s', + \ ale#Var(a:buffer, 'dockerfile_hadolint_docker_image'), + \ l:opts) endif - return 'hadolint -' + return 'hadolint ' . l:opts endfunction call ale#linter#Define('dockerfile', { \ 'name': 'hadolint', -\ 'executable_callback': 'ale_linters#dockerfile#hadolint#GetExecutable', -\ 'command_callback': 'ale_linters#dockerfile#hadolint#GetCommand', +\ 'executable': function('ale_linters#dockerfile#hadolint#GetExecutable'), +\ 'command': function('ale_linters#dockerfile#hadolint#GetCommand'), \ 'callback': 'ale_linters#dockerfile#hadolint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/elixir/credo.vim b/vim-config/plugins/ale/ale_linters/elixir/credo.vim old mode 100755 new mode 100644 index d778471c..d6a861f4 --- a/vim-config/plugins/ale/ale_linters/elixir/credo.vim +++ b/vim-config/plugins/ale/ale_linters/elixir/credo.vim @@ -37,16 +37,35 @@ function! ale_linters#elixir#credo#Handle(buffer, lines) abort return l:output endfunction -function! ale_linters#elixir#credo#GetCommand(buffer) abort - let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) +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#GetConfigFile() abort + let l:config_file = get(g:, 'ale_elixir_credo_config_file', '') + + if empty(l:config_file) + return '' + endif - return ale#path#CdString(l:project_root) - \ . ' mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + return ' --config-file ' . l:config_file +endfunction + +function! ale_linters#elixir#credo#GetCommand(buffer) abort + return 'mix help credo && ' + \ . 'mix credo ' . ale_linters#elixir#credo#GetMode() + \ . ale_linters#elixir#credo#GetConfigFile() + \ . ' --format=flycheck --read-from-stdin %s' endfunction call ale#linter#Define('elixir', { \ 'name': 'credo', \ 'executable': 'mix', -\ 'command_callback': 'ale_linters#elixir#credo#GetCommand', +\ 'cwd': function('ale#handlers#elixir#FindMixUmbrellaRoot'), +\ 'command': function('ale_linters#elixir#credo#GetCommand'), \ 'callback': 'ale_linters#elixir#credo#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/elixir/dialyxir.vim b/vim-config/plugins/ale/ale_linters/elixir/dialyxir.vim old mode 100755 new mode 100644 index d28d3c70..9b8a5cda --- a/vim-config/plugins/ale/ale_linters/elixir/dialyxir.vim +++ b/vim-config/plugins/ale/ale_linters/elixir/dialyxir.vim @@ -25,17 +25,10 @@ function! ale_linters#elixir#dialyxir#Handle(buffer, lines) abort return l:output endfunction -function! ale_linters#elixir#dialyxir#GetCommand(buffer) abort - let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) - - return ale#path#CdString(l:project_root) - \ . ' mix help dialyzer && mix dialyzer' -endfunction - call ale#linter#Define('elixir', { \ 'name': 'dialyxir', \ 'executable': 'mix', -\ 'command_callback': 'ale_linters#elixir#dialyxir#GetCommand', +\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'), +\ 'command': 'mix help dialyzer && mix dialyzer', \ 'callback': 'ale_linters#elixir#dialyxir#Handle', \}) - diff --git a/vim-config/plugins/ale/ale_linters/elixir/dogma.vim b/vim-config/plugins/ale/ale_linters/elixir/dogma.vim old mode 100755 new mode 100644 index dcfb6f28..28e7f420 --- a/vim-config/plugins/ale/ale_linters/elixir/dogma.vim +++ b/vim-config/plugins/ale/ale_linters/elixir/dogma.vim @@ -29,17 +29,11 @@ function! ale_linters#elixir#dogma#Handle(buffer, lines) abort return l:output endfunction -function! ale_linters#elixir#dogma#GetCommand(buffer) abort - let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) - - return ale#path#CdString(l:project_root) - \ . ' mix help dogma && mix dogma %s --format=flycheck' -endfunction - call ale#linter#Define('elixir', { \ 'name': 'dogma', \ 'executable': 'mix', -\ 'command_callback': 'ale_linters#elixir#dogma#GetCommand', +\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'), +\ 'command': 'mix help dogma && mix dogma %s --format=flycheck', \ 'lint_file': 1, \ 'callback': 'ale_linters#elixir#dogma#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/elixir/elixir_ls.vim b/vim-config/plugins/ale/ale_linters/elixir/elixir_ls.vim old mode 100755 new mode 100644 index 3b299ec6..d5517de5 --- a/vim-config/plugins/ale/ale_linters/elixir/elixir_ls.vim +++ b/vim-config/plugins/ale/ale_linters/elixir/elixir_ls.vim @@ -6,7 +6,7 @@ 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 = ale#Has('win32') ? '\language_server.bat' : '/language_server.sh' + let l:cmd = has('win32') ? '\language_server.bat' : '/language_server.sh' return l:dir . l:cmd endfunction @@ -14,8 +14,8 @@ endfunction call ale#linter#Define('elixir', { \ 'name': 'elixir-ls', \ 'lsp': 'stdio', -\ 'executable_callback': 'ale_linters#elixir#elixir_ls#GetExecutable', -\ 'command_callback': 'ale_linters#elixir#elixir_ls#GetExecutable', -\ 'project_root_callback': 'ale#handlers#elixir#FindMixUmbrellaRoot', -\ 'lsp_config_callback': ale#VarFunc('elixir_elixir_ls_config'), +\ '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/vim-config/plugins/ale/ale_linters/elixir/mix.vim b/vim-config/plugins/ale/ale_linters/elixir/mix.vim old mode 100755 new mode 100644 index dc3c1818..948c6d36 --- a/vim-config/plugins/ale/ale_linters/elixir/mix.vim +++ b/vim-config/plugins/ale/ale_linters/elixir/mix.vim @@ -30,23 +30,16 @@ function! ale_linters#elixir#mix#Handle(buffer, lines) abort endfunction function! ale_linters#elixir#mix#GetCommand(buffer) abort - let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) + let l:temp_dir = ale#command#CreateDirectory(a:buffer) - let l:temp_dir = ale#engine#CreateDirectory(a:buffer) - - let l:mix_build_path = has('win32') - \ ? 'set MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) . ' &&' - \ : 'MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) - - return ale#path#CdString(l:project_root) - \ . l:mix_build_path - \ . ' mix compile %s' + return ale#Env('MIX_BUILD_PATH', l:temp_dir) . 'mix compile %s' endfunction call ale#linter#Define('elixir', { \ 'name': 'mix', \ 'executable': 'mix', -\ 'command_callback': 'ale_linters#elixir#mix#GetCommand', +\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'), +\ 'command': function('ale_linters#elixir#mix#GetCommand'), \ 'callback': 'ale_linters#elixir#mix#Handle', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/elm/elm_ls.vim b/vim-config/plugins/ale/ale_linters/elm/elm_ls.vim new file mode 100644 index 00000000..a02dbf42 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/elm/elm_ls.vim @@ -0,0 +1,40 @@ +" Author: antew - https://github.com/antew +" Description: elm-language-server integration for elm (diagnostics, formatting, and more) + +call ale#Set('elm_ls_executable', 'elm-language-server') +call ale#Set('elm_ls_use_global', get(g:, 'ale_use_global_executables', 1)) + +" elm-language-server will search for local and global binaries, if empty +call ale#Set('elm_ls_elm_path', '') +call ale#Set('elm_ls_elm_format_path', '') +call ale#Set('elm_ls_elm_test_path', '') +call ale#Set('elm_ls_elm_analyse_trigger', 'change') + +function! elm_ls#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 + +function! elm_ls#GetOptions(buffer) abort + return { + \ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'), + \ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'), + \ 'elmTestPath': ale#Var(a:buffer, 'elm_ls_elm_test_path'), + \ 'elmAnalyseTrigger': ale#Var(a:buffer, 'elm_ls_elm_analyse_trigger'), + \} +endfunction + +call ale#linter#Define('elm', { +\ 'name': 'elm_ls', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#path#FindExecutable(b, 'elm_ls', [ +\ 'node_modules/.bin/elm-language-server', +\ 'node_modules/.bin/elm-lsp', +\ 'elm-lsp' +\ ])}, +\ 'command': '%e --stdio', +\ 'project_root': function('elm_ls#GetRootDir'), +\ 'language': 'elm', +\ 'initialization_options': function('elm_ls#GetOptions') +\}) diff --git a/vim-config/plugins/ale/ale_linters/elm/make.vim b/vim-config/plugins/ale/ale_linters/elm/make.vim old mode 100755 new mode 100644 index 76622028..a7f9ea7b --- a/vim-config/plugins/ale/ale_linters/elm/make.vim +++ b/vim-config/plugins/ale/ale_linters/elm/make.vim @@ -186,22 +186,35 @@ function! ale_linters#elm#make#IsTest(buffer) abort endif endfunction +function! ale_linters#elm#make#GetCwd(buffer) abort + let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer) + + return !empty(l:root_dir) ? l:root_dir : '' +endfunction + " Return the command to execute the linter in the projects directory. " If it doesn't, then this will fail when imports are needed. function! ale_linters#elm#make#GetCommand(buffer) abort - let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer) + let l:executable = ale_linters#elm#make#GetExecutable(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 = '' + " elm-test needs to know the path of elm-make if elm isn't installed globally. + " https://github.com/rtfeldman/node-test-runner/blob/57728f10668f2d2ab3179e7e3208bcfa9a1f19aa/README.md#--compiler + if l:is_v19 && l:is_using_elm_test + let l:elm_make_executable = ale#path#FindExecutable(a:buffer, 'elm_make', ['node_modules/.bin/elm']) + let l:elm_test_compiler_flag = ' --compiler ' . l:elm_make_executable . ' ' else - let l:dir_set_cmd = 'cd ' . ale#Escape(l:root_dir) . ' && ' + 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 %t' + return '%e make --report=json --output=/dev/null' + \ . l:elm_test_compiler_flag + \ . '%t' endfunction function! ale_linters#elm#make#GetExecutable(buffer) abort @@ -209,20 +222,21 @@ function! ale_linters#elm#make#GetExecutable(buffer) abort let l:is_v19 = ale_linters#elm#make#IsVersionGte19(a:buffer) if l:is_test && l:is_v19 - return ale#node#FindExecutable( -\ a:buffer, -\ 'elm_make', -\ ['node_modules/.bin/elm-test', 'node_modules/.bin/elm'] -\ ) + return ale#path#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']) + return ale#path#FindExecutable(a:buffer, 'elm_make', ['node_modules/.bin/elm']) endif endfunction call ale#linter#Define('elm', { \ 'name': 'make', -\ 'executable_callback': 'ale_linters#elm#make#GetExecutable', +\ 'executable': function('ale_linters#elm#make#GetExecutable'), \ 'output_stream': 'both', -\ 'command_callback': 'ale_linters#elm#make#GetCommand', +\ 'cwd': function('ale_linters#elm#make#GetCwd'), +\ 'command': function('ale_linters#elm#make#GetCommand'), \ 'callback': 'ale_linters#elm#make#Handle' \}) diff --git a/vim-config/plugins/ale/ale_linters/erlang/dialyzer.vim b/vim-config/plugins/ale/ale_linters/erlang/dialyzer.vim new file mode 100644 index 00000000..a97c9520 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/erlang/dialyzer.vim @@ -0,0 +1,97 @@ +" Author: Autoine Gagne - https://github.com/AntoineGagne +" Description: Define a checker that runs dialyzer on Erlang files. + +let g:ale_erlang_dialyzer_executable = +\ get(g:, 'ale_erlang_dialyzer_executable', 'dialyzer') +let g:ale_erlang_dialyzer_options = +\ get(g:, 'ale_erlang_dialyzer_options', '-Wunmatched_returns' +\ . ' -Werror_handling' +\ . ' -Wrace_conditions' +\ . ' -Wunderspecs') +let g:ale_erlang_dialyzer_plt_file = +\ get(g:, 'ale_erlang_dialyzer_plt_file', '') +let g:ale_erlang_dialyzer_rebar3_profile = +\ get(g:, 'ale_erlang_dialyzer_rebar3_profile', 'default') + +function! ale_linters#erlang#dialyzer#GetRebar3Profile(buffer) abort + return ale#Var(a:buffer, 'erlang_dialyzer_rebar3_profile') +endfunction + +function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort + let l:plt_file = '' + let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer) + let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build/' . l:rebar3_profile) + + if !empty(l:plt_file_directory) + let l:plt_file = globpath(l:plt_file_directory, '*_plt', 0, 1) + endif + + if !empty(l:plt_file) + return l:plt_file[0] + endif + + if !empty($REBAR_PLT_DIR) + return expand('$REBAR_PLT_DIR/dialyzer/plt') + endif + + return expand('$HOME/.dialyzer_plt') +endfunction + +function! ale_linters#erlang#dialyzer#GetPlt(buffer) abort + let l:plt_file = ale#Var(a:buffer, 'erlang_dialyzer_plt_file') + + if !empty(l:plt_file) + return l:plt_file + endif + + return ale_linters#erlang#dialyzer#FindPlt(a:buffer) +endfunction + +function! ale_linters#erlang#dialyzer#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'erlang_dialyzer_executable') +endfunction + +function! ale_linters#erlang#dialyzer#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'erlang_dialyzer_options') + + let l:command = ale#Escape(ale_linters#erlang#dialyzer#GetExecutable(a:buffer)) + \ . ' -n' + \ . ' --plt ' . ale#Escape(ale_linters#erlang#dialyzer#GetPlt(a:buffer)) + \ . ' ' . l:options + \ . ' %s' + + return l:command +endfunction + +function! ale_linters#erlang#dialyzer#Handle(buffer, lines) abort + " Match patterns like the following: + " + " erl_tidy_prv_fmt.erl:3: Callback info about the provider behaviour is not available + let l:pattern = '^\S\+:\(\d\+\): \(.\+\)$' + let l:output = [] + + for l:line in a:lines + let l:match = matchlist(l:line, l:pattern) + + if len(l:match) != 0 + let l:code = l:match[2] + + call add(l:output, { + \ 'lnum': str2nr(l:match[1]), + \ 'lcol': 0, + \ 'text': l:code, + \ 'type': 'W' + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('erlang', { +\ 'name': 'dialyzer', +\ 'executable': function('ale_linters#erlang#dialyzer#GetExecutable'), +\ 'command': function('ale_linters#erlang#dialyzer#GetCommand'), +\ 'callback': function('ale_linters#erlang#dialyzer#Handle'), +\ 'lint_file': 1 +\}) diff --git a/vim-config/plugins/ale/ale_linters/erlang/elvis.vim b/vim-config/plugins/ale/ale_linters/erlang/elvis.vim new file mode 100644 index 00000000..31dea3dd --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/erlang/elvis.vim @@ -0,0 +1,39 @@ +" Author: Dmitri Vereshchagin +" Description: Elvis linter for Erlang files + +call ale#Set('erlang_elvis_executable', 'elvis') + +function! ale_linters#erlang#elvis#Handle(buffer, lines) abort + let l:pattern = '\v:(\d+):[^:]+:(.+)' + let l:loclist = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:loclist, { + \ 'lnum': str2nr(l:match[1]), + \ 'text': s:AbbreviateMessage(l:match[2]), + \ 'type': 'W', + \}) + endfor + + return l:loclist +endfunction + +function! s:AbbreviateMessage(text) abort + let l:pattern = '\v\c^(line \d+ is too long):.*$' + + return substitute(a:text, l:pattern, '\1.', '') +endfunction + +function! s:GetCommand(buffer) abort + let l:file = ale#Escape(expand('#' . a:buffer . ':.')) + + return '%e rock --output-format=parsable ' . l:file +endfunction + +call ale#linter#Define('erlang', { +\ 'name': 'elvis', +\ 'callback': 'ale_linters#erlang#elvis#Handle', +\ 'executable': {b -> ale#Var(b, 'erlang_elvis_executable')}, +\ 'command': function('s:GetCommand'), +\ 'lint_file': 1, +\}) diff --git a/vim-config/plugins/ale/ale_linters/erlang/erlc.vim b/vim-config/plugins/ale/ale_linters/erlang/erlc.vim old mode 100755 new mode 100644 index 0bdb4dea..0c67a73f --- a/vim-config/plugins/ale/ale_linters/erlang/erlc.vim +++ b/vim-config/plugins/ale/ale_linters/erlang/erlc.vim @@ -1,14 +1,22 @@ " Author: Magnus Ottenklinger - https://github.com/evnu +let g:ale_erlang_erlc_executable = get(g:, 'ale_erlang_erlc_executable', 'erlc') let g:ale_erlang_erlc_options = get(g:, 'ale_erlang_erlc_options', '') +function! ale_linters#erlang#erlc#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'erlang_erlc_executable') +endfunction + function! ale_linters#erlang#erlc#GetCommand(buffer) abort let l:output_file = ale#util#Tempname() - call ale#engine#ManageFile(a:buffer, l:output_file) + call ale#command#ManageFile(a:buffer, l:output_file) + + let l:command = ale#Escape(ale_linters#erlang#erlc#GetExecutable(a:buffer)) + \ . ' -o ' . ale#Escape(l:output_file) + \ . ' ' . ale#Var(a:buffer, 'erlang_erlc_options') + \ . ' %t' - return 'erlc -o ' . ale#Escape(l:output_file) - \ . ' ' . ale#Var(a:buffer, 'erlang_erlc_options') - \ . ' %t' + return l:command endfunction function! ale_linters#erlang#erlc#Handle(buffer, lines) abort @@ -17,7 +25,7 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort " error.erl:4: variable 'B' is unbound " error.erl:3: Warning: function main/0 is unused " error.erl:4: Warning: variable 'A' is unused - let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+): (Warning: )?(.+)$' + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+:)? (Warning: )?(.+)$' " parse_transforms are a special case. The error message does not indicate a location: " error.erl: undefined parse transform 'some_parse_transform' @@ -57,8 +65,8 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort endif let l:line = l:match[2] - let l:warning_or_text = l:match[3] - let l:text = l:match[4] + let l:warning_or_text = l:match[4] + let l:text = l:match[5] " If this file is a header .hrl, ignore the following expected messages: " - 'no module definition' @@ -90,7 +98,7 @@ endfunction call ale#linter#Define('erlang', { \ 'name': 'erlc', -\ 'executable': 'erlc', -\ 'command_callback': 'ale_linters#erlang#erlc#GetCommand', +\ 'executable': function('ale_linters#erlang#erlc#GetExecutable'), +\ 'command': function('ale_linters#erlang#erlc#GetCommand'), \ 'callback': 'ale_linters#erlang#erlc#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/erlang/syntaxerl.vim b/vim-config/plugins/ale/ale_linters/erlang/syntaxerl.vim old mode 100755 new mode 100644 index 5b679743..5d555a8d --- a/vim-config/plugins/ale/ale_linters/erlang/syntaxerl.vim +++ b/vim-config/plugins/ale/ale_linters/erlang/syntaxerl.vim @@ -3,7 +3,17 @@ call ale#Set('erlang_syntaxerl_executable', 'syntaxerl') -function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output) abort +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') @@ -26,10 +36,7 @@ endfunction call ale#linter#Define('erlang', { \ 'name': 'syntaxerl', -\ 'executable_callback': ale#VarFunc('erlang_syntaxerl_executable'), -\ 'command_chain': [ -\ {'callback': {-> '%e -h'}}, -\ {'callback': 'ale_linters#erlang#syntaxerl#GetCommand'}, -\ ], +\ '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/vim-config/plugins/ale/ale_linters/eruby/erb.vim b/vim-config/plugins/ale/ale_linters/eruby/erb.vim old mode 100755 new mode 100644 index 61d97032..f3438320 --- a/vim-config/plugins/ale/ale_linters/eruby/erb.vim +++ b/vim-config/plugins/ale/ale_linters/eruby/erb.vim @@ -19,7 +19,7 @@ call ale#linter#Define('eruby', { \ 'aliases': ['erubylint'], \ 'executable': 'erb', \ 'output_stream': 'stderr', -\ 'command_callback': 'ale_linters#eruby#erb#GetCommand', +\ 'command': function('ale_linters#eruby#erb#GetCommand'), \ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', \}) diff --git a/vim-config/plugins/ale/ale_linters/eruby/erblint.vim b/vim-config/plugins/ale/ale_linters/eruby/erblint.vim new file mode 100644 index 00000000..19960185 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/eruby/erblint.vim @@ -0,0 +1,51 @@ +" Author: Roeland Moors - https://github.com/roelandmoors +" based on the ale ruumba and robocop linters +" Description: ERB Lint, support for https://github.com/Shopify/erb-lint + +call ale#Set('eruby_erblint_executable', 'erblint') +call ale#Set('eruby_erblint_options', '') + +function! ale_linters#eruby#erblint#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'eruby_erblint_executable') + + return ale#ruby#EscapeExecutable(l:executable, 'erblint') + \ . ' --format json ' + \ . ale#Var(a:buffer, 'eruby_erblint_options') + \ . ' --stdin %s' +endfunction + +function! ale_linters#eruby#erblint#Handle(buffer, lines) abort + if empty(a:lines) + return [] + endif + + let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], []) + + if !has_key(l:errors, 'summary') + \|| l:errors['summary']['offenses'] == 0 + \|| empty(l:errors['files']) + return [] + endif + + let l:output = [] + + for l:error in l:errors['files'][0]['offenses'] + call add(l:output, { + \ 'lnum': l:error['location']['start_line'] + 0, + \ 'col': l:error['location']['start_column'] + 0, + \ 'end_col': l:error['location']['last_column'] + 0, + \ 'code': l:error['linter'], + \ 'text': l:error['message'], + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('eruby', { +\ 'name': 'erblint', +\ 'executable': {b -> ale#Var(b, 'eruby_erblint_executable')}, +\ 'command': function('ale_linters#eruby#erblint#GetCommand'), +\ 'callback': 'ale_linters#eruby#erblint#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/eruby/erubi.vim b/vim-config/plugins/ale/ale_linters/eruby/erubi.vim old mode 100755 new mode 100644 index 6f2d3ac6..ddca3f61 --- a/vim-config/plugins/ale/ale_linters/eruby/erubi.vim +++ b/vim-config/plugins/ale/ale_linters/eruby/erubi.vim @@ -1,14 +1,10 @@ " Author: Eddie Lebow https://github.com/elebow " Description: eruby checker using `erubi` -function! ale_linters#eruby#erubi#CheckErubi(buffer) abort - return 'ruby -r erubi/capture_end -e ' . ale#Escape('""') -endfunction - -function! ale_linters#eruby#erubi#GetCommand(buffer, check_erubi_output) abort +function! ale_linters#eruby#erubi#GetCommand(buffer, output, meta) abort let l:rails_root = ale#ruby#FindRailsRoot(a:buffer) - if (!empty(a:check_erubi_output)) + if !empty(a:output) " The empty command in CheckErubi returns nothing if erubi runs and " emits an error if erubi is not present return '' @@ -27,9 +23,10 @@ endfunction call ale#linter#Define('eruby', { \ 'name': 'erubi', \ 'executable': 'ruby', -\ 'command_chain': [ -\ {'callback': 'ale_linters#eruby#erubi#CheckErubi'}, -\ {'callback': 'ale_linters#eruby#erubi#GetCommand', 'output_stream': 'stderr'}, -\ ], +\ '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/vim-config/plugins/ale/ale_linters/eruby/erubis.vim b/vim-config/plugins/ale/ale_linters/eruby/erubis.vim old mode 100755 new mode 100644 index 1ebd4a05..755c5803 --- a/vim-config/plugins/ale/ale_linters/eruby/erubis.vim +++ b/vim-config/plugins/ale/ale_linters/eruby/erubis.vim @@ -18,6 +18,6 @@ call ale#linter#Define('eruby', { \ 'name': 'erubis', \ 'executable': 'erubis', \ 'output_stream': 'stderr', -\ 'command_callback': 'ale_linters#eruby#erubis#GetCommand', +\ 'command': function('ale_linters#eruby#erubis#GetCommand'), \ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', \}) diff --git a/vim-config/plugins/ale/ale_linters/eruby/ruumba.vim b/vim-config/plugins/ale/ale_linters/eruby/ruumba.vim old mode 100755 new mode 100644 index 24f112e4..f415f1ab --- a/vim-config/plugins/ale/ale_linters/eruby/ruumba.vim +++ b/vim-config/plugins/ale/ale_linters/eruby/ruumba.vim @@ -8,10 +8,10 @@ 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') + return ale#ruby#EscapeExecutable(l:executable, 'ruumba') \ . ' --format json --force-exclusion ' \ . ale#Var(a:buffer, 'eruby_ruumba_options') - \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) + \ . ' --stdin %s' endfunction function! ale_linters#eruby#ruumba#Handle(buffer, lines) abort @@ -56,7 +56,7 @@ endfunction call ale#linter#Define('eruby', { \ 'name': 'ruumba', -\ 'executable_callback': ale#VarFunc('eruby_ruumba_executable'), -\ 'command_callback': 'ale_linters#eruby#ruumba#GetCommand', +\ 'executable': {b -> ale#Var(b, 'eruby_ruumba_executable')}, +\ 'command': function('ale_linters#eruby#ruumba#GetCommand'), \ 'callback': 'ale_linters#eruby#ruumba#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/fish/fish.vim b/vim-config/plugins/ale/ale_linters/fish/fish.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/fortran/gcc.vim b/vim-config/plugins/ale/ale_linters/fortran/gcc.vim old mode 100755 new mode 100644 index f1595789..6e97d6fd --- a/vim-config/plugins/ale/ale_linters/fortran/gcc.vim +++ b/vim-config/plugins/ale/ale_linters/fortran/gcc.vim @@ -66,7 +66,7 @@ endfunction call ale#linter#Define('fortran', { \ 'name': 'gcc', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('fortran_gcc_executable'), -\ 'command_callback': 'ale_linters#fortran#gcc#GetCommand', +\ 'executable': {b -> ale#Var(b, 'fortran_gcc_executable')}, +\ 'command': function('ale_linters#fortran#gcc#GetCommand'), \ 'callback': 'ale_linters#fortran#gcc#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/fortran/language_server.vim b/vim-config/plugins/ale/ale_linters/fortran/language_server.vim old mode 100755 new mode 100644 index 4e5f5dc4..00aa0577 --- a/vim-config/plugins/ale/ale_linters/fortran/language_server.vim +++ b/vim-config/plugins/ale/ale_linters/fortran/language_server.vim @@ -13,7 +13,7 @@ endfunction call ale#linter#Define('fortran', { \ 'name': 'language_server', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('fortran_language_server_executable'), +\ 'executable': {b -> ale#Var(b, 'fortran_language_server_executable')}, \ 'command': '%e', -\ 'project_root_callback': 'ale_linters#fortran#language_server#GetProjectRoot', +\ 'project_root': function('ale_linters#fortran#language_server#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/fountain/proselint.vim b/vim-config/plugins/ale/ale_linters/fountain/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/fuse/fusionlint.vim b/vim-config/plugins/ale/ale_linters/fuse/fusionlint.vim old mode 100755 new mode 100644 index ab8f143b..ffb25d33 --- a/vim-config/plugins/ale/ale_linters/fuse/fusionlint.vim +++ b/vim-config/plugins/ale/ale_linters/fuse/fusionlint.vim @@ -27,7 +27,7 @@ endfunction call ale#linter#Define('fuse', { \ 'name': 'fusionlint', -\ 'executable_callback': ale#VarFunc('fuse_fusionlint_executable'), -\ 'command_callback': 'ale_linters#fuse#fusionlint#GetCommand', +\ 'executable': {b -> ale#Var(b, 'fuse_fusionlint_executable')}, +\ 'command': function('ale_linters#fuse#fusionlint#GetCommand'), \ 'callback': 'ale_linters#fuse#fusionlint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/gitcommit/gitlint.vim b/vim-config/plugins/ale/ale_linters/gitcommit/gitlint.vim old mode 100755 new mode 100644 index a9c4822d..4b9cec63 --- a/vim-config/plugins/ale/ale_linters/gitcommit/gitlint.vim +++ b/vim-config/plugins/ale/ale_linters/gitcommit/gitlint.vim @@ -45,7 +45,7 @@ endfunction call ale#linter#Define('gitcommit', { \ 'name': 'gitlint', \ 'output_stream': 'stderr', -\ 'executable_callback': 'ale_linters#gitcommit#gitlint#GetExecutable', -\ 'command_callback': 'ale_linters#gitcommit#gitlint#GetCommand', +\ 'executable': function('ale_linters#gitcommit#gitlint#GetExecutable'), +\ 'command': function('ale_linters#gitcommit#gitlint#GetCommand'), \ 'callback': 'ale_linters#gitcommit#gitlint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/glsl/glslang.vim b/vim-config/plugins/ale/ale_linters/glsl/glslang.vim old mode 100755 new mode 100644 index d55a5e7c..bbddce90 --- a/vim-config/plugins/ale/ale_linters/glsl/glslang.vim +++ b/vim-config/plugins/ale/ale_linters/glsl/glslang.vim @@ -34,7 +34,7 @@ endfunction call ale#linter#Define('glsl', { \ 'name': 'glslang', -\ 'executable_callback': ale#VarFunc('glsl_glslang_executable'), -\ 'command_callback': 'ale_linters#glsl#glslang#GetCommand', +\ 'executable': {b -> ale#Var(b, 'glsl_glslang_executable')}, +\ 'command': function('ale_linters#glsl#glslang#GetCommand'), \ 'callback': 'ale_linters#glsl#glslang#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/glsl/glslls.vim b/vim-config/plugins/ale/ale_linters/glsl/glslls.vim old mode 100755 new mode 100644 index 8c6d9bd9..b62844c7 --- a/vim-config/plugins/ale/ale_linters/glsl/glslls.vim +++ b/vim-config/plugins/ale/ale_linters/glsl/glslls.vim @@ -24,7 +24,7 @@ endfunction call ale#linter#Define('glsl', { \ 'name': 'glslls', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('glsl_glslls_executable'), -\ 'command_callback': 'ale_linters#glsl#glslls#GetCommand', -\ 'project_root_callback': 'ale_linters#glsl#glslls#GetProjectRoot', +\ '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/vim-config/plugins/ale/ale_linters/go/bingo.vim b/vim-config/plugins/ale/ale_linters/go/bingo.vim old mode 100755 new mode 100644 index ba80fbe8..1e43f8e4 --- a/vim-config/plugins/ale/ale_linters/go/bingo.vim +++ b/vim-config/plugins/ale/ale_linters/go/bingo.vim @@ -5,11 +5,13 @@ 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')) + return ale#go#EnvString(a:buffer) . '%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:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off' + let l:project_root = l:go_modules_off ? + \ '' : ale#path#FindNearestFile(a:buffer, 'go.mod') let l:mods = ':h' if empty(l:project_root) @@ -23,7 +25,7 @@ endfunction call ale#linter#Define('go', { \ 'name': 'bingo', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('go_bingo_executable'), -\ 'command_callback': 'ale_linters#go#bingo#GetCommand', -\ 'project_root_callback': 'ale_linters#go#bingo#FindProjectRoot', +\ '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/vim-config/plugins/ale/ale_linters/go/gobuild.vim b/vim-config/plugins/ale/ale_linters/go/gobuild.vim old mode 100755 new mode 100644 index cef1ff88..5210c5a8 --- a/vim-config/plugins/ale/ale_linters/go/gobuild.vim +++ b/vim-config/plugins/ale/ale_linters/go/gobuild.vim @@ -10,7 +10,7 @@ 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) + return ale#go#EnvString(a:buffer) \ . ale#Var(a:buffer, 'go_go_executable') . ' test' \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -c -o /dev/null ./' @@ -48,8 +48,9 @@ endfunction call ale#linter#Define('go', { \ 'name': 'gobuild', \ 'aliases': ['go build'], -\ 'executable_callback': ale#VarFunc('go_go_executable'), -\ 'command_callback': 'ale_linters#go#gobuild#GetCommand', +\ 'executable': {b -> ale#Var(b, 'go_go_executable')}, +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#go#gobuild#GetCommand'), \ 'output_stream': 'stderr', \ 'callback': 'ale_linters#go#gobuild#Handler', \ 'lint_file': 1, diff --git a/vim-config/plugins/ale/ale_linters/go/gofmt.vim b/vim-config/plugins/ale/ale_linters/go/gofmt.vim old mode 100755 new mode 100644 index 337deef8..b313f9ca --- a/vim-config/plugins/ale/ale_linters/go/gofmt.vim +++ b/vim-config/plugins/ale/ale_linters/go/gofmt.vim @@ -1,10 +1,15 @@ " Author: neersighted " Description: gofmt for Go files +function! ale_linters#go#gofmt#GetCommand(buffer) abort + return ale#go#EnvString(a:buffer) + \ . '%e -e %t' +endfunction + call ale#linter#Define('go', { \ 'name': 'gofmt', \ 'output_stream': 'stderr', \ 'executable': 'gofmt', -\ 'command': 'gofmt -e %t', +\ 'command': function('ale_linters#go#gofmt#GetCommand'), \ 'callback': 'ale#handlers#unix#HandleAsError', \}) diff --git a/vim-config/plugins/ale/ale_linters/go/golangci_lint.vim b/vim-config/plugins/ale/ale_linters/go/golangci_lint.vim old mode 100755 new mode 100644 index dd9a3c64..2c4b1a4f --- a/vim-config/plugins/ale/ale_linters/go/golangci_lint.vim +++ b/vim-config/plugins/ale/ale_linters/go/golangci_lint.vim @@ -10,13 +10,14 @@ function! ale_linters#go#golangci_lint#GetCommand(buffer) abort 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) + return ale#go#EnvString(a:buffer) \ . '%e run ' \ . l:options endif - return ale#path#BufferCdString(a:buffer) + return ale#go#EnvString(a:buffer) \ . '%e run ' \ . ale#Escape(l:filename) \ . ' ' . l:options @@ -49,8 +50,9 @@ endfunction call ale#linter#Define('go', { \ 'name': 'golangci-lint', -\ 'executable_callback': ale#VarFunc('go_golangci_lint_executable'), -\ 'command_callback': 'ale_linters#go#golangci_lint#GetCommand', +\ 'executable': {b -> ale#Var(b, 'go_golangci_lint_executable')}, +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#go#golangci_lint#GetCommand'), \ 'callback': 'ale_linters#go#golangci_lint#Handler', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/go/golint.vim b/vim-config/plugins/ale/ale_linters/go/golint.vim old mode 100755 new mode 100644 index 4bf14fcc..79bfaeb5 --- a/vim-config/plugins/ale/ale_linters/go/golint.vim +++ b/vim-config/plugins/ale/ale_linters/go/golint.vim @@ -7,7 +7,7 @@ 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' + return ale#go#EnvString(a:buffer) . '%e' \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' %t' endfunction @@ -15,7 +15,7 @@ endfunction call ale#linter#Define('go', { \ 'name': 'golint', \ 'output_stream': 'both', -\ 'executable_callback': ale#VarFunc('go_golint_executable'), -\ 'command_callback': 'ale_linters#go#golint#GetCommand', +\ 'executable': {b -> ale#Var(b, 'go_golint_executable')}, +\ 'command': function('ale_linters#go#golint#GetCommand'), \ 'callback': 'ale#handlers#unix#HandleAsWarning', \}) diff --git a/vim-config/plugins/ale/ale_linters/go/gometalinter.vim b/vim-config/plugins/ale/ale_linters/go/gometalinter.vim old mode 100755 new mode 100644 index d005e1d2..ac33a9f3 --- a/vim-config/plugins/ale/ale_linters/go/gometalinter.vim +++ b/vim-config/plugins/ale/ale_linters/go/gometalinter.vim @@ -13,12 +13,12 @@ function! ale_linters#go#gometalinter#GetCommand(buffer) abort " 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) + return ale#go#EnvString(a:buffer) \ . '%e' \ . (!empty(l:options) ? ' ' . l:options : '') . ' .' endif - return ale#path#BufferCdString(a:buffer) + return ale#go#EnvString(a:buffer) \ . '%e' \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename)) \ . (!empty(l:options) ? ' ' . l:options : '') . ' .' @@ -50,8 +50,9 @@ endfunction call ale#linter#Define('go', { \ 'name': 'gometalinter', -\ 'executable_callback': ale#VarFunc('go_gometalinter_executable'), -\ 'command_callback': 'ale_linters#go#gometalinter#GetCommand', +\ 'executable': {b -> ale#Var(b, 'go_gometalinter_executable')}, +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#go#gometalinter#GetCommand'), \ 'callback': 'ale_linters#go#gometalinter#Handler', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/go/gopls.vim b/vim-config/plugins/ale/ale_linters/go/gopls.vim new file mode 100644 index 00000000..80909830 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/go/gopls.vim @@ -0,0 +1,39 @@ +" 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') +call ale#Set('go_gopls_init_options', {}) +call ale#Set('go_gopls_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#go#gopls#GetCommand(buffer) abort + return ale#go#EnvString(a:buffer) + \ . '%e' + \ . ale#Pad(ale#Var(a:buffer, 'go_gopls_options')) +endfunction + +function! ale_linters#go#gopls#FindProjectRoot(buffer) abort + let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off' + let l:project_root = l:go_modules_off ? + \ '' : 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#path#FindExecutable(b, 'go_gopls', [ +\ ale#go#GetGoPathExecutable('bin/gopls'), +\ ])}, +\ 'command': function('ale_linters#go#gopls#GetCommand'), +\ 'project_root': function('ale_linters#go#gopls#FindProjectRoot'), +\ 'initialization_options': {b -> ale#Var(b, 'go_gopls_init_options')}, +\}) diff --git a/vim-config/plugins/ale/ale_linters/go/gosimple.vim b/vim-config/plugins/ale/ale_linters/go/gosimple.vim old mode 100755 new mode 100644 index dbdc3fcf..490d15a9 --- a/vim-config/plugins/ale/ale_linters/go/gosimple.vim +++ b/vim-config/plugins/ale/ale_linters/go/gosimple.vim @@ -1,14 +1,11 @@ " 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_callback': 'ale_linters#go#gosimple#GetCommand', +\ 'cwd': '%s:h', +\ 'command': {b -> ale#go#EnvString(b) . 'gosimple .'}, \ 'callback': 'ale#handlers#go#Handler', \ 'output_stream': 'both', \ 'lint_file': 1, diff --git a/vim-config/plugins/ale/ale_linters/go/gotype.vim b/vim-config/plugins/ale/ale_linters/go/gotype.vim old mode 100755 new mode 100644 index a678e0f3..8fd6df27 --- a/vim-config/plugins/ale/ale_linters/go/gotype.vim +++ b/vim-config/plugins/ale/ale_linters/go/gotype.vim @@ -1,19 +1,24 @@ " Author: Jelte Fennema " Description: gotype for Go files -function! ale_linters#go#gotype#GetCommand(buffer) abort +function! ale_linters#go#gotype#GetExecutable(buffer) abort if expand('#' . a:buffer . ':p') =~# '_test\.go$' return '' endif - return ale#path#BufferCdString(a:buffer) . ' gotype .' + return 'gotype' +endfunction + +function! ale_linters#go#gotype#GetCommand(buffer) abort + return ale#go#EnvString(a:buffer) . 'gotype -e .' endfunction call ale#linter#Define('go', { \ 'name': 'gotype', \ 'output_stream': 'stderr', -\ 'executable': 'gotype', -\ 'command_callback': 'ale_linters#go#gotype#GetCommand', +\ 'executable': function('ale_linters#go#gotype#GetExecutable'), +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#go#gotype#GetCommand'), \ 'callback': 'ale#handlers#go#Handler', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/go/govet.vim b/vim-config/plugins/ale/ale_linters/go/govet.vim old mode 100755 new mode 100644 index 3d0d2adf..5da8261c --- a/vim-config/plugins/ale/ale_linters/go/govet.vim +++ b/vim-config/plugins/ale/ale_linters/go/govet.vim @@ -10,7 +10,7 @@ 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) . ' ' + return ale#go#EnvString(a:buffer) \ . ale#Var(a:buffer, 'go_go_executable') . ' vet ' \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' .' @@ -20,8 +20,9 @@ call ale#linter#Define('go', { \ 'name': 'govet', \ 'aliases': ['go vet'], \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('go_go_executable'), -\ 'command_callback': 'ale_linters#go#govet#GetCommand', +\ 'executable': {b -> ale#Var(b, 'go_go_executable')}, +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#go#govet#GetCommand'), \ 'callback': 'ale#handlers#go#Handler', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/go/langserver.vim b/vim-config/plugins/ale/ale_linters/go/langserver.vim old mode 100755 new mode 100644 index df956483..7130db40 --- a/vim-config/plugins/ale/ale_linters/go/langserver.vim +++ b/vim-config/plugins/ale/ale_linters/go/langserver.vim @@ -10,19 +10,20 @@ function! ale_linters#go#langserver#GetCommand(buffer) abort 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') == 1) - call add(l:options, '-gocodecompletion') + if ale#Var(a:buffer, 'completion_enabled') + call add(l:options, '-gocodecompletion') endif let l:options = uniq(sort(l:options)) + let l:env = ale#go#EnvString(a:buffer) - return join(extend(l:executable, l:options), ' ') + return l:env . join(extend(l:executable, l:options), ' ') endfunction call ale#linter#Define('go', { \ 'name': 'golangserver', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('go_langserver_executable'), -\ 'command_callback': 'ale_linters#go#langserver#GetCommand', -\ 'project_root_callback': 'ale#go#FindProjectRoot', +\ 'executable': {b -> ale#Var(b, 'go_langserver_executable')}, +\ 'command': function('ale_linters#go#langserver#GetCommand'), +\ 'project_root': function('ale#go#FindProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/go/revive.vim b/vim-config/plugins/ale/ale_linters/go/revive.vim new file mode 100644 index 00000000..b14b5ab9 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/go/revive.vim @@ -0,0 +1,21 @@ +" Author: Penghui Liao +" Description: Adds support for revive + +call ale#Set('go_revive_executable', 'revive') +call ale#Set('go_revive_options', '') + +function! ale_linters#go#revive#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'go_revive_options') + + return ale#go#EnvString(a:buffer) . '%e' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' %t' +endfunction + +call ale#linter#Define('go', { +\ 'name': 'revive', +\ 'output_stream': 'both', +\ 'executable': {b -> ale#Var(b, 'go_revive_executable')}, +\ 'command': function('ale_linters#go#revive#GetCommand'), +\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\}) diff --git a/vim-config/plugins/ale/ale_linters/go/staticcheck.vim b/vim-config/plugins/ale/ale_linters/go/staticcheck.vim old mode 100755 new mode 100644 index a3464015..36622440 --- a/vim-config/plugins/ale/ale_linters/go/staticcheck.vim +++ b/vim-config/plugins/ale/ale_linters/go/staticcheck.vim @@ -1,32 +1,33 @@ " Author: Ben Reedy " Description: staticcheck for Go files +call ale#Set('go_staticcheck_executable', 'staticcheck') call ale#Set('go_staticcheck_options', '') -call ale#Set('go_staticcheck_lint_package', 0) +call ale#Set('go_staticcheck_lint_package', 1) +call ale#Set('go_staticcheck_use_global', get(g:, 'ale_use_global_executables', 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') + let l:env = ale#go#EnvString(a:buffer) - " 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' + return l:env . '%e' \ . (!empty(l:options) ? ' ' . l:options : '') . ' .' endif - return ale#path#BufferCdString(a:buffer) - \ . 'staticcheck' + return l:env . '%e' \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' ' . ale#Escape(l:filename) + \ . ' %s:t' endfunction call ale#linter#Define('go', { \ 'name': 'staticcheck', -\ 'executable': 'staticcheck', -\ 'command_callback': 'ale_linters#go#staticcheck#GetCommand', +\ 'executable': {b -> ale#path#FindExecutable(b, 'go_staticcheck', [ +\ ale#go#GetGoPathExecutable('bin/staticcheck'), +\ ])}, +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#go#staticcheck#GetCommand'), \ 'callback': 'ale#handlers#go#Handler', \ 'output_stream': 'both', \ 'lint_file': 1, diff --git a/vim-config/plugins/ale/ale_linters/graphql/eslint.vim b/vim-config/plugins/ale/ale_linters/graphql/eslint.vim old mode 100755 new mode 100644 index dfcbf9d9..a98233e9 --- a/vim-config/plugins/ale/ale_linters/graphql/eslint.vim +++ b/vim-config/plugins/ale/ale_linters/graphql/eslint.vim @@ -3,7 +3,8 @@ call ale#linter#Define('graphql', { \ 'name': 'eslint', -\ 'executable_callback': 'ale#handlers#eslint#GetExecutable', -\ 'command_callback': 'ale#handlers#eslint#GetCommand', -\ 'callback': 'ale#handlers#eslint#Handle', +\ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/vim-config/plugins/ale/ale_linters/graphql/gqlint.vim b/vim-config/plugins/ale/ale_linters/graphql/gqlint.vim old mode 100755 new mode 100644 index e45bf4c8..6f1ca54a --- a/vim-config/plugins/ale/ale_linters/graphql/gqlint.vim +++ b/vim-config/plugins/ale/ale_linters/graphql/gqlint.vim @@ -1,15 +1,10 @@ " 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_callback': 'ale_linters#graphql#gqlint#GetCommand', +\ 'cwd': '%s:h', +\ 'command': 'gqlint --reporter=simple %t', \ 'callback': 'ale#handlers#unix#HandleAsWarning', \}) diff --git a/vim-config/plugins/ale/ale_linters/hack/hack.vim b/vim-config/plugins/ale/ale_linters/hack/hack.vim old mode 100755 new mode 100644 index aea428cc..822b5c87 --- a/vim-config/plugins/ale/ale_linters/hack/hack.vim +++ b/vim-config/plugins/ale/ale_linters/hack/hack.vim @@ -16,7 +16,7 @@ endfunction call ale#linter#Define('hack', { \ 'name': 'hack', \ 'lsp': 'stdio', -\ 'executable_callback': 'ale_linters#hack#hack#GetExecutable', +\ 'executable': function('ale_linters#hack#hack#GetExecutable'), \ 'command': '%e lsp --from vim-ale', -\ 'project_root_callback': 'ale_linters#hack#hack#GetProjectRoot', +\ 'project_root': function('ale_linters#hack#hack#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/hack/hhast.vim b/vim-config/plugins/ale/ale_linters/hack/hhast.vim old mode 100755 new mode 100644 index 710b7b25..5e6d4dec --- a/vim-config/plugins/ale/ale_linters/hack/hhast.vim +++ b/vim-config/plugins/ale/ale_linters/hack/hhast.vim @@ -9,7 +9,7 @@ function! ale_linters#hack#hhast#GetProjectRoot(buffer) abort let l:hhconfig = ale#path#FindNearestFile(a:buffer, '.hhconfig') if empty(l:hhconfig) - return '' + return '' endif let l:root = fnamemodify(l:hhconfig, ':h') @@ -33,8 +33,8 @@ endfunction call ale#linter#Define('hack', { \ 'name': 'hhast', \ 'lsp': 'stdio', -\ 'executable_callback': 'ale_linters#hack#hhast#GetExecutable', +\ 'executable': function('ale_linters#hack#hhast#GetExecutable'), \ 'command': '%e --mode lsp --from vim-ale', -\ 'project_root_callback': 'ale_linters#hack#hhast#GetProjectRoot', -\ 'initialization_options_callback': 'ale_linters#hack#hhast#GetInitializationOptions', +\ 'project_root': function('ale_linters#hack#hhast#GetProjectRoot'), +\ 'initialization_options': function('ale_linters#hack#hhast#GetInitializationOptions'), \}) diff --git a/vim-config/plugins/ale/ale_linters/haml/hamllint.vim b/vim-config/plugins/ale/ale_linters/haml/hamllint.vim old mode 100755 new mode 100644 index 6598f81a..9fcd999f --- a/vim-config/plugins/ale/ale_linters/haml/hamllint.vim +++ b/vim-config/plugins/ale/ale_linters/haml/hamllint.vim @@ -19,7 +19,7 @@ function! ale_linters#haml#hamllint#GetCommand(buffer) abort " See https://github.com/brigade/haml-lint/blob/master/lib/haml_lint/linter/rubocop.rb#L89 " HamlLint::Linter::RuboCop#rubocop_flags if !empty(l:rubocop_config_file_path) - if ale#Has('win32') + 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) @@ -51,7 +51,7 @@ endfunction call ale#linter#Define('haml', { \ 'name': 'hamllint', -\ 'executable_callback': 'ale_linters#haml#hamllint#GetExecutable', -\ 'command_callback': 'ale_linters#haml#hamllint#GetCommand', +\ 'executable': function('ale_linters#haml#hamllint#GetExecutable'), +\ 'command': function('ale_linters#haml#hamllint#GetCommand'), \ 'callback': 'ale_linters#haml#hamllint#Handle' \}) diff --git a/vim-config/plugins/ale/ale_linters/handlebars/embertemplatelint.vim b/vim-config/plugins/ale/ale_linters/handlebars/embertemplatelint.vim old mode 100755 new mode 100644 index 4fc0f20d..8362bb1c --- a/vim-config/plugins/ale/ale_linters/handlebars/embertemplatelint.vim +++ b/vim-config/plugins/ale/ale_linters/handlebars/embertemplatelint.vim @@ -4,6 +4,28 @@ call ale#Set('handlebars_embertemplatelint_executable', 'ember-template-lint') call ale#Set('handlebars_embertemplatelint_use_global', get(g:, 'ale_use_global_executables', 0)) +function! ale_linters#handlebars#embertemplatelint#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'handlebars_embertemplatelint', [ + \ 'node_modules/.bin/ember-template-lint', + \]) +endfunction + +function! ale_linters#handlebars#embertemplatelint#GetCommand(buffer, version) abort + " Reading from stdin was introduced in ember-template-lint@1.6.0 + return ale#semver#GTE(a:version, [1, 6, 0]) + \ ? '%e --json --filename %s' + \ : '%e --json %t' +endfunction + +function! ale_linters#handlebars#embertemplatelint#GetCommandWithVersionCheck(buffer) abort + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ ale_linters#handlebars#embertemplatelint#GetExecutable(a:buffer), + \ '%e --version', + \ function('ale_linters#handlebars#embertemplatelint#GetCommand'), + \) +endfunction + function! ale_linters#handlebars#embertemplatelint#Handle(buffer, lines) abort let l:output = [] let l:json = ale#util#FuzzyJSONDecode(a:lines, {}) @@ -30,10 +52,9 @@ function! ale_linters#handlebars#embertemplatelint#Handle(buffer, lines) abort endfunction call ale#linter#Define('handlebars', { -\ 'name': 'ember-template-lint', -\ 'executable_callback': ale#node#FindExecutableFunc('handlebars_embertemplatelint', [ -\ 'node_modules/.bin/ember-template-lint', -\ ]), -\ 'command': '%e --json %t', +\ 'name': 'embertemplatelint', +\ 'aliases': ['ember-template-lint'], +\ 'executable': function('ale_linters#handlebars#embertemplatelint#GetExecutable'), +\ 'command': function('ale_linters#handlebars#embertemplatelint#GetCommandWithVersionCheck'), \ 'callback': 'ale_linters#handlebars#embertemplatelint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/haskell/cabal_ghc.vim b/vim-config/plugins/ale/ale_linters/haskell/cabal_ghc.vim old mode 100755 new mode 100644 index 003adf5d..1bb31ebb --- a/vim-config/plugins/ale/ale_linters/haskell/cabal_ghc.vim +++ b/vim-config/plugins/ale/ale_linters/haskell/cabal_ghc.vim @@ -14,6 +14,7 @@ call ale#linter#Define('haskell', { \ 'aliases': ['cabal-ghc'], \ 'output_stream': 'stderr', \ 'executable': 'cabal', -\ 'command_callback': 'ale_linters#haskell#cabal_ghc#GetCommand', +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#haskell#cabal_ghc#GetCommand'), \ 'callback': 'ale#handlers#haskell#HandleGHCFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/haskell/ghc.vim b/vim-config/plugins/ale/ale_linters/haskell/ghc.vim old mode 100755 new mode 100644 index daf91c8f..9c3906b2 --- a/vim-config/plugins/ale/ale_linters/haskell/ghc.vim +++ b/vim-config/plugins/ale/ale_linters/haskell/ghc.vim @@ -13,6 +13,6 @@ call ale#linter#Define('haskell', { \ 'name': 'ghc', \ 'output_stream': 'stderr', \ 'executable': 'ghc', -\ 'command_callback': 'ale_linters#haskell#ghc#GetCommand', +\ 'command': function('ale_linters#haskell#ghc#GetCommand'), \ 'callback': 'ale#handlers#haskell#HandleGHCFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/haskell/ghc_mod.vim b/vim-config/plugins/ale/ale_linters/haskell/ghc_mod.vim old mode 100755 new mode 100644 index 9762be7a..30e96b40 --- a/vim-config/plugins/ale/ale_linters/haskell/ghc_mod.vim +++ b/vim-config/plugins/ale/ale_linters/haskell/ghc_mod.vim @@ -13,7 +13,7 @@ endfunction call ale#linter#Define('haskell', { \ 'name': 'ghc_mod', \ 'aliases': ['ghc-mod'], -\ 'executable_callback': ale#VarFunc('haskell_ghc_mod_executable'), -\ 'command_callback': 'ale_linters#haskell#ghc_mod#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/haskell/hdevtools.vim b/vim-config/plugins/ale/ale_linters/haskell/hdevtools.vim old mode 100755 new mode 100644 index cc5ce56f..3e55e4f0 --- a/vim-config/plugins/ale/ale_linters/haskell/hdevtools.vim +++ b/vim-config/plugins/ale/ale_linters/haskell/hdevtools.vim @@ -14,7 +14,7 @@ endfunction call ale#linter#Define('haskell', { \ 'name': 'hdevtools', -\ 'executable_callback': ale#VarFunc('haskell_hdevtools_executable'), -\ 'command_callback': 'ale_linters#haskell#hdevtools#GetCommand', +\ 'executable': {b -> ale#Var(b, 'haskell_hdevtools_executable')}, +\ 'command': function('ale_linters#haskell#hdevtools#GetCommand'), \ 'callback': 'ale#handlers#haskell#HandleGHCFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/haskell/hie.vim b/vim-config/plugins/ale/ale_linters/haskell/hie.vim old mode 100755 new mode 100644 index 3ff1180a..c4b5f1df --- a/vim-config/plugins/ale/ale_linters/haskell/hie.vim +++ b/vim-config/plugins/ale/ale_linters/haskell/hie.vim @@ -9,39 +9,33 @@ function! ale_linters#haskell#hie#GetProjectRoot(buffer) abort " If it's empty, search for the cabal file if empty(l:project_file) - let l:cabal_file = fnamemodify(bufname(a:buffer), ':p:h') - let l:paths = '' - - while empty(matchstr(l:cabal_file, '^\(\/\|\(\w:\\\)\)$')) - let l:cabal_file = fnamemodify(l:cabal_file, ':h') - let l:paths = l:paths . l:cabal_file . ',' - endwhile - + " 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 - " Either extract the project directory or take the current working - " directory - if !empty(l:project_file) - let l:project_file = fnamemodify(l:project_file, ':h') - else - let l:project_file = expand('#' . a:buffer . ':p:h') + " 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 l:project_file + 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' + \ . ' --lsp' endfunction call ale#linter#Define('haskell', { \ 'name': 'hie', \ 'lsp': 'stdio', -\ 'command_callback': 'ale_linters#haskell#hie#GetCommand', -\ 'executable_callback': ale#VarFunc('haskell_hie_executable'), -\ 'project_root_callback': 'ale_linters#haskell#hie#GetProjectRoot', +\ '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/vim-config/plugins/ale/ale_linters/haskell/hlint.vim b/vim-config/plugins/ale/ale_linters/haskell/hlint.vim old mode 100755 new mode 100644 index 0cc7437f..1425251a --- a/vim-config/plugins/ale/ale_linters/haskell/hlint.vim +++ b/vim-config/plugins/ale/ale_linters/haskell/hlint.vim @@ -40,7 +40,7 @@ endfunction call ale#linter#Define('haskell', { \ 'name': 'hlint', -\ 'executable_callback': ale#VarFunc('haskell_hlint_executable'), -\ 'command_callback': 'ale_linters#haskell#hlint#GetCommand' , +\ 'executable': {b -> ale#Var(b, 'haskell_hlint_executable')}, +\ 'command': function('ale_linters#haskell#hlint#GetCommand') , \ 'callback': 'ale_linters#haskell#hlint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/haskell/hls.vim b/vim-config/plugins/ale/ale_linters/haskell/hls.vim new file mode 100644 index 00000000..ae0556a4 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/haskell/hls.vim @@ -0,0 +1,63 @@ +" Author: Yen3 +" Description: A language server for haskell +" The file is based on hie.vim (author: Luxed +" ). It search more project root files. +" +call ale#Set('haskell_hls_executable', 'haskell-language-server-wrapper') + +function! ale_linters#haskell#hls#FindRootFile(buffer) abort + let l:serach_root_files = [ + \ 'stack.yaml', + \ 'cabal.project', + \ 'package.yaml', + \ 'hie.yaml' + \ ] + + for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) + for l:root_file in l:serach_root_files + if filereadable(l:path . l:root_file) + return l:path + endif + endfor + endfor + + return '' +endfunction + +function! ale_linters#haskell#hls#GetProjectRoot(buffer) abort + " Search for the project file first + let l:project_file = ale_linters#haskell#hls#FindRootFile(a:buffer) + + " 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#hls#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_hls_executable') + + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, + \ 'haskell-language-server-wrapper') + \ . ' --lsp' +endfunction + +call ale#linter#Define('haskell', { +\ 'name': 'hls', +\ 'lsp': 'stdio', +\ 'command': function('ale_linters#haskell#hls#GetCommand'), +\ 'executable': {b -> ale#Var(b, 'haskell_hls_executable')}, +\ 'project_root': function('ale_linters#haskell#hls#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/haskell/stack_build.vim b/vim-config/plugins/ale/ale_linters/haskell/stack_build.vim old mode 100755 new mode 100644 index 95a54587..8f2d9fd9 --- a/vim-config/plugins/ale/ale_linters/haskell/stack_build.vim +++ b/vim-config/plugins/ale/ale_linters/haskell/stack_build.vim @@ -16,8 +16,8 @@ call ale#linter#Define('haskell', { \ 'name': 'stack_build', \ 'aliases': ['stack-build'], \ 'output_stream': 'stderr', -\ 'executable_callback': 'ale#handlers#haskell#GetStackExecutable', -\ 'command_callback': 'ale_linters#haskell#stack_build#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/haskell/stack_ghc.vim b/vim-config/plugins/ale/ale_linters/haskell/stack_ghc.vim old mode 100755 new mode 100644 index 8f42b96c..51ecc744 --- a/vim-config/plugins/ale/ale_linters/haskell/stack_ghc.vim +++ b/vim-config/plugins/ale/ale_linters/haskell/stack_ghc.vim @@ -1,11 +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#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_callback': 'ale#handlers#haskell#GetStackExecutable', -\ 'command': 'stack ghc -- -fno-code -v0 %t', +\ 'executable': function('ale#handlers#haskell#GetStackExecutable'), +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#haskell#stack_ghc#GetCommand'), \ 'callback': 'ale#handlers#haskell#HandleGHCFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/help/alex.vim b/vim-config/plugins/ale/ale_linters/help/alex.vim old mode 100755 new mode 100644 index 21b23b4f..9be00a82 --- a/vim-config/plugins/ale/ale_linters/help/alex.vim +++ b/vim-config/plugins/ale/ale_linters/help/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for help files -call ale#linter#Define('help', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('help', '--text') diff --git a/vim-config/plugins/ale/ale_linters/help/proselint.vim b/vim-config/plugins/ale/ale_linters/help/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/help/writegood.vim b/vim-config/plugins/ale/ale_linters/help/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/html/alex.vim b/vim-config/plugins/ale/ale_linters/html/alex.vim old mode 100755 new mode 100644 index 5a1f61e9..97756753 --- a/vim-config/plugins/ale/ale_linters/html/alex.vim +++ b/vim-config/plugins/ale/ale_linters/html/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for HTML files -call ale#linter#Define('html', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('html', '--html') diff --git a/vim-config/plugins/ale/ale_linters/html/angular.vim b/vim-config/plugins/ale/ale_linters/html/angular.vim new file mode 100644 index 00000000..17c0a751 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/html/angular.vim @@ -0,0 +1,52 @@ +" Author: w0rp +" Description: tsserver integration for ALE + +call ale#Set('html_angular_executable', 'ngserver') +call ale#Set('html_angular_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#html#angular#GetProjectRoot(buffer) abort + return ale#path#Dirname( + \ ale#path#FindNearestDirectory(a:buffer, 'node_modules') + \) +endfunction + +function! ale_linters#html#angular#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'html_angular', [ + \ 'node_modules/@angular/language-server/bin/ngserver', + \ 'node_modules/@angular/language-server/index.js', + \]) +endfunction + +function! ale_linters#html#angular#GetCommand(buffer) abort + let l:language_service_dir = ale#path#Simplify( + \ ale#path#FindNearestDirectory( + \ a:buffer, + \ 'node_modules/@angular/language-service' + \ ) + \) + + if empty(l:language_service_dir) + return '' + endif + + let l:language_service_dir = fnamemodify(l:language_service_dir, ':h') + let l:typescript_dir = ale#path#Simplify( + \ fnamemodify(l:language_service_dir, ':h:h') + \ . '/typescript' + \) + let l:executable = ale_linters#html#angular#GetExecutable(a:buffer) + + return ale#node#Executable(a:buffer, l:executable) + \ . ' --ngProbeLocations ' . ale#Escape(l:language_service_dir) + \ . ' --tsProbeLocations ' . ale#Escape(l:typescript_dir) + \ . ' --stdio' +endfunction + +call ale#linter#Define('html', { +\ 'name': 'angular', +\ 'aliases': ['angular-language-server'], +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#html#angular#GetExecutable'), +\ 'command': function('ale_linters#html#angular#GetCommand'), +\ 'project_root': function('ale_linters#html#angular#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/html/fecs.vim b/vim-config/plugins/ale/ale_linters/html/fecs.vim new file mode 100644 index 00000000..15e00e12 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/html/htmlhint.vim b/vim-config/plugins/ale/ale_linters/html/htmlhint.vim old mode 100755 new mode 100644 index 234c1176..25bf5137 --- a/vim-config/plugins/ale/ale_linters/html/htmlhint.vim +++ b/vim-config/plugins/ale/ale_linters/html/htmlhint.vim @@ -24,9 +24,9 @@ endfunction call ale#linter#Define('html', { \ 'name': 'htmlhint', -\ 'executable_callback': ale#node#FindExecutableFunc('html_htmlhint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'html_htmlhint', [ \ 'node_modules/.bin/htmlhint', -\ ]), -\ 'command_callback': 'ale_linters#html#htmlhint#GetCommand', +\ ])}, +\ 'command': function('ale_linters#html#htmlhint#GetCommand'), \ 'callback': 'ale#handlers#unix#HandleAsError', \}) diff --git a/vim-config/plugins/ale/ale_linters/html/proselint.vim b/vim-config/plugins/ale/ale_linters/html/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/html/stylelint.vim b/vim-config/plugins/ale/ale_linters/html/stylelint.vim old mode 100755 new mode 100644 index 908c4b02..6b7aba40 --- a/vim-config/plugins/ale/ale_linters/html/stylelint.vim +++ b/vim-config/plugins/ale/ale_linters/html/stylelint.vim @@ -5,7 +5,7 @@ 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', [ + return ale#path#FindExecutable(a:buffer, 'html_stylelint', [ \ 'node_modules/.bin/stylelint', \]) endfunction @@ -21,7 +21,7 @@ endfunction call ale#linter#Define('html', { \ 'name': 'stylelint', -\ 'executable_callback': 'ale_linters#html#stylelint#GetExecutable', -\ 'command_callback': 'ale_linters#html#stylelint#GetCommand', +\ 'executable': function('ale_linters#html#stylelint#GetExecutable'), +\ 'command': function('ale_linters#html#stylelint#GetCommand'), \ 'callback': 'ale#handlers#css#HandleStyleLintFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/html/tidy.vim b/vim-config/plugins/ale/ale_linters/html/tidy.vim old mode 100755 new mode 100644 index 4ec29091..1e476d40 --- a/vim-config/plugins/ale/ale_linters/html/tidy.vim +++ b/vim-config/plugins/ale/ale_linters/html/tidy.vim @@ -63,8 +63,8 @@ endfunction call ale#linter#Define('html', { \ 'name': 'tidy', -\ 'executable_callback': ale#VarFunc('html_tidy_executable'), +\ 'executable': {b -> ale#Var(b, 'html_tidy_executable')}, \ 'output_stream': 'stderr', -\ 'command_callback': 'ale_linters#html#tidy#GetCommand', +\ 'command': function('ale_linters#html#tidy#GetCommand'), \ 'callback': 'ale_linters#html#tidy#Handle', \ }) diff --git a/vim-config/plugins/ale/ale_linters/html/writegood.vim b/vim-config/plugins/ale/ale_linters/html/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/idris/idris.vim b/vim-config/plugins/ale/ale_linters/idris/idris.vim old mode 100755 new mode 100644 index feac0f10..879e92f2 --- a/vim-config/plugins/ale/ale_linters/idris/idris.vim +++ b/vim-config/plugins/ale/ale_linters/idris/idris.vim @@ -49,11 +49,11 @@ function! ale_linters#idris#idris#Handle(buffer, lines) abort 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] + 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] + 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' @@ -75,7 +75,7 @@ endfunction call ale#linter#Define('idris', { \ 'name': 'idris', -\ 'executable_callback': ale#VarFunc('idris_idris_executable'), -\ 'command_callback': 'ale_linters#idris#idris#GetCommand', +\ 'executable': {b -> ale#Var(b, 'idris_idris_executable')}, +\ 'command': function('ale_linters#idris#idris#GetCommand'), \ 'callback': 'ale_linters#idris#idris#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/ink/ls.vim b/vim-config/plugins/ale/ale_linters/ink/ls.vim new file mode 100644 index 00000000..00b2f323 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/ink/ls.vim @@ -0,0 +1,35 @@ +" Author: Andreww Hayworth +" Description: Integrate ALE with ink-language-server + +call ale#Set('ink_ls_executable', 'ink-language-server') +call ale#Set('ink_ls_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('ink_ls_initialization_options', {}) + +function! ale_linters#ink#ls#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'ink_ls', [ + \ 'ink-language-server', + \ 'node_modules/.bin/ink-language-server', + \]) +endfunction + +function! ale_linters#ink#ls#GetCommand(buffer) abort + let l:executable = ale_linters#ink#ls#GetExecutable(a:buffer) + + return ale#Escape(l:executable) . ' --stdio' +endfunction + +function! ale_linters#ink#ls#FindProjectRoot(buffer) abort + let l:main_file = get(ale#Var(a:buffer, 'ink_ls_initialization_options'), 'mainStoryPath', 'main.ink') + let l:config = ale#path#ResolveLocalPath(a:buffer, l:main_file, expand('#' . a:buffer . ':p')) + + return ale#path#Dirname(l:config) +endfunction + +call ale#linter#Define('ink', { +\ 'name': 'ink-language-server', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#ink#ls#GetExecutable'), +\ 'command': function('ale_linters#ink#ls#GetCommand'), +\ 'project_root': function('ale_linters#ink#ls#FindProjectRoot'), +\ 'initialization_options': {b -> ale#Var(b, 'ink_ls_initialization_options')}, +\}) diff --git a/vim-config/plugins/ale/ale_linters/inko/inko.vim b/vim-config/plugins/ale/ale_linters/inko/inko.vim new file mode 100644 index 00000000..11558897 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/inko/inko.vim @@ -0,0 +1,33 @@ +" Author: Yorick Peterse +" Description: linting of Inko source code using the Inko compiler + +call ale#Set('inko_inko_executable', 'inko') + +function! ale_linters#inko#inko#GetCommand(buffer) abort + let l:include = '' + + " Include the tests source directory, but only for test files. + if expand('#' . a:buffer . ':p') =~? '\vtests[/\\]test[/\\]' + let l:test_dir = ale#path#FindNearestDirectory(a:buffer, 'tests') + + if isdirectory(l:test_dir) + let l:include = '--include ' . ale#Escape(l:test_dir) + endif + endif + + " We use %s instead of %t so the compiler determines the correct module + " names for the file being edited. Not doing so may lead to errors in + " certain cases. + return '%e build --check --format=json' + \ . ale#Pad(l:include) + \ . ' %s' +endfunction + +call ale#linter#Define('inko', { +\ 'name': 'inko', +\ 'executable': {b -> ale#Var(b, 'inko_inko_executable')}, +\ 'command': function('ale_linters#inko#inko#GetCommand'), +\ 'callback': 'ale#handlers#inko#Handle', +\ 'output_stream': 'stderr', +\ 'lint_file': 1 +\}) diff --git a/vim-config/plugins/ale/ale_linters/ispc/ispc.vim b/vim-config/plugins/ale/ale_linters/ispc/ispc.vim old mode 100755 new mode 100644 index de7ceafa..eb365117 --- a/vim-config/plugins/ale/ale_linters/ispc/ispc.vim +++ b/vim-config/plugins/ale/ale_linters/ispc/ispc.vim @@ -38,8 +38,8 @@ endfunction call ale#linter#Define('ispc', { \ 'name': 'ispc', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('ispc_ispc_executable'), -\ 'command_callback': 'ale_linters#ispc#ispc#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/java/checkstyle.vim b/vim-config/plugins/ale/ale_linters/java/checkstyle.vim old mode 100755 new mode 100644 index c07b65d0..1ccbc505 --- a/vim-config/plugins/ale/ale_linters/java/checkstyle.vim +++ b/vim-config/plugins/ale/ale_linters/java/checkstyle.vim @@ -1,15 +1,20 @@ " 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+)?:? (.*) \[(.+)\]$' + 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', + \ 'sub_type': 'style', \ 'lnum': l:match[2] + 0, \ 'col': l:match[3] + 0, \ 'text': l:match[4], @@ -17,12 +22,17 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort \}) 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', + \ 'sub_type': 'style', \ 'lnum': l:match[2] + 0, \ 'text': l:match[4], \}) @@ -31,20 +41,33 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort return l:output endfunction +function! s:GetConfig(buffer, config) abort + if ale#path#IsAbsolute(a:config) + return a:config + endif + + let s:file = ale#path#FindNearestFile(a:buffer, a:config) + + return !empty(s:file) ? s:file : a:config +endfunction + function! ale_linters#java#checkstyle#GetCommand(buffer) abort - return 'checkstyle ' - \ . ale#Var(a:buffer, 'java_checkstyle_options') + 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) + \ ? s:GetConfig(a:buffer, l:config_option) + \ : '' + + return '%e' + \ . ale#Pad(l:options) + \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') \ . ' %s' endfunction -if !exists('g:ale_java_checkstyle_options') - let g:ale_java_checkstyle_options = '-c /google_checks.xml' -endif - call ale#linter#Define('java', { \ 'name': 'checkstyle', -\ 'executable': 'checkstyle', -\ 'command_callback': 'ale_linters#java#checkstyle#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/java/eclipselsp.vim b/vim-config/plugins/ale/ale_linters/java/eclipselsp.vim new file mode 100644 index 00000000..adfd1b09 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/java/eclipselsp.vim @@ -0,0 +1,195 @@ +" 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') +call ale#Set('java_eclipselsp_javaagent', '') + +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) + + if has('win32') + let l:platform = 'win32' + elseif has('macunix') + let l:platform = 'macosx' + else + let l:platform = 'linux' + endif + + " Search jar file within repository path when manually built using mvn + let l:files = globpath(l:path, '**/'.l:platform.'/**/plugins/org.eclipse.equinox.launcher_*\.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, '**/'.l:platform.'/plugins/org.eclipse.equinox.launcher_*\.jar', 1, 1) + + if len(l:files) >= 1 + return l:files[0] + endif + + " Search jar file within unzipped tar.gz file + let l:files = globpath(l:path, 'plugins/org.eclipse.equinox.launcher_*\.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_*\.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#Javaagent(buffer) abort + let l:rets = [] + let l:raw = ale#Var(a:buffer, 'java_eclipselsp_javaagent') + + if empty(l:raw) + return '' + endif + + let l:jars = split(l:raw) + + for l:jar in l:jars + call add(l:rets, ale#Escape('-javaagent:' . l:jar)) + endfor + + return join(l:rets, ' ') +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), + \ ale_linters#java#eclipselsp#Javaagent(a:buffer), + \ '-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'), + \ { 'output_stream': 'both' } + \) +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/vim-config/plugins/ale/ale_linters/java/javac.vim b/vim-config/plugins/ale/ale_linters/java/javac.vim old mode 100755 new mode 100644 index 63dcdd94..971e8de0 --- a/vim-config/plugins/ale/ale_linters/java/javac.vim +++ b/vim-config/plugins/ale/ale_linters/java/javac.vim @@ -6,38 +6,52 @@ 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', '') +call ale#Set('java_javac_sourcepath', '') -function! ale_linters#java#javac#GetImportPaths(buffer) abort - let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml') +function! ale_linters#java#javac#RunWithImportPaths(buffer) abort + let [l:cwd, l:command] = ale#maven#BuildClasspathCommand(a:buffer) - if !empty(l:pom_path) && executable('mvn') - return ale#path#CdString(fnamemodify(l:pom_path, ':h')) - \ . 'mvn dependency:build-classpath' + " Try to use Gradle if Maven isn't available. + if empty(l:command) + let [l:cwd, l:command] = ale#gradle#BuildClasspathCommand(a:buffer) endif - let l:classpath_command = ale#gradle#BuildClasspathCommand(a:buffer) + " Try to use Ant if Gradle and Maven aren't available + if empty(l:command) + let [l:cwd, l:command] = ale#ant#BuildClasspathCommand(a:buffer) + endif - if !empty(l:classpath_command) - return l:classpath_command + if empty(l:command) + return ale_linters#java#javac#GetCommand(a:buffer, [], {}) endif - return '' + return ale#command#Run( + \ a:buffer, + \ l:command, + \ function('ale_linters#java#javac#GetCommand'), + \ {'cwd': l:cwd}, + \) 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), - \) + let l:cls_path = ale#Var(a:buffer, 'java_javac_classpath') + + if !empty(l:cls_path) && type(l:cls_path) is v:t_string + call extend(l:class_paths, split(l:cls_path, s:classpath_sep)) + endif + + if !empty(l:cls_path) && type(l:cls_path) is v:t_list + call extend(l:class_paths, l:cls_path) + endif return !empty(l:class_paths) \ ? '-cp ' . ale#Escape(join(l:class_paths, s:classpath_sep)) \ : '' endfunction -function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort +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 = '' @@ -55,30 +69,49 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort 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 = fnamemodify(l:src_dir, ':h:h:h') - \ . (has('win32') ? '\test\java\' : '/test/java/') + " 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 + if isdirectory(l:test_dir) + call add(l:sp_dirs, l:test_dir) endif endif + let l:source_paths = [] + let l:source_path = ale#Var(a:buffer, 'java_javac_sourcepath') + + if !empty(l:source_path) && type(l:source_path) is v:t_string + let l:source_paths = split(l:source_path, s:classpath_sep) + endif + + if !empty(l:source_path) && type(l:source_path) is v:t_list + let l:source_paths = l:source_path + endif + + if !empty(l:source_paths) + for l:path in l:source_paths + let l:sp_path = ale#path#FindNearestDirectory(a:buffer, l:path) + + if !empty(l:sp_path) + call add(l:sp_dirs, l:sp_path) + endif + endfor + 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#engine#CreateDirectory(a:buffer) + 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' + return '%e -Xlint' \ . ale#Pad(l:cp_option) \ . ale#Pad(l:sp_option) \ . ' -d ' . ale#Escape(l:class_file_directory) @@ -92,14 +125,16 @@ function! ale_linters#java#javac#Handle(buffer, lines) abort " 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+): (.+):(.+)$' + 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]) + if !empty(l:match[1]) && !empty(l:output) + let l:output[-1].col = len(l:match[1]) + endif elseif empty(l:match[3]) " Add symbols to 'cannot find symbol' errors. if l:output[-1].text is# 'error: cannot find symbol' @@ -120,10 +155,9 @@ endfunction call ale#linter#Define('java', { \ 'name': 'javac', -\ 'executable_callback': ale#VarFunc('java_javac_executable'), -\ 'command_chain': [ -\ {'callback': 'ale_linters#java#javac#GetImportPaths', 'output_stream': 'stdout'}, -\ {'callback': 'ale_linters#java#javac#GetCommand', 'output_stream': 'stderr'}, -\ ], +\ 'executable': {b -> ale#Var(b, 'java_javac_executable')}, +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#java#javac#RunWithImportPaths'), +\ 'output_stream': 'stderr', \ 'callback': 'ale_linters#java#javac#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/java/javalsp.vim b/vim-config/plugins/ale/ale_linters/java/javalsp.vim old mode 100755 new mode 100644 index 1436a52c..baf584c8 --- a/vim-config/plugins/ale/ale_linters/java/javalsp.vim +++ b/vim-config/plugins/ale/ale_linters/java/javalsp.vim @@ -1,25 +1,55 @@ " Author: Horacio Sanson " Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac -call ale#Set('java_javalsp_jar', 'javacs.jar') -call ale#Set('java_javalsp_executable', 'java') +call ale#Set('java_javalsp_executable', '') +call ale#Set('java_javalsp_config', {}) function! ale_linters#java#javalsp#Executable(buffer) abort return ale#Var(a:buffer, 'java_javalsp_executable') endfunction +function! ale_linters#java#javalsp#Config(buffer) abort + let l:defaults = { 'java': { 'classPath': [], 'externalDependencies': [] } } + let l:config = ale#Var(a:buffer, 'java_javalsp_config') + + " Ensure the config dictionary contains both classPath and + " externalDependencies keys to avoid a NPE crash on Java Language Server. + call extend(l:config, l:defaults, 'keep') + call extend(l:config['java'], l:defaults['java'], 'keep') + + return l:config +endfunction + function! ale_linters#java#javalsp#Command(buffer) abort - let l:jar = ale#Var(a:buffer, 'java_javalsp_jar') let l:executable = ale_linters#java#javalsp#Executable(a:buffer) - return ale#Escape(l:executable) . ' -cp ' . l:jar . ' -Xverify:none org.javacs.Main' + 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_callback': 'ale_linters#java#javalsp#Executable', -\ 'command_callback': 'ale_linters#java#javalsp#Command', +\ 'executable': function('ale_linters#java#javalsp#Executable'), +\ 'command': function('ale_linters#java#javalsp#Command'), \ 'language': 'java', -\ 'project_root_callback': 'ale#java#FindProjectRoot', +\ 'project_root': function('ale#java#FindProjectRoot'), +\ 'lsp_config': function('ale_linters#java#javalsp#Config') \}) diff --git a/vim-config/plugins/ale/ale_linters/java/pmd.vim b/vim-config/plugins/ale/ale_linters/java/pmd.vim old mode 100755 new mode 100644 index b530ad09..a1f4c93c --- a/vim-config/plugins/ale/ale_linters/java/pmd.vim +++ b/vim-config/plugins/ale/ale_linters/java/pmd.vim @@ -31,6 +31,6 @@ endif call ale#linter#Define('java', { \ 'name': 'pmd', \ 'executable': 'pmd', -\ 'command_callback': 'ale_linters#java#pmd#GetCommand', +\ 'command': function('ale_linters#java#pmd#GetCommand'), \ 'callback': 'ale_linters#java#pmd#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/javascript/deno.vim b/vim-config/plugins/ale/ale_linters/javascript/deno.vim new file mode 100644 index 00000000..659eb855 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/javascript/deno.vim @@ -0,0 +1,11 @@ +" Author: Arnold Chand +" Description: Deno lsp linter for JavaScript files. + +call ale#linter#Define('javascript', { +\ 'name': 'deno', +\ 'lsp': 'stdio', +\ 'executable': function('ale#handlers#deno#GetExecutable'), +\ 'command': '%e lsp', +\ 'project_root': function('ale#handlers#deno#GetProjectRoot'), +\ 'initialization_options': function('ale#handlers#deno#GetInitializationOptions'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/javascript/eslint.vim b/vim-config/plugins/ale/ale_linters/javascript/eslint.vim old mode 100755 new mode 100644 index 23e16949..cf4de6ec --- a/vim-config/plugins/ale/ale_linters/javascript/eslint.vim +++ b/vim-config/plugins/ale/ale_linters/javascript/eslint.vim @@ -4,7 +4,8 @@ call ale#linter#Define('javascript', { \ 'name': 'eslint', \ 'output_stream': 'both', -\ 'executable_callback': 'ale#handlers#eslint#GetExecutable', -\ 'command_callback': 'ale#handlers#eslint#GetCommand', -\ 'callback': 'ale#handlers#eslint#Handle', +\ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/vim-config/plugins/ale/ale_linters/javascript/fecs.vim b/vim-config/plugins/ale/ale_linters/javascript/fecs.vim new file mode 100644 index 00000000..e47c0a0b --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/javascript/flow.vim b/vim-config/plugins/ale/ale_linters/javascript/flow.vim old mode 100755 new mode 100644 index a4664fda..601bac33 --- a/vim-config/plugins/ale/ale_linters/javascript/flow.vim +++ b/vim-config/plugins/ale/ale_linters/javascript/flow.vim @@ -22,37 +22,18 @@ function! ale_linters#javascript#flow#GetExecutable(buffer) abort return '' endif - return ale#node#FindExecutable(a:buffer, 'javascript_flow', [ + return ale#path#FindExecutable(a:buffer, 'javascript_flow', [ \ 'node_modules/.bin/flow', \]) endfunction -function! ale_linters#javascript#flow#VersionCheck(buffer) abort - let l:executable = ale_linters#javascript#flow#GetExecutable(a:buffer) - - if empty(l:executable) - return '' - endif - - return ale#Escape(l:executable) . ' --version' -endfunction - -function! ale_linters#javascript#flow#GetCommand(buffer, version_lines) abort - let l:executable = ale_linters#javascript#flow#GetExecutable(a:buffer) - - if empty(l:executable) - return '' - endif - - let l:version = ale#semver#GetVersion(l:executable, a:version_lines) - +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(l:version) || ale#semver#GTE(l:version, [0, 36])) + \ && (empty(a:version) || ale#semver#GTE(a:version, [0, 36])) - return ale#Escape(l:executable) - \ . ' check-contents' + return '%e check-contents' \ . (l:use_respect_pragma ? ' --respect-pragma': '') \ . ' --json --from ale %s < %t' \ . (!has('win32') ? '; echo' : '') @@ -87,7 +68,6 @@ function! s:ExtraErrorMsg(current, new) abort return l:newMsg endfunction - function! s:GetDetails(error) abort let l:detail = '' @@ -156,7 +136,8 @@ function! ale_linters#javascript#flow#Handle(buffer, lines) abort \} if has_key(l:error, 'extra') - let l:errorToAdd.detail = s:GetDetails(l:error) + let l:errorToAdd.detail = l:errorToAdd.text + \ . "\n" . s:GetDetails(l:error) endif call add(l:output, l:errorToAdd) @@ -167,11 +148,13 @@ endfunction call ale#linter#Define('javascript', { \ 'name': 'flow', -\ 'executable_callback': 'ale_linters#javascript#flow#GetExecutable', -\ 'command_chain': [ -\ {'callback': 'ale_linters#javascript#flow#VersionCheck'}, -\ {'callback': 'ale_linters#javascript#flow#GetCommand'}, -\ ], +\ '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/vim-config/plugins/ale/ale_linters/javascript/flow_ls.vim b/vim-config/plugins/ale/ale_linters/javascript/flow_ls.vim old mode 100755 new mode 100644 index 75377183..fec34011 --- a/vim-config/plugins/ale/ale_linters/javascript/flow_ls.vim +++ b/vim-config/plugins/ale/ale_linters/javascript/flow_ls.vim @@ -19,10 +19,10 @@ endfunction call ale#linter#Define('javascript', { \ 'name': 'flow-language-server', \ 'lsp': 'stdio', -\ 'executable_callback': ale#node#FindExecutableFunc('javascript_flow_ls', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'javascript_flow_ls', [ \ 'node_modules/.bin/flow', -\ ]), +\ ])}, \ 'command': '%e lsp --from ale-lsp', -\ 'project_root_callback': 'ale_linters#javascript#flow_ls#FindProjectRoot', +\ 'project_root': function('ale_linters#javascript#flow_ls#FindProjectRoot'), \ 'language': 'javascript', \}) diff --git a/vim-config/plugins/ale/ale_linters/javascript/jscs.vim b/vim-config/plugins/ale/ale_linters/javascript/jscs.vim old mode 100755 new mode 100644 index a38766a6..ae3be68c --- a/vim-config/plugins/ale/ale_linters/javascript/jscs.vim +++ b/vim-config/plugins/ale/ale_linters/javascript/jscs.vim @@ -53,9 +53,9 @@ endfunction call ale#linter#Define('javascript', { \ 'name': 'jscs', -\ 'executable_callback': ale#node#FindExecutableFunc('javascript_jscs', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'javascript_jscs', [ \ 'node_modules/.bin/jscs', -\ ]), -\ 'command_callback': 'ale_linters#javascript#jscs#GetCommand', +\ ])}, +\ 'command': function('ale_linters#javascript#jscs#GetCommand'), \ 'callback': 'ale_linters#javascript#jscs#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/javascript/jshint.vim b/vim-config/plugins/ale/ale_linters/javascript/jshint.vim old mode 100755 new mode 100644 index cb7f66fc..26d4fda2 --- a/vim-config/plugins/ale/ale_linters/javascript/jshint.vim +++ b/vim-config/plugins/ale/ale_linters/javascript/jshint.vim @@ -25,9 +25,9 @@ endfunction call ale#linter#Define('javascript', { \ 'name': 'jshint', -\ 'executable_callback': ale#node#FindExecutableFunc('javascript_jshint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'javascript_jshint', [ \ 'node_modules/.bin/jshint', -\ ]), -\ 'command_callback': 'ale_linters#javascript#jshint#GetCommand', +\ ])}, +\ 'command': function('ale_linters#javascript#jshint#GetCommand'), \ 'callback': 'ale#handlers#unix#HandleAsError', \}) diff --git a/vim-config/plugins/ale/ale_linters/javascript/standard.vim b/vim-config/plugins/ale/ale_linters/javascript/standard.vim old mode 100755 new mode 100644 index f16b837a..addf41dd --- a/vim-config/plugins/ale/ale_linters/javascript/standard.vim +++ b/vim-config/plugins/ale/ale_linters/javascript/standard.vim @@ -6,8 +6,10 @@ call ale#Set('javascript_standard_use_global', get(g:, 'ale_use_global_executabl call ale#Set('javascript_standard_options', '') function! ale_linters#javascript#standard#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'javascript_standard', [ + return ale#path#FindExecutable(a:buffer, 'javascript_standard', [ + \ 'node_modules/standardx/bin/cmd.js', \ 'node_modules/standard/bin/cmd.js', + \ 'node_modules/semistandard/bin/cmd.js', \ 'node_modules/.bin/standard', \]) endfunction @@ -24,7 +26,7 @@ endfunction " standard uses eslint and the output format is the same call ale#linter#Define('javascript', { \ 'name': 'standard', -\ 'executable_callback': 'ale_linters#javascript#standard#GetExecutable', -\ 'command_callback': 'ale_linters#javascript#standard#GetCommand', +\ 'executable': function('ale_linters#javascript#standard#GetExecutable'), +\ 'command': function('ale_linters#javascript#standard#GetCommand'), \ 'callback': 'ale#handlers#eslint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/javascript/tsserver.vim b/vim-config/plugins/ale/ale_linters/javascript/tsserver.vim old mode 100755 new mode 100644 index 6cf08dd6..caf6972b --- a/vim-config/plugins/ale/ale_linters/javascript/tsserver.vim +++ b/vim-config/plugins/ale/ale_linters/javascript/tsserver.vim @@ -8,10 +8,10 @@ call ale#Set('javascript_tsserver_use_global', get(g:, 'ale_use_global_executabl call ale#linter#Define('javascript', { \ 'name': 'tsserver', \ 'lsp': 'tsserver', -\ 'executable_callback': ale#node#FindExecutableFunc('javascript_tsserver', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'javascript_tsserver', [ \ 'node_modules/.bin/tsserver', -\ ]), +\ ])}, \ 'command': '%e', -\ 'project_root_callback': {-> ''}, +\ 'project_root': function('ale#handlers#tsserver#GetProjectRoot'), \ 'language': '', \}) diff --git a/vim-config/plugins/ale/ale_linters/javascript/xo.vim b/vim-config/plugins/ale/ale_linters/javascript/xo.vim old mode 100755 new mode 100644 index bc8657ed..5e04ad5c --- a/vim-config/plugins/ale/ale_linters/javascript/xo.vim +++ b/vim-config/plugins/ale/ale_linters/javascript/xo.vim @@ -1,26 +1,9 @@ " 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 unix --stdin --stdin-filename %s' -endfunction - -" xo uses eslint and the output format is the same call ale#linter#Define('javascript', { \ 'name': 'xo', -\ 'executable_callback': 'ale_linters#javascript#xo#GetExecutable', -\ 'command_callback': 'ale_linters#javascript#xo#GetCommand', -\ 'callback': 'ale#handlers#eslint#Handle', +\ 'executable': function('ale#handlers#xo#GetExecutable'), +\ 'command': function('ale#handlers#xo#GetLintCommand'), +\ 'callback': 'ale#handlers#xo#HandleJSON', \}) diff --git a/vim-config/plugins/ale/ale_linters/json/eslint.vim b/vim-config/plugins/ale/ale_linters/json/eslint.vim new file mode 100644 index 00000000..bdabb9fa --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/json/eslint.vim @@ -0,0 +1,16 @@ +" Author: João Pesce +" Description: eslint for JSON files. +" +" Requires eslint-plugin-jsonc or a similar plugin to work +" +" Uses the same funtcions as ale_linters/javascript/eslint.vim by w0rp +" + +call ale#linter#Define('json', { +\ 'name': 'eslint', +\ 'output_stream': 'both', +\ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', +\}) diff --git a/vim-config/plugins/ale/ale_linters/json/jq.vim b/vim-config/plugins/ale/ale_linters/json/jq.vim new file mode 100644 index 00000000..2f36a29e --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/json/jq.vim @@ -0,0 +1,24 @@ +" Author: jD91mZM2 +call ale#Set('json_jq_executable', 'jq') +call ale#Set('json_jq_options', '') +call ale#Set('json_jq_filters', '.') + +" Matches patterns like the following: +" parse error: Expected another key-value pair at line 4, column 3 +let s:pattern = '^parse error: \(.\+\) at line \(\d\+\), column \(\d\+\)$' + +function! ale_linters#json#jq#Handle(buffer, lines) abort + return ale#util#MapMatches(a:lines, s:pattern, {match -> { + \ 'text': match[1], + \ 'lnum': match[2] + 0, + \ 'col': match[3] + 0, + \}}) +endfunction + +call ale#linter#Define('json', { +\ 'name': 'jq', +\ 'executable': {b -> ale#Var(b, 'json_jq_executable')}, +\ 'output_stream': 'stderr', +\ 'command': '%e', +\ 'callback': 'ale_linters#json#jq#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/json/jsonlint.vim b/vim-config/plugins/ale/ale_linters/json/jsonlint.vim old mode 100755 new mode 100644 index f01553d6..812540af --- a/vim-config/plugins/ale/ale_linters/json/jsonlint.vim +++ b/vim-config/plugins/ale/ale_linters/json/jsonlint.vim @@ -1,4 +1,21 @@ -" Author: KabbAmine +" 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#path#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: @@ -19,8 +36,8 @@ endfunction call ale#linter#Define('json', { \ 'name': 'jsonlint', -\ 'executable': 'jsonlint', +\ 'executable': function('ale_linters#json#jsonlint#GetExecutable'), \ 'output_stream': 'stderr', -\ 'command': 'jsonlint --compact -', +\ 'command': function('ale_linters#json#jsonlint#GetCommand'), \ 'callback': 'ale_linters#json#jsonlint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/json/spectral.vim b/vim-config/plugins/ale/ale_linters/json/spectral.vim new file mode 100644 index 00000000..14129c56 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/json/spectral.vim @@ -0,0 +1,14 @@ +" Author: t2h5 +" Description: Integration of Stoplight Spectral CLI with ALE. + +call ale#Set('json_spectral_executable', 'spectral') +call ale#Set('json_spectral_use_global', get(g:, 'ale_use_global_executables', 0)) + +call ale#linter#Define('json', { +\ 'name': 'spectral', +\ 'executable': {b -> ale#path#FindExecutable(b, 'json_spectral', [ +\ 'node_modules/.bin/spectral', +\ ])}, +\ 'command': '%e lint --ignore-unknown-format -q -f text %t', +\ 'callback': 'ale#handlers#spectral#HandleSpectralOutput' +\}) diff --git a/vim-config/plugins/ale/ale_linters/json5/eslint.vim b/vim-config/plugins/ale/ale_linters/json5/eslint.vim new file mode 100644 index 00000000..6207f2d7 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/json5/eslint.vim @@ -0,0 +1,16 @@ +" Author: João Pesce +" Description: eslint for JSON5 files. +" +" Requires eslint-plugin-jsonc or a similar plugin to work +" +" Uses the same funtcions as ale_linters/javascript/eslint.vim by w0rp +" + +call ale#linter#Define('json5', { +\ 'name': 'eslint', +\ 'output_stream': 'both', +\ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', +\}) diff --git a/vim-config/plugins/ale/ale_linters/jsonc/eslint.vim b/vim-config/plugins/ale/ale_linters/jsonc/eslint.vim new file mode 100644 index 00000000..1a5cc528 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/jsonc/eslint.vim @@ -0,0 +1,16 @@ +" Author: João Pesce +" Description: eslint for JSONC files. +" +" Requires eslint-plugin-jsonc or a similar plugin to work +" +" Uses the same funtcions as ale_linters/javascript/eslint.vim by w0rp +" + +call ale#linter#Define('jsonc', { +\ 'name': 'eslint', +\ 'output_stream': 'both', +\ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', +\}) diff --git a/vim-config/plugins/ale/ale_linters/jsonnet/jsonnet_lint.vim b/vim-config/plugins/ale/ale_linters/jsonnet/jsonnet_lint.vim new file mode 100644 index 00000000..a5ebdc39 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/jsonnet/jsonnet_lint.vim @@ -0,0 +1,59 @@ +" Author: Trevor Whitney +" Description: jsonnet-lint for jsonnet files + +call ale#Set('jsonnet_jsonnet_lint_executable', 'jsonnet-lint') +call ale#Set('jsonnet_jsonnet_lint_options', '') + +function! ale_linters#jsonnet#jsonnet_lint#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'jsonnet_jsonnet_lint_options') + + return '%e' + \ . ale#Pad(l:options) + \ . ' %t' +endfunction + + +function! ale_linters#jsonnet#jsonnet_lint#Handle(buffer, lines) abort + " Matches patterns line the following: + " + " ERROR: foo.jsonnet:22:3-12 expected token OPERATOR but got (IDENTIFIER, "bar") + " ERROR: hoge.jsonnet:20:3 unexpected: "}" while parsing terminal + " ERROR: main.jsonnet:212:1-14 Expected , or ; but got (IDENTIFIER, "older_cluster") + let l:pattern = '^ERROR: [^:]*:\(\d\+\):\(\d\+\)\(-\d\+\)* \(.*\)' + let l:output = [] + + for l:line in a:lines + let l:match = matchlist(l:line, l:pattern) + + if len(l:match) == 0 + continue + endif + + let line_number = l:match[1] + 0 + let column = l:match[2] + 0 + " l:match[3] has optional -14, when linter is showing a range + let text = l:match[4] + + + " vcol is Needed to indicate that the column is a character. + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': line_number, + \ 'vcol': 0, + \ 'col': column, + \ 'text': text, + \ 'type': 'E', + \ 'nr': -1, + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('jsonnet', { +\ 'name': 'jsonnet_lint', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'jsonnet_jsonnet_lint_executable')}, +\ 'command': function('ale_linters#jsonnet#jsonnet_lint#GetCommand'), +\ 'callback': 'ale_linters#jsonnet#jsonnet_lint#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/jsonnet/jsonnetfmt.vim b/vim-config/plugins/ale/ale_linters/jsonnet/jsonnetfmt.vim new file mode 100644 index 00000000..8904019e --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/jsonnet/jsonnetfmt.vim @@ -0,0 +1,52 @@ +" Authors: Trevor Whitney and Takuya Kosugiyama +" Description: jsonnetfmt for jsonnet files + +call ale#Set('jsonnet_jsonnetfmt_executable', 'jsonnetfmt') +call ale#Set('jsonnet_jsonnetfmt_options', '') + +function! ale_linters#jsonnet#jsonnetfmt#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'jsonnet_jsonnetfmt_options') + + return '%e' + \ . ale#Pad(l:options) + \ . ' %t' +endfunction + + +function! ale_linters#jsonnet#jsonnetfmt#Handle(buffer, lines) abort + " Matches patterns line the following: + " + " STATIC ERROR: foo.jsonnet:22:3-12: expected token OPERATOR but got (IDENTIFIER, "bar") + " STATIC ERROR: hoge.jsonnet:20:3: unexpected: "}" while parsing terminal + let l:pattern = '^STATIC ERROR:[^:]*:\(\d\+\):\(\d\+\):*\(-\d\+\)* \(.*\)' + let l:output = [] + + for l:line in a:lines + let l:match = matchlist(l:line, l:pattern) + + if len(l:match) == 0 + continue + endif + + " vcol is Needed to indicate that the column is a character. + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': l:match[1] + 0, + \ 'vcol': 0, + \ 'col': l:match[2] + 0, + \ 'text': l:match[4], + \ 'type': 'E', + \ 'nr': -1, + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('jsonnet', { +\ 'name': 'jsonnetfmt', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'jsonnet_jsonnetfmt_executable')}, +\ 'command': function('ale_linters#jsonnet#jsonnetfmt#GetCommand'), +\ 'callback': 'ale_linters#jsonnet#jsonnetfmt#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/julia/languageserver.vim b/vim-config/plugins/ale/ale_linters/julia/languageserver.vim old mode 100755 new mode 100644 index cd2000de..999ad815 --- a/vim-config/plugins/ale/ale_linters/julia/languageserver.vim +++ b/vim-config/plugins/ale/ale_linters/julia/languageserver.vim @@ -6,16 +6,16 @@ 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);' + let l:cmd_string = 'using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);' - return ale#Escape(l:julia_executable) . ' --startup-file=no --history-file=no -e ' . ale#Escape(l:cmd_string) + return ale#Escape(l:julia_executable) . ' --project=@. --startup-file=no --history-file=no -e ' . ale#Escape(l:cmd_string) endfunction call ale#linter#Define('julia', { \ 'name': 'languageserver', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('julia_executable'), -\ 'command_callback': 'ale_linters#julia#languageserver#GetCommand', +\ 'executable': {b -> ale#Var(b, 'julia_executable')}, +\ 'command': function('ale_linters#julia#languageserver#GetCommand'), \ 'language': 'julia', -\ 'project_root_callback': 'ale#julia#FindProjectRoot', +\ 'project_root': function('ale#julia#FindProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/kotlin/kotlinc.vim b/vim-config/plugins/ale/ale_linters/kotlin/kotlinc.vim old mode 100755 new mode 100644 index 4a993986..e8bc924d --- a/vim-config/plugins/ale/ale_linters/kotlin/kotlinc.vim +++ b/vim-config/plugins/ale/ale_linters/kotlin/kotlinc.vim @@ -11,26 +11,31 @@ let g:ale_kotlin_kotlinc_module_filename = get(g:, 'ale_kotlin_kotlinc_module_fi let s:classpath_sep = has('unix') ? ':' : ';' -function! ale_linters#kotlin#kotlinc#GetImportPaths(buffer) abort - " exec maven/gradle only if classpath is not set - if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# '' - return '' - else - let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml') +function! ale_linters#kotlin#kotlinc#RunWithImportPaths(buffer) abort + let l:command = '' - if !empty(l:pom_path) && executable('mvn') - return ale#path#CdString(fnamemodify(l:pom_path, ':h')) - \ . 'mvn dependency:build-classpath' - endif + " exec maven/gradle only if classpath is not set + if !empty(ale#Var(a:buffer, 'kotlin_kotlinc_classpath')) + return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {}) + endif - let l:classpath_command = ale#gradle#BuildClasspathCommand(a:buffer) + let [l:cwd, l:command] = ale#maven#BuildClasspathCommand(a:buffer) - if !empty(l:classpath_command) - return l:classpath_command - endif + " Try to use Gradle if Maven isn't available. + if empty(l:command) + let [l:cwd, l:command] = ale#gradle#BuildClasspathCommand(a:buffer) + endif - return '' + 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'), + \ {'cwd': l:cwd}, + \) endfunction function! s:BuildClassPathOption(buffer, import_paths) abort @@ -46,7 +51,7 @@ function! s:BuildClassPathOption(buffer, import_paths) abort \ : '' endfunction -function! ale_linters#kotlin#kotlinc#GetCommand(buffer, import_paths) abort +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 ' @@ -165,11 +170,8 @@ endfunction call ale#linter#Define('kotlin', { \ 'name': 'kotlinc', \ 'executable': 'kotlinc', -\ 'command_chain': [ -\ {'callback': 'ale_linters#kotlin#kotlinc#GetImportPaths', 'output_stream': 'stdout'}, -\ {'callback': 'ale_linters#kotlin#kotlinc#GetCommand', 'output_stream': 'stderr'}, -\ ], +\ 'output_stream': 'stderr', +\ 'command': function('ale_linters#kotlin#kotlinc#RunWithImportPaths'), \ 'callback': 'ale_linters#kotlin#kotlinc#Handle', \ 'lint_file': 1, \}) - diff --git a/vim-config/plugins/ale/ale_linters/kotlin/ktlint.vim b/vim-config/plugins/ale/ale_linters/kotlin/ktlint.vim old mode 100755 new mode 100644 index f474e845..0bb64b19 --- a/vim-config/plugins/ale/ale_linters/kotlin/ktlint.vim +++ b/vim-config/plugins/ale/ale_linters/kotlin/ktlint.vim @@ -1,54 +1,10 @@ " Author: Francis Agyapong " Description: Lint kotlin files using ktlint -call ale#Set('kotlin_ktlint_executable', 'ktlint') -call ale#Set('kotlin_ktlint_rulesets', []) -call ale#Set('kotlin_ktlint_format', 0) - - -function! ale_linters#kotlin#ktlint#GetCommand(buffer) abort - let l:executable = ale#Var(a:buffer, 'kotlin_ktlint_executable') - let l:file_path = expand('#' . a:buffer . ':p') - let l:options = '' - - " Formmatted content written to original file, not sure how to handle - " if ale#Var(a:buffer, 'kotlin_ktlint_format') - " let l:options = l:options . ' --format' - " endif - - for l:ruleset in ale#Var(a:buffer, 'kotlin_ktlint_rulesets') - let l:options = l:options . ' --ruleset ' . l:ruleset - endfor - - return l:executable . ' ' . l:options . ' ' . l:file_path -endfunction - -function! ale_linters#kotlin#ktlint#Handle(buffer, lines) abort - let l:message_pattern = '^\(.*\):\([0-9]\+\):\([0-9]\+\):\s\+\(.*\)' - let l:output = [] - - for l:match in ale#util#GetMatches(a:lines, l:message_pattern) - let l:line = l:match[2] + 0 - let l:column = l:match[3] + 0 - let l:text = l:match[4] - - let l:type = l:text =~? 'not a valid kotlin file' ? 'E' : 'W' - - call add(l:output, { - \ 'lnum': l:line, - \ 'col': l:column, - \ 'text': l:text, - \ 'type': l:type - \}) - endfor - - return l:output -endfunction - call ale#linter#Define('kotlin', { \ 'name': 'ktlint', \ 'executable': 'ktlint', -\ 'command_callback': 'ale_linters#kotlin#ktlint#GetCommand', -\ 'callback': 'ale_linters#kotlin#ktlint#Handle', -\ 'lint_file': 1 +\ 'command': function('ale#handlers#ktlint#GetCommand'), +\ 'callback': 'ale#handlers#ktlint#Handle', +\ 'output_stream': 'stderr' \}) diff --git a/vim-config/plugins/ale/ale_linters/kotlin/languageserver.vim b/vim-config/plugins/ale/ale_linters/kotlin/languageserver.vim old mode 100755 new mode 100644 index aea817ba..af78c0e0 --- a/vim-config/plugins/ale/ale_linters/kotlin/languageserver.vim +++ b/vim-config/plugins/ale/ale_linters/kotlin/languageserver.vim @@ -22,8 +22,8 @@ endfunction call ale#linter#Define('kotlin', { \ 'name': 'languageserver', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('kotlin_languageserver_executable'), +\ 'executable': {b -> ale#Var(b, 'kotlin_languageserver_executable')}, \ 'command': '%e', \ 'language': 'kotlin', -\ 'project_root_callback': 'ale_linters#kotlin#languageserver#GetProjectRoot', +\ 'project_root': function('ale_linters#kotlin#languageserver#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/less/lessc.vim b/vim-config/plugins/ale/ale_linters/less/lessc.vim old mode 100755 new mode 100644 index 37600649..8e21f5b4 --- a/vim-config/plugins/ale/ale_linters/less/lessc.vim +++ b/vim-config/plugins/ale/ale_linters/less/lessc.vim @@ -38,10 +38,10 @@ endfunction call ale#linter#Define('less', { \ 'name': 'lessc', -\ 'executable_callback': ale#node#FindExecutableFunc('less_lessc', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'less_lessc', [ \ 'node_modules/.bin/lessc', -\ ]), -\ 'command_callback': 'ale_linters#less#lessc#GetCommand', +\ ])}, +\ 'command': function('ale_linters#less#lessc#GetCommand'), \ 'callback': 'ale_linters#less#lessc#Handle', \ 'output_stream': 'stderr', \}) diff --git a/vim-config/plugins/ale/ale_linters/less/stylelint.vim b/vim-config/plugins/ale/ale_linters/less/stylelint.vim old mode 100755 new mode 100644 index 479808c2..83f784c4 --- a/vim-config/plugins/ale/ale_linters/less/stylelint.vim +++ b/vim-config/plugins/ale/ale_linters/less/stylelint.vim @@ -12,9 +12,9 @@ endfunction call ale#linter#Define('less', { \ 'name': 'stylelint', -\ 'executable_callback': ale#node#FindExecutableFunc('less_stylelint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'less_stylelint', [ \ 'node_modules/.bin/stylelint', -\ ]), -\ 'command_callback': 'ale_linters#less#stylelint#GetCommand', +\ ])}, +\ 'command': function('ale_linters#less#stylelint#GetCommand'), \ 'callback': 'ale#handlers#css#HandleStyleLintFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/llvm/llc.vim b/vim-config/plugins/ale/ale_linters/llvm/llc.vim old mode 100755 new mode 100644 index 044f8c44..594be063 --- a/vim-config/plugins/ale/ale_linters/llvm/llc.vim +++ b/vim-config/plugins/ale/ale_linters/llvm/llc.vim @@ -17,8 +17,8 @@ endfunction call ale#linter#Define('llvm', { \ 'name': 'llc', -\ 'executable_callback': ale#VarFunc('llvm_llc_executable'), +\ 'executable': {b -> ale#Var(b, 'llvm_llc_executable')}, \ 'output_stream': 'stderr', -\ 'command_callback': {-> '%e -filetype=null -o=' . g:ale#util#nul_file}, +\ 'command': {-> '%e -filetype=null -o=' . g:ale#util#nul_file}, \ 'callback': 'ale_linters#llvm#llc#HandleErrors', \}) diff --git a/vim-config/plugins/ale/ale_linters/lua/luac.vim b/vim-config/plugins/ale/ale_linters/lua/luac.vim old mode 100755 new mode 100644 index bca2cd8d..41674a43 --- a/vim-config/plugins/ale/ale_linters/lua/luac.vim +++ b/vim-config/plugins/ale/ale_linters/lua/luac.vim @@ -24,7 +24,7 @@ endfunction call ale#linter#Define('lua', { \ 'name': 'luac', -\ 'executable_callback': ale#VarFunc('lua_luac_executable'), +\ 'executable': {b -> ale#Var(b, 'lua_luac_executable')}, \ 'command': '%e -p -', \ 'output_stream': 'stderr', \ 'callback': 'ale_linters#lua#luac#Handle', diff --git a/vim-config/plugins/ale/ale_linters/lua/luacheck.vim b/vim-config/plugins/ale/ale_linters/lua/luacheck.vim old mode 100755 new mode 100644 index 669103b8..34be2b5a --- a/vim-config/plugins/ale/ale_linters/lua/luacheck.vim +++ b/vim-config/plugins/ale/ale_linters/lua/luacheck.vim @@ -38,7 +38,7 @@ endfunction call ale#linter#Define('lua', { \ 'name': 'luacheck', -\ 'executable_callback': ale#VarFunc('lua_luacheck_executable'), -\ 'command_callback': 'ale_linters#lua#luacheck#GetCommand', +\ 'executable': {b -> ale#Var(b, 'lua_luacheck_executable')}, +\ 'command': function('ale_linters#lua#luacheck#GetCommand'), \ 'callback': 'ale_linters#lua#luacheck#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/mail/alex.vim b/vim-config/plugins/ale/ale_linters/mail/alex.vim old mode 100755 new mode 100644 index b0651ccd..0fceea7b --- a/vim-config/plugins/ale/ale_linters/mail/alex.vim +++ b/vim-config/plugins/ale/ale_linters/mail/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke -" Description: alex for HTML files +" Description: alex for mail files -call ale#linter#Define('mail', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('mail', '--text') diff --git a/vim-config/plugins/ale/ale_linters/mail/languagetool.vim b/vim-config/plugins/ale/ale_linters/mail/languagetool.vim new file mode 100644 index 00000000..f68dab7a --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/mail/languagetool.vim @@ -0,0 +1,5 @@ +" Author: Vincent (wahrwolf [at] wolfpit.net) +" Description: languagetool for mails + + +call ale#handlers#languagetool#DefineLinter('mail') diff --git a/vim-config/plugins/ale/ale_linters/mail/proselint.vim b/vim-config/plugins/ale/ale_linters/mail/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/mail/vale.vim b/vim-config/plugins/ale/ale_linters/mail/vale.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/make/checkmake.vim b/vim-config/plugins/ale/ale_linters/make/checkmake.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/markdown/alex.vim b/vim-config/plugins/ale/ale_linters/markdown/alex.vim old mode 100755 new mode 100644 index 29306141..63769b5e --- a/vim-config/plugins/ale/ale_linters/markdown/alex.vim +++ b/vim-config/plugins/ale/ale_linters/markdown/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for markdown files -call ale#linter#Define('markdown', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('markdown', '') diff --git a/vim-config/plugins/ale/ale_linters/markdown/languagetool.vim b/vim-config/plugins/ale/ale_linters/markdown/languagetool.vim new file mode 100644 index 00000000..422a38c3 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/markdown/languagetool.vim @@ -0,0 +1,5 @@ +" Author: Vincent (wahrwolf [at] wolfpit.net) +" Description: languagetool for markdown files + + +call ale#handlers#languagetool#DefineLinter('markdown') diff --git a/vim-config/plugins/ale/ale_linters/markdown/markdownlint.vim b/vim-config/plugins/ale/ale_linters/markdown/markdownlint.vim old mode 100755 new mode 100644 index 5c8af650..7a293938 --- a/vim-config/plugins/ale/ale_linters/markdown/markdownlint.vim +++ b/vim-config/plugins/ale/ale_linters/markdown/markdownlint.vim @@ -1,11 +1,22 @@ " Author: Ty-Lucas Kelley " Description: Adds support for markdownlint +call ale#Set('markdown_markdownlint_options', '') + +function! ale_linters#markdown#markdownlint#GetCommand(buffer) abort + let l:executable = 'markdownlint' + + let l:options = ale#Var(a:buffer, 'markdown_markdownlint_options') + + return ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') . ' %s' +endfunction + call ale#linter#Define('markdown', { - \ 'name': 'markdownlint', - \ 'executable': 'markdownlint', - \ 'lint_file': 1, - \ 'output_stream': 'both', - \ 'command': 'markdownlint %s', - \ 'callback': 'ale#handlers#markdownlint#Handle' -\ }) +\ 'name': 'markdownlint', +\ 'executable': 'markdownlint', +\ 'lint_file': 1, +\ 'output_stream': 'both', +\ 'command': function('ale_linters#markdown#markdownlint#GetCommand'), +\ 'callback': 'ale#handlers#markdownlint#Handle' +\}) diff --git a/vim-config/plugins/ale/ale_linters/markdown/mdl.vim b/vim-config/plugins/ale/ale_linters/markdown/mdl.vim old mode 100755 new mode 100644 index 0953144b..fd44de6e --- a/vim-config/plugins/ale/ale_linters/markdown/mdl.vim +++ b/vim-config/plugins/ale/ale_linters/markdown/mdl.vim @@ -17,18 +17,17 @@ function! ale_linters#markdown#mdl#GetCommand(buffer) abort let l:options = ale#Var(a:buffer, 'markdown_mdl_options') return ale#Escape(l:executable) . l:exec_args - \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -j' . (!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) + for l:error in ale#util#FuzzyJSONDecode(a:lines, []) call add(l:output, { - \ 'lnum': l:match[1] + 0, - \ 'text': l:match[2], + \ 'lnum': l:error['line'], + \ 'code': l:error['rule'] . '/' . join(l:error['aliases'], '/'), + \ 'text': l:error['description'], \ 'type': 'W', \}) endfor @@ -38,7 +37,7 @@ endfunction call ale#linter#Define('markdown', { \ 'name': 'mdl', -\ 'executable_callback': 'ale_linters#markdown#mdl#GetExecutable', -\ 'command_callback': 'ale_linters#markdown#mdl#GetCommand', +\ 'executable': function('ale_linters#markdown#mdl#GetExecutable'), +\ 'command': function('ale_linters#markdown#mdl#GetCommand'), \ 'callback': 'ale_linters#markdown#mdl#Handle' \}) diff --git a/vim-config/plugins/ale/ale_linters/markdown/proselint.vim b/vim-config/plugins/ale/ale_linters/markdown/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/markdown/redpen.vim b/vim-config/plugins/ale/ale_linters/markdown/redpen.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/markdown/remark_lint.vim b/vim-config/plugins/ale/ale_linters/markdown/remark_lint.vim old mode 100755 new mode 100644 index 4f8d48fa..6085e7ef --- a/vim-config/plugins/ale/ale_linters/markdown/remark_lint.vim +++ b/vim-config/plugins/ale/ale_linters/markdown/remark_lint.vim @@ -39,10 +39,10 @@ endfunction call ale#linter#Define('markdown', { \ 'name': 'remark_lint', \ 'aliases': ['remark-lint'], -\ 'executable_callback': ale#node#FindExecutableFunc('markdown_remark_lint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'markdown_remark_lint', [ \ 'node_modules/.bin/remark', -\ ]), -\ 'command_callback': 'ale_linters#markdown#remark_lint#GetCommand', +\ ])}, +\ 'command': function('ale_linters#markdown#remark_lint#GetCommand'), \ 'callback': 'ale_linters#markdown#remark_lint#Handle', \ 'output_stream': 'stderr', \}) diff --git a/vim-config/plugins/ale/ale_linters/markdown/textlint.vim b/vim-config/plugins/ale/ale_linters/markdown/textlint.vim old mode 100755 new mode 100644 index 26458506..613c8411 --- a/vim-config/plugins/ale/ale_linters/markdown/textlint.vim +++ b/vim-config/plugins/ale/ale_linters/markdown/textlint.vim @@ -3,7 +3,7 @@ call ale#linter#Define('markdown', { \ 'name': 'textlint', -\ 'executable_callback': 'ale#handlers#textlint#GetExecutable', -\ 'command_callback': 'ale#handlers#textlint#GetCommand', +\ 'executable': function('ale#handlers#textlint#GetExecutable'), +\ 'command': function('ale#handlers#textlint#GetCommand'), \ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', \}) diff --git a/vim-config/plugins/ale/ale_linters/markdown/vale.vim b/vim-config/plugins/ale/ale_linters/markdown/vale.vim old mode 100755 new mode 100644 index 838c4db2..06a64416 --- a/vim-config/plugins/ale/ale_linters/markdown/vale.vim +++ b/vim-config/plugins/ale/ale_linters/markdown/vale.vim @@ -1,9 +1,24 @@ " Author: chew-z https://github.com/chew-z " Description: vale for Markdown files +call ale#Set('markdown_vale_executable', 'vale') +call ale#Set('markdown_vale_input_file', '%t') +call ale#Set('markdown_vale_options', '') + +function! ale_linters#markdown#vale#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'markdown_vale_executable') + let l:input_file = ale#Var(a:buffer, 'markdown_vale_input_file') + + " Defaults to `vale --output=JSON %t` + return ale#Escape(l:executable) + \ . ' --output=JSON ' + \ . ale#Var(a:buffer, 'markdown_vale_options') + \ . ' ' . l:input_file +endfunction + call ale#linter#Define('markdown', { \ 'name': 'vale', -\ 'executable': 'vale', -\ 'command': 'vale --output=JSON %t', +\ 'executable': {b -> ale#Var(b, 'markdown_vale_executable')}, +\ 'command': function('ale_linters#markdown#vale#GetCommand'), \ 'callback': 'ale#handlers#vale#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/markdown/writegood.vim b/vim-config/plugins/ale/ale_linters/markdown/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/matlab/mlint.vim b/vim-config/plugins/ale/ale_linters/matlab/mlint.vim old mode 100755 new mode 100644 index 3435045e..f58f8b6d --- a/vim-config/plugins/ale/ale_linters/matlab/mlint.vim +++ b/vim-config/plugins/ale/ale_linters/matlab/mlint.vim @@ -37,7 +37,7 @@ endfunction call ale#linter#Define('matlab', { \ 'name': 'mlint', -\ 'executable_callback': ale#VarFunc('matlab_mlint_executable'), +\ 'executable': {b -> ale#Var(b, 'matlab_mlint_executable')}, \ 'command': '%e -id %t', \ 'output_stream': 'stderr', \ 'callback': 'ale_linters#matlab#mlint#Handle', diff --git a/vim-config/plugins/ale/ale_linters/mercury/mmc.vim b/vim-config/plugins/ale/ale_linters/mercury/mmc.vim old mode 100755 new mode 100644 index 76d357f0..85969e10 --- a/vim-config/plugins/ale/ale_linters/mercury/mmc.vim +++ b/vim-config/plugins/ale/ale_linters/mercury/mmc.vim @@ -5,12 +5,9 @@ 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 ' + return '%e --errorcheck-only ' \ . ale#Var(a:buffer, 'mercury_mmc_options') - \ . ' ' . l:module_name + \ . ' %s:t:r' endfunction function! ale_linters#mercury#mmc#Handle(buffer, lines) abort @@ -33,8 +30,9 @@ endfunction call ale#linter#Define('mercury', { \ 'name': 'mmc', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('mercury_mmc_executable'), -\ 'command_callback': 'ale_linters#mercury#mmc#GetCommand', +\ 'executable': {b -> ale#Var(b, 'mercury_mmc_executable')}, +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#mercury#mmc#GetCommand'), \ 'callback': 'ale_linters#mercury#mmc#Handle', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/nasm/nasm.vim b/vim-config/plugins/ale/ale_linters/nasm/nasm.vim old mode 100755 new mode 100644 index cb2119a6..c4f53629 --- a/vim-config/plugins/ale/ale_linters/nasm/nasm.vim +++ b/vim-config/plugins/ale/ale_linters/nasm/nasm.vim @@ -7,10 +7,9 @@ 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) + return '%e -X gnu -I %s:h' . l:separator \ . ale#Pad(ale#Var(a:buffer, 'nasm_nasm_options')) \ . ' %s' \ . ' -o ' . l:output_null @@ -36,7 +35,7 @@ call ale#linter#Define('nasm', { \ 'name': 'nasm', \ 'output_stream': 'stderr', \ 'lint_file': 1, -\ 'executable_callback': ale#VarFunc('nasm_nasm_executable'), -\ 'command_callback': 'ale_linters#nasm#nasm#GetCommand', +\ 'executable': {b -> ale#Var(b, 'nasm_nasm_executable')}, +\ 'command': function('ale_linters#nasm#nasm#GetCommand'), \ 'callback': 'ale_linters#nasm#nasm#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/nim/nimcheck.vim b/vim-config/plugins/ale/ale_linters/nim/nimcheck.vim old mode 100755 new mode 100644 index bff45f7d..b739ca04 --- a/vim-config/plugins/ale/ale_linters/nim/nimcheck.vim +++ b/vim-config/plugins/ale/ale_linters/nim/nimcheck.vim @@ -1,6 +1,15 @@ " Author: Baabelfish " Description: Typechecking for nim files +let s:end_col_patterns = [ +\ '\v''([^'']+)'' is declared but not used.*', +\ '\videntifier expected, but found ''([^'']+)''', +\ '\vimported and not used: ''([^'']+)''.*', +\ '\vundeclared identifier: ''([^'']+)''', +\ '\v''([^'']+)'' cannot be assigned to', +\ '\vredefinition of ''([^'']+)'';', +\] + 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\+\)) \(.\+\)' @@ -43,6 +52,11 @@ function! ale_linters#nim#nimcheck#Handle(buffer, lines) abort let l:item.code = l:code_match[2] endif + " Find position end_col. + for l:col_match in ale#util#GetMatches(l:item.text, s:end_col_patterns) + let l:item.end_col = l:item.col + len(l:col_match[1]) - 1 + endfor + call add(l:output, l:item) endfor @@ -59,7 +73,7 @@ call ale#linter#Define('nim', { \ 'name': 'nimcheck', \ 'executable': 'nim', \ 'output_stream': 'both', -\ 'command_callback': 'ale_linters#nim#nimcheck#GetCommand', +\ 'command': function('ale_linters#nim#nimcheck#GetCommand'), \ 'callback': 'ale_linters#nim#nimcheck#Handle', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/nim/nimlsp.vim b/vim-config/plugins/ale/ale_linters/nim/nimlsp.vim new file mode 100644 index 00000000..5d041043 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/nim/nimlsp.vim @@ -0,0 +1,33 @@ +" Author: jeremija +" Description: Support for nimlsp (language server for nim) + +call ale#Set('nim_nimlsp_nim_sources', '') + +function! ale_linters#nim#nimlsp#GetProjectRoot(buffer) abort + let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git') + + if !empty(l:project_root) + return fnamemodify(l:project_root, ':h:h') + endif + + return '' +endfunction + +function! ale_linters#nim#nimlsp#GetCommand(buffer) abort + let l:nim_sources = ale#Var(a:buffer, 'nim_nimlsp_nim_sources') + + if !empty(l:nim_sources) + let l:nim_sources = ale#Escape(l:nim_sources) + endif + + return '%e' . ale#Pad(l:nim_sources) +endfunction + +call ale#linter#Define('nim', { +\ 'name': 'nimlsp', +\ 'lsp': 'stdio', +\ 'executable': 'nimlsp', +\ 'command': function('ale_linters#nim#nimlsp#GetCommand'), +\ 'language': 'nim', +\ 'project_root': function('ale_linters#nim#nimlsp#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/nix/nix.vim b/vim-config/plugins/ale/ale_linters/nix/nix.vim old mode 100755 new mode 100644 index 0a0c5c3e..3d91a9ec --- a/vim-config/plugins/ale/ale_linters/nix/nix.vim +++ b/vim-config/plugins/ale/ale_linters/nix/nix.vim @@ -1,18 +1,51 @@ " Author: Alistair Bill <@alibabzo> +" Author: Maximilian Bosch " Description: nix-instantiate linter for nix files +function! ale_linters#nix#nix#Command(buffer, output, meta) abort + let l:version = a:output[0][22:] + + if l:version =~# '^\(2.4\|3\).*' + return 'nix-instantiate --log-format internal-json --parse -' + else + return 'nix-instantiate --parse -' + endif +endfunction + 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 + if empty(a:lines) + return l:output + endif + + if a:lines[0] =~# '^@nix .*' + for l:line in a:lines + if l:line =~# '^@nix .*' + let l:result = json_decode(strpart(l:line, 4)) + + if has_key(l:result, 'column') + call add(l:output, { + \ 'type': 'E', + \ 'lnum': l:result.line, + \ 'col': l:result.column, + \ 'text': l:result.raw_msg + \}) + endif + endif + endfor + else + let l:pattern = '^\(.\+\): \(.\+\) at .*:\(\d\+\):\(\d\+\)$' + + 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] . ': ' . substitute(l:match[2], ',$', '', ''), + \ 'type': l:match[1] =~# '^error' ? 'E' : 'W', + \}) + endfor + endif return l:output endfunction @@ -21,6 +54,10 @@ call ale#linter#Define('nix', { \ 'name': 'nix', \ 'output_stream': 'stderr', \ 'executable': 'nix-instantiate', -\ 'command': 'nix-instantiate --parse -', +\ 'command': {buffer -> ale#command#Run( +\ buffer, +\ 'nix-instantiate --version', +\ function('ale_linters#nix#nix#Command') +\ )}, \ 'callback': 'ale_linters#nix#nix#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/nix/rnix_lsp.vim b/vim-config/plugins/ale/ale_linters/nix/rnix_lsp.vim new file mode 100644 index 00000000..949bed1c --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/nix/rnix_lsp.vim @@ -0,0 +1,16 @@ +" Author: jD91mZM2 +" Description: rnix-lsp language client + +function! ale_linters#nix#rnix_lsp#GetProjectRoot(buffer) abort + " rnix-lsp does not yet use the project root, so getting it right is not + " important + return fnamemodify(a:buffer, ':h') +endfunction + +call ale#linter#Define('nix', { +\ 'name': 'rnix_lsp', +\ 'lsp': 'stdio', +\ 'executable': 'rnix-lsp', +\ 'command': '%e', +\ 'project_root': function('ale_linters#nix#rnix_lsp#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/nroff/alex.vim b/vim-config/plugins/ale/ale_linters/nroff/alex.vim old mode 100755 new mode 100644 index a10db2dd..3f06af26 --- a/vim-config/plugins/ale/ale_linters/nroff/alex.vim +++ b/vim-config/plugins/ale/ale_linters/nroff/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for nroff files -call ale#linter#Define('nroff', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('nroff', '--text') diff --git a/vim-config/plugins/ale/ale_linters/nroff/proselint.vim b/vim-config/plugins/ale/ale_linters/nroff/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/nroff/writegood.vim b/vim-config/plugins/ale/ale_linters/nroff/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/objc/ccls.vim b/vim-config/plugins/ale/ale_linters/objc/ccls.vim old mode 100755 new mode 100644 index 0aa6a5e5..7aef5325 --- a/vim-config/plugins/ale/ale_linters/objc/ccls.vim +++ b/vim-config/plugins/ale/ale_linters/objc/ccls.vim @@ -3,12 +3,13 @@ call ale#Set('objc_ccls_executable', 'ccls') call ale#Set('objc_ccls_init_options', {}) +call ale#Set('c_build_dir', '') call ale#linter#Define('objc', { \ 'name': 'ccls', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('objc_ccls_executable'), +\ 'executable': {b -> ale#Var(b, 'objc_ccls_executable')}, \ 'command': '%e', -\ 'project_root_callback': 'ale#handlers#ccls#GetProjectRoot', -\ 'initialization_options_callback': ale#VarFunc('objc_ccls_init_options'), +\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'), +\ 'initialization_options': {b -> ale#handlers#ccls#GetInitOpts(b, 'objc_ccls_init_options')}, \}) diff --git a/vim-config/plugins/ale/ale_linters/objc/clang.vim b/vim-config/plugins/ale/ale_linters/objc/clang.vim old mode 100755 new mode 100644 index 4e80ac5c..cafb97db --- a/vim-config/plugins/ale/ale_linters/objc/clang.vim +++ b/vim-config/plugins/ale/ale_linters/objc/clang.vim @@ -10,7 +10,7 @@ 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')) + \ . '-iquote %s:h' \ . ' ' . ale#Var(a:buffer, 'objc_clang_options') . ' -' endfunction @@ -18,6 +18,6 @@ call ale#linter#Define('objc', { \ 'name': 'clang', \ 'output_stream': 'stderr', \ 'executable': 'clang', -\ 'command_callback': 'ale_linters#objc#clang#GetCommand', +\ 'command': function('ale_linters#objc#clang#GetCommand'), \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \}) diff --git a/vim-config/plugins/ale/ale_linters/objc/clangd.vim b/vim-config/plugins/ale/ale_linters/objc/clangd.vim old mode 100755 new mode 100644 index f090e6ce..318d85b5 --- a/vim-config/plugins/ale/ale_linters/objc/clangd.vim +++ b/vim-config/plugins/ale/ale_linters/objc/clangd.vim @@ -4,12 +4,6 @@ call ale#Set('objc_clangd_executable', 'clangd') call ale#Set('objc_clangd_options', '') -function! ale_linters#objc#clangd#GetProjectRoot(buffer) abort - let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') - - return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' -endfunction - function! ale_linters#objc#clangd#GetCommand(buffer) abort return '%e' . ale#Pad(ale#Var(a:buffer, 'objc_clangd_options')) endfunction @@ -17,7 +11,7 @@ endfunction call ale#linter#Define('objc', { \ 'name': 'clangd', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('objc_clangd_executable'), -\ 'command_callback': 'ale_linters#objc#clangd#GetCommand', -\ 'project_root_callback': 'ale_linters#objc#clangd#GetProjectRoot', +\ 'executable': {b -> ale#Var(b, 'objc_clangd_executable')}, +\ 'command': function('ale_linters#objc#clangd#GetCommand'), +\ 'project_root': function('ale#c#FindProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/objcpp/clang.vim b/vim-config/plugins/ale/ale_linters/objcpp/clang.vim old mode 100755 new mode 100644 index d1474f17..35a40c6f --- a/vim-config/plugins/ale/ale_linters/objcpp/clang.vim +++ b/vim-config/plugins/ale/ale_linters/objcpp/clang.vim @@ -10,7 +10,7 @@ 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')) + \ . '-iquote %s:h' \ . ' ' . ale#Var(a:buffer, 'objcpp_clang_options') . ' -' endfunction @@ -18,6 +18,6 @@ call ale#linter#Define('objcpp', { \ 'name': 'clang', \ 'output_stream': 'stderr', \ 'executable': 'clang++', -\ 'command_callback': 'ale_linters#objcpp#clang#GetCommand', +\ 'command': function('ale_linters#objcpp#clang#GetCommand'), \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \}) diff --git a/vim-config/plugins/ale/ale_linters/objcpp/clangd.vim b/vim-config/plugins/ale/ale_linters/objcpp/clangd.vim old mode 100755 new mode 100644 index a09753be..29455325 --- a/vim-config/plugins/ale/ale_linters/objcpp/clangd.vim +++ b/vim-config/plugins/ale/ale_linters/objcpp/clangd.vim @@ -4,12 +4,6 @@ call ale#Set('objcpp_clangd_executable', 'clangd') call ale#Set('objcpp_clangd_options', '') -function! ale_linters#objcpp#clangd#GetProjectRoot(buffer) abort - let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') - - return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' -endfunction - function! ale_linters#objcpp#clangd#GetCommand(buffer) abort return '%e' . ale#Pad(ale#Var(a:buffer, 'objcpp_clangd_options')) endfunction @@ -17,7 +11,7 @@ endfunction call ale#linter#Define('objcpp', { \ 'name': 'clangd', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('objcpp_clangd_executable'), -\ 'command_callback': 'ale_linters#objcpp#clangd#GetCommand', -\ 'project_root_callback': 'ale_linters#objcpp#clangd#GetProjectRoot', +\ 'executable': {b -> ale#Var(b, 'objcpp_clangd_executable')}, +\ 'command': function('ale_linters#objcpp#clangd#GetCommand'), +\ 'project_root': function('ale#c#FindProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/ocaml/merlin.vim b/vim-config/plugins/ale/ale_linters/ocaml/merlin.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/ocaml/ocamllsp.vim b/vim-config/plugins/ale/ale_linters/ocaml/ocamllsp.vim new file mode 100644 index 00000000..4ff7419c --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/ocaml/ocamllsp.vim @@ -0,0 +1,13 @@ +" Author: Risto Stevcev +" Description: The official language server for OCaml + +call ale#Set('ocaml_ocamllsp_use_opam', 1) + +call ale#linter#Define('ocaml', { +\ 'name': 'ocamllsp', +\ 'lsp': 'stdio', +\ 'executable': function('ale#handlers#ocamllsp#GetExecutable'), +\ 'command': function('ale#handlers#ocamllsp#GetCommand'), +\ 'language': function('ale#handlers#ocamllsp#GetLanguage'), +\ 'project_root': function('ale#handlers#ocamllsp#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/ocaml/ols.vim b/vim-config/plugins/ale/ale_linters/ocaml/ols.vim old mode 100755 new mode 100644 index 077862fc..ec71bdb4 --- a/vim-config/plugins/ale/ale_linters/ocaml/ols.vim +++ b/vim-config/plugins/ale/ale_linters/ocaml/ols.vim @@ -7,8 +7,8 @@ call ale#Set('ocaml_ols_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#linter#Define('ocaml', { \ 'name': 'ols', \ 'lsp': 'stdio', -\ 'executable_callback': 'ale#handlers#ols#GetExecutable', -\ 'command_callback': 'ale#handlers#ols#GetCommand', -\ 'language_callback': 'ale#handlers#ols#GetLanguage', -\ 'project_root_callback': 'ale#handlers#ols#GetProjectRoot', +\ 'executable': function('ale#handlers#ols#GetExecutable'), +\ 'command': function('ale#handlers#ols#GetCommand'), +\ 'language': function('ale#handlers#ols#GetLanguage'), +\ 'project_root': function('ale#handlers#ols#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/ocamlinterface/merlin.vim b/vim-config/plugins/ale/ale_linters/ocamlinterface/merlin.vim new file mode 100644 index 00000000..799490f7 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/ocamlinterface/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#ocamlinterface#merlin#Handle(buffer, lines) abort + return merlin#ErrorLocList() +endfunction + +call ale#linter#Define('ocamlinterface', { +\ 'name': 'merlin', +\ 'executable': 'ocamlmerlin', +\ 'command': 'true', +\ 'callback': 'ale_linters#ocamlinterface#merlin#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/ocamlinterface/ocamllsp.vim b/vim-config/plugins/ale/ale_linters/ocamlinterface/ocamllsp.vim new file mode 100644 index 00000000..cd4bea80 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/ocamlinterface/ocamllsp.vim @@ -0,0 +1,13 @@ +" Author: Risto Stevcev +" Description: The official language server for OCaml + +call ale#Set('ocaml_ocamllsp_use_opam', 1) + +call ale#linter#Define('ocamlinterface', { +\ 'name': 'ocamllsp', +\ 'lsp': 'stdio', +\ 'executable': function('ale#handlers#ocamllsp#GetExecutable'), +\ 'command': function('ale#handlers#ocamllsp#GetCommand'), +\ 'language': function('ale#handlers#ocamllsp#GetLanguage'), +\ 'project_root': function('ale#handlers#ocamllsp#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/openapi/ibm_validator.vim b/vim-config/plugins/ale/ale_linters/openapi/ibm_validator.vim new file mode 100644 index 00000000..446931a2 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/openapi/ibm_validator.vim @@ -0,0 +1,58 @@ +" Author: Horacio Sanson + +call ale#Set('openapi_ibm_validator_executable', 'lint-openapi') +call ale#Set('openapi_ibm_validator_options', '') + +function! ale_linters#openapi#ibm_validator#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'openapi_ibm_validator_options')) + \ . ' %t' +endfunction + +function! ale_linters#openapi#ibm_validator#Handle(buffer, lines) abort + let l:output = [] + let l:type = 'E' + let l:message = '' + let l:nr = -1 + + for l:line in a:lines + let l:match = matchlist(l:line, '^errors$') + + if !empty(l:match) + let l:type = 'E' + endif + + let l:match = matchlist(l:line, '^warnings$') + + if !empty(l:match) + let l:type = 'W' + endif + + let l:match = matchlist(l:line, '^ *Message : *\(.\+\)$') + + if !empty(l:match) + let l:message = l:match[1] + endif + + let l:match = matchlist(l:line, '^ *Line *: *\(\d\+\)$') + + if !empty(l:match) + let l:nr = l:match[1] + + call add(l:output, { + \ 'lnum': l:nr + 0, + \ 'col': 0, + \ 'text': l:message, + \ 'type': l:type, + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('openapi', { +\ 'name': 'ibm_validator', +\ 'executable': {b -> ale#Var(b, 'openapi_ibm_validator_executable')}, +\ 'command': function('ale_linters#openapi#ibm_validator#GetCommand'), +\ 'callback': 'ale_linters#openapi#ibm_validator#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/openapi/yamllint.vim b/vim-config/plugins/ale/ale_linters/openapi/yamllint.vim new file mode 100644 index 00000000..2b8952cc --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/openapi/yamllint.vim @@ -0,0 +1,9 @@ +call ale#Set('yaml_yamllint_executable', 'yamllint') +call ale#Set('yaml_yamllint_options', '') + +call ale#linter#Define('openapi', { +\ 'name': 'yamllint', +\ 'executable': {b -> ale#Var(b, 'yaml_yamllint_executable')}, +\ 'command': function('ale#handlers#yamllint#GetCommand'), +\ 'callback': 'ale#handlers#yamllint#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/perl/perl.vim b/vim-config/plugins/ale/ale_linters/perl/perl.vim old mode 100755 new mode 100644 index 4b954f0d..0f06528a --- a/vim-config/plugins/ale/ale_linters/perl/perl.vim +++ b/vim-config/plugins/ale/ale_linters/perl/perl.vim @@ -57,8 +57,8 @@ endfunction call ale#linter#Define('perl', { \ 'name': 'perl', -\ 'executable_callback': ale#VarFunc('perl_perl_executable'), +\ 'executable': {b -> ale#Var(b, 'perl_perl_executable')}, \ 'output_stream': 'both', -\ 'command_callback': 'ale_linters#perl#perl#GetCommand', +\ 'command': function('ale_linters#perl#perl#GetCommand'), \ 'callback': 'ale_linters#perl#perl#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/perl/perlcritic.vim b/vim-config/plugins/ale/ale_linters/perl/perlcritic.vim old mode 100755 new mode 100644 index 8619a404..f3154c09 --- a/vim-config/plugins/ale/ale_linters/perl/perlcritic.vim +++ b/vim-config/plugins/ale/ale_linters/perl/perlcritic.vim @@ -55,7 +55,7 @@ endfunction call ale#linter#Define('perl', { \ 'name': 'perlcritic', \ 'output_stream': 'stdout', -\ 'executable_callback': ale#VarFunc('perl_perlcritic_executable'), -\ 'command_callback': 'ale_linters#perl#perlcritic#GetCommand', +\ 'executable': {b -> ale#Var(b, 'perl_perlcritic_executable')}, +\ 'command': function('ale_linters#perl#perlcritic#GetCommand'), \ 'callback': 'ale_linters#perl#perlcritic#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/perl6/perl6.vim b/vim-config/plugins/ale/ale_linters/perl6/perl6.vim old mode 100755 new mode 100644 index b33a0c51..444ae4d7 --- a/vim-config/plugins/ale/ale_linters/perl6/perl6.vim +++ b/vim-config/plugins/ale/ale_linters/perl6/perl6.vim @@ -36,8 +36,8 @@ function! ale_linters#perl6#perl6#ExtractError(dict, item, type, buffer) abort 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 + 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']) @@ -61,7 +61,7 @@ function! ale_linters#perl6#perl6#ExtractError(dict, item, type, buffer) abort " 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# '' ) + \&& ( ale#path#IsBufferPath(a:buffer, l:file) || l:file is# '' ) return { \ 'lnum': '' . l:line, \ 'text': l:text, @@ -83,12 +83,12 @@ function! ale_linters#perl6#perl6#Handle(buffer, lines) abort endif if a:lines[0] is# 'Syntax OK' - return l:output + return l:output endif try let l:json = json_decode(join(a:lines, '')) - catch /E474/ + catch /E474\|E491/ call add(l:output, { \ 'lnum': '1', \ 'text': 'Received output in the default Perl6 error format. See :ALEDetail for details', @@ -101,8 +101,8 @@ function! ale_linters#perl6#perl6#Handle(buffer, lines) abort 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 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) @@ -115,7 +115,7 @@ function! ale_linters#perl6#perl6#Handle(buffer, lines) abort \ ) if l:result isnot# '' - call add(l:output, l:result) + call add(l:output, l:result) endif endfor endfor @@ -133,7 +133,7 @@ function! ale_linters#perl6#perl6#Handle(buffer, lines) abort \ ) if l:result isnot# '' - call add(l:output, l:result) + call add(l:output, l:result) endif endfor endfor @@ -147,7 +147,7 @@ function! ale_linters#perl6#perl6#Handle(buffer, lines) abort \ ) if l:result isnot# '' - call add(l:output, l:result) + call add(l:output, l:result) endif endif endfor @@ -158,9 +158,9 @@ endfunction call ale#linter#Define('perl6', { \ 'name': 'perl6', -\ 'executable_callback': 'ale_linters#perl6#perl6#GetExecutable', +\ 'executable': function('ale_linters#perl6#perl6#GetExecutable'), \ 'output_stream': 'both', -\ 'command_callback': 'ale_linters#perl6#perl6#GetCommand', +\ 'command': function('ale_linters#perl6#perl6#GetCommand'), \ 'callback': 'ale_linters#perl6#perl6#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/php/intelephense.vim b/vim-config/plugins/ale/ale_linters/php/intelephense.vim new file mode 100755 index 00000000..0fdcc93e --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/php/intelephense.vim @@ -0,0 +1,32 @@ +" Author: Eric Stern , +" Arnold Chand +" Description: Intelephense language server integration for ALE + +call ale#Set('php_intelephense_executable', 'intelephense') +call ale#Set('php_intelephense_use_global', 1) +call ale#Set('php_intelephense_config', {}) + +function! ale_linters#php#intelephense#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 + +function! ale_linters#php#intelephense#GetInitializationOptions(buffer) abort + return ale#Var(a:buffer, 'php_intelephense_config') +endfunction + +call ale#linter#Define('php', { +\ 'name': 'intelephense', +\ 'lsp': 'stdio', +\ 'initialization_options': function('ale_linters#php#intelephense#GetInitializationOptions'), +\ 'executable': {b -> ale#path#FindExecutable(b, 'php_intelephense', [])}, +\ 'command': '%e --stdio', +\ 'project_root': function('ale_linters#php#intelephense#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/php/langserver.vim b/vim-config/plugins/ale/ale_linters/php/langserver.vim old mode 100755 new mode 100644 index ca91db4c..c3d89a00 --- a/vim-config/plugins/ale/ale_linters/php/langserver.vim +++ b/vim-config/plugins/ale/ale_linters/php/langserver.vim @@ -5,6 +5,12 @@ 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') : '' @@ -13,9 +19,9 @@ endfunction call ale#linter#Define('php', { \ 'name': 'langserver', \ 'lsp': 'stdio', -\ 'executable_callback': ale#node#FindExecutableFunc('php_langserver', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'php_langserver', [ \ 'vendor/bin/php-language-server.php', -\ ]), +\ ])}, \ 'command': 'php %e', -\ 'project_root_callback': 'ale_linters#php#langserver#GetProjectRoot', +\ 'project_root': function('ale_linters#php#langserver#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/php/phan.vim b/vim-config/plugins/ale/ale_linters/php/phan.vim old mode 100755 new mode 100644 index c6f16356..50c6d6e6 --- a/vim-config/plugins/ale/ale_linters/php/phan.vim +++ b/vim-config/plugins/ale/ale_linters/php/phan.vim @@ -39,7 +39,7 @@ function! ale_linters#php#phan#Handle(buffer, lines) abort 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\(.\+\)$' + let l:pattern = '^\(.*\):\(\d\+\)\s\(\w\+\)\s\(.\+\)$' endif let l:output = [] @@ -49,13 +49,15 @@ function! ale_linters#php#phan#Handle(buffer, lines) abort let l:dict = { \ 'lnum': l:match[4] + 0, \ 'text': l:match[2], + \ 'filename': l:match[3], \ 'type': 'W', \} else let l:dict = { - \ 'lnum': l:match[1] + 0, - \ 'text': l:match[3], + \ 'lnum': l:match[2] + 0, + \ 'text': l:match[4], \ 'type': 'W', + \ 'filename': l:match[1], \} endif @@ -67,7 +69,7 @@ endfunction call ale#linter#Define('php', { \ 'name': 'phan', -\ 'executable_callback': 'ale_linters#php#phan#GetExecutable', -\ 'command_callback': 'ale_linters#php#phan#GetCommand', +\ 'executable': function('ale_linters#php#phan#GetExecutable'), +\ 'command': function('ale_linters#php#phan#GetCommand'), \ 'callback': 'ale_linters#php#phan#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/php/php.vim b/vim-config/plugins/ale/ale_linters/php/php.vim old mode 100755 new mode 100644 index 5d87196c..51a109b9 --- a/vim-config/plugins/ale/ale_linters/php/php.vim +++ b/vim-config/plugins/ale/ale_linters/php/php.vim @@ -32,7 +32,7 @@ endfunction call ale#linter#Define('php', { \ 'name': 'php', -\ 'executable_callback': ale#VarFunc('php_php_executable'), +\ 'executable': {b -> 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/vim-config/plugins/ale/ale_linters/php/phpcs.vim b/vim-config/plugins/ale/ale_linters/php/phpcs.vim old mode 100755 new mode 100644 index 408c2652..ce47a13b --- a/vim-config/plugins/ale/ale_linters/php/phpcs.vim +++ b/vim-config/plugins/ale/ale_linters/php/phpcs.vim @@ -10,20 +10,19 @@ 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=' . l:standard + \ ? '--standard=' . ale#Escape(l:standard) \ : '' - let l:options = ale#Var(a:buffer, 'php_phpcs_options') return '%e -s --report=emacs --stdin-path=%s' - \ . ale#Pad(l:standard_option) - \ . ale#Pad(l:options) + \ . 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:pattern = '^.*:\(\d\+\):\(\d\+\): \(.\+\) - \(.\+\) (\(.\+\)).*$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) @@ -36,6 +35,7 @@ function! ale_linters#php#phpcs#Handle(buffer, lines) abort \ 'col': l:match[2] + 0, \ 'text': l:text, \ 'type': l:type is# 'error' ? 'E' : 'W', + \ 'sub_type': 'style', \}) endfor @@ -44,10 +44,11 @@ endfunction call ale#linter#Define('php', { \ 'name': 'phpcs', -\ 'executable_callback': ale#node#FindExecutableFunc('php_phpcs', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'php_phpcs', [ \ 'vendor/bin/phpcs', \ 'phpcs' -\ ]), -\ 'command_callback': 'ale_linters#php#phpcs#GetCommand', +\ ])}, +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#php#phpcs#GetCommand'), \ 'callback': 'ale_linters#php#phpcs#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/php/phpmd.vim b/vim-config/plugins/ale/ale_linters/php/phpmd.vim old mode 100755 new mode 100644 index 65f1cc3c..9b1d1e44 --- a/vim-config/plugins/ale/ale_linters/php/phpmd.vim +++ b/vim-config/plugins/ale/ale_linters/php/phpmd.vim @@ -32,7 +32,7 @@ endfunction call ale#linter#Define('php', { \ 'name': 'phpmd', -\ 'executable_callback': ale#VarFunc('php_phpmd_executable'), -\ 'command_callback': 'ale_linters#php#phpmd#GetCommand', +\ 'executable': {b -> ale#Var(b, 'php_phpmd_executable')}, +\ 'command': function('ale_linters#php#phpmd#GetCommand'), \ 'callback': 'ale_linters#php#phpmd#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/php/phpstan.vim b/vim-config/plugins/ale/ale_linters/php/phpstan.vim old mode 100755 new mode 100644 index 1c831e1b..58d4dce2 --- a/vim-config/plugins/ale/ale_linters/php/phpstan.vim +++ b/vim-config/plugins/ale/ale_linters/php/phpstan.vim @@ -3,60 +3,60 @@ " Set to change the ruleset let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpstan') -let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4') +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', '') +call ale#Set('php_phpstan_use_global', get(g:, 'ale_use_global_executables', 0)) -function! ale_linters#php#phpstan#GetExecutable(buffer) abort - return ale#Var(a:buffer, 'php_phpstan_executable') -endfunction - -function! ale_linters#php#phpstan#VersionCheck(buffer) abort - let l:executable = ale_linters#php#phpstan#GetExecutable(a:buffer) +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) + \ : '' - " If we have previously stored the version number in a cache, then - " don't look it up again. - if ale#semver#HasVersion(l:executable) - " Returning an empty string skips this command. - return '' - endif + let l:autoload = ale#Var(a:buffer, 'php_phpstan_autoload') + let l:autoload_option = !empty(l:autoload) + \ ? ' -a ' . ale#Escape(l:autoload) + \ : '' - let l:executable = ale#Escape(l:executable) + let l:level = ale#Var(a:buffer, 'php_phpstan_level') + let l:config_file_exists = ale#path#FindNearestFile(a:buffer, 'phpstan.neon') + let l:dist_config_file_exists = ale#path#FindNearestFile(a:buffer, 'phpstan.neon.dist') - return l:executable . ' --version' -endfunction + if empty(l:level) && empty(l:config_file_exists) && empty(l:dist_config_file_exists) + " if no configuration file is found, then use 4 as a default level + let l:level = '4' + endif -function! ale_linters#php#phpstan#GetCommand(buffer, version_output) abort - let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration') - let l:configuration_option = !empty(l:configuration) - \ ? ' -c ' . l:configuration + let l:level_option = !empty(l:level) + \ ? ' -l ' . ale#Escape(l:level) \ : '' - let l:executable = ale_linters#php#phpstan#GetExecutable(a:buffer) - let l:version = ale#semver#GetVersion(l:executable, a:version_output) - let l:error_format = ale#semver#GTE(l:version, [0, 10, 3]) - \ ? ' --error-format raw' - \ : ' --errorFormat raw' + let l:error_format = ale#semver#GTE(a:version, [0, 10, 3]) + \ ? ' --error-format json' + \ : ' --errorFormat json' - return '%e analyze -l' - \ . ale#Var(a:buffer, 'php_phpstan_level') + 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:res = ale#util#FuzzyJSONDecode(a:lines, {'files': []}) let l:output = [] - for l:match in ale#util#GetMatches(a:lines, l:pattern) + if type(l:res.files) is v:t_list + return l:output + endif + + for l:err in l:res.files[expand('#' . a:buffer .':p')].messages call add(l:output, { - \ 'lnum': l:match[2] + 0, - \ 'text': l:match[3], - \ 'type': 'W', + \ 'lnum': l:err.line, + \ 'text': l:err.message, + \ 'type': 'E', \}) endfor @@ -65,10 +65,18 @@ endfunction call ale#linter#Define('php', { \ 'name': 'phpstan', -\ 'executable_callback': 'ale_linters#php#phpstan#GetExecutable', -\ 'command_chain': [ -\ {'callback': 'ale_linters#php#phpstan#VersionCheck'}, -\ {'callback': 'ale_linters#php#phpstan#GetCommand'}, -\ ], +\ 'executable': {buffer -> ale#path#FindExecutable(buffer, 'php_phpstan', [ +\ 'vendor/bin/phpstan', +\ 'phpstan' +\ ])}, +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale#path#FindExecutable(buffer, 'php_phpstan', [ +\ 'vendor/bin/phpstan', +\ 'phpstan' +\ ]), +\ '%e --version', +\ function('ale_linters#php#phpstan#GetCommand'), +\ )}, \ 'callback': 'ale_linters#php#phpstan#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/php/psalm.vim b/vim-config/plugins/ale/ale_linters/php/psalm.vim old mode 100755 new mode 100644 index dce59178..dbbe9453 --- a/vim-config/plugins/ale/ale_linters/php/psalm.vim +++ b/vim-config/plugins/ale/ale_linters/php/psalm.vim @@ -1,8 +1,9 @@ " 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)) +call ale#Set('php_psalm_executable', 'psalm') +call ale#Set('php_psalm_options', '') +call ale#Set('php_psalm_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') @@ -10,12 +11,16 @@ function! ale_linters#php#psalm#GetProjectRoot(buffer) abort return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : '' endfunction +function! ale_linters#php#psalm#GetCommand(buffer) abort + return '%e --language-server' . ale#Pad(ale#Var(a:buffer, 'php_psalm_options')) +endfunction + call ale#linter#Define('php', { \ 'name': 'psalm', \ 'lsp': 'stdio', -\ 'executable_callback': ale#node#FindExecutableFunc('psalm_langserver', [ -\ 'vendor/bin/psalm-language-server', -\ ]), -\ 'command': '%e', -\ 'project_root_callback': 'ale_linters#php#psalm#GetProjectRoot', +\ 'executable': {b -> ale#path#FindExecutable(b, 'php_psalm', [ +\ 'vendor/bin/psalm', +\ ])}, +\ 'command': function('ale_linters#php#psalm#GetCommand'), +\ 'project_root': function('ale_linters#php#psalm#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/php/tlint.vim b/vim-config/plugins/ale/ale_linters/php/tlint.vim new file mode 100644 index 00000000..80bdd1f6 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/php/tlint.vim @@ -0,0 +1,80 @@ +" Author: Jose Soto +" +" Description: Tighten Opinionated PHP Linting +" Website: https://github.com/tightenco/tlint + +call ale#Set('php_tlint_executable', 'tlint') +call ale#Set('php_tlint_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('php_tlint_options', '') + +function! ale_linters#php#tlint#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 + +function! ale_linters#php#tlint#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'php_tlint', [ + \ 'vendor/bin/tlint', + \ 'tlint', + \]) +endfunction + +function! ale_linters#php#tlint#GetCommand(buffer) abort + let l:executable = ale_linters#php#tlint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'php_tlint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' lint %s' +endfunction + +function! ale_linters#php#tlint#Handle(buffer, lines) abort + " Matches against lines like the following: + " + " ! There should be 1 space around `.` concatenations, and additional lines should always start with a `.` + " 22 : ` $something = 'a'.'name';` + " + let l:loop_count = 0 + let l:messages_pattern = '^\! \(.*\)' + let l:output = [] + let l:pattern = '^\(\d\+\) \:' + let l:temp_messages = [] + + for l:message in ale#util#GetMatches(a:lines, l:messages_pattern) + call add(l:temp_messages, l:message) + endfor + + let l:loop_count = 0 + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:num = l:match[1] + let l:text = l:temp_messages[l:loop_count] + + call add(l:output, { + \ 'lnum': l:num, + \ 'col': 0, + \ 'text': l:text, + \ 'type': 'W', + \ 'sub_type': 'style', + \}) + + let l:loop_count += 1 + endfor + + return l:output +endfunction + +call ale#linter#Define('php', { +\ 'name': 'tlint', +\ 'executable': function('ale_linters#php#tlint#GetExecutable'), +\ 'command': function('ale_linters#php#tlint#GetCommand'), +\ 'callback': 'ale_linters#php#tlint#Handle', +\ 'project_root': function('ale_linters#php#tlint#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/po/alex.vim b/vim-config/plugins/ale/ale_linters/po/alex.vim old mode 100755 new mode 100644 index 411d835b..05c67f15 --- a/vim-config/plugins/ale/ale_linters/po/alex.vim +++ b/vim-config/plugins/ale/ale_linters/po/alex.vim @@ -1,11 +1,4 @@ " Author: Cian Butler https://github.com/butlerx " Description: alex for PO files -call ale#linter#Define('po', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('po', '--text') diff --git a/vim-config/plugins/ale/ale_linters/po/msgfmt.vim b/vim-config/plugins/ale/ale_linters/po/msgfmt.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/po/proselint.vim b/vim-config/plugins/ale/ale_linters/po/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/po/writegood.vim b/vim-config/plugins/ale/ale_linters/po/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/pod/alex.vim b/vim-config/plugins/ale/ale_linters/pod/alex.vim old mode 100755 new mode 100644 index 5c09befb..c89f8330 --- a/vim-config/plugins/ale/ale_linters/pod/alex.vim +++ b/vim-config/plugins/ale/ale_linters/pod/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for pod files -call ale#linter#Define('pod', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('pod', '--text') diff --git a/vim-config/plugins/ale/ale_linters/pod/proselint.vim b/vim-config/plugins/ale/ale_linters/pod/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/pod/writegood.vim b/vim-config/plugins/ale/ale_linters/pod/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/pony/ponyc.vim b/vim-config/plugins/ale/ale_linters/pony/ponyc.vim old mode 100755 new mode 100644 index 19e7e828..6d4594f9 --- a/vim-config/plugins/ale/ale_linters/pony/ponyc.vim +++ b/vim-config/plugins/ale/ale_linters/pony/ponyc.vim @@ -10,7 +10,7 @@ endfunction call ale#linter#Define('pony', { \ 'name': 'ponyc', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('pony_ponyc_executable'), -\ 'command_callback': 'ale_linters#pony#ponyc#GetCommand', +\ 'executable': {b -> ale#Var(b, 'pony_ponyc_executable')}, +\ 'command': function('ale_linters#pony#ponyc#GetCommand'), \ 'callback': 'ale#handlers#pony#HandlePonycFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/powershell/powershell.vim b/vim-config/plugins/ale/ale_linters/powershell/powershell.vim new file mode 100644 index 00000000..5f49f72c --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/powershell/powershell.vim @@ -0,0 +1,100 @@ +" 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); + \ $ErrorView = "Normal"; + \ 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 + + " If the match is 0, it was a failed match + " probably due to an unexpected token which + " contained a newline. Reset matchcount. to + " continue to the next match + if !empty(l:match[1]) + let l:item = { + \ 'lnum': str2nr(l:match[1]), + \ 'col': str2nr(l:match[2]), + \ 'type': 'E', + \} + else + let l:matchcount = 0 + endif + 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': function('ale_linters#powershell#powershell#GetExecutable'), +\ 'command': function('ale_linters#powershell#powershell#GetCommand'), +\ 'output_stream': 'stdout', +\ 'callback': 'ale_linters#powershell#powershell#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/powershell/psscriptanalyzer.vim b/vim-config/plugins/ale/ale_linters/powershell/psscriptanalyzer.vim new file mode 100644 index 00000000..4794d9d8 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/prolog/swipl.vim b/vim-config/plugins/ale/ale_linters/prolog/swipl.vim old mode 100755 new mode 100644 index 401e52b6..82859eb0 --- a/vim-config/plugins/ale/ale_linters/prolog/swipl.vim +++ b/vim-config/plugins/ale/ale_linters/prolog/swipl.vim @@ -35,10 +35,11 @@ function! s:Subst(format, vars) abort 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 + let l:pattern = '\v^(ERROR|Warning)+%(:\s*[^:]+:(\d+)%(:(\d+))?)?:\s*(.*)$' + while l:i < len(a:lines) let l:match = matchlist(a:lines[l:i], l:pattern) @@ -72,8 +73,17 @@ function! s:GetErrMsg(i, lines, text) abort 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:pattern = '\v^(ERROR|Warning)?:?(.*)$' + + while l:i < len(a:lines) + let l:match = matchlist(a:lines[l:i], l:pattern) + + if empty(l:match) || empty(l:match[2]) + let l:i += 1 + break + endif + + call add(l:text, s:Trim(l:match[2])) let l:i += 1 endwhile @@ -87,14 +97,14 @@ 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' + 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_callback': ale#VarFunc('prolog_swipl_executable'), -\ 'command_callback': 'ale_linters#prolog#swipl#GetCommand', +\ 'executable': {b -> ale#Var(b, 'prolog_swipl_executable')}, +\ 'command': function('ale_linters#prolog#swipl#GetCommand'), \ 'callback': 'ale_linters#prolog#swipl#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/proto/protoc_gen_lint.vim b/vim-config/plugins/ale/ale_linters/proto/protoc_gen_lint.vim old mode 100755 new mode 100644 index c8b5c331..c3d10935 --- a/vim-config/plugins/ale/ale_linters/proto/protoc_gen_lint.vim +++ b/vim-config/plugins/ale/ale_linters/proto/protoc_gen_lint.vim @@ -22,6 +22,6 @@ call ale#linter#Define('proto', { \ 'lint_file': 1, \ 'output_stream': 'stderr', \ 'executable': 'protoc', -\ 'command_callback': 'ale_linters#proto#protoc_gen_lint#GetCommand', +\ 'command': function('ale_linters#proto#protoc_gen_lint#GetCommand'), \ 'callback': 'ale#handlers#unix#HandleAsError', \}) diff --git a/vim-config/plugins/ale/ale_linters/proto/protolint.vim b/vim-config/plugins/ale/ale_linters/proto/protolint.vim new file mode 100644 index 00000000..2754c7b6 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/proto/protolint.vim @@ -0,0 +1,24 @@ +" Author: Yohei Yoshimuta +" Description: run the protolint for Protocol Buffer files + +call ale#Set('proto_protolint_executable', 'protolint') +call ale#Set('proto_protolint_config', '') + +function! ale_linters#proto#protolint#GetCommand(buffer) abort + let l:config = ale#Var(a:buffer, 'proto_protolint_config') + + return '%e lint' + \ . (!empty(l:config) ? ' -config_path=' . ale#Escape(l:config) : '') + \ . ' -reporter=unix' + \ . ' %s' +endfunction + +call ale#linter#Define('proto', { +\ 'name': 'protolint', +\ 'lint_file': 1, +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'proto_protolint_executable')}, +\ 'command': function('ale_linters#proto#protolint#GetCommand'), +\ 'callback': 'ale#handlers#unix#HandleAsError', +\}) + diff --git a/vim-config/plugins/ale/ale_linters/pug/puglint.vim b/vim-config/plugins/ale/ale_linters/pug/puglint.vim old mode 100755 new mode 100644 index 63208986..b552cc06 --- a/vim-config/plugins/ale/ale_linters/pug/puglint.vim +++ b/vim-config/plugins/ale/ale_linters/pug/puglint.vim @@ -31,12 +31,26 @@ function! ale_linters#pug#puglint#GetCommand(buffer) abort \ . ' -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_callback': ale#node#FindExecutableFunc('pug_puglint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'pug_puglint', [ \ 'node_modules/.bin/pug-lint', -\ ]), +\ ])}, \ 'output_stream': 'stderr', -\ 'command_callback': 'ale_linters#pug#puglint#GetCommand', -\ 'callback': 'ale#handlers#unix#HandleAsError', +\ 'command': function('ale_linters#pug#puglint#GetCommand'), +\ 'callback': 'ale_linters#pug#puglint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/puppet/languageserver.vim b/vim-config/plugins/ale/ale_linters/puppet/languageserver.vim old mode 100755 new mode 100644 index a3060e65..2078695f --- a/vim-config/plugins/ale/ale_linters/puppet/languageserver.vim +++ b/vim-config/plugins/ale/ale_linters/puppet/languageserver.vim @@ -30,8 +30,8 @@ endfunction call ale#linter#Define('puppet', { \ 'name': 'languageserver', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('puppet_languageserver_executable'), +\ 'executable': {b -> ale#Var(b, 'puppet_languageserver_executable')}, \ 'command': '%e --stdio', \ 'language': 'puppet', -\ 'project_root_callback': 'ale_linters#puppet#languageserver#GetProjectRoot', +\ 'project_root': function('ale_linters#puppet#languageserver#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/puppet/puppet.vim b/vim-config/plugins/ale/ale_linters/puppet/puppet.vim old mode 100755 new mode 100644 index 0e37bdbd..59228dc8 --- a/vim-config/plugins/ale/ale_linters/puppet/puppet.vim +++ b/vim-config/plugins/ale/ale_linters/puppet/puppet.vim @@ -8,13 +8,15 @@ function! ale_linters#puppet#puppet#Handle(buffer, lines) abort " 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*\)' + " Error: Illegal attempt to assign to 'a Name'. Not an assignable reference (file: /tmp/modules/waffles/manifests/syrup.pp, line: 5, column: 11) + " Error: Could not parse for environment production: Syntax error at end of input (file: /tmp/modules/bob/manifests/init.pp) + 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, + \ 'lnum': l:match[5] + 0, + \ 'col': l:match[7] + 0, \ 'text': l:match[1], \}) endfor @@ -30,8 +32,8 @@ endfunction call ale#linter#Define('puppet', { \ 'name': 'puppet', -\ 'executable_callback': ale#VarFunc('puppet_puppet_executable'), +\ 'executable': {b -> ale#Var(b, 'puppet_puppet_executable')}, \ 'output_stream': 'stderr', -\ 'command_callback': 'ale_linters#puppet#puppet#GetCommand', +\ 'command': function('ale_linters#puppet#puppet#GetCommand'), \ 'callback': 'ale_linters#puppet#puppet#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/puppet/puppetlint.vim b/vim-config/plugins/ale/ale_linters/puppet/puppetlint.vim old mode 100755 new mode 100644 index c9c16f5e..985d6a4d --- a/vim-config/plugins/ale/ale_linters/puppet/puppetlint.vim +++ b/vim-config/plugins/ale/ale_linters/puppet/puppetlint.vim @@ -12,7 +12,7 @@ endfunction call ale#linter#Define('puppet', { \ 'name': 'puppetlint', -\ 'executable_callback': ale#VarFunc('puppet_puppetlint_executable'), -\ 'command_callback': 'ale_linters#puppet#puppetlint#GetCommand', +\ 'executable': {b -> ale#Var(b, 'puppet_puppetlint_executable')}, +\ 'command': function('ale_linters#puppet#puppetlint#GetCommand'), \ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/purescript/ls.vim b/vim-config/plugins/ale/ale_linters/purescript/ls.vim new file mode 100644 index 00000000..a20fae47 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/purescript/ls.vim @@ -0,0 +1,49 @@ +" Author: Drew Olson +" Description: Integrate ALE with purescript-language-server. + +call ale#Set('purescript_ls_executable', 'purescript-language-server') +call ale#Set('purescript_ls_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('purescript_ls_config', {}) + +function! ale_linters#purescript#ls#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'purescript_ls', [ + \ 'node_modules/.bin/purescript-language-server', + \]) +endfunction + +function! ale_linters#purescript#ls#GetCommand(buffer) abort + let l:executable = ale_linters#purescript#ls#GetExecutable(a:buffer) + + return ale#Escape(l:executable) . ' --stdio' +endfunction + +function! ale_linters#purescript#ls#FindProjectRoot(buffer) abort + let l:config = ale#path#FindNearestFile(a:buffer, 'bower.json') + + if !empty(l:config) + return fnamemodify(l:config, ':h') + endif + + let l:config = ale#path#FindNearestFile(a:buffer, 'psc-package.json') + + if !empty(l:config) + return fnamemodify(l:config, ':h') + endif + + let l:config = ale#path#FindNearestFile(a:buffer, 'spago.dhall') + + if !empty(l:config) + return fnamemodify(l:config, ':h') + endif + + return '' +endfunction + +call ale#linter#Define('purescript', { +\ 'name': 'purescript-language-server', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#purescript#ls#GetExecutable'), +\ 'command': function('ale_linters#purescript#ls#GetCommand'), +\ 'project_root': function('ale_linters#purescript#ls#FindProjectRoot'), +\ 'lsp_config': {b -> ale#Var(b, 'purescript_ls_config')}, +\}) diff --git a/vim-config/plugins/ale/ale_linters/pyrex/cython.vim b/vim-config/plugins/ale/ale_linters/pyrex/cython.vim old mode 100755 new mode 100644 index d260698c..247c3060 --- a/vim-config/plugins/ale/ale_linters/pyrex/cython.vim +++ b/vim-config/plugins/ale/ale_linters/pyrex/cython.vim @@ -6,9 +6,7 @@ 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 + return '%e --working %s:h --include-dir %s:h' \ . ale#Pad(ale#Var(a:buffer, 'pyrex_cython_options')) \ . ' --output-file ' . g:ale#util#nul_file . ' %t' endfunction @@ -32,7 +30,7 @@ endfunction call ale#linter#Define('pyrex', { \ 'name': 'cython', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('pyrex_cython_executable'), -\ 'command_callback': 'ale_linters#pyrex#cython#GetCommand', +\ 'executable': {b -> ale#Var(b, 'pyrex_cython_executable')}, +\ 'command': function('ale_linters#pyrex#cython#GetCommand'), \ 'callback': 'ale_linters#pyrex#cython#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/python/bandit.vim b/vim-config/plugins/ale/ale_linters/python/bandit.vim new file mode 100644 index 00000000..9cfca7c0 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/python/bandit.vim @@ -0,0 +1,76 @@ +" 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) +call ale#Set('python_bandit_auto_poetry', 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 + + if ( + \ ale#Var(a:buffer, 'python_auto_poetry') + \ || ale#Var(a:buffer, 'python_bandit_auto_poetry') + \) && ale#python#PoetryPresent(a:buffer) + return 'poetry' + 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\|poetry$' + \ ? ' 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/vim-config/plugins/ale/ale_linters/python/flake8.vim b/vim-config/plugins/ale/ale_linters/python/flake8.vim old mode 100755 new mode 100644 index 14b67d77..9950614a --- a/vim-config/plugins/ale/ale_linters/python/flake8.vim +++ b/vim-config/plugins/ale/ale_linters/python/flake8.vim @@ -4,8 +4,9 @@ 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_change_directory', 'project') call ale#Set('python_flake8_auto_pipenv', 0) +call ale#Set('python_flake8_auto_poetry', 0) function! s:UsingModule(buffer) abort return ale#Var(a:buffer, 'python_flake8_options') =~# ' *-m flake8' @@ -17,6 +18,11 @@ function! ale_linters#python#flake8#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_flake8_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + if !s:UsingModule(a:buffer) return ale#python#FindExecutable(a:buffer, 'python_flake8', ['flake8']) endif @@ -24,43 +30,57 @@ function! ale_linters#python#flake8#GetExecutable(buffer) abort return ale#Var(a:buffer, 'python_flake8_executable') endfunction -function! ale_linters#python#flake8#VersionCheck(buffer) abort +function! ale_linters#python#flake8#RunWithVersionCheck(buffer) abort let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) - " If we have previously stored the version number in a cache, then - " don't look it up again. - if ale#semver#HasVersion(l:executable) - " Returning an empty string skips this command. - return '' + 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#GetCwd(buffer) abort + let l:change_directory = ale#Var(a:buffer, 'python_flake8_change_directory') + let l:cwd = '' + + if l:change_directory is# 'project' + let l:project_root = ale#python#FindProjectRootIni(a:buffer) + + if !empty(l:project_root) + let l:cwd = l:project_root + endif endif - let l:executable = ale#Escape(l:executable) - let l:module_string = s:UsingModule(a:buffer) ? ' -m flake8' : '' + if (l:change_directory is# 'project' && empty(l:cwd)) + \|| l:change_directory is# 1 + \|| l:change_directory is# 'file' + let l:cwd = '%s:h' + endif - return l:executable . l:module_string . ' --version' + return l:cwd endfunction -function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort - let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory') - \ ? ale#path#BufferCdString(a:buffer) - \ : '' +function! ale_linters#python#flake8#GetCommand(buffer, version) abort let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) - let l:version = ale#semver#GetVersion(l:executable, a:version_output) - let l:exec_args = l:executable =~? 'pipenv$' + let l:exec_args = l:executable =~? 'pipenv\|poetry$' \ ? ' 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(l:version, [3, 0, 0]) + 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 + return ale#Escape(l:executable) . l:exec_args \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --format=default' \ . l:display_name_args . ' -' @@ -74,23 +94,18 @@ let s:end_col_pattern_map = { \} function! ale_linters#python#flake8#Handle(buffer, lines) abort - for l:line in a:lines[:10] - if match(l:line, '^Traceback') >= 0 - return [{ - \ 'lnum': 1, - \ 'text': 'An exception was thrown. See :ALEDetail', - \ 'detail': join(a:lines, "\n"), - \}] - endif - endfor + 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:]]+) (.*)$' - let l:output = [] + 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] @@ -148,10 +163,8 @@ endfunction call ale#linter#Define('python', { \ 'name': 'flake8', -\ 'executable_callback': 'ale_linters#python#flake8#GetExecutable', -\ 'command_chain': [ -\ {'callback': 'ale_linters#python#flake8#VersionCheck'}, -\ {'callback': 'ale_linters#python#flake8#GetCommand', 'output_stream': 'both'}, -\ ], +\ 'executable': function('ale_linters#python#flake8#GetExecutable'), +\ 'cwd': function('ale_linters#python#flake8#GetCwd'), +\ 'command': function('ale_linters#python#flake8#RunWithVersionCheck'), \ 'callback': 'ale_linters#python#flake8#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/python/flakehell.vim b/vim-config/plugins/ale/ale_linters/python/flakehell.vim new file mode 100644 index 00000000..ffe87e29 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/python/flakehell.vim @@ -0,0 +1,175 @@ +" Author: w0rp +" Description: flakehell for python files + +call ale#Set('python_flakehell_executable', 'flakehell') +call ale#Set('python_flakehell_options', '') +call ale#Set('python_flakehell_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_flakehell_change_directory', 'project') +call ale#Set('python_flakehell_auto_pipenv', 0) +call ale#Set('python_flakehell_auto_poetry', 0) + +function! s:UsingModule(buffer) abort + return ale#Var(a:buffer, 'python_flakehell_executable') is? 'python' +endfunction + +function! ale_linters#python#flakehell#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_flakehell_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_flakehell_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + if !s:UsingModule(a:buffer) + return ale#python#FindExecutable(a:buffer, 'python_flakehell', ['flakehell']) + endif + + return ale#Var(a:buffer, 'python_flakehell_executable') +endfunction + +function! ale_linters#python#flakehell#RunWithVersionCheck(buffer) abort + let l:executable = ale_linters#python#flakehell#GetExecutable(a:buffer) + + let l:module_string = s:UsingModule(a:buffer) ? ' -m flakehell' : '' + 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#flakehell#GetCommand'), + \) +endfunction + +function! ale_linters#python#flakehell#GetCwd(buffer) abort + let l:change_directory = ale#Var(a:buffer, 'python_flakehell_change_directory') + let l:cwd = '' + + if l:change_directory is# 'project' + let l:project_root = ale#python#FindProjectRootIni(a:buffer) + + if !empty(l:project_root) + let l:cwd = l:project_root + endif + endif + + if (l:change_directory is# 'project' && empty(l:cwd)) + \|| l:change_directory is# 1 + \|| l:change_directory is# 'file' + let l:cwd = '%s:h' + endif + + return l:cwd +endfunction + +function! ale_linters#python#flakehell#GetCommand(buffer, version) abort + let l:executable = ale_linters#python#flakehell#GetExecutable(a:buffer) + + if (l:executable =~? 'pipenv\|poetry$') + let l:exec_args = ' run flakehell' + elseif (l:executable is? 'python') + let l:exec_args = ' -m flakehell' + else + let l:exec_args = '' + endif + + " Only include the --stdin-display-name argument if we can parse the + " flakehell version, and it is recent enough to support it. + let l:display_name_args = ale#semver#GTE(a:version, [0, 8, 0]) + \ ? ' --stdin-display-name %s' + \ : '' + + let l:options = ale#Var(a:buffer, 'python_flakehell_options') + + return ale#Escape(l:executable) + \ . l:exec_args + \ . (!empty(l:options) ? ' lint ' . l:options : ' lint') + \ . ' --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#flakehell#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': 'flakehell', +\ 'executable': function('ale_linters#python#flakehell#GetExecutable'), +\ 'cwd': function('ale_linters#python#flakehell#GetCwd'), +\ 'command': function('ale_linters#python#flakehell#RunWithVersionCheck'), +\ 'callback': 'ale_linters#python#flakehell#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/python/jedils.vim b/vim-config/plugins/ale/ale_linters/python/jedils.vim new file mode 100644 index 00000000..eae5fb07 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/python/jedils.vim @@ -0,0 +1,34 @@ +" Author: Dalius Dobravolskas +" Description: https://github.com/pappasam/jedi-language-server + +call ale#Set('python_jedils_executable', 'jedi-language-server') +call ale#Set('python_jedils_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_jedils_auto_pipenv', 0) + +function! ale_linters#python#jedils#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_jedils_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_jedils', ['jedi-language-server']) +endfunction + +function! ale_linters#python#jedils#GetCommand(buffer) abort + let l:executable = ale_linters#python#jedils#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run jedi-language-server' + \ : '' + + return ale#Escape(l:executable) . l:exec_args +endfunction + +call ale#linter#Define('python', { +\ 'name': 'jedils', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#python#jedils#GetExecutable'), +\ 'command': function('ale_linters#python#jedils#GetCommand'), +\ 'project_root': function('ale#python#FindProjectRoot'), +\ 'completion_filter': 'ale#completion#python#CompletionItemFilter', +\}) diff --git a/vim-config/plugins/ale/ale_linters/python/mypy.vim b/vim-config/plugins/ale/ale_linters/python/mypy.vim old mode 100755 new mode 100644 index 0c90a3c7..9d469a1a --- a/vim-config/plugins/ale/ale_linters/python/mypy.vim +++ b/vim-config/plugins/ale/ale_linters/python/mypy.vim @@ -3,9 +3,11 @@ call ale#Set('python_mypy_executable', 'mypy') call ale#Set('python_mypy_ignore_invalid_syntax', 0) +call ale#Set('python_mypy_show_notes', 1) 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) +call ale#Set('python_mypy_auto_poetry', 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')) @@ -13,11 +15,25 @@ function! ale_linters#python#mypy#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_mypy_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + return ale#python#FindExecutable(a:buffer, 'python_mypy', ['mypy']) endfunction " The directory to change to before running mypy -function! s:GetDir(buffer) abort +function! ale_linters#python#mypy#GetCwd(buffer) abort + " If we find a directory with "mypy.ini" in it use that, + " else try and find the "python project" root, or failing + " that, run from the same folder as the current file + for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) + if filereadable(l:path . '/mypy.ini') + return l:path + endif + endfor + let l:project_root = ale#python#FindProjectRoot(a:buffer) return !empty(l:project_root) @@ -26,24 +42,19 @@ function! s:GetDir(buffer) abort 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$' + let l:exec_args = l:executable =~? 'pipenv\|poetry$' \ ? ' 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') + return '%e' . l:exec_args + \ . ale#Pad(ale#Var(a:buffer, 'python_mypy_options')) + \ . ' --show-column-numbers' \ . ' --shadow-file %s %t %s' endfunction function! ale_linters#python#mypy#Handle(buffer, lines) abort - let l:dir = s:GetDir(a:buffer) + let l:dir = ale_linters#python#mypy#GetCwd(a:buffer) " Look for lines like the following: " " file.py:4: error: No library stub file for module 'django.db' @@ -51,7 +62,16 @@ function! ale_linters#python#mypy#Handle(buffer, lines) abort " 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:types = 'error|warning' + + if ale#Var(a:buffer, 'python_mypy_show_notes') + let l:types = 'error|warning|note' + endif + + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: (' + \ . l:types + \ . '): (.+)$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) @@ -65,7 +85,7 @@ function! ale_linters#python#mypy#Handle(buffer, lines) abort \ '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', + \ 'type': l:match[4] is# 'error' ? 'E' : (l:match[4] is# 'note' ? 'I': 'W'), \ 'text': l:match[5], \}) endfor @@ -75,7 +95,9 @@ endfunction call ale#linter#Define('python', { \ 'name': 'mypy', -\ 'executable_callback': 'ale_linters#python#mypy#GetExecutable', -\ 'command_callback': 'ale_linters#python#mypy#GetCommand', +\ 'executable': function('ale_linters#python#mypy#GetExecutable'), +\ 'cwd': function('ale_linters#python#mypy#GetCwd'), +\ 'command': function('ale_linters#python#mypy#GetCommand'), \ 'callback': 'ale_linters#python#mypy#Handle', +\ 'output_stream': 'both' \}) diff --git a/vim-config/plugins/ale/ale_linters/python/prospector.vim b/vim-config/plugins/ale/ale_linters/python/prospector.vim old mode 100755 new mode 100644 index b01cec87..3623bda0 --- a/vim-config/plugins/ale/ale_linters/python/prospector.vim +++ b/vim-config/plugins/ale/ale_linters/python/prospector.vim @@ -2,6 +2,7 @@ " Description: prospector linter python files call ale#Set('python_prospector_auto_pipenv', 0) +call ale#Set('python_prospector_auto_poetry', 0) let g:ale_python_prospector_executable = \ get(g:, 'ale_python_prospector_executable', 'prospector') @@ -17,13 +18,18 @@ function! ale_linters#python#prospector#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_prospector_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + 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$' + let l:exec_args = l:executable =~? 'pipenv\|poetry$' \ ? ' run prospector' \ : '' @@ -93,8 +99,8 @@ endfunction call ale#linter#Define('python', { \ 'name': 'prospector', -\ 'executable_callback': 'ale_linters#python#prospector#GetExecutable', -\ 'command_callback': 'ale_linters#python#prospector#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/python/pycodestyle.vim b/vim-config/plugins/ale/ale_linters/python/pycodestyle.vim old mode 100755 new mode 100644 index f0269585..3fb94d69 --- a/vim-config/plugins/ale/ale_linters/python/pycodestyle.vim +++ b/vim-config/plugins/ale/ale_linters/python/pycodestyle.vim @@ -5,6 +5,7 @@ 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) +call ale#Set('python_pycodestyle_auto_poetry', 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')) @@ -12,13 +13,18 @@ function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pycodestyle_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + 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$' + let l:exec_args = l:executable =~? 'pipenv\|poetry$' \ ? ' run pycodestyle' \ : '' @@ -69,7 +75,7 @@ endfunction call ale#linter#Define('python', { \ 'name': 'pycodestyle', -\ 'executable_callback': 'ale_linters#python#pycodestyle#GetExecutable', -\ 'command_callback': 'ale_linters#python#pycodestyle#GetCommand', +\ 'executable': function('ale_linters#python#pycodestyle#GetExecutable'), +\ 'command': function('ale_linters#python#pycodestyle#GetCommand'), \ 'callback': 'ale_linters#python#pycodestyle#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/python/pydocstyle.vim b/vim-config/plugins/ale/ale_linters/python/pydocstyle.vim old mode 100755 new mode 100644 index ebf92bf1..aa0e8b20 --- a/vim-config/plugins/ale/ale_linters/python/pydocstyle.vim +++ b/vim-config/plugins/ale/ale_linters/python/pydocstyle.vim @@ -5,6 +5,7 @@ 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) +call ale#Set('python_pydocstyle_auto_poetry', 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')) @@ -12,29 +13,30 @@ function! ale_linters#python#pydocstyle#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pydocstyle_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + 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$' + let l:exec_args = l:executable =~? 'pipenv\|poetry$' \ ? ' 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')) + return ale#Escape(l:executable) . l:exec_args + \ . ale#Pad(ale#Var(a:buffer, 'python_pydocstyle_options')) + \ . ' %s: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:fname = ale#Escape(fnamemodify(bufname(a:buffer), ':p:t')) - let l:line1_pattern = '\v^' . l:fname . ':\s*(\d+)\s+.*$' + let l:line1_pattern = '\v^.*:\s*(\d+)\s+.*$' let l:line2_pattern = '\v^.*([a-zA-Z]\d+):\s*(.*)$' let l:output = [] @@ -68,7 +70,8 @@ endfunction call ale#linter#Define('python', { \ 'name': 'pydocstyle', -\ 'executable_callback': 'ale_linters#python#pydocstyle#GetExecutable', -\ 'command_callback': 'ale_linters#python#pydocstyle#GetCommand', +\ 'executable': function('ale_linters#python#pydocstyle#GetExecutable'), +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#python#pydocstyle#GetCommand'), \ 'callback': 'ale_linters#python#pydocstyle#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/python/pyflakes.vim b/vim-config/plugins/ale/ale_linters/python/pyflakes.vim old mode 100755 new mode 100644 index 091408d5..2567c533 --- a/vim-config/plugins/ale/ale_linters/python/pyflakes.vim +++ b/vim-config/plugins/ale/ale_linters/python/pyflakes.vim @@ -4,6 +4,7 @@ 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) +call ale#Set('python_pyflakes_auto_poetry', 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')) @@ -11,13 +12,18 @@ function! ale_linters#python#pyflakes#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pyflakes_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + 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$' + let l:exec_args = l:executable =~? 'pipenv\|poetry$' \ ? ' run pyflakes' \ : '' @@ -43,8 +49,8 @@ endfunction call ale#linter#Define('python', { \ 'name': 'pyflakes', -\ 'executable_callback': 'ale_linters#python#pyflakes#GetExecutable', -\ 'command_callback': 'ale_linters#python#pyflakes#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/python/pylama.vim b/vim-config/plugins/ale/ale_linters/python/pylama.vim new file mode 100644 index 00000000..73b59b07 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/python/pylama.vim @@ -0,0 +1,99 @@ +" 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_auto_poetry', 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 + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pylama_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pylama', ['pylama']) +endfunction + +function! ale_linters#python#pylama#GetCwd(buffer) abort + 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) + + return !empty(l:project_root) ? l:project_root : '%s:h' + endif + + return '' +endfunction + +function! ale_linters#python#pylama#GetCommand(buffer) abort + let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer) + let l:exec_args = l:executable =~? 'pipenv\|poetry$' + \ ? ' 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 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'), +\ 'cwd': function('ale_linters#python#pylama#GetCwd'), +\ 'command': function('ale_linters#python#pylama#GetCommand'), +\ 'callback': 'ale_linters#python#pylama#Handle', +\ 'lint_file': 1, +\}) diff --git a/vim-config/plugins/ale/ale_linters/python/pylint.vim b/vim-config/plugins/ale/ale_linters/python/pylint.vim old mode 100755 new mode 100644 index 01c3cb37..2ce5376f --- a/vim-config/plugins/ale/ale_linters/python/pylint.vim +++ b/vim-config/plugins/ale/ale_linters/python/pylint.vim @@ -6,6 +6,8 @@ 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_auto_poetry', 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')) @@ -13,33 +15,51 @@ function! ale_linters#python#pylint#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pylint_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint']) endfunction -function! ale_linters#python#pylint#GetCommand(buffer) abort - let l:cd_string = ale#Var(a:buffer, 'python_pylint_change_directory') - \ ? ale#path#BufferCdString(a:buffer) - \ : '' +function! ale_linters#python#pylint#GetCwd(buffer) abort + 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:executable = ale_linters#python#pylint#GetExecutable(a:buffer) + return !empty(l:project_root) ? l:project_root : '%s:h' + endif - let l:exec_args = l:executable =~? 'pipenv$' + return '' +endfunction + +function! ale_linters#python#pylint#GetCommand(buffer, version) abort + let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer) + let l:exec_args = l:executable =~? 'pipenv\|poetry$' \ ? ' run pylint' \ : '' - return l:cd_string - \ . ale#Escape(l:executable) . l:exec_args - \ . ' ' . ale#Var(a:buffer, 'python_pylint_options') + return ale#Escape(l:executable) . l:exec_args + \ . ale#Pad(ale#Var(a:buffer, 'python_pylint_options')) \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n' + \ . (ale#semver#GTE(a:version, [2, 4, 0]) ? ' --from-stdin' : '') \ . ' %s' endfunction function! ale_linters#python#pylint#Handle(buffer, lines) abort + let l:output = ale#python#HandleTraceback(a:lines, 10) + + if !empty(l:output) + return l:output + endif + " 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) @@ -53,16 +73,28 @@ function! ale_linters#python#pylint#Handle(buffer, lines) abort if l:code is# 'I0011' " Skip 'Locally disabling' message - continue + 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, { + let l:item = { \ 'lnum': l:match[1] + 0, \ 'col': l:match[2] + 1, \ 'text': l:match[5], - \ 'code': l:match[4], - \ 'type': l:code[:0] is# 'E' ? 'E' : 'W', - \}) + \ 'code': l:code_out, + \ 'type': 'W', + \} + + if l:code[:0] is# 'E' + let l:item.type = 'E' + endif + + call add(l:output, l:item) endfor return l:output @@ -70,8 +102,19 @@ endfunction call ale#linter#Define('python', { \ 'name': 'pylint', -\ 'executable_callback': 'ale_linters#python#pylint#GetExecutable', -\ 'command_callback': 'ale_linters#python#pylint#GetCommand', +\ 'executable': function('ale_linters#python#pylint#GetExecutable'), +\ 'lint_file': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale#Var(buffer, 'python_pylint_executable'), +\ '%e --version', +\ {buffer, version -> !ale#semver#GTE(version, [2, 4, 0])}, +\ )}, +\ 'cwd': function('ale_linters#python#pylint#GetCwd'), +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale#Var(buffer, 'python_pylint_executable'), +\ '%e --version', +\ function('ale_linters#python#pylint#GetCommand'), +\ )}, \ 'callback': 'ale_linters#python#pylint#Handle', -\ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/python/pyls.vim b/vim-config/plugins/ale/ale_linters/python/pyls.vim deleted file mode 100755 index 2c2ed94c..00000000 --- a/vim-config/plugins/ale/ale_linters/python/pyls.vim +++ /dev/null @@ -1,36 +0,0 @@ -" 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_callback': 'ale_linters#python#pyls#GetExecutable', -\ 'command_callback': 'ale_linters#python#pyls#GetCommand', -\ 'project_root_callback': 'ale#python#FindProjectRoot', -\ 'completion_filter': 'ale#completion#python#CompletionItemFilter', -\ 'lsp_config_callback': ale#VarFunc('python_pyls_config'), -\}) diff --git a/vim-config/plugins/ale/ale_linters/python/pylsp.vim b/vim-config/plugins/ale/ale_linters/python/pylsp.vim new file mode 100644 index 00000000..537d1e74 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/python/pylsp.vim @@ -0,0 +1,43 @@ +" Author: aurieh +" Description: A language server for Python + +call ale#Set('python_pylsp_executable', 'pylsp') +call ale#Set('python_pylsp_options', '') +call ale#Set('python_pylsp_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pylsp_auto_pipenv', 0) +call ale#Set('python_pylsp_auto_poetry', 0) +call ale#Set('python_pylsp_config', {}) + +function! ale_linters#python#pylsp#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylsp_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pylsp_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pylsp', ['pylsp']) +endfunction + +function! ale_linters#python#pylsp#GetCommand(buffer) abort + let l:executable = ale_linters#python#pylsp#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv\|poetry$' + \ ? ' run pylsp' + \ : '' + + return ale#Escape(l:executable) . l:exec_args . ale#Pad(ale#Var(a:buffer, 'python_pylsp_options')) +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pylsp', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#python#pylsp#GetExecutable'), +\ 'command': function('ale_linters#python#pylsp#GetCommand'), +\ 'project_root': function('ale#python#FindProjectRoot'), +\ 'completion_filter': 'ale#completion#python#CompletionItemFilter', +\ 'lsp_config': {b -> ale#Var(b, 'python_pylsp_config')}, +\}) diff --git a/vim-config/plugins/ale/ale_linters/python/pyre.vim b/vim-config/plugins/ale/ale_linters/python/pyre.vim old mode 100755 new mode 100644 index adc185f2..5e5786f9 --- a/vim-config/plugins/ale/ale_linters/python/pyre.vim +++ b/vim-config/plugins/ale/ale_linters/python/pyre.vim @@ -4,6 +4,7 @@ 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) +call ale#Set('python_pyre_auto_poetry', 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')) @@ -11,24 +12,33 @@ function! ale_linters#python#pyre#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pyre_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + 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' + let l:exec_args = (l:executable =~? 'pipenv\|poetry$' ? ' run pyre' : '') . ' persistent' return ale#Escape(l:executable) . l:exec_args endfunction +function! ale_linters#python#pyre#GetCwd(buffer) abort + let l:local_config = ale#path#FindNearestFile(a:buffer, '.pyre_configuration.local') + + return fnamemodify(l:local_config, ':h') +endfunction + call ale#linter#Define('python', { \ 'name': 'pyre', \ 'lsp': 'stdio', -\ 'executable_callback': 'ale_linters#python#pyre#GetExecutable', -\ 'command_callback': 'ale_linters#python#pyre#GetCommand', -\ 'project_root_callback': 'ale#python#FindProjectRoot', +\ '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', +\ 'cwd': function('ale_linters#python#pyre#GetCwd'), \}) diff --git a/vim-config/plugins/ale/ale_linters/python/pyright.vim b/vim-config/plugins/ale/ale_linters/python/pyright.vim new file mode 100644 index 00000000..422ecd61 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/python/pyright.vim @@ -0,0 +1,43 @@ +call ale#Set('python_pyright_executable', 'pyright-langserver') +call ale#Set('python_pyright_config', {}) + +function! ale_linters#python#pyright#GetConfig(buffer) abort + let l:config = deepcopy(ale#Var(a:buffer, 'python_pyright_config')) + + if !has_key(l:config, 'python') + let l:config.python = {} + endif + + if type(l:config.python) is v:t_dict + " Automatically detect the virtualenv path and use it. + if !has_key(l:config.python, 'venvPath') + let l:venv = ale#python#FindVirtualenv(a:buffer) + + if !empty(l:venv) + let l:config.python.venvPath = l:venv + endif + endif + + " Automatically use the version of Python in virtualenv. + if type(get(l:config.python, 'venvPath')) is v:t_string + \&& !empty(l:config.python.venvPath) + \&& !has_key(l:config.python, 'pythonPath') + let l:config.python.pythonPath = ale#path#Simplify( + \ l:config.python.venvPath + \ . (has('win32') ? '/Scripts/python' : '/bin/python') + \) + endif + endif + + return l:config +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pyright', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'python_pyright_executable')}, +\ 'command': '%e --stdio', +\ 'project_root': function('ale#python#FindProjectRoot'), +\ 'completion_filter': 'ale#completion#python#CompletionItemFilter', +\ 'lsp_config': function('ale_linters#python#pyright#GetConfig'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/python/vulture.vim b/vim-config/plugins/ale/ale_linters/python/vulture.vim old mode 100755 new mode 100644 index 80828013..a7ba1860 --- a/vim-config/plugins/ale/ale_linters/python/vulture.vim +++ b/vim-config/plugins/ale/ale_linters/python/vulture.vim @@ -6,7 +6,6 @@ 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) @@ -16,29 +15,28 @@ function! s:GetDir(buffer) abort \ : 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#GetCwd(buffer) abort + if !ale#Var(a:buffer, 'python_vulture_change_directory') + return '' + endif -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)) - \ : '' + return s:GetDir(a:buffer) +endfunction +function! ale_linters#python#vulture#GetCommand(buffer) abort let l:executable = ale_linters#python#vulture#GetExecutable(a:buffer) - - let l:exec_args = l:executable =~? 'pipenv$' + let l:exec_args = l:executable =~? 'pipenv\|poetry$' \ ? ' 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 + return ale#Escape(l:executable) . l:exec_args \ . ' ' \ . ale#Var(a:buffer, 'python_vulture_options') \ . l:lint_dest @@ -46,19 +44,14 @@ endfunction function! ale_linters#python#vulture#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 + 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:output = [] let l:dir = s:GetDir(a:buffer) for l:match in ale#util#GetMatches(a:lines, l:pattern) @@ -78,8 +71,9 @@ endfunction call ale#linter#Define('python', { \ 'name': 'vulture', -\ 'executable_callback': 'ale_linters#python#vulture#GetExecutable', -\ 'command_callback': 'ale_linters#python#vulture#GetCommand', +\ 'executable': function('ale_linters#python#vulture#GetExecutable'), +\ 'cwd': function('ale_linters#python#vulture#GetCwd'), +\ 'command': function('ale_linters#python#vulture#GetCommand'), \ 'callback': 'ale_linters#python#vulture#Handle', \ 'lint_file': 1, \}) diff --git a/vim-config/plugins/ale/ale_linters/qml/qmlfmt.vim b/vim-config/plugins/ale/ale_linters/qml/qmlfmt.vim old mode 100755 new mode 100644 index 12f3e97b..11cc9413 --- a/vim-config/plugins/ale/ale_linters/qml/qmlfmt.vim +++ b/vim-config/plugins/ale/ale_linters/qml/qmlfmt.vim @@ -19,7 +19,7 @@ endfunction call ale#linter#Define('qml', { \ 'name': 'qmlfmt', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('qml_qmlfmt_executable'), +\ 'executable': {b -> ale#Var(b, 'qml_qmlfmt_executable')}, \ 'command': '%e -e', \ 'callback': 'ale_linters#qml#qmlfmt#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/qml/qmllint.vim b/vim-config/plugins/ale/ale_linters/qml/qmllint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/r/languageserver.vim b/vim-config/plugins/ale/ale_linters/r/languageserver.vim new file mode 100644 index 00000000..bab869d1 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/r/languageserver.vim @@ -0,0 +1,27 @@ +" Author: Eric Zhao <21zhaoe@protonmail.com> +" Author: ourigen +" Description: Implementation of the Language Server Protocol for R. + +call ale#Set('r_languageserver_cmd', 'languageserver::run()') +call ale#Set('r_languageserver_config', {}) + +function! ale_linters#r#languageserver#GetCommand(buffer) abort + let l:cmd_string = ale#Var(a:buffer, 'r_languageserver_cmd') + + return 'Rscript --no-save --no-restore --no-site-file --no-init-file -e ' . ale#Escape(l:cmd_string) +endfunction + +function! ale_linters#r#languageserver#GetProjectRoot(buffer) abort + let l:project_root = ale#path#FindNearestFile(a:buffer, '.Rprofile') + + return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : fnamemodify(a:buffer, ':h') +endfunction + +call ale#linter#Define('r', { +\ 'name': 'languageserver', +\ 'lsp': 'stdio', +\ 'lsp_config': {b -> ale#Var(b, 'r_languageserver_config')}, +\ 'executable': 'Rscript', +\ 'command': function('ale_linters#r#languageserver#GetCommand'), +\ 'project_root': function('ale_linters#r#languageserver#GetProjectRoot') +\}) diff --git a/vim-config/plugins/ale/ale_linters/r/lintr.vim b/vim-config/plugins/ale/ale_linters/r/lintr.vim old mode 100755 new mode 100644 index 8f74c9b8..339ad2b0 --- a/vim-config/plugins/ale/ale_linters/r/lintr.vim +++ b/vim-config/plugins/ale/ale_linters/r/lintr.vim @@ -1,5 +1,6 @@ " Author: Michel Lang , w0rp , -" Fenner Macrae +" Fenner Macrae , +" ourigen " 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()') @@ -21,15 +22,14 @@ function! ale_linters#r#lintr#GetCommand(buffer) abort 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' + return 'Rscript --no-save --no-restore --no-site-file --no-init-file -e ' . ale#Escape(l:cmd_string) . ' %t' endfunction call ale#linter#Define('r', { \ 'name': 'lintr', \ 'executable': 'Rscript', -\ 'command_callback': 'ale_linters#r#lintr#GetCommand', +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#r#lintr#GetCommand'), \ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \ 'output_stream': 'both', \}) diff --git a/vim-config/plugins/ale/ale_linters/racket/langserver.vim b/vim-config/plugins/ale/ale_linters/racket/langserver.vim new file mode 100644 index 00000000..ec80ed7b --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/racket/langserver.vim @@ -0,0 +1,7 @@ +call ale#linter#Define('racket', { +\ 'name': 'racket_langserver', +\ 'lsp': 'stdio', +\ 'executable': 'racket', +\ 'command': '%e -l racket-langserver', +\ 'project_root': function('ale#racket#FindProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/racket/raco.vim b/vim-config/plugins/ale/ale_linters/racket/raco.vim old mode 100755 new mode 100644 index e5ee4fb4..5b26065f --- a/vim-config/plugins/ale/ale_linters/racket/raco.vim +++ b/vim-config/plugins/ale/ale_linters/racket/raco.vim @@ -14,6 +14,7 @@ function! ale_linters#racket#raco#Handle(buffer, lines) abort for l:match in ale#util#GetMatches(a:lines, l:pattern) call add(l:output, { + \ 'filename': l:match[2], \ 'lnum': l:match[3] + 0, \ 'col': l:match[4] + 0, \ 'type': 'E', diff --git a/vim-config/plugins/ale/ale_linters/reason/ls.vim b/vim-config/plugins/ale/ale_linters/reason/ls.vim new file mode 100644 index 00000000..fb1114ae --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/reason/merlin.vim b/vim-config/plugins/ale/ale_linters/reason/merlin.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/reason/ols.vim b/vim-config/plugins/ale/ale_linters/reason/ols.vim old mode 100755 new mode 100644 index 4e5bd395..9fbd9b4f --- a/vim-config/plugins/ale/ale_linters/reason/ols.vim +++ b/vim-config/plugins/ale/ale_linters/reason/ols.vim @@ -7,8 +7,8 @@ call ale#Set('reason_ols_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#linter#Define('reason', { \ 'name': 'ols', \ 'lsp': 'stdio', -\ 'executable_callback': 'ale#handlers#ols#GetExecutable', -\ 'command_callback': 'ale#handlers#ols#GetCommand', -\ 'language_callback': 'ale#handlers#ols#GetLanguage', -\ 'project_root_callback': 'ale#handlers#ols#GetProjectRoot', +\ 'executable': function('ale#handlers#ols#GetExecutable'), +\ 'command': function('ale#handlers#ols#GetCommand'), +\ 'language': function('ale#handlers#ols#GetLanguage'), +\ 'project_root': function('ale#handlers#ols#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/review/redpen.vim b/vim-config/plugins/ale/ale_linters/review/redpen.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/robot/rflint.vim b/vim-config/plugins/ale/ale_linters/robot/rflint.vim new file mode 100644 index 00000000..8fe2d797 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/robot/rflint.vim @@ -0,0 +1,46 @@ +" Author: Samuel Branisa +" Description: rflint linting for robot framework files + +call ale#Set('robot_rflint_executable', 'rflint') + +function! ale_linters#robot#rflint#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'robot_rflint_executable') +endfunction + +function! ale_linters#robot#rflint#GetCommand(buffer) abort + let l:executable = ale_linters#robot#rflint#GetExecutable(a:buffer) + let l:flags = '--format' + \ . ' "{filename}:{severity}:{linenumber}:{char}:{rulename}:{message}"' + + return l:executable + \ . ' ' + \ . l:flags + \ . ' %s' +endfunction + +function! ale_linters#robot#rflint#Handle(buffer, lines) abort + let l:pattern = '\v^([[:alnum:][:punct:]]+):(W|E):([[:digit:]]+):([[:digit:]]+):([[:alnum:]]+):(.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'filename': l:match[1], + \ 'type': l:match[2], + \ 'lnum': str2nr(l:match[3]), + \ 'col': str2nr(l:match[4]), + \ 'text': l:match[5], + \ 'detail': l:match[6], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('robot', { +\ 'name': 'rflint', +\ 'executable': function('ale_linters#robot#rflint#GetExecutable'), +\ 'command': function('ale_linters#robot#rflint#GetCommand'), +\ 'callback': 'ale_linters#robot#rflint#Handle', +\}) + diff --git a/vim-config/plugins/ale/ale_linters/rst/alex.vim b/vim-config/plugins/ale/ale_linters/rst/alex.vim old mode 100755 new mode 100644 index e637eae7..e7ca6fa0 --- a/vim-config/plugins/ale/ale_linters/rst/alex.vim +++ b/vim-config/plugins/ale/ale_linters/rst/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for rst files -call ale#linter#Define('rst', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('rst', '--text') diff --git a/vim-config/plugins/ale/ale_linters/rst/proselint.vim b/vim-config/plugins/ale/ale_linters/rst/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/rst/redpen.vim b/vim-config/plugins/ale/ale_linters/rst/redpen.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/rst/rstcheck.vim b/vim-config/plugins/ale/ale_linters/rst/rstcheck.vim old mode 100755 new mode 100644 index 8504738b..e0cf0798 --- a/vim-config/plugins/ale/ale_linters/rst/rstcheck.vim +++ b/vim-config/plugins/ale/ale_linters/rst/rstcheck.vim @@ -1,6 +1,5 @@ " 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 @@ -22,17 +21,11 @@ function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort 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_callback': 'ale_linters#rst#rstcheck#GetCommand', +\ 'cwd': '%s:h', +\ 'command': 'rstcheck %t', \ 'callback': 'ale_linters#rst#rstcheck#Handle', \ 'output_stream': 'both', \}) diff --git a/vim-config/plugins/ale/ale_linters/rst/textlint.vim b/vim-config/plugins/ale/ale_linters/rst/textlint.vim old mode 100755 new mode 100644 index a14411cf..56dd8db8 --- a/vim-config/plugins/ale/ale_linters/rst/textlint.vim +++ b/vim-config/plugins/ale/ale_linters/rst/textlint.vim @@ -3,7 +3,7 @@ call ale#linter#Define('rst', { \ 'name': 'textlint', -\ 'executable_callback': 'ale#handlers#textlint#GetExecutable', -\ 'command_callback': 'ale#handlers#textlint#GetCommand', +\ 'executable': function('ale#handlers#textlint#GetExecutable'), +\ 'command': function('ale#handlers#textlint#GetCommand'), \ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', \}) diff --git a/vim-config/plugins/ale/ale_linters/rst/vale.vim b/vim-config/plugins/ale/ale_linters/rst/vale.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/rst/writegood.vim b/vim-config/plugins/ale/ale_linters/rst/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/ruby/brakeman.vim b/vim-config/plugins/ale/ale_linters/ruby/brakeman.vim old mode 100755 new mode 100644 index 122e0b5b..2dc48740 --- a/vim-config/plugins/ale/ale_linters/ruby/brakeman.vim +++ b/vim-config/plugins/ale/ale_linters/ruby/brakeman.vim @@ -36,7 +36,7 @@ function! ale_linters#ruby#brakeman#GetCommand(buffer) abort let l:executable = ale#Var(a:buffer, 'ruby_brakeman_executable') - return ale#handlers#ruby#EscapeExecutable(l:executable, 'brakeman') + return ale#ruby#EscapeExecutable(l:executable, 'brakeman') \ . ' -f json -q ' \ . ale#Var(a:buffer, 'ruby_brakeman_options') \ . ' -p ' . ale#Escape(l:rails_root) @@ -44,8 +44,8 @@ endfunction call ale#linter#Define('ruby', { \ 'name': 'brakeman', -\ 'executable_callback': ale#VarFunc('ruby_brakeman_executable'), -\ 'command_callback': 'ale_linters#ruby#brakeman#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/ruby/debride.vim b/vim-config/plugins/ale/ale_linters/ruby/debride.vim new file mode 100644 index 00000000..3b2cc443 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/ruby/debride.vim @@ -0,0 +1,42 @@ +" Author: Eddie Lebow https://github.com/elebow +" Description: debride, a dead method detector for Ruby files + +call ale#Set('ruby_debride_executable', 'debride') +call ale#Set('ruby_debride_options', '') + +function! ale_linters#ruby#debride#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_debride_executable') + + return ale#ruby#EscapeExecutable(l:executable, 'debride') + \ . ale#Var(a:buffer, 'ruby_debride_options') + \ . ' %s' +endfunction + +function! ale_linters#ruby#debride#HandleOutput(buffer, lines) abort + let l:output = [] + + for l:line in a:lines + if l:line !~# '^ ' + continue + endif + + let l:elements = split(l:line) + let l:method_name = l:elements[0] + let l:lnum = split(l:elements[1], ':')[1] + + call add(l:output, { + \ 'lnum': 0 + l:lnum, + \ 'text': 'Possible unused method: ' . l:method_name, + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('ruby', { +\ 'name': 'debride', +\ 'executable': {b -> ale#Var(b, 'ruby_debride_executable')}, +\ 'command': function('ale_linters#ruby#debride#GetCommand'), +\ 'callback': 'ale_linters#ruby#debride#HandleOutput', +\}) diff --git a/vim-config/plugins/ale/ale_linters/ruby/rails_best_practices.vim b/vim-config/plugins/ale/ale_linters/ruby/rails_best_practices.vim old mode 100755 new mode 100644 index 20cadca8..36646647 --- a/vim-config/plugins/ale/ale_linters/ruby/rails_best_practices.vim +++ b/vim-config/plugins/ale/ale_linters/ruby/rails_best_practices.vim @@ -30,10 +30,10 @@ function! ale_linters#ruby#rails_best_practices#GetCommand(buffer) abort endif let l:executable = ale#Var(a:buffer, 'ruby_rails_best_practices_executable') - let l:output_file = ale#Has('win32') ? '%t ' : '/dev/stdout ' - let l:cat_file = ale#Has('win32') ? '; type %t' : '' + 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') + return ale#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) @@ -42,8 +42,8 @@ endfunction call ale#linter#Define('ruby', { \ 'name': 'rails_best_practices', -\ 'executable_callback': ale#VarFunc('ruby_rails_best_practices_executable'), -\ 'command_callback': 'ale_linters#ruby#rails_best_practices#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/ruby/reek.vim b/vim-config/plugins/ale/ale_linters/ruby/reek.vim old mode 100755 new mode 100644 index 53363d31..226b452e --- a/vim-config/plugins/ale/ale_linters/ruby/reek.vim +++ b/vim-config/plugins/ale/ale_linters/ruby/reek.vim @@ -6,30 +6,15 @@ 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#VersionCheck(buffer) abort - " If we have previously stored the version number in a cache, then - " don't look it up again. - if ale#semver#HasVersion('reek') - " Returning an empty string skips this command. - return '' - endif - - let l:executable = ale#Var(a:buffer, 'ruby_reek_executable') - - return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek') - \ . ' --version' -endfunction - -function! ale_linters#ruby#reek#GetCommand(buffer, version_output) abort - let l:version = ale#semver#GetVersion('reek', a:version_output) +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(l:version, [5, 0, 0]) + let l:display_name_args = ale#semver#GTE(a:version, [5, 0, 0]) \ ? ' --stdin-filename %s' \ : '' - return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek') + return ale#ruby#EscapeExecutable(l:executable, 'reek') \ . ' -f json --no-progress --no-color --force-exclusion' \ . l:display_name_args endfunction @@ -69,10 +54,12 @@ endfunction call ale#linter#Define('ruby', { \ 'name': 'reek', -\ 'executable_callback': ale#VarFunc('ruby_reek_executable'), -\ 'command_chain': [ -\ {'callback': 'ale_linters#ruby#reek#VersionCheck'}, -\ {'callback': 'ale_linters#ruby#reek#GetCommand'}, -\ ], +\ '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/vim-config/plugins/ale/ale_linters/ruby/rubocop.vim b/vim-config/plugins/ale/ale_linters/ruby/rubocop.vim old mode 100755 new mode 100644 index 790ca82c..483806a6 --- a/vim-config/plugins/ale/ale_linters/ruby/rubocop.vim +++ b/vim-config/plugins/ale/ale_linters/ruby/rubocop.vim @@ -7,10 +7,10 @@ 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') + return ale#ruby#EscapeExecutable(l:executable, 'rubocop') \ . ' --format json --force-exclusion ' \ . ale#Var(a:buffer, 'ruby_rubocop_options') - \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) + \ . ' --stdin %s' endfunction function! ale_linters#ruby#rubocop#GetType(severity) abort @@ -25,7 +25,7 @@ endfunction call ale#linter#Define('ruby', { \ 'name': 'rubocop', -\ 'executable_callback': ale#VarFunc('ruby_rubocop_executable'), -\ 'command_callback': 'ale_linters#ruby#rubocop#GetCommand', +\ 'executable': {b -> ale#Var(b, 'ruby_rubocop_executable')}, +\ 'command': function('ale_linters#ruby#rubocop#GetCommand'), \ 'callback': 'ale#ruby#HandleRubocopOutput', \}) diff --git a/vim-config/plugins/ale/ale_linters/ruby/ruby.vim b/vim-config/plugins/ale/ale_linters/ruby/ruby.vim old mode 100755 new mode 100644 index 2bc4ec4b..621fcbc0 --- a/vim-config/plugins/ale/ale_linters/ruby/ruby.vim +++ b/vim-config/plugins/ale/ale_linters/ruby/ruby.vim @@ -5,8 +5,8 @@ call ale#Set('ruby_ruby_executable', 'ruby') call ale#linter#Define('ruby', { \ 'name': 'ruby', -\ 'executable_callback': ale#VarFunc('ruby_ruby_executable'), -\ 'command': '%e -w -c -T1 %t', +\ 'executable': {b -> ale#Var(b, 'ruby_ruby_executable')}, +\ 'command': '%e -w -c %t', \ 'output_stream': 'stderr', \ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', \}) diff --git a/vim-config/plugins/ale/ale_linters/ruby/solargraph.vim b/vim-config/plugins/ale/ale_linters/ruby/solargraph.vim old mode 100755 new mode 100644 index 5ff0a759..bf54a55c --- a/vim-config/plugins/ale/ale_linters/ruby/solargraph.vim +++ b/vim-config/plugins/ale/ale_linters/ruby/solargraph.vim @@ -15,8 +15,8 @@ call ale#linter#Define('ruby', { \ 'name': 'solargraph', \ 'lsp': 'stdio', \ 'language': 'ruby', -\ 'executable_callback': ale#VarFunc('ruby_solargraph_executable'), -\ 'command_callback': 'ale_linters#ruby#solargraph#GetCommand', -\ 'project_root_callback': 'ale#ruby#FindProjectRoot', -\ 'initialization_options_callback': ale#VarFunc('ruby_solargraph_options'), +\ '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/vim-config/plugins/ale/ale_linters/ruby/sorbet.vim b/vim-config/plugins/ale/ale_linters/ruby/sorbet.vim new file mode 100644 index 00000000..c67e20cc --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/ruby/sorbet.vim @@ -0,0 +1,26 @@ +call ale#Set('ruby_sorbet_executable', 'srb') +call ale#Set('ruby_sorbet_options', '') +call ale#Set('ruby_sorbet_enable_watchman', 0) + +function! ale_linters#ruby#sorbet#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable') + let l:options = ale#Var(a:buffer, 'ruby_sorbet_options') + let l:enable_watchman = ale#Var(a:buffer, 'ruby_sorbet_enable_watchman') + + return ale#ruby#EscapeExecutable(l:executable, 'srb') + \ . ' tc' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --lsp' + \ . (l:enable_watchman ? '' : ' --disable-watchman') +endfunction + +call ale#linter#Define('ruby', { +\ 'name': 'sorbet', +\ 'aliases': ['srb'], +\ 'lsp': 'stdio', +\ 'language': 'ruby', +\ 'executable': {b -> ale#Var(b, 'ruby_sorbet_executable')}, +\ 'command': function('ale_linters#ruby#sorbet#GetCommand'), +\ 'project_root': function('ale#ruby#FindProjectRoot') +\}) + diff --git a/vim-config/plugins/ale/ale_linters/ruby/standardrb.vim b/vim-config/plugins/ale/ale_linters/ruby/standardrb.vim old mode 100755 new mode 100644 index 95e10934..6ccfd2d6 --- a/vim-config/plugins/ale/ale_linters/ruby/standardrb.vim +++ b/vim-config/plugins/ale/ale_linters/ruby/standardrb.vim @@ -8,16 +8,16 @@ 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') + return ale#ruby#EscapeExecutable(l:executable, 'standardrb') \ . ' --format json --force-exclusion ' \ . ale#Var(a:buffer, 'ruby_standardrb_options') - \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) + \ . ' --stdin %s' endfunction " standardrb is based on RuboCop so the callback is the same call ale#linter#Define('ruby', { \ 'name': 'standardrb', -\ 'executable_callback': ale#VarFunc('ruby_standardrb_executable'), -\ 'command_callback': 'ale_linters#ruby#standardrb#GetCommand', +\ 'executable': {b -> ale#Var(b, 'ruby_standardrb_executable')}, +\ 'command': function('ale_linters#ruby#standardrb#GetCommand'), \ 'callback': 'ale#ruby#HandleRubocopOutput', \}) diff --git a/vim-config/plugins/ale/ale_linters/rust/analyzer.vim b/vim-config/plugins/ale/ale_linters/rust/analyzer.vim new file mode 100644 index 00000000..77d946f7 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/rust/analyzer.vim @@ -0,0 +1,24 @@ +" Author: Jon Gjengset +" Description: The next generation language server for Rust + +call ale#Set('rust_analyzer_executable', 'rust-analyzer') +call ale#Set('rust_analyzer_config', {}) + +function! ale_linters#rust#analyzer#GetCommand(buffer) abort + return '%e' +endfunction + +function! ale_linters#rust#analyzer#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': 'analyzer', +\ 'lsp': 'stdio', +\ 'initialization_options': {b -> ale#Var(b, 'rust_analyzer_config')}, +\ 'executable': {b -> ale#Var(b, 'rust_analyzer_executable')}, +\ 'command': function('ale_linters#rust#analyzer#GetCommand'), +\ 'project_root': function('ale_linters#rust#analyzer#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/rust/cargo.vim b/vim-config/plugins/ale/ale_linters/rust/cargo.vim old mode 100755 new mode 100644 index cf6187f8..37fd10a8 --- a/vim-config/plugins/ale/ale_linters/rust/cargo.vim +++ b/vim-config/plugins/ale/ale_linters/rust/cargo.vim @@ -11,6 +11,7 @@ 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', '') +call ale#Set('rust_cargo_target_dir', '') function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort if ale#path#FindNearestFile(a:bufnr, 'Cargo.toml') isnot# '' @@ -22,26 +23,31 @@ function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort endif endfunction -function! ale_linters#rust#cargo#VersionCheck(buffer) abort - return !ale#semver#HasVersion('cargo') - \ ? 'cargo --version' - \ : '' -endfunction +function! ale_linters#rust#cargo#GetCwd(buffer) abort + if ale#Var(a:buffer, 'rust_cargo_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# '.' + return l:nearest_cargo_dir + endif + endif -function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort - let l:version = ale#semver#GetVersion('cargo', a:version_output) + return '' +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(l:version, [0, 17, 0]) - let l:use_all_targets = l:use_check - \ && ale#Var(a:buffer, 'rust_cargo_check_all_targets') - \ && ale#semver#GTE(l:version, [0, 22, 0]) - let l:use_examples = l:use_check - \ && ale#Var(a:buffer, 'rust_cargo_check_examples') - \ && ale#semver#GTE(l:version, [0, 22, 0]) - let l:use_tests = l:use_check - \ && ale#Var(a:buffer, 'rust_cargo_check_tests') - \ && ale#semver#GTE(l:version, [0, 22, 0]) + \ && ale#semver#GTE(a:version, [0, 17, 0]) + let l:use_all_targets = ale#Var(a:buffer, 'rust_cargo_check_all_targets') + \ && ale#semver#GTE(a:version, [0, 22, 0]) + let l:use_examples = ale#Var(a:buffer, 'rust_cargo_check_examples') + \ && ale#semver#GTE(a:version, [0, 22, 0]) + let l:use_tests = ale#Var(a:buffer, 'rust_cargo_check_tests') + \ && ale#semver#GTE(a:version, [0, 22, 0]) + let l:target_dir = ale#Var(a:buffer, 'rust_cargo_target_dir') + let l:use_target_dir = !empty(l:target_dir) + \ && ale#semver#GTE(a:version, [0, 17, 0]) let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features') @@ -49,18 +55,6 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort 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' @@ -77,14 +71,23 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort 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') + let l:clippy_options = ale#Var(a:buffer, 'rust_cargo_clippy_options') + + if l:clippy_options =~# '^-- ' + let l:clippy_options = join(split(l:clippy_options, '-- ')) + endif + + if l:clippy_options isnot# '' + let l:clippy_options = ' -- ' . l:clippy_options + endif endif - return l:nearest_cargo_prefix . 'cargo ' + return 'cargo ' \ . l:subcommand \ . (l:use_all_targets ? ' --all-targets' : '') \ . (l:use_examples ? ' --examples' : '') \ . (l:use_tests ? ' --tests' : '') + \ . (l:use_target_dir ? (' --target-dir ' . ale#Escape(l:target_dir)) : '') \ . ' --frozen --message-format=json -q' \ . l:default_feature \ . l:include_features @@ -93,11 +96,14 @@ endfunction call ale#linter#Define('rust', { \ 'name': 'cargo', -\ 'executable_callback': 'ale_linters#rust#cargo#GetCargoExecutable', -\ 'command_chain': [ -\ {'callback': 'ale_linters#rust#cargo#VersionCheck'}, -\ {'callback': 'ale_linters#rust#cargo#GetCommand'}, -\ ], +\ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'), +\ 'cwd': function('ale_linters#rust#cargo#GetCwd'), +\ '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/vim-config/plugins/ale/ale_linters/rust/rls.vim b/vim-config/plugins/ale/ale_linters/rust/rls.vim old mode 100755 new mode 100644 index 60dd3667..111d7558 --- a/vim-config/plugins/ale/ale_linters/rust/rls.vim +++ b/vim-config/plugins/ale/ale_linters/rust/rls.vim @@ -2,7 +2,8 @@ " Description: A language server for Rust call ale#Set('rust_rls_executable', 'rls') -call ale#Set('rust_rls_toolchain', 'nightly') +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') @@ -19,7 +20,8 @@ endfunction call ale#linter#Define('rust', { \ 'name': 'rls', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('rust_rls_executable'), -\ 'command_callback': 'ale_linters#rust#rls#GetCommand', -\ 'project_root_callback': 'ale_linters#rust#rls#GetProjectRoot', +\ '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/vim-config/plugins/ale/ale_linters/rust/rustc.vim b/vim-config/plugins/ale/ale_linters/rust/rustc.vim old mode 100755 new mode 100644 index 33fb72f4..f140b58b --- a/vim-config/plugins/ale/ale_linters/rust/rustc.vim +++ b/vim-config/plugins/ale/ale_linters/rust/rustc.vim @@ -27,7 +27,7 @@ endfunction call ale#linter#Define('rust', { \ 'name': 'rustc', \ 'executable': 'rustc', -\ 'command_callback': 'ale_linters#rust#rustc#RustcCommand', +\ 'command': function('ale_linters#rust#rustc#RustcCommand'), \ 'callback': 'ale#handlers#rust#HandleRustErrors', \ 'output_stream': 'stderr', \}) diff --git a/vim-config/plugins/ale/ale_linters/salt/salt_lint.vim b/vim-config/plugins/ale/ale_linters/salt/salt_lint.vim new file mode 100644 index 00000000..47f66d83 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/salt/salt_lint.vim @@ -0,0 +1,33 @@ +" Author: Benjamin BINIER +" Description: salt-lint, saltstack linter + +call ale#Set('salt_salt_lint_executable', 'salt-lint') +call ale#Set('salt_salt_lint_options', '') + +function! ale_linters#salt#salt_lint#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'salt_salt_lint_options')) + \ . ' --json' +endfunction + +function! ale_linters#salt#salt_lint#Handle(buffer, lines) abort + let l:output = [] + + for l:error in ale#util#FuzzyJSONDecode(a:lines, []) + call add(l:output, { + \ 'lnum': l:error.linenumber + 0, + \ 'code': l:error.id + 0, + \ 'text': l:error.message, + \ 'type': l:error.severity is# 'HIGH' ? 'E' : 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('salt', { +\ 'name': 'salt_lint', +\ 'aliases': ['salt-lint'], +\ 'executable': {b -> ale#Var(b, 'salt_salt_lint_executable')}, +\ 'command': function('ale_linters#salt#salt_lint#GetCommand'), +\ 'callback': 'ale_linters#salt#salt_lint#Handle' +\}) diff --git a/vim-config/plugins/ale/ale_linters/sass/sasslint.vim b/vim-config/plugins/ale/ale_linters/sass/sasslint.vim old mode 100755 new mode 100644 index 8d24185d..ff396e68 --- a/vim-config/plugins/ale/ale_linters/sass/sasslint.vim +++ b/vim-config/plugins/ale/ale_linters/sass/sasslint.vim @@ -5,7 +5,7 @@ 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', [ + return ale#path#FindExecutable(a:buffer, 'sass_sasslint', [ \ 'node_modules/sass-lint/bin/sass-lint.js', \ 'node_modules/.bin/sass-lint', \]) @@ -22,7 +22,7 @@ endfunction call ale#linter#Define('sass', { \ 'name': 'sasslint', -\ 'executable_callback': 'ale_linters#sass#sasslint#GetExecutable', -\ 'command_callback': 'ale_linters#sass#sasslint#GetCommand', +\ 'executable': function('ale_linters#sass#sasslint#GetExecutable'), +\ 'command': function('ale_linters#sass#sasslint#GetCommand'), \ 'callback': 'ale#handlers#css#HandleCSSLintFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/sass/stylelint.vim b/vim-config/plugins/ale/ale_linters/sass/stylelint.vim old mode 100755 new mode 100644 index b6286f18..22abef9b --- a/vim-config/plugins/ale/ale_linters/sass/stylelint.vim +++ b/vim-config/plugins/ale/ale_linters/sass/stylelint.vim @@ -5,9 +5,9 @@ call ale#Set('sass_stylelint_use_global', get(g:, 'ale_use_global_executables', call ale#linter#Define('sass', { \ 'name': 'stylelint', -\ 'executable_callback': ale#node#FindExecutableFunc('sass_stylelint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'sass_stylelint', [ \ 'node_modules/.bin/stylelint', -\ ]), +\ ])}, \ 'command': '%e --stdin-filename %s', \ 'callback': 'ale#handlers#css#HandleStyleLintFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/scala/fsc.vim b/vim-config/plugins/ale/ale_linters/scala/fsc.vim old mode 100755 new mode 100644 index fbdce20e..94135235 --- a/vim-config/plugins/ale/ale_linters/scala/fsc.vim +++ b/vim-config/plugins/ale/ale_linters/scala/fsc.vim @@ -7,7 +7,7 @@ endfunction call ale#linter#Define('scala', { \ 'name': 'fsc', -\ 'executable_callback': {buf -> s:IsSbt(buf) ? '' : 'fsc'}, +\ 'executable': {buf -> s:IsSbt(buf) ? '' : 'fsc'}, \ 'command': '%e -Ystop-after:parser %t', \ 'callback': 'ale#handlers#scala#HandleScalacLintFormat', \ 'output_stream': 'stderr', diff --git a/vim-config/plugins/ale/ale_linters/scala/metals.vim b/vim-config/plugins/ale/ale_linters/scala/metals.vim new file mode 100644 index 00000000..da9e855d --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/scala/metals.vim @@ -0,0 +1,50 @@ +" Author: Jeffrey Lau - https://github.com/zoonfafer +" Description: Metals Language Server for Scala https://scalameta.org/metals/ + +call ale#Set('scala_metals_executable', 'metals-vim') +call ale#Set('scala_metals_project_root', '') + +function! ale_linters#scala#metals#GetProjectRoot(buffer) abort + let l:project_root = ale#Var(a:buffer, 'scala_metals_project_root') + + if !empty(l:project_root) + return l:project_root + endif + + let l:potential_roots = [ + \ 'build.sc', + \ 'build.sbt', + \ '.bloop', + \ '.metals', + \] + + for l:root in l:potential_roots + let l:project_root = ale#path#ResolveLocalPath( + \ a:buffer, + \ l:root, + \ '' + \) + + if !empty(l:project_root) + return fnamemodify( + \ l:project_root, + \ ':h', + \) + endif + endfor + + return '' +endfunction + +function! ale_linters#scala#metals#GetCommand(buffer) abort + return '%e' . ale#Pad('stdio') +endfunction + +call ale#linter#Define('scala', { +\ 'name': 'metals', +\ 'lsp': 'stdio', +\ 'language': 'scala', +\ 'executable': {b -> ale#Var(b, 'scala_metals_executable')}, +\ 'command': function('ale_linters#scala#metals#GetCommand'), +\ 'project_root': function('ale_linters#scala#metals#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/scala/sbtserver.vim b/vim-config/plugins/ale/ale_linters/scala/sbtserver.vim old mode 100755 new mode 100644 index 694241d7..d4f137c2 --- a/vim-config/plugins/ale/ale_linters/scala/sbtserver.vim +++ b/vim-config/plugins/ale/ale_linters/scala/sbtserver.vim @@ -25,7 +25,7 @@ endfunction call ale#linter#Define('scala', { \ 'name': 'sbtserver', \ 'lsp': 'socket', -\ 'address_callback': 'ale_linters#scala#sbtserver#GetAddress', +\ 'address': function('ale_linters#scala#sbtserver#GetAddress'), \ 'language': 'scala', -\ 'project_root_callback': 'ale_linters#scala#sbtserver#GetProjectRoot', +\ 'project_root': function('ale_linters#scala#sbtserver#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/scala/scalac.vim b/vim-config/plugins/ale/ale_linters/scala/scalac.vim old mode 100755 new mode 100644 index 3dbdd925..1dd579b4 --- a/vim-config/plugins/ale/ale_linters/scala/scalac.vim +++ b/vim-config/plugins/ale/ale_linters/scala/scalac.vim @@ -8,7 +8,7 @@ endfunction call ale#linter#Define('scala', { \ 'name': 'scalac', -\ 'executable_callback': {buf -> s:IsSbt(buf) ? '' : 'scalac'}, +\ 'executable': {buf -> s:IsSbt(buf) ? '' : 'scalac'}, \ 'command': '%e -Ystop-after:parser %t', \ 'callback': 'ale#handlers#scala#HandleScalacLintFormat', \ 'output_stream': 'stderr', diff --git a/vim-config/plugins/ale/ale_linters/scala/scalastyle.vim b/vim-config/plugins/ale/ale_linters/scala/scalastyle.vim old mode 100755 new mode 100644 index 42228cf6..6e9e4c13 --- a/vim-config/plugins/ale/ale_linters/scala/scalastyle.vim +++ b/vim-config/plugins/ale/ale_linters/scala/scalastyle.vim @@ -81,6 +81,6 @@ call ale#linter#Define('scala', { \ 'name': 'scalastyle', \ 'executable': 'scalastyle', \ 'output_stream': 'stdout', -\ 'command_callback': 'ale_linters#scala#scalastyle#GetCommand', +\ 'command': function('ale_linters#scala#scalastyle#GetCommand'), \ 'callback': 'ale_linters#scala#scalastyle#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/scss/sasslint.vim b/vim-config/plugins/ale/ale_linters/scss/sasslint.vim old mode 100755 new mode 100644 index 8b725ba6..99027051 --- a/vim-config/plugins/ale/ale_linters/scss/sasslint.vim +++ b/vim-config/plugins/ale/ale_linters/scss/sasslint.vim @@ -5,7 +5,7 @@ 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', [ + return ale#path#FindExecutable(a:buffer, 'scss_sasslint', [ \ 'node_modules/sass-lint/bin/sass-lint.js', \ 'node_modules/.bin/sass-lint', \]) @@ -22,7 +22,7 @@ endfunction call ale#linter#Define('scss', { \ 'name': 'sasslint', -\ 'executable_callback': 'ale_linters#scss#sasslint#GetExecutable', -\ 'command_callback': 'ale_linters#scss#sasslint#GetCommand', +\ 'executable': function('ale_linters#scss#sasslint#GetExecutable'), +\ 'command': function('ale_linters#scss#sasslint#GetCommand'), \ 'callback': 'ale#handlers#css#HandleCSSLintFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/scss/scsslint.vim b/vim-config/plugins/ale/ale_linters/scss/scsslint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/scss/stylelint.vim b/vim-config/plugins/ale/ale_linters/scss/stylelint.vim old mode 100755 new mode 100644 index 2bffa8e1..fea4ea8f --- a/vim-config/plugins/ale/ale_linters/scss/stylelint.vim +++ b/vim-config/plugins/ale/ale_linters/scss/stylelint.vim @@ -11,9 +11,9 @@ endfunction call ale#linter#Define('scss', { \ 'name': 'stylelint', -\ 'executable_callback': ale#node#FindExecutableFunc('scss_stylelint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'scss_stylelint', [ \ 'node_modules/.bin/stylelint', -\ ]), -\ 'command_callback': 'ale_linters#scss#stylelint#GetCommand', +\ ])}, +\ 'command': function('ale_linters#scss#stylelint#GetCommand'), \ 'callback': 'ale#handlers#css#HandleStyleLintFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/sh/bashate.vim b/vim-config/plugins/ale/ale_linters/sh/bashate.vim new file mode 100644 index 00000000..3cd84245 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/sh/bashate.vim @@ -0,0 +1,43 @@ +" Author: hsanson +" Description: Lints sh files using bashate +" URL: https://github.com/openstack/bashate + +call ale#Set('sh_bashate_executable', 'bashate') +call ale#Set('sh_bashate_options', '') + +function! ale_linters#sh#bashate#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'sh_bashate_executable') +endfunction + +function! ale_linters#sh#bashate#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'sh_bashate_options') + let l:executable = ale_linters#sh#bashate#GetExecutable(a:buffer) + + return ale#Escape(l:executable) . ' ' . l:options . ' ' . '%t' +endfunction + +function! ale_linters#sh#bashate#Handle(buffer, lines) abort + " Matches patterns line the following: + " + " /path/to/script/file:694:1: E003 Indent not multiple of 4 + 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[1]), + \ 'col': str2nr(l:match[2]), + \ 'text': l:match[3], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('sh', { +\ 'name': 'bashate', +\ 'output_stream': 'stdout', +\ 'executable': function('ale_linters#sh#bashate#GetExecutable'), +\ 'command': function('ale_linters#sh#bashate#GetCommand'), +\ 'callback': 'ale_linters#sh#bashate#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/sh/language_server.vim b/vim-config/plugins/ale/ale_linters/sh/language_server.vim old mode 100755 new mode 100644 index 385d1119..c6781584 --- a/vim-config/plugins/ale/ale_linters/sh/language_server.vim +++ b/vim-config/plugins/ale/ale_linters/sh/language_server.vim @@ -6,7 +6,7 @@ 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', [ + return ale#path#FindExecutable(a:buffer, 'sh_language_server', [ \ 'node_modules/.bin/bash-language-server', \]) endfunction @@ -26,7 +26,7 @@ endfunction call ale#linter#Define('sh', { \ 'name': 'language_server', \ 'lsp': 'stdio', -\ 'executable_callback': 'ale_linters#sh#language_server#GetExecutable', -\ 'command_callback': 'ale_linters#sh#language_server#GetCommand', -\ 'project_root_callback': 'ale_linters#sh#language_server#GetProjectRoot', +\ '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/vim-config/plugins/ale/ale_linters/sh/shell.vim b/vim-config/plugins/ale/ale_linters/sh/shell.vim old mode 100755 new mode 100644 index cf5e4e6c..73ab3608 --- a/vim-config/plugins/ale/ale_linters/sh/shell.vim +++ b/vim-config/plugins/ale/ale_linters/sh/shell.vim @@ -1,5 +1,5 @@ " Author: w0rp -" Description: Lints sh files using bash -n +" Description: Lints shell files by invoking the shell with -n " Backwards compatibility if exists('g:ale_linters_sh_shell_default_shell') @@ -34,8 +34,10 @@ function! ale_linters#sh#shell#Handle(buffer, lines) abort " Matches patterns line the following: " " bash: line 13: syntax error near unexpected token `d' + " bash:行0: 未预期的符号“done”附近有语法错误 + " bash: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符 " sh: 11: Syntax error: "(" unexpected - let l:pattern = '\v(line |: ?)(\d+): (.+)$' + let l:pattern = '\v([^:]+:\D*)(\d+): (.+)$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) @@ -51,7 +53,7 @@ endfunction call ale#linter#Define('sh', { \ 'name': 'shell', \ 'output_stream': 'stderr', -\ 'executable_callback': 'ale_linters#sh#shell#GetExecutable', -\ 'command_callback': 'ale_linters#sh#shell#GetCommand', +\ 'executable': function('ale_linters#sh#shell#GetExecutable'), +\ 'command': function('ale_linters#sh#shell#GetCommand'), \ 'callback': 'ale_linters#sh#shell#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/sh/shellcheck.vim b/vim-config/plugins/ale/ale_linters/sh/shellcheck.vim old mode 100755 new mode 100644 index 0f68e62c..d9945126 --- a/vim-config/plugins/ale/ale_linters/sh/shellcheck.vim +++ b/vim-config/plugins/ale/ale_linters/sh/shellcheck.vim @@ -1,112 +1,4 @@ " Author: w0rp -" Description: This file adds support for using the shellcheck linter with -" shell scripts. +" Description: shellcheck linter for 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_options', '') - -function! ale_linters#sh#shellcheck#GetExecutable(buffer) abort - return ale#Var(a:buffer, 'sh_shellcheck_executable') -endfunction - -function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort - let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) - - if !empty(l:shell_type) - " 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#VersionCheck(buffer) abort - let l:executable = ale_linters#sh#shellcheck#GetExecutable(a:buffer) - - " Don't check the version again if we've already cached it. - return !ale#semver#HasVersion(l:executable) - \ ? ale#Escape(l:executable) . ' --version' - \ : '' -endfunction - -function! ale_linters#sh#shellcheck#GetCommand(buffer, version_output) abort - let l:executable = ale_linters#sh#shellcheck#GetExecutable(a:buffer) - let l:version = ale#semver#GetVersion(l:executable, a:version_output) - - let l:options = ale#Var(a:buffer, 'sh_shellcheck_options') - let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions') - let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer) - let l:external_option = ale#semver#GTE(l:version, [0, 4, 0]) ? ' -x' : '' - - return ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) - \ . (!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_callback': 'ale_linters#sh#shellcheck#GetExecutable', -\ 'command_chain': [ -\ {'callback': 'ale_linters#sh#shellcheck#VersionCheck'}, -\ {'callback': 'ale_linters#sh#shellcheck#GetCommand'}, -\ ], -\ 'callback': 'ale_linters#sh#shellcheck#Handle', -\}) +call ale#handlers#shellcheck#DefineLinter('sh') diff --git a/vim-config/plugins/ale/ale_linters/slim/slimlint.vim b/vim-config/plugins/ale/ale_linters/slim/slimlint.vim old mode 100755 new mode 100644 index 00c6b26c..1b365e25 --- a/vim-config/plugins/ale/ale_linters/slim/slimlint.vim +++ b/vim-config/plugins/ale/ale_linters/slim/slimlint.vim @@ -11,11 +11,11 @@ function! ale_linters#slim#slimlint#GetCommand(buffer) abort " " See https://github.com/sds/slim-lint/blob/master/lib/slim_lint/linter/README.md#rubocop if !empty(l:rubocop_config) - if ale#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 + 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 @@ -50,6 +50,6 @@ endfunction call ale#linter#Define('slim', { \ 'name': 'slimlint', \ 'executable': 'slim-lint', -\ 'command_callback': 'ale_linters#slim#slimlint#GetCommand', +\ 'command': function('ale_linters#slim#slimlint#GetCommand'), \ 'callback': 'ale_linters#slim#slimlint#Handle' \}) diff --git a/vim-config/plugins/ale/ale_linters/sml/smlnj.vim b/vim-config/plugins/ale/ale_linters/sml/smlnj.vim old mode 100755 new mode 100644 index f15579ea..852ea170 --- a/vim-config/plugins/ale/ale_linters/sml/smlnj.vim +++ b/vim-config/plugins/ale/ale_linters/sml/smlnj.vim @@ -3,7 +3,7 @@ call ale#linter#Define('sml', { \ 'name': 'smlnj', -\ 'executable_callback': 'ale#handlers#sml#GetExecutableSmlnjFile', +\ 'executable': function('ale#handlers#sml#GetExecutableSmlnjFile'), \ 'command': 'sml', \ 'callback': 'ale#handlers#sml#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/sml/smlnj_cm.vim b/vim-config/plugins/ale/ale_linters/sml/smlnj_cm.vim old mode 100755 new mode 100644 index bfa4bc05..9ad24af4 --- a/vim-config/plugins/ale/ale_linters/sml/smlnj_cm.vim +++ b/vim-config/plugins/ale/ale_linters/sml/smlnj_cm.vim @@ -12,9 +12,9 @@ endfunction call ale#linter#Define('sml', { \ 'name': 'smlnj_cm', \ 'aliases': ['smlnj-cm'], -\ 'executable_callback': 'ale#handlers#sml#GetExecutableSmlnjCm', +\ 'executable': function('ale#handlers#sml#GetExecutableSmlnjCm'), \ 'lint_file': 1, -\ 'command_callback': 'ale_linters#sml#smlnj_cm#GetCommand', +\ 'command': function('ale_linters#sml#smlnj_cm#GetCommand'), \ 'callback': 'ale#handlers#sml#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/solidity/solc.vim b/vim-config/plugins/ale/ale_linters/solidity/solc.vim new file mode 100644 index 00000000..28977083 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/solidity/solc.vim @@ -0,0 +1,53 @@ +" Author: Karl Bartel - http://karl.berlin/ +" Description: Report solc compiler errors in Solidity code + +call ale#Set('solidity_solc_executable', 'solc') +call ale#Set('solidity_solc_options', '') + +function! ale_linters#solidity#solc#Handle(buffer, lines) abort + " Matches patterns like the following: + " Error: Expected ';' but got '(' + " --> /path/to/file/file.sol:1:10:) + let l:pattern = '\v(Error|Warning): (.*)$' + let l:line_and_column_pattern = '\v\.sol:(\d+):(\d+):' + let l:output = [] + + for l:line in a:lines + let l:match = matchlist(l:line, l:pattern) + + if len(l:match) == 0 + let l:match = matchlist(l:line, l:line_and_column_pattern) + + if len(l:match) > 0 + let l:index = len(l:output) - 1 + let l:output[l:index]['lnum'] = l:match[1] + 0 + let l:output[l:index]['col'] = l:match[2] + 0 + endif + else + let l:isError = l:match[1] is? 'Error' + + call add(l:output, { + \ 'lnum': 0, + \ 'col': 0, + \ 'text': l:match[2], + \ 'type': l:isError ? 'E' : 'W', + \}) + endif + endfor + + return l:output +endfunction + +function! ale_linters#solidity#solc#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'solidity_solc_executable') + + return l:executable . ale#Pad(ale#Var(a:buffer, 'solidity_solc_options')) . ' %s' +endfunction + +call ale#linter#Define('solidity', { +\ 'name': 'solc', +\ 'executable': {b -> ale#Var(b, 'solidity_solc_executable')}, +\ 'command': function('ale_linters#solidity#solc#GetCommand'), +\ 'callback': 'ale_linters#solidity#solc#Handle', +\ 'output_stream': 'stderr', +\}) diff --git a/vim-config/plugins/ale/ale_linters/solidity/solhint.vim b/vim-config/plugins/ale/ale_linters/solidity/solhint.vim old mode 100755 new mode 100644 index 8ea33e07..505bd5bb --- a/vim-config/plugins/ale/ale_linters/solidity/solhint.vim +++ b/vim-config/plugins/ale/ale_linters/solidity/solhint.vim @@ -1,29 +1,12 @@ -" Author: Franco Victorio - https://github.com/fvictorio +" Authors: Franco Victorio - https://github.com/fvictorio, Henrique Barcelos +" https://github.com/hbarcelos " 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', +\ 'output_stream': 'both', +\ 'executable': function('ale#handlers#solhint#GetExecutable'), +\ 'cwd': function('ale#handlers#solhint#GetCwd'), +\ 'command': function('ale#handlers#solhint#GetCommand'), +\ 'callback': 'ale#handlers#solhint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/solidity/solium.vim b/vim-config/plugins/ale/ale_linters/solidity/solium.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/spec/rpmlint.vim b/vim-config/plugins/ale/ale_linters/spec/rpmlint.vim old mode 100755 new mode 100644 index 486bef1e..5594e3b8 --- a/vim-config/plugins/ale/ale_linters/spec/rpmlint.vim +++ b/vim-config/plugins/ale/ale_linters/spec/rpmlint.vim @@ -29,11 +29,18 @@ call ale#Set('spec_rpmlint_executable', 'rpmlint') call ale#Set('spec_rpmlint_options', '') -function! ale_linters#spec#rpmlint#GetCommand(buffer) abort +function! ale_linters#spec#rpmlint#GetCommand(buffer, version) abort + if ale#semver#GTE(a:version, [2, 0, 0]) + " The -o/--option flag was removed in version 2.0.0 + let l:version_dependent_args = '' + else + let l:version_dependent_args = ' -o "NetworkEnabled False"' + endif + return '%e' \ . ale#Pad(ale#Var(a:buffer, 'spec_rpmlint_options')) - \ . ' -o "NetworkEnabled False"' \ . ' -v' + \ . l:version_dependent_args \ . ' %t' endfunction @@ -72,7 +79,12 @@ endfunction call ale#linter#Define('spec', { \ 'name': 'rpmlint', -\ 'executable_callback': ale#VarFunc('spec_rpmlint_executable'), -\ 'command_callback': 'ale_linters#spec#rpmlint#GetCommand', +\ 'executable': {b -> ale#Var(b, 'spec_rpmlint_executable')}, +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale#Var(buffer, 'spec_rpmlint_executable'), +\ '%e --version', +\ function('ale_linters#spec#rpmlint#GetCommand'), +\ )}, \ 'callback': 'ale_linters#spec#rpmlint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/sql/sqlint.vim b/vim-config/plugins/ale/ale_linters/sql/sqlint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/sql/sqllint.vim b/vim-config/plugins/ale/ale_linters/sql/sqllint.vim new file mode 100644 index 00000000..78396fe9 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/sql/sqllint.vim @@ -0,0 +1,33 @@ +" ale_linters/sql/sqllint.vim +" Author: Joe Reynolds +" Description: sql-lint for SQL files. +" sql-lint can be found at +" https://www.npmjs.com/package/sql-lint +" https://github.com/joereynolds/sql-lint + +function! ale_linters#sql#sqllint#Handle(buffer, lines) abort + " Matches patterns like the following: + " + " stdin:1 [ER_NO_DB_ERROR] No database selected + 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, + \ 'col': l:match[2] + 0, + \ 'type': l:match[3][0], + \ 'text': l:match[0], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('sql', { +\ 'name': 'sqllint', +\ 'aliases': ['sql-lint'], +\ 'executable': 'sql-lint', +\ 'command': 'sql-lint', +\ 'callback': 'ale_linters#sql#sqllint#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/stylus/stylelint.vim b/vim-config/plugins/ale/ale_linters/stylus/stylelint.vim old mode 100755 new mode 100644 index 2256f3c0..b60e38ed --- a/vim-config/plugins/ale/ale_linters/stylus/stylelint.vim +++ b/vim-config/plugins/ale/ale_linters/stylus/stylelint.vim @@ -12,9 +12,9 @@ endfunction call ale#linter#Define('stylus', { \ 'name': 'stylelint', -\ 'executable_callback': ale#node#FindExecutableFunc('stylus_stylelint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'stylus_stylelint', [ \ 'node_modules/.bin/stylelint', -\ ]), -\ 'command_callback': 'ale_linters#stylus#stylelint#GetCommand', +\ ])}, +\ 'command': function('ale_linters#stylus#stylelint#GetCommand'), \ 'callback': 'ale#handlers#css#HandleStyleLintFormat', \}) diff --git a/vim-config/plugins/ale/ale_linters/sugarss/stylelint.vim b/vim-config/plugins/ale/ale_linters/sugarss/stylelint.vim new file mode 100644 index 00000000..879ff0ca --- /dev/null +++ b/vim-config/plugins/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#path#FindExecutable(b, 'sugarss_stylelint', [ +\ 'node_modules/.bin/stylelint', +\ ])}, +\ 'command': function('ale_linters#sugarss#stylelint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleStyleLintFormat', +\}) diff --git a/vim-config/plugins/ale/ale_linters/svelte/svelteserver.vim b/vim-config/plugins/ale/ale_linters/svelte/svelteserver.vim new file mode 100644 index 00000000..2200b582 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/svelte/svelteserver.vim @@ -0,0 +1,21 @@ +" Author: Joakim Repomaa +" Description: Svelte Language Server integration for ALE + +call ale#Set('svelte_svelteserver_executable', 'svelteserver') +call ale#Set('svelte_svelteserver_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#svelte#svelteserver#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('svelte', { +\ 'name': 'svelteserver', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#path#FindExecutable(b, 'svelte_svelteserver', [ +\ 'node_modules/.bin/svelteserver', +\ ])}, +\ 'command': '%e --stdio', +\ 'project_root': function('ale_linters#svelte#svelteserver#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/swift/appleswiftformat.vim b/vim-config/plugins/ale/ale_linters/swift/appleswiftformat.vim new file mode 100644 index 00000000..4c61764d --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/swift/appleswiftformat.vim @@ -0,0 +1,43 @@ +" Authors: Klaas Pieter Annema , bosr +" Description: Support for swift-format https://github.com/apple/swift-format + +function! ale_linters#swift#appleswiftformat#GetLinterCommand(buffer) abort + let l:command_args = ale#swift#GetAppleSwiftFormatCommand(a:buffer) . ' lint %t' + let l:config_args = ale#swift#GetAppleSwiftFormatConfigArgs(a:buffer) + + if l:config_args isnot# '' + let l:command_args = l:command_args . ' ' . l:config_args + endif + + return l:command_args +endfunction + +function! ale_linters#swift#appleswiftformat#Handle(buffer, lines) abort + " Matches the typical output of swift-format, that is lines of the following pattern: + " + " Sources/main.swift:4:21: warning: [DoNotUseSemicolons] remove ';' and move the next statement to the new line + " Sources/main.swift:3:12: warning: [Spacing] remove 1 space + let l:pattern = '\v^.*:(\d+):(\d+): (\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# 'error' ? 'E' : 'W', + \ 'code': l:match[4], + \ 'text': l:match[5], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('swift', { +\ 'name': 'apple-swift-format', +\ 'executable': function('ale#swift#GetAppleSwiftFormatExecutable'), +\ 'command': function('ale_linters#swift#appleswiftformat#GetLinterCommand'), +\ 'output_stream': 'stderr', +\ 'language': 'swift', +\ 'callback': 'ale_linters#swift#appleswiftformat#Handle' +\}) diff --git a/vim-config/plugins/ale/ale_linters/swift/sourcekitlsp.vim b/vim-config/plugins/ale/ale_linters/swift/sourcekitlsp.vim new file mode 100644 index 00000000..560893bf --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/swift/swiftlint.vim b/vim-config/plugins/ale/ale_linters/swift/swiftlint.vim old mode 100755 new mode 100644 index a1150658..d08c68f6 --- a/vim-config/plugins/ale/ale_linters/swift/swiftlint.vim +++ b/vim-config/plugins/ale/ale_linters/swift/swiftlint.vim @@ -5,11 +5,11 @@ 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', - \]) + return ale#path#FindExecutable(a:buffer, 'swift_swiftlint', [ + \ 'Pods/SwiftLint/swiftlint', + \ 'ios/Pods/SwiftLint/swiftlint', + \ 'swiftlint', + \]) endfunction function! ale_linters#swift#swiftlint#GetCommand(buffer) abort @@ -17,7 +17,7 @@ function! ale_linters#swift#swiftlint#GetCommand(buffer) abort let l:args = 'lint --use-stdin' return ale#Escape(l:executable) - \ . ' ' .l:args + \ . ' ' .l:args endfunction function! ale_linters#swift#swiftlint#Handle(buffer, lines) abort @@ -26,10 +26,10 @@ function! ale_linters#swift#swiftlint#Handle(buffer, lines) abort 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], - \} + \ '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' @@ -63,7 +63,7 @@ endfunction call ale#linter#Define('swift', { \ 'name': 'swiftlint', -\ 'executable_callback': 'ale_linters#swift#swiftlint#GetExecutable', -\ 'command_callback': 'ale_linters#swift#swiftlint#GetCommand', +\ 'executable': function('ale_linters#swift#swiftlint#GetExecutable'), +\ 'command': function('ale_linters#swift#swiftlint#GetCommand'), \ 'callback': 'ale_linters#swift#swiftlint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/systemd/systemd_analyze.vim b/vim-config/plugins/ale/ale_linters/systemd/systemd_analyze.vim new file mode 100644 index 00000000..64eef8cf --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/systemd/systemd_analyze.vim @@ -0,0 +1,18 @@ +function! ale_linters#systemd#systemd_analyze#Handle(buffer, lines) abort + return ale#util#MapMatches(a:lines, '\v(.+):([0-9]+): (.+)', {match -> { + \ 'lnum': str2nr(match[2]), + \ 'col': 1, + \ 'type': 'W', + \ 'text': match[3], + \}}) +endfunction + +call ale#linter#Define('systemd', { +\ 'name': 'systemd_analyze', +\ 'aliases': ['systemd-analyze'], +\ 'executable': 'systemd-analyze', +\ 'command': 'SYSTEMD_LOG_COLOR=0 %e --user verify %s', +\ 'callback': 'ale_linters#systemd#systemd_analyze#Handle', +\ 'output_stream': 'both', +\ 'lint_file': 1, +\}) diff --git a/vim-config/plugins/ale/ale_linters/tcl/nagelfar.vim b/vim-config/plugins/ale/ale_linters/tcl/nagelfar.vim old mode 100755 new mode 100644 index 05fe581b..5a4940e1 --- a/vim-config/plugins/ale/ale_linters/tcl/nagelfar.vim +++ b/vim-config/plugins/ale/ale_linters/tcl/nagelfar.vim @@ -32,8 +32,8 @@ endfunction call ale#linter#Define('tcl', { \ 'name': 'nagelfar', \ 'output_stream': 'stdout', -\ 'executable_callback': ale#VarFunc('tcl_nagelfar_executable'), -\ 'command_callback': 'ale_linters#tcl#nagelfar#GetCommand', +\ '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/vim-config/plugins/ale/ale_linters/terraform/terraform.vim b/vim-config/plugins/ale/ale_linters/terraform/terraform.vim new file mode 100644 index 00000000..cf134460 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/terraform/terraform.vim @@ -0,0 +1,63 @@ +" 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)) + \ . ' validate -no-color -json ' +endfunction + +function! ale_linters#terraform#terraform#GetType(severity) abort + if a:severity is? 'warning' + return 'W' + endif + + return 'E' +endfunction + +function! ale_linters#terraform#terraform#GetDetail(error) abort + return get(a:error, 'detail', get(a:error, 'summary', '')) +endfunction + +function! ale_linters#terraform#terraform#Handle(buffer, lines) abort + let l:output = [] + + let l:errors = ale#util#FuzzyJSONDecode(a:lines, {'diagnostics': []}) + let l:dir = expand('#' . a:buffer . ':p:h') + let l:file = expand('#' . a:buffer . ':p') + + for l:error in l:errors['diagnostics'] + if has_key(l:error, 'range') + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:error['range']['filename']), + \ 'lnum': l:error['range']['start']['line'], + \ 'col': l:error['range']['start']['column'], + \ 'text': ale_linters#terraform#terraform#GetDetail(l:error), + \ 'type': ale_linters#terraform#terraform#GetType(l:error['severity']), + \}) + else + call add(l:output, { + \ 'filename': l:file, + \ 'lnum': 0, + \ 'col': 0, + \ 'text': ale_linters#terraform#terraform#GetDetail(l:error), + \ 'type': ale_linters#terraform#terraform#GetType(l:error['severity']), + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('terraform', { +\ 'name': 'terraform', +\ 'output_stream': 'stdout', +\ 'executable': function('ale_linters#terraform#terraform#GetExecutable'), +\ 'command': function('ale_linters#terraform#terraform#GetCommand'), +\ 'callback': 'ale_linters#terraform#terraform#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/terraform/terraform_ls.vim b/vim-config/plugins/ale/ale_linters/terraform/terraform_ls.vim new file mode 100644 index 00000000..ab35126e --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/terraform/terraform_ls.vim @@ -0,0 +1,38 @@ +" Author: Horacio Sanson +" Description: terraform-ls integration for ALE (cf. https://github.com/hashicorp/terraform-ls) + +call ale#Set('terraform_terraform_executable', 'terraform') +call ale#Set('terraform_ls_executable', 'terraform-ls') +call ale#Set('terraform_ls_options', '') + +function! ale_linters#terraform#terraform_ls#GetTerraformExecutable(buffer) abort + let l:terraform_executable = ale#Var(a:buffer, 'terraform_terraform_executable') + + if(ale#path#IsAbsolute(l:terraform_executable)) + return '-tf-exec ' . l:terraform_executable + endif + + return '' +endfunction + +function! ale_linters#terraform#terraform_ls#GetCommand(buffer) abort + return '%e' + \ . ale#Pad('serve') + \ . ale#Pad(ale_linters#terraform#terraform_ls#GetTerraformExecutable(a:buffer)) + \ . ale#Pad(ale#Var(a:buffer, 'terraform_ls_options')) +endfunction + +function! ale_linters#terraform#terraform_ls#GetProjectRoot(buffer) abort + let l:tf_dir = ale#path#FindNearestDirectory(a:buffer, '.terraform') + + return !empty(l:tf_dir) ? fnamemodify(l:tf_dir, ':h:h') : '' +endfunction + +call ale#linter#Define('terraform', { +\ 'name': 'terraform_ls', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'terraform_ls_executable')}, +\ 'command': function('ale_linters#terraform#terraform_ls#GetCommand'), +\ 'project_root': function('ale_linters#terraform#terraform_ls#GetProjectRoot'), +\ 'language': 'terraform', +\}) diff --git a/vim-config/plugins/ale/ale_linters/terraform/terraform_lsp.vim b/vim-config/plugins/ale/ale_linters/terraform/terraform_lsp.vim new file mode 100644 index 00000000..e2408c15 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/terraform/terraform_lsp.vim @@ -0,0 +1,25 @@ +" Author: OJFord +" Description: terraform-lsp integration for ALE (cf. https://github.com/juliosueiras/terraform-lsp) + +call ale#Set('terraform_langserver_executable', 'terraform-lsp') +call ale#Set('terraform_langserver_options', '') + +function! ale_linters#terraform#terraform_lsp#GetCommand(buffer) abort + return '%e' + \ . ale#Pad(ale#Var(a:buffer, 'terraform_langserver_options')) +endfunction + +function! ale_linters#terraform#terraform_lsp#GetProjectRoot(buffer) abort + let l:tf_dir = ale#path#FindNearestDirectory(a:buffer, '.terraform') + + return !empty(l:tf_dir) ? fnamemodify(l:tf_dir, ':h:h') : '' +endfunction + +call ale#linter#Define('terraform', { +\ 'name': 'terraform_lsp', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'terraform_langserver_executable')}, +\ 'command': function('ale_linters#terraform#terraform_lsp#GetCommand'), +\ 'project_root': function('ale_linters#terraform#terraform_lsp#GetProjectRoot'), +\ 'language': 'terraform', +\}) diff --git a/vim-config/plugins/ale/ale_linters/terraform/tflint.vim b/vim-config/plugins/ale/ale_linters/terraform/tflint.vim old mode 100755 new mode 100644 index 0d77835a..86b5b74a --- a/vim-config/plugins/ale/ale_linters/terraform/tflint.vim +++ b/vim-config/plugins/ale/ale_linters/terraform/tflint.vim @@ -9,23 +9,69 @@ call ale#Set('terraform_tflint_executable', 'tflint') function! ale_linters#terraform#tflint#Handle(buffer, lines) abort let l:output = [] + let l:pattern = '\v^(.*):(\d+),(\d+)-(\d+)?,?(\d+): (.{-1,}); (.+)$' + let l:json = ale#util#FuzzyJSONDecode(a:lines, {}) - 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 + " This is a rough test for tflint's output format + " On versions prior to 0.11 it outputs all errors as a single level list + if type(l:json) is v:t_list + for l:error in l:json + 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 + else + for l:error in get(l:json, 'errors', []) + for l:match in ale#util#GetMatches(l:error.message, [l:pattern]) + if l:match[4] is# '' + let l:match[4] = l:match[2] + endif + + call add(l:output, { + \ 'filename': l:match[1], + \ 'lnum': str2nr(l:match[2]), + \ 'col': str2nr(l:match[3]), + \ 'end_lnum': str2nr(l:match[4]), + \ 'end_col': str2nr(l:match[5]), + \ 'text': l:match[7], + \ 'code': l:match[6], + \ 'type': 'E', + \}) + endfor + endfor + + for l:error in get(l:json, 'issues', []) + if l:error.rule.severity is# 'ERROR' + let l:type = 'E' + elseif l:error.rule.severity is# 'NOTICE' + let l:type = 'I' + else + let l:type = 'W' + endif + + call add(l:output, { + \ 'filename': l:error.range.filename, + \ 'lnum': l:error.range.start.line, + \ 'col': l:error.range.start.column, + \ 'end_lnum': l:error.range.end.line, + \ 'end_col': l:error.range.end.column, + \ 'text': l:error.message, + \ 'code': l:error.rule.name, + \ 'type': l:type, + \}) + endfor + endif return l:output endfunction @@ -45,14 +91,15 @@ function! ale_linters#terraform#tflint#GetCommand(buffer) abort let l:cmd .= ' ' . l:opts endif - let l:cmd .= ' -f json %t' + let l:cmd .= ' -f json' return l:cmd endfunction call ale#linter#Define('terraform', { \ 'name': 'tflint', -\ 'executable_callback': ale#VarFunc('terraform_tflint_executable'), -\ 'command_callback': 'ale_linters#terraform#tflint#GetCommand', +\ 'executable': {b -> ale#Var(b, 'terraform_tflint_executable')}, +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#terraform#tflint#GetCommand'), \ 'callback': 'ale_linters#terraform#tflint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/testft/testlinter.vim b/vim-config/plugins/ale/ale_linters/testft/testlinter.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/tex/alex.vim b/vim-config/plugins/ale/ale_linters/tex/alex.vim old mode 100755 new mode 100644 index 78c530f7..5d9aec66 --- a/vim-config/plugins/ale/ale_linters/tex/alex.vim +++ b/vim-config/plugins/ale/ale_linters/tex/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for TeX files -call ale#linter#Define('tex', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('tex', '--text') diff --git a/vim-config/plugins/ale/ale_linters/tex/chktex.vim b/vim-config/plugins/ale/ale_linters/tex/chktex.vim old mode 100755 new mode 100644 index 7f1b0c72..160baf0d --- a/vim-config/plugins/ale/ale_linters/tex/chktex.vim +++ b/vim-config/plugins/ale/ale_linters/tex/chktex.vim @@ -49,6 +49,6 @@ endfunction call ale#linter#Define('tex', { \ 'name': 'chktex', \ 'executable': 'chktex', -\ 'command_callback': 'ale_linters#tex#chktex#GetCommand', +\ 'command': function('ale_linters#tex#chktex#GetCommand'), \ 'callback': 'ale_linters#tex#chktex#Handle' \}) diff --git a/vim-config/plugins/ale/ale_linters/tex/lacheck.vim b/vim-config/plugins/ale/ale_linters/tex/lacheck.vim old mode 100755 new mode 100644 index ee09fb41..19d69403 --- a/vim-config/plugins/ale/ale_linters/tex/lacheck.vim +++ b/vim-config/plugins/ale/ale_linters/tex/lacheck.vim @@ -37,7 +37,7 @@ endfunction call ale#linter#Define('tex', { \ 'name': 'lacheck', -\ 'executable_callback': ale#VarFunc('tex_lacheck_executable'), +\ 'executable': {b -> ale#Var(b, 'tex_lacheck_executable')}, \ 'command': '%e %t', \ 'callback': 'ale_linters#tex#lacheck#Handle' \}) diff --git a/vim-config/plugins/ale/ale_linters/tex/proselint.vim b/vim-config/plugins/ale/ale_linters/tex/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/tex/redpen.vim b/vim-config/plugins/ale/ale_linters/tex/redpen.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/tex/texlab.vim b/vim-config/plugins/ale/ale_linters/tex/texlab.vim new file mode 100644 index 00000000..0794bf51 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/tex/texlab.vim @@ -0,0 +1,24 @@ +" Author: Ricardo Liang +" Author: ourigen +" 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 + let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git') + + return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : '' +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/vim-config/plugins/ale/ale_linters/tex/textlint.vim b/vim-config/plugins/ale/ale_linters/tex/textlint.vim new file mode 100644 index 00000000..5edac46d --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/tex/vale.vim b/vim-config/plugins/ale/ale_linters/tex/vale.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/tex/writegood.vim b/vim-config/plugins/ale/ale_linters/tex/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/texinfo/alex.vim b/vim-config/plugins/ale/ale_linters/texinfo/alex.vim old mode 100755 new mode 100644 index 4a884579..4d245524 --- a/vim-config/plugins/ale/ale_linters/texinfo/alex.vim +++ b/vim-config/plugins/ale/ale_linters/texinfo/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for texinfo files -call ale#linter#Define('texinfo', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('texinfo', '--text') diff --git a/vim-config/plugins/ale/ale_linters/texinfo/proselint.vim b/vim-config/plugins/ale/ale_linters/texinfo/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/texinfo/writegood.vim b/vim-config/plugins/ale/ale_linters/texinfo/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/text/alex.vim b/vim-config/plugins/ale/ale_linters/text/alex.vim old mode 100755 new mode 100644 index c696367b..d87ed915 --- a/vim-config/plugins/ale/ale_linters/text/alex.vim +++ b/vim-config/plugins/ale/ale_linters/text/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for text files -call ale#linter#Define('text', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('text', '--text') diff --git a/vim-config/plugins/ale/ale_linters/text/languagetool.vim b/vim-config/plugins/ale/ale_linters/text/languagetool.vim new file mode 100644 index 00000000..58c99ba2 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/text/proselint.vim b/vim-config/plugins/ale/ale_linters/text/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/text/redpen.vim b/vim-config/plugins/ale/ale_linters/text/redpen.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/text/textlint.vim b/vim-config/plugins/ale/ale_linters/text/textlint.vim old mode 100755 new mode 100644 index 8fafdd7d..67c4e378 --- a/vim-config/plugins/ale/ale_linters/text/textlint.vim +++ b/vim-config/plugins/ale/ale_linters/text/textlint.vim @@ -3,7 +3,7 @@ call ale#linter#Define('text', { \ 'name': 'textlint', -\ 'executable_callback': 'ale#handlers#textlint#GetExecutable', -\ 'command_callback': 'ale#handlers#textlint#GetCommand', +\ 'executable': function('ale#handlers#textlint#GetExecutable'), +\ 'command': function('ale#handlers#textlint#GetCommand'), \ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', \}) diff --git a/vim-config/plugins/ale/ale_linters/text/vale.vim b/vim-config/plugins/ale/ale_linters/text/vale.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/text/writegood.vim b/vim-config/plugins/ale/ale_linters/text/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/thrift/thrift.vim b/vim-config/plugins/ale/ale_linters/thrift/thrift.vim old mode 100755 new mode 100644 index 36a8656e..345c7abe --- a/vim-config/plugins/ale/ale_linters/thrift/thrift.vim +++ b/vim-config/plugins/ale/ale_linters/thrift/thrift.vim @@ -16,7 +16,7 @@ function! ale_linters#thrift#thrift#GetCommand(buffer) abort let l:generators = ['cpp'] endif - let l:output_dir = ale#engine#CreateDirectory(a:buffer) + let l:output_dir = ale#command#CreateDirectory(a:buffer) return '%e' \ . ale#Pad(join(map(copy(l:generators), "'--gen ' . v:val"))) @@ -80,9 +80,8 @@ endfunction call ale#linter#Define('thrift', { \ 'name': 'thrift', -\ 'executable': 'thrift', \ 'output_stream': 'both', -\ 'executable_callback': ale#VarFunc('thrift_thrift_executable'), -\ 'command_callback': 'ale_linters#thrift#thrift#GetCommand', +\ 'executable': {b -> ale#Var(b, 'thrift_thrift_executable')}, +\ 'command': function('ale_linters#thrift#thrift#GetCommand'), \ 'callback': 'ale_linters#thrift#thrift#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/thrift/thriftcheck.vim b/vim-config/plugins/ale/ale_linters/thrift/thriftcheck.vim new file mode 100644 index 00000000..bf929d10 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/thrift/thriftcheck.vim @@ -0,0 +1,46 @@ +" Author: Jon Parise + +call ale#Set('thrift_thriftcheck_executable', 'thriftcheck') +call ale#Set('thrift_thriftcheck_options', '') + +function! ale_linters#thrift#thriftcheck#GetCommand(buffer) abort + return '%e' + \ . ale#Pad(ale#Var(a:buffer, 'thrift_thriftcheck_options')) + \ . ' --stdin-filename %s' + \ . ' %t' +endfunction + +function! ale_linters#thrift#thriftcheck#Handle(buffer, lines) abort + " Matches lines like the following: + " + " file.thrift:1:1: error: "py" namespace must match "^idl\\." (namespace.pattern) + " file.thrift:3:5: warning: 64-bit integer constant -2147483649 may not work in all languages (int.64bit) + 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[3] is# 'warning' + let l:type = 'W' + else + let l:type = 'E' + endif + + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'type': l:type, + \ 'text': l:match[4], + \ 'code': l:match[5], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('thrift', { +\ 'name': 'thriftcheck', +\ 'executable': {b -> ale#Var(b, 'thrift_thriftcheck_executable')}, +\ 'command': function('ale_linters#thrift#thriftcheck#GetCommand'), +\ 'callback': 'ale_linters#thrift#thriftcheck#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/typescript/deno.vim b/vim-config/plugins/ale/ale_linters/typescript/deno.vim new file mode 100644 index 00000000..f47fac7a --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/typescript/deno.vim @@ -0,0 +1,12 @@ +" Author: Mohammed Chelouti - https://github.com/motato1 +" Arnold Chand +" Description: Deno lsp linter for TypeScript files. + +call ale#linter#Define('typescript', { +\ 'name': 'deno', +\ 'lsp': 'stdio', +\ 'executable': function('ale#handlers#deno#GetExecutable'), +\ 'command': '%e lsp', +\ 'project_root': function('ale#handlers#deno#GetProjectRoot'), +\ 'initialization_options': function('ale#handlers#deno#GetInitializationOptions'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/typescript/eslint.vim b/vim-config/plugins/ale/ale_linters/typescript/eslint.vim old mode 100755 new mode 100644 index f1ae54e7..eaeac307 --- a/vim-config/plugins/ale/ale_linters/typescript/eslint.vim +++ b/vim-config/plugins/ale/ale_linters/typescript/eslint.vim @@ -3,7 +3,8 @@ call ale#linter#Define('typescript', { \ 'name': 'eslint', -\ 'executable_callback': 'ale#handlers#eslint#GetExecutable', -\ 'command_callback': 'ale#handlers#eslint#GetCommand', -\ 'callback': 'ale#handlers#eslint#Handle', +\ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/vim-config/plugins/ale/ale_linters/typescript/standard.vim b/vim-config/plugins/ale/ale_linters/typescript/standard.vim new file mode 100644 index 00000000..1d524a10 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/typescript/standard.vim @@ -0,0 +1,31 @@ +" Author: Ahmed El Gabri <@ahmedelgabri> +" Description: standardjs for typescript files + +call ale#Set('typescript_standard_executable', 'standard') +call ale#Set('typescript_standard_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('typescript_standard_options', '') + +function! ale_linters#typescript#standard#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'typescript_standard', [ + \ 'node_modules/standardx/bin/cmd.js', + \ 'node_modules/standard/bin/cmd.js', + \ 'node_modules/.bin/standard', + \]) +endfunction + +function! ale_linters#typescript#standard#GetCommand(buffer) abort + let l:executable = ale_linters#typescript#standard#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'typescript_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('typescript', { +\ 'name': 'standard', +\ 'executable': function('ale_linters#typescript#standard#GetExecutable'), +\ 'command': function('ale_linters#typescript#standard#GetCommand'), +\ 'callback': 'ale#handlers#eslint#Handle', +\}) diff --git a/vim-config/plugins/ale/ale_linters/typescript/tslint.vim b/vim-config/plugins/ale/ale_linters/typescript/tslint.vim old mode 100755 new mode 100644 index ccdca936..886a3cd4 --- a/vim-config/plugins/ale/ale_linters/typescript/tslint.vim +++ b/vim-config/plugins/ale/ale_linters/typescript/tslint.vim @@ -59,8 +59,7 @@ function! ale_linters#typescript#tslint#GetCommand(buffer) abort \ ? ' -r ' . ale#Escape(l:tslint_rules_dir) \ : '' - return ale#path#BufferCdString(a:buffer) - \ . ale#Escape(ale#handlers#tslint#GetExecutable(a:buffer)) + return ale#Escape(ale#handlers#tslint#GetExecutable(a:buffer)) \ . ' --format json' \ . l:tslint_config_option \ . l:tslint_rules_option @@ -69,7 +68,8 @@ endfunction call ale#linter#Define('typescript', { \ 'name': 'tslint', -\ 'executable_callback': 'ale#handlers#tslint#GetExecutable', -\ 'command_callback': 'ale_linters#typescript#tslint#GetCommand', +\ 'executable': function('ale#handlers#tslint#GetExecutable'), +\ 'cwd': '%s:h', +\ 'command': function('ale_linters#typescript#tslint#GetCommand'), \ 'callback': 'ale_linters#typescript#tslint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/typescript/tsserver.vim b/vim-config/plugins/ale/ale_linters/typescript/tsserver.vim old mode 100755 new mode 100644 index bac63229..d97becca --- a/vim-config/plugins/ale/ale_linters/typescript/tsserver.vim +++ b/vim-config/plugins/ale/ale_linters/typescript/tsserver.vim @@ -8,10 +8,11 @@ call ale#Set('typescript_tsserver_use_global', get(g:, 'ale_use_global_executabl call ale#linter#Define('typescript', { \ 'name': 'tsserver', \ 'lsp': 'tsserver', -\ 'executable_callback': ale#node#FindExecutableFunc('typescript_tsserver', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'typescript_tsserver', [ +\ '.yarn/sdks/typescript/bin/tsserver', \ 'node_modules/.bin/tsserver', -\ ]), +\ ])}, \ 'command': '%e', -\ 'project_root_callback': {-> ''}, +\ 'project_root': function('ale#handlers#tsserver#GetProjectRoot'), \ 'language': '', \}) diff --git a/vim-config/plugins/ale/ale_linters/typescript/typecheck.vim b/vim-config/plugins/ale/ale_linters/typescript/typecheck.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/typescript/xo.vim b/vim-config/plugins/ale/ale_linters/typescript/xo.vim new file mode 100644 index 00000000..6f4ee50c --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/typescript/xo.vim @@ -0,0 +1,6 @@ +call ale#linter#Define('typescript', { +\ 'name': 'xo', +\ 'executable': function('ale#handlers#xo#GetExecutable'), +\ 'command': function('ale#handlers#xo#GetLintCommand'), +\ 'callback': 'ale#handlers#xo#HandleJSON', +\}) diff --git a/vim-config/plugins/ale/ale_linters/v/v.vim b/vim-config/plugins/ale/ale_linters/v/v.vim new file mode 100644 index 00000000..afa98c56 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/v/v.vim @@ -0,0 +1,82 @@ +" Author: fiatjaf +" Description: v build for V files + +call ale#Set('v_v_executable', 'v') +call ale#Set('v_v_options', '') + +function! ale_linters#v#v#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'v_v_options') + + " Run v in local directory with relative path + let l:command = ale#Var(a:buffer, 'v_v_executable') + \ . ale#Pad(l:options) + \ . ' .' . ' -o /tmp/vim-ale-v' + + return l:command +endfunction + +function! ale_linters#v#v#Handler(buffer, lines) abort + let l:dir = expand('#' . a:buffer . ':p:h') + let l:output = [] + + " Matches patterns like the following: + " + " ./const.v:4:3: warning: const names cannot contain uppercase letters, use snake_case instead + " 2 | + " 3 | const ( + " 4 | BUTTON_TEXT = 'OK' + " | ~~~~~~~~~~~ + " 5 | ) + " ./main.v:4:8: warning: module 'os' is imported but never used + " 2 | + " 3 | import ui + " 4 | import os + " | ~~ + " 5 | + " 6 | const ( + " ./main.v:20:10: error: undefined ident: `win_widt` + " 18 | mut app := &App{} + " 19 | app.window = ui.window({ + " 20 | width: win_widt + " | ~~~~~~~~ + " 21 | height: win_height + " 22 | title: 'Counter' + let l:current = {} + + for l:line in a:lines + " matches basic error description + let l:match = matchlist(l:line, + \ '\([^:]\+\):\([^:]\+\):\([^:]\+\): \([^:]\+\): \(.*\)') + + if !empty(l:match) + let l:current = { + \ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]), + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[5], + \ 'type': l:match[4] is# 'error' ? 'E' : 'W', + \} + call add(l:output, l:current) + continue + endif + + " try to get information about the ending column + let l:tildematch = matchstr(l:line, '\~\+') + + if !empty(l:tildematch) + let l:current['end_col'] = l:current['col'] + len(l:tildematch) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('v', { +\ 'name': 'v', +\ 'aliases': [], +\ 'executable': {b -> ale#Var(b, 'v_v_executable')}, +\ 'command': function('ale_linters#v#v#GetCommand'), +\ 'output_stream': 'stderr', +\ 'callback': 'ale_linters#v#v#Handler', +\ 'lint_file': 1, +\}) diff --git a/vim-config/plugins/ale/ale_linters/vala/vala_lint.vim b/vim-config/plugins/ale/ale_linters/vala/vala_lint.vim new file mode 100644 index 00000000..7f8a566a --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/vala/vala_lint.vim @@ -0,0 +1,66 @@ +" Author: Atsuya Takagi +" Description: A linter for Vala using Vala-Lint. + +call ale#Set('vala_vala_lint_config_filename', 'vala-lint.conf') +call ale#Set('vala_vala_lint_executable', 'io.elementary.vala-lint') + +function! ale_linters#vala#vala_lint#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'vala_vala_lint_executable') +endfunction + +function! ale_linters#vala#vala_lint#GetCommand(buffer) abort + let l:command = ale_linters#vala#vala_lint#GetExecutable(a:buffer) + + let l:config_filename = ale#Var(a:buffer, 'vala_vala_lint_config_filename') + let l:config_path = ale#path#FindNearestFile(a:buffer, l:config_filename) + + if !empty(l:config_path) + let l:command .= ' -c ' . l:config_path + endif + + return l:command . ' %s' +endfunction + +function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort + let l:pattern = '^\s*\(\d\+\)\.\(\d\+\)\s\+\(error\|warn\)\s\+\(.\+\)\s\([A-Za-z0-9_\-]\+\)' + let l:output = [] + + for l:line in a:lines + " remove color escape sequences since vala-lint doesn't support + " output without colors + let l:cleaned_line = substitute(l:line, '\e\[[0-9;]\+[mK]', '', 'g') + let l:match = matchlist(l:cleaned_line, l:pattern) + + if len(l:match) == 0 + continue + endif + + let l:refined_type = l:match[3] is# 'warn' ? 'W' : 'E' + let l:cleaned_text = substitute(l:match[4], '^\s*\(.\{-}\)\s*$', '\1', '') + + let l:lnum = l:match[1] + 0 + let l:column = l:match[2] + 0 + let l:type = l:refined_type + let l:text = l:cleaned_text + let l:code = l:match[5] + + call add(l:output, { + \ 'lnum': l:lnum, + \ 'col': l:column, + \ 'text': l:text, + \ 'type': l:type, + \ 'code': l:code, + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('vala', { +\ 'name': 'vala_lint', +\ 'output_stream': 'stdout', +\ 'executable': function('ale_linters#vala#vala_lint#GetExecutable'), +\ 'command': function('ale_linters#vala#vala_lint#GetCommand'), +\ 'callback': 'ale_linters#vala#vala_lint#Handle', +\ 'lint_file': 1, +\}) diff --git a/vim-config/plugins/ale/ale_linters/verilog/hdl_checker.vim b/vim-config/plugins/ale/ale_linters/verilog/hdl_checker.vim new file mode 100644 index 00000000..b05d8565 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/verilog/hdl_checker.vim @@ -0,0 +1,5 @@ +" Author: suoto +" Description: Adds support for HDL Code Checker, which wraps vcom/vlog, ghdl +" or xvhdl. More info on https://github.com/suoto/hdl_checker + +call ale#handlers#hdl_checker#DefineLinter('verilog') diff --git a/vim-config/plugins/ale/ale_linters/verilog/iverilog.vim b/vim-config/plugins/ale/ale_linters/verilog/iverilog.vim old mode 100755 new mode 100644 index c64a3be6..e081f33f --- a/vim-config/plugins/ale/ale_linters/verilog/iverilog.vim +++ b/vim-config/plugins/ale/ale_linters/verilog/iverilog.vim @@ -38,6 +38,6 @@ call ale#linter#Define('verilog', { \ 'name': 'iverilog', \ 'output_stream': 'stderr', \ 'executable': 'iverilog', -\ 'command_callback': 'ale_linters#verilog#iverilog#GetCommand', +\ 'command': function('ale_linters#verilog#iverilog#GetCommand'), \ 'callback': 'ale_linters#verilog#iverilog#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/verilog/verilator.vim b/vim-config/plugins/ale/ale_linters/verilog/verilator.vim old mode 100755 new mode 100644 index 83d5f59d..006e310d --- a/vim-config/plugins/ale/ale_linters/verilog/verilator.vim +++ b/vim-config/plugins/ale/ale_linters/verilog/verilator.vim @@ -7,16 +7,11 @@ if !exists('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#engine#ManageFile(a:buffer, l:filename) - let l:lines = getbufline(a:buffer, 1, '$') - call ale#util#Writefile(a:buffer, l:lines, l:filename) - + " the path to the current file is systematically added to the search path return 'verilator --lint-only -Wall -Wno-DECLFILENAME ' + \ . '-I%s:h ' \ . ale#Var(a:buffer, 'verilog_verilator_options') .' ' - \ . ale#Escape(l:filename) + \ . '%t' endfunction function! ale_linters#verilog#verilator#Handle(buffer, lines) abort @@ -28,22 +23,28 @@ function! ale_linters#verilog#verilator#Handle(buffer, lines) abort " %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\+\): \(.\+\)$' + " Since version 4.032 (04/2020) verilator linter messages also contain the column number, + " and look like: + " %Error: /tmp/test.sv:3:1: syntax error, unexpected endmodule, expecting ';' + " + " to stay compatible with old versions of the tool, the column number is + " optional in the researched pattern + let l:pattern = '^%\(Warning\|Error\)[^:]*:\s*\([^:]\+\):\(\d\+\):\(\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, - \}) + let l:item = { + \ 'lnum': str2nr(l:match[3]), + \ 'text': l:match[5], + \ 'type': l:match[1] is# 'Error' ? 'E' : 'W', + \ 'filename': l:match[2], + \} + + if !empty(l:match[4]) + let l:item.col = str2nr(l:match[4]) endif + + call add(l:output, l:item) endfor return l:output @@ -53,7 +54,7 @@ call ale#linter#Define('verilog', { \ 'name': 'verilator', \ 'output_stream': 'stderr', \ 'executable': 'verilator', -\ 'command_callback': 'ale_linters#verilog#verilator#GetCommand', +\ 'command': function('ale_linters#verilog#verilator#GetCommand'), \ 'callback': 'ale_linters#verilog#verilator#Handle', \ 'read_buffer': 0, \}) diff --git a/vim-config/plugins/ale/ale_linters/verilog/vlog.vim b/vim-config/plugins/ale/ale_linters/verilog/vlog.vim new file mode 100644 index 00000000..45e1977c --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/verilog/vlog.vim @@ -0,0 +1,52 @@ +" 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[3] + 0, + \ 'type': l:match[1] is? 'Error' ? 'E' : 'W', + \ 'text': l:match[4], + \ 'filename': l:match[2], + \}) + endfor + + "Matches patterns like the following: + "** Warning: (vlog-2623) add.v(7): Undefined variable: C. + "** Error: (vlog-13294) file.v(1): Identifier must be declared with a port mode: C. + " let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)' + let l:pattern = '^**\s\(\w*\):\s\([^)]*)\) \([a-zA-Z0-9\-\.\_\/ ]\+\)(\(\d\+\)):\s\+\(.*\)' + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[4] + 0, + \ 'type': l:match[1] is? 'Error' ? 'E' : 'W', + \ 'text': l:match[2] . ' ' . l:match[5], + \ 'filename': 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/vim-config/plugins/ale/ale_linters/verilog/xvlog.vim b/vim-config/plugins/ale/ale_linters/verilog/xvlog.vim new file mode 100644 index 00000000..98b5aae7 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/verilog/yosys.vim b/vim-config/plugins/ale/ale_linters/verilog/yosys.vim new file mode 100644 index 00000000..29657755 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/verilog/yosys.vim @@ -0,0 +1,42 @@ +" Author: Nathan Sharp +" Description: Yosys for Verilog files + +call ale#Set('verilog_yosys_executable', 'yosys') +call ale#Set('verilog_yosys_options', '-Q -T -p ''read_verilog %s''') + +function! ale_linters#verilog#yosys#GetCommand(buffer) abort + return '%e ' . ale#Var(a:buffer, 'verilog_yosys_options') . ' 2>&1' +endfunction + +function! ale_linters#verilog#yosys#Handle(buffer, lines) abort + let l:output = [] + let l:path = fnamemodify(bufname(a:buffer), ':p') + + for l:match in ale#util#GetMatches(a:lines, '^\([^:]\+\):\(\d\+\): \(WARNING\|ERROR\): \(.\+\)$') + call add(l:output, { + \ 'lnum': str2nr(l:match[2]), + \ 'text': l:match[4], + \ 'type': l:match[3][0], + \ 'filename': l:match[1], + \}) + endfor + + for l:match in ale#util#GetMatches(a:lines, '^\(Warning\|ERROR\): \(.\+\)$') + call add(l:output, { + \ 'lnum': 1, + \ 'text': l:match[2], + \ 'type': l:match[1][0], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('verilog', { +\ 'name': 'yosys', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'verilog_yosys_executable')}, +\ 'command': function('ale_linters#verilog#yosys#GetCommand'), +\ 'callback': 'ale_linters#verilog#yosys#Handle', +\ 'lint_file': 1, +\}) diff --git a/vim-config/plugins/ale/ale_linters/vhdl/ghdl.vim b/vim-config/plugins/ale/ale_linters/vhdl/ghdl.vim new file mode 100644 index 00000000..b09e620b --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/vhdl/hdl_checker.vim b/vim-config/plugins/ale/ale_linters/vhdl/hdl_checker.vim new file mode 100644 index 00000000..c9d306b3 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/vhdl/hdl_checker.vim @@ -0,0 +1,5 @@ +" Author: suoto +" Description: Adds support for HDL Code Checker, which wraps vcom/vlog, ghdl +" or xvhdl. More info on https://github.com/suoto/hdl_checker + +call ale#handlers#hdl_checker#DefineLinter('vhdl') diff --git a/vim-config/plugins/ale/ale_linters/vhdl/vcom.vim b/vim-config/plugins/ale/ale_linters/vhdl/vcom.vim new file mode 100644 index 00000000..1914fd33 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/vhdl/xvhdl.vim b/vim-config/plugins/ale/ale_linters/vhdl/xvhdl.vim new file mode 100644 index 00000000..8010ff14 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/ale_linters/vim/ale_custom_linting_rules.vim b/vim-config/plugins/ale/ale_linters/vim/ale_custom_linting_rules.vim old mode 100755 new mode 100644 index 3da44206..5ca2f149 --- a/vim-config/plugins/ale/ale_linters/vim/ale_custom_linting_rules.vim +++ b/vim-config/plugins/ale/ale_linters/vim/ale_custom_linting_rules.vim @@ -22,16 +22,20 @@ function! s:GetALEProjectDir(buffer) abort 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) +function! ale_linters#vim#ale_custom_linting_rules#GetCwd(buffer) abort + let l:executable = ale_linters#vim#ale_custom_linting_rules#GetExecutable(a:buffer) - let l:temp_dir = ale#engine#CreateDirectory(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: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) + return '%e ' . ale#Escape(l:temp_dir) endfunction function! ale_linters#vim#ale_custom_linting_rules#Handle(buffer, lines) abort @@ -58,8 +62,9 @@ endfunction call ale#linter#Define('vim', { \ 'name': 'ale_custom_linting_rules', -\ 'executable_callback': 'ale_linters#vim#ale_custom_linting_rules#GetExecutable', -\ 'command_callback': 'ale_linters#vim#ale_custom_linting_rules#GetCommand', +\ 'executable': function('ale_linters#vim#ale_custom_linting_rules#GetExecutable'), +\ 'cwd': function('ale_linters#vim#ale_custom_linting_rules#GetCwd'), +\ '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/vim-config/plugins/ale/ale_linters/vim/vimls.vim b/vim-config/plugins/ale/ale_linters/vim/vimls.vim new file mode 100644 index 00000000..7003eb04 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/vim/vimls.vim @@ -0,0 +1,61 @@ +" Author: Jeffrey Lau - https://github.com/zoonfafer +" Description: Vim Language Server integration for ALE + +call ale#Set('vim_vimls_executable', 'vim-language-server') +call ale#Set('vim_vimls_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('vim_vimls_config', {}) + +function! ale_linters#vim#vimls#GetProjectRoot(buffer) abort + let l:trigger_file_candidates = [ + \ '.vimrc', + \ 'init.vim', + \] + + for l:candidate in l:trigger_file_candidates + let l:trigger_file = fnamemodify(bufname(a:buffer), ':t') + + if l:trigger_file is# l:candidate + return fnamemodify( + \ bufname(a:buffer), + \ ':h', + \) + endif + endfor + + let l:trigger_dir_candidates = [ + \ 'autoload', + \ 'plugin', + \ '.git', + \] + + let l:path_upwards = ale#path#Upwards(fnamemodify(bufname(a:buffer), ':p:h')) + + for l:path in l:path_upwards + for l:candidate in l:trigger_dir_candidates + let l:trigger_dir = ale#path#Simplify( + \ l:path . '/' . l:candidate, + \) + + if isdirectory(l:trigger_dir) + return fnamemodify( + \ l:trigger_dir, + \ ':p:h:h', + \) + endif + endfor + endfor + + return '' +endfunction + +call ale#linter#Define('vim', { +\ 'name': 'vimls', +\ 'lsp': 'stdio', +\ 'lsp_config': {b -> ale#Var(b, 'vim_vimls_config')}, +\ 'executable': {b -> ale#path#FindExecutable(b, 'vim_vimls', [ +\ 'node_modules/.bin/vim-language-server', +\ ])}, +\ 'command': '%e --stdio', +\ 'language': 'vim', +\ 'project_root': function('ale_linters#vim#vimls#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/ale_linters/vim/vint.vim b/vim-config/plugins/ale/ale_linters/vim/vint.vim old mode 100755 new mode 100644 index cf2d4afd..f7054ffb --- a/vim-config/plugins/ale/ale_linters/vim/vint.vim +++ b/vim-config/plugins/ale/ale_linters/vim/vint.vim @@ -5,36 +5,25 @@ 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})"' +let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {policy_name} - {description} (see {reference})"' -function! ale_linters#vim#vint#GetExecutable(buffer) abort - return ale#Var(a:buffer, 'vim_vint_executable') -endfunction - -function! ale_linters#vim#vint#VersionCommand(buffer) abort - let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer) - - " Check the Vint version if we haven't checked it already. - return !ale#semver#HasVersion(l:executable) - \ ? ale#Escape(l:executable) . ' --version' - \ : '' -endfunction - -function! ale_linters#vim#vint#GetCommand(buffer, version_output) abort - let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer) - let l:version = ale#semver#GetVersion(l:executable, a:version_output) - - let l:can_use_no_color_flag = empty(l:version) - \ || ale#semver#GTE(l:version, [0, 3, 7]) +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 ale#Escape(l:executable) + " Use the --stdin-display-name argument if supported, temp file otherwise. + let l:stdin_or_temp = ale#semver#GTE(a:version, [0, 4, 0]) + \ ? ' --stdin-display-name %s -' + \ : ' %t' + + return '%e' \ . ' ' . l:warning_flag \ . (l:can_use_no_color_flag ? ' --no-color' : '') \ . s:enable_neovim \ . ' ' . s:format - \ . ' %t' + \ . l:stdin_or_temp endfunction let s:word_regex_list = [ @@ -65,10 +54,12 @@ endfunction call ale#linter#Define('vim', { \ 'name': 'vint', -\ 'executable_callback': 'ale_linters#vim#vint#GetExecutable', -\ 'command_chain': [ -\ {'callback': 'ale_linters#vim#vint#VersionCommand', 'output_stream': 'stderr'}, -\ {'callback': 'ale_linters#vim#vint#GetCommand', 'output_stream': 'stdout'}, -\ ], +\ '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/vim-config/plugins/ale/ale_linters/vue/vls.vim b/vim-config/plugins/ale/ale_linters/vue/vls.vim old mode 100755 new mode 100644 index 7116128b..4bd75286 --- a/vim-config/plugins/ale/ale_linters/vue/vls.vim +++ b/vim-config/plugins/ale/ale_linters/vue/vls.vim @@ -13,10 +13,10 @@ endfunction call ale#linter#Define('vue', { \ 'name': 'vls', \ 'lsp': 'stdio', -\ 'executable_callback': ale#node#FindExecutableFunc('vue_vls', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'vue_vls', [ \ 'node_modules/.bin/vls', -\ ]), +\ ])}, \ 'command': '%e --stdio', \ 'language': 'vue', -\ 'project_root_callback': 'ale_linters#vue#vls#GetProjectRoot', +\ 'project_root': function('ale_linters#vue#vls#GetProjectRoot'), \}) diff --git a/vim-config/plugins/ale/ale_linters/xhtml/alex.vim b/vim-config/plugins/ale/ale_linters/xhtml/alex.vim old mode 100755 new mode 100644 index 60a9a7c9..97f3b59a --- a/vim-config/plugins/ale/ale_linters/xhtml/alex.vim +++ b/vim-config/plugins/ale/ale_linters/xhtml/alex.vim @@ -1,11 +1,4 @@ " Author: Johannes Wienke " Description: alex for XHTML files -call ale#linter#Define('xhtml', { -\ 'name': 'alex', -\ 'executable': 'alex', -\ 'command': 'alex %s -t', -\ 'output_stream': 'stderr', -\ 'callback': 'ale#handlers#alex#Handle', -\ 'lint_file': 1, -\}) +call ale#handlers#alex#DefineLinter('xhtml', '--text') diff --git a/vim-config/plugins/ale/ale_linters/xhtml/proselint.vim b/vim-config/plugins/ale/ale_linters/xhtml/proselint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/xhtml/writegood.vim b/vim-config/plugins/ale/ale_linters/xhtml/writegood.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ale_linters/xml/xmllint.vim b/vim-config/plugins/ale/ale_linters/xml/xmllint.vim old mode 100755 new mode 100644 index 59f43d16..553d0883 --- a/vim-config/plugins/ale/ale_linters/xml/xmllint.vim +++ b/vim-config/plugins/ale/ale_linters/xml/xmllint.vim @@ -29,27 +29,27 @@ function! ale_linters#xml#xmllint#Handle(buffer, lines) abort 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] + 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, - \}) + call add(l:output, { + \ 'lnum': l:line, + \ 'text': l:text, + \ 'type': l:type, + \}) - continue + 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]) + let l:previous = l:output[len(l:output) - 1] + let l:previous['col'] = len(l:match_column_token[0]) - continue + continue endif endfor @@ -59,7 +59,7 @@ endfunction call ale#linter#Define('xml', { \ 'name': 'xmllint', \ 'output_stream': 'stderr', -\ 'executable_callback': ale#VarFunc('xml_xmllint_executable'), -\ 'command_callback': 'ale_linters#xml#xmllint#GetCommand', +\ 'executable': {b -> ale#Var(b, 'xml_xmllint_executable')}, +\ 'command': function('ale_linters#xml#xmllint#GetCommand'), \ 'callback': 'ale_linters#xml#xmllint#Handle', \ }) diff --git a/vim-config/plugins/ale/ale_linters/yaml/circleci.vim b/vim-config/plugins/ale/ale_linters/yaml/circleci.vim new file mode 100644 index 00000000..20835454 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/yaml/circleci.vim @@ -0,0 +1,35 @@ +function! ale_linters#yaml#circleci#Handle(buffer, lines) abort + let l:match_index = -1 + let l:output = [] + + for l:index in range(len(a:lines)) + let l:line = a:lines[l:index] + + if l:line =~? 'Error: ERROR IN CONFIG FILE:' + let l:match_index = l:index + 1 + break + endif + endfor + + if l:match_index > 0 + return [{ + \ 'type': 'E', + \ 'lnum': 1, + \ 'text': a:lines[l:match_index], + \ 'detail': join(a:lines[l:match_index :], "\n"), + \}] + endif + + return [] +endfunction + +" The circleci validate requires network requests, so we'll only run it when +" files are saved to prevent the server from being hammered. +call ale#linter#Define('yaml', { +\ 'name': 'circleci', +\ 'executable': {b -> expand('#' . b . ':p') =~? '\.circleci' ? 'circleci' : ''}, +\ 'command': 'circleci --skip-update-check config validate - < %s', +\ 'callback': 'ale_linters#yaml#circleci#Handle', +\ 'output_stream': 'stderr', +\ 'lint_file': 1, +\}) diff --git a/vim-config/plugins/ale/ale_linters/yaml/spectral.vim b/vim-config/plugins/ale/ale_linters/yaml/spectral.vim new file mode 100644 index 00000000..13654f06 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/yaml/spectral.vim @@ -0,0 +1,14 @@ +" Author: t2h5 +" Description: Integration of Stoplight Spectral CLI with ALE. + +call ale#Set('yaml_spectral_executable', 'spectral') +call ale#Set('yaml_spectral_use_global', get(g:, 'ale_use_global_executables', 0)) + +call ale#linter#Define('yaml', { +\ 'name': 'spectral', +\ 'executable': {b -> ale#path#FindExecutable(b, 'yaml_spectral', [ +\ 'node_modules/.bin/spectral', +\ ])}, +\ 'command': '%e lint --ignore-unknown-format -q -f text %t', +\ 'callback': 'ale#handlers#spectral#HandleSpectralOutput' +\}) diff --git a/vim-config/plugins/ale/ale_linters/yaml/swaglint.vim b/vim-config/plugins/ale/ale_linters/yaml/swaglint.vim old mode 100755 new mode 100644 index 7362536e..7fc2b430 --- a/vim-config/plugins/ale/ale_linters/yaml/swaglint.vim +++ b/vim-config/plugins/ale/ale_linters/yaml/swaglint.vim @@ -32,9 +32,9 @@ endfunction call ale#linter#Define('yaml', { \ 'name': 'swaglint', -\ 'executable_callback': ale#node#FindExecutableFunc('yaml_swaglint', [ +\ 'executable': {b -> ale#path#FindExecutable(b, 'yaml_swaglint', [ \ 'node_modules/.bin/swaglint', -\ ]), +\ ])}, \ 'command': '%e -r compact --stdin', \ 'callback': 'ale_linters#yaml#swaglint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/yaml/yamllint.vim b/vim-config/plugins/ale/ale_linters/yaml/yamllint.vim old mode 100755 new mode 100644 index 9d2cc7c2..39011df1 --- a/vim-config/plugins/ale/ale_linters/yaml/yamllint.vim +++ b/vim-config/plugins/ale/ale_linters/yaml/yamllint.vim @@ -3,48 +3,9 @@ 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_callback': ale#VarFunc('yaml_yamllint_executable'), -\ 'command_callback': 'ale_linters#yaml#yamllint#GetCommand', -\ 'callback': 'ale_linters#yaml#yamllint#Handle', +\ 'executable': {b -> ale#Var(b, 'yaml_yamllint_executable')}, +\ 'command': function('ale#handlers#yamllint#GetCommand'), +\ 'callback': 'ale#handlers#yamllint#Handle', \}) diff --git a/vim-config/plugins/ale/ale_linters/yang/yang_lsp.vim b/vim-config/plugins/ale/ale_linters/yang/yang_lsp.vim old mode 100755 new mode 100644 index 45776f98..81fcaa0e --- a/vim-config/plugins/ale/ale_linters/yang/yang_lsp.vim +++ b/vim-config/plugins/ale/ale_linters/yang/yang_lsp.vim @@ -9,7 +9,7 @@ endfunction call ale#linter#Define('yang', { \ 'name': 'yang_lsp', \ 'lsp': 'stdio', -\ 'executable_callback': ale#VarFunc('yang_lsp_executable'), -\ 'project_root_callback': 'ale_linters#yang#yang_lsp#GetProjectRoot', +\ 'executable': {b -> ale#Var(b, 'yang_lsp_executable')}, +\ 'project_root': function('ale_linters#yang#yang_lsp#GetProjectRoot'), \ 'command': '%e', \}) diff --git a/vim-config/plugins/ale/ale_linters/zeek/zeek.vim b/vim-config/plugins/ale/ale_linters/zeek/zeek.vim new file mode 100644 index 00000000..e976d75c --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/zeek/zeek.vim @@ -0,0 +1,22 @@ +" Author: Benjamin Bannier +" Description: Support for checking Zeek files. +" +call ale#Set('zeek_zeek_executable', 'zeek') + +function! ale_linters#zeek#zeek#HandleErrors(buffer, lines) abort + let l:pattern = 'error in \v.*, line (\d+): (.*)$' + + return map(ale#util#GetMatches(a:lines, l:pattern), "{ + \ 'lnum': str2nr(v:val[1]), + \ 'text': v:val[2], + \}") +endfunction + +call ale#linter#Define('zeek', { +\ 'name': 'zeek', +\ 'executable': {b -> ale#Var(b, 'zeek_zeek_executable')}, +\ 'output_stream': 'stderr', +\ 'command': {-> '%e --parse-only %s'}, +\ 'callback': 'ale_linters#zeek#zeek#HandleErrors', +\ 'lint_file': 1, +\}) diff --git a/vim-config/plugins/ale/ale_linters/zig/zls.vim b/vim-config/plugins/ale/ale_linters/zig/zls.vim new file mode 100644 index 00000000..1390f6b1 --- /dev/null +++ b/vim-config/plugins/ale/ale_linters/zig/zls.vim @@ -0,0 +1,20 @@ +" Author: CherryMan +" Description: A language server for Zig + +call ale#Set('zig_zls_executable', 'zls') +call ale#Set('zig_zls_config', {}) + +function! ale_linters#zig#zls#GetProjectRoot(buffer) abort + let l:build_rs = ale#path#FindNearestFile(a:buffer, 'build.zig') + + return !empty(l:build_rs) ? fnamemodify(l:build_rs, ':h') : '' +endfunction + +call ale#linter#Define('zig', { +\ 'name': 'zls', +\ 'lsp': 'stdio', +\ 'lsp_config': {b -> ale#Var(b, 'zig_zls_config')}, +\ 'executable': {b -> ale#Var(b, 'zig_zls_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#zig#zls#GetProjectRoot'), +\}) diff --git a/vim-config/plugins/ale/autoload/ale.vim b/vim-config/plugins/ale/autoload/ale.vim old mode 100755 new mode 100644 index f6c23d72..97483b45 --- a/vim-config/plugins/ale/autoload/ale.vim +++ b/vim-config/plugins/ale/autoload/ale.vim @@ -5,9 +5,17 @@ " 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_log_str = get(g:, 'ale_echo_msg_log_str', 'Log') 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) + +" LSP window/showMessage format +let g:ale_lsp_show_message_format = get(g:, 'ale_lsp_show_message_format', '%severity%:%linter%: %s') +" Valid values mimic LSP definitions (error, warning and information; log is +" never shown) +let g:ale_lsp_show_message_severity = get(g:, 'ale_lsp_show_message_severity', 'error') let s:lint_timer = -1 let s:getcmdwintype_exists = exists('*getcmdwintype') @@ -42,6 +50,11 @@ function! ale#ShouldDoNothing(buffer) abort 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 @@ -87,12 +100,7 @@ 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:linters = !empty(l:ignore_config) - \ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config) - \ : l:linters + let l:linters = ale#linter#RemoveIgnored(a:buffer, l:filetype, l:linters) " Tell other sources that they can start checking the buffer now. let g:ale_want_results_buffer = a:buffer @@ -149,12 +157,19 @@ function! ale#Queue(delay, ...) abort endif endfunction -let g:ale_has_override = get(g:, 'ale_has_override', {}) +let s:current_ale_version = [3, 1, 0] -" Call has(), but check a global Dictionary so we can force flags on or off -" for testing purposes. +" A function used to check for ALE features in files outside of the project. function! ale#Has(feature) abort - return get(g:ale_has_override, a:feature, has(a:feature)) + 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 @@ -169,11 +184,6 @@ function! ale#Var(buffer, variable_name) abort return get(l:vars, l:full_name, g:[l:full_name]) endfunction -" As above, but curry the arguments so only the buffer number is required. -function! ale#VarFunc(variable_name) abort - return {buf -> ale#Var(buf, a:variable_name)} -endfunction - " Initialize a variable with a default value, if it isn't already set. " " Every variable name will be prefixed with 'ale_'. @@ -242,11 +252,33 @@ function! ale#GetLocItemMessage(item, format_string) abort " Replace special markers with certain information. " \=l:variable is used to avoid escaping issues. + let l:msg = substitute(l:msg, '\v\%([^\%]*)code([^\%]*)\%', l:code_repl, 'g') 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') + " Windows may insert carriage return line endings (^M), strip these characters. + let l:msg = substitute(l:msg, '\r', '', 'g') return l:msg endfunction + +" Given a buffer and a linter or fixer name, return an Array of two-item +" Arrays describing how to map filenames to and from the local to foreign file +" systems. +function! ale#GetFilenameMappings(buffer, name) abort + let l:linter_mappings = ale#Var(a:buffer, 'filename_mappings') + + if type(l:linter_mappings) is v:t_list + return l:linter_mappings + endif + + let l:name = a:name + + if !has_key(l:linter_mappings, l:name) + " Use * as a default setting for all tools. + let l:name = '*' + endif + + return get(l:linter_mappings, l:name, []) +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/ant.vim b/vim-config/plugins/ale/autoload/ale/ant.vim new file mode 100644 index 00000000..b6d4217f --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/ant.vim @@ -0,0 +1,45 @@ +" 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, get a working directory and command to print the +" classpath of the root project. +" +" Returns an empty string for the command if Ant is not detected. +function! ale#ant#BuildClasspathCommand(buffer) abort + let l:executable = ale#ant#FindExecutable(a:buffer) + + if !empty(l:executable) + let l:project_root = ale#ant#FindProjectRoot(a:buffer) + + if !empty(l:project_root) + return [ + \ l:project_root, + \ ale#Escape(l:executable) .' classpath -S -q' + \] + endif + endif + + return ['', ''] +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/args.vim b/vim-config/plugins/ale/autoload/ale/args.vim new file mode 100644 index 00000000..70afb2e5 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/autoload/ale/assert.vim b/vim-config/plugins/ale/autoload/ale/assert.vim old mode 100755 new mode 100644 index ed08ed09..141cd0f2 --- a/vim-config/plugins/ale/autoload/ale/assert.vim +++ b/vim-config/plugins/ale/autoload/ale/assert.vim @@ -1,7 +1,7 @@ -let s:chain_results = [] +let s:command_output = [] -function! ale#assert#WithChainResults(...) abort - let s:chain_results = a:000 +function! ale#assert#GivenCommandOutput(...) abort + let s:command_output = a:000 endfunction function! s:GetLinter() abort @@ -19,6 +19,69 @@ function! s:GetLinter() abort 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 + +function! s:ProcessDeferredCwds(initial_command, initial_cwd) abort + let l:result = a:initial_command + let l:last_cwd = v:null + let l:command_index = 0 + let l:cwd_list = [] + + while ale#command#IsDeferred(l:result) + call add(l:cwd_list, l:result.cwd) + + 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:cwd_list, a:initial_cwd is v:null ? l:last_cwd : a:initial_cwd) + + return l:cwd_list +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 @@ -26,42 +89,25 @@ function! ale#assert#Linter(expected_executable, expected_command) abort let l:linter = s:GetLinter() let l:executable = ale#linter#GetExecutable(l:buffer, l:linter) - if has_key(l:linter, 'command_chain') - let l:callbacks = map(copy(l:linter.command_chain), 'v:val.callback') - - " If the expected command is a string, just check the last one. - if type(a:expected_command) is v:t_string - if len(l:callbacks) is 1 - let l:command = call(l:callbacks[0], [l:buffer]) - else - let l:input = get(s:chain_results, len(l:callbacks) - 2, []) - let l:command = call(l:callbacks[-1], [l:buffer, l:input]) - endif - else - let l:command = [] - let l:chain_index = 0 - - for l:Callback in l:callbacks - if l:chain_index is 0 - call add(l:command, call(l:Callback, [l:buffer])) - else - let l:input = get(s:chain_results, l:chain_index - 1, []) - call add(l:command, call(l:Callback, [l:buffer, l:input])) - endif - - let l:chain_index += 1 - endfor - endif - else - let l:command = ale#linter#GetCommand(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 = substitute(l:command, '%e', '\=ale#Escape(l:executable)', 'g') - else - call map(l:command, 'substitute(v:val, ''%e'', ''\=ale#Escape(l:executable)'', ''g'')') + 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 @@ -69,12 +115,75 @@ function! ale#assert#Linter(expected_executable, expected_command) abort \ [l:executable, l:command] endfunction +function! ale#assert#LinterCwd(expected_cwd) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + + let l:initial_cwd = ale#linter#GetCwd(l:buffer, l:linter) + call ale#command#SetCwd(l:buffer, l:initial_cwd) + + let l:cwd = s:ProcessDeferredCwds( + \ ale#linter#GetCommand(l:buffer, l:linter), + \ l:initial_cwd, + \) + + call ale#command#ResetCwd(l:buffer) + + if type(a:expected_cwd) isnot v:t_list + let l:cwd = l:cwd[-1] + endif + + AssertEqual a:expected_cwd, l:cwd +endfunction + +function! ale#assert#FixerCwd(expected_cwd) abort + let l:buffer = bufnr('') + let l:cwd = s:ProcessDeferredCwds(s:FixerFunction(l:buffer), v:null) + + if type(a:expected_cwd) isnot v:t_list + let l:cwd = l:cwd[-1] + endif + + AssertEqual a:expected_cwd, l:cwd +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) + let l:executed = 1 + + if !empty(l:executable) + let l:command = ale#linter#GetCommand(l:buffer, l:linter) + + if type(l:command) is v:t_list + let l:command = l:command[-1] + endif - Assert empty(l:executable), "The linter will be executed when it shouldn't be" + let l:executed = !empty(l:command) + else + let l:executed = 0 + endif + + Assert !l:executed, "The linter will be executed when it shouldn't be" endfunction function! ale#assert#LSPOptions(expected_options) abort @@ -96,7 +205,7 @@ 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) + let l:language = ale#linter#GetLanguage(l:buffer, l:linter) AssertEqual a:expected_language, l:language endfunction @@ -104,7 +213,7 @@ endfunction function! ale#assert#LSPProject(expected_root) abort let l:buffer = bufnr('') let l:linter = s:GetLinter() - let l:root = ale#util#GetFunction(l:linter.project_root_callback)(l:buffer) + let l:root = ale#lsp_linter#FindProjectRoot(l:buffer, l:linter) AssertEqual a:expected_root, l:root endfunction @@ -112,11 +221,54 @@ endfunction function! ale#assert#LSPAddress(expected_address) abort let l:buffer = bufnr('') let l:linter = s:GetLinter() - let l:address = ale#util#GetFunction(l:linter.address_callback)(l:buffer) + 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=+ AssertLinterCwd :call ale#assert#LinterCwd() + 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=+ AssertFixerCwd :call ale#assert#FixerCwd() + command! -nargs=+ AssertFixer :call ale#assert#Fixer() + command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted() +endfunction + +function! ale#assert#ResetVariables(filetype, name, ...) abort + " If the suffix of the option names format is different, an additional + " argument can be used for that instead. + if a:0 > 1 + throw 'Too many arguments' + endif + + let l:option_suffix = get(a:000, 0, a:name) + let l:prefix = 'ale_' . a:filetype . '_' + \ . substitute(l:option_suffix, '-', '_', 'g') + let l:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix' + + " Save and clear linter variables. + " We'll load the runtime file to reset them to defaults. + for l:key in filter(keys(g:), l:filter_expr) + execute 'Save g:' . l:key + unlet g:[l:key] + endfor + + for l:key in filter(keys(b:), l:filter_expr) + unlet b:[l:key] + endfor +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. @@ -126,47 +278,44 @@ function! ale#assert#SetUpLinterTest(filetype, name) abort 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_root + let g:ale_root = {} - Save g:ale_c_build_dir - unlet! g:ale_c_build_dir + Save b:ale_root + unlet! b:ale_root - " 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 + call ale#assert#ResetVariables(a:filetype, a:name) + Save g:ale_c_build_dir + unlet! g:ale_c_build_dir 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') + call ale#test#SetDirectory('/testplugin/test/linter') endif - command! -nargs=+ WithChainResults :call ale#assert#WithChainResults() - 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() + 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 - let s:chain_results = [] + 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(':WithChainResults') - delcommand WithChainResults + if exists(':AssertLinterCwd') + delcommand AssertLinterCwd endif if exists(':AssertLinter') @@ -209,3 +358,67 @@ function! ale#assert#TearDownLinterTest() abort call ale#semver#ResetVersionCache() endif endfunction + +function! ale#assert#SetUpFixerTest(filetype, name, ...) abort + " If the suffix of the option names format is different, an additional + " argument can be used for that instead. + if a:0 > 1 + throw 'Too many arguments' + endif + + " 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:option_suffix = get(a:000, 0, a:name) + call ale#assert#ResetVariables(a:filetype, a:name, l:option_suffix) + + execute 'runtime autoload/ale/fixers/' . substitute(a:name, '-', '_', 'g') . '.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(':AssertFixerCwd') + delcommand AssertFixerCwd + endif + + if exists(':AssertFixer') + delcommand AssertFixer + endif + + if exists(':AssertFixerNotExecuted') + delcommand AssertFixerNotExecuted + endif +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/balloon.vim b/vim-config/plugins/ale/autoload/ale/balloon.vim old mode 100755 new mode 100644 index 72f6b91c..8678376f --- a/vim-config/plugins/ale/autoload/ale/balloon.vim +++ b/vim-config/plugins/ale/autoload/ale/balloon.vim @@ -2,23 +2,39 @@ " Description: balloonexpr support for ALE. function! ale#balloon#MessageForPos(bufnr, lnum, col) abort + let l:set_balloons = ale#Var(a:bufnr, 'set_balloons') + let l:show_problems = 0 + let l:show_hover = 0 + + if l:set_balloons is 1 + let l:show_problems = 1 + let l:show_hover = 1 + elseif l:set_balloons is# 'hover' + let l:show_hover = 1 + endif + " Don't show balloons if they are disabled, or linting is disabled. - if !ale#Var(a:bufnr, 'set_balloons') + if !(l:show_problems || l:show_hover) \|| !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) + if l:show_problems + 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) + endif " Show the diagnostics message if found, 'Hover' output otherwise - if l:index >= 0 + if l:show_problems && 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) + elseif l:show_hover && ( + \ 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 diff --git a/vim-config/plugins/ale/autoload/ale/c.vim b/vim-config/plugins/ale/autoload/ale/c.vim old mode 100755 new mode 100644 index 6ad5d328..e729aec8 --- a/vim-config/plugins/ale/autoload/ale/c.vim +++ b/vim-config/plugins/ale/autoload/ale/c.vim @@ -2,20 +2,28 @@ " Description: Functions for integrating with C-family linters. call ale#Set('c_parse_makefile', 0) -call ale#Set('c_parse_compile_commands', 0) +call ale#Set('c_always_make', has('unix') && !has('macunix')) +call ale#Set('c_parse_compile_commands', 1) + 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 g:ale_c_build_dir_names = get(g:, 'ale_c_build_dir_names', [ +\ 'build', +\ 'bin', +\]) +function! s:CanParseMakefile(buffer) abort + " Something somewhere seems to delete this setting in tests, so ensure we + " always have a default value. + call ale#Set('c_parse_makefile', 0) + + return ale#Var(a:buffer, 'c_parse_makefile') +endfunction + +function! ale#c#GetBuildDirectory(buffer) abort let l:build_dir = ale#Var(a:buffer, 'c_build_dir') " c_build_dir has the priority if defined @@ -23,112 +31,187 @@ function! ale#c#GetBuildDirectory(buffer) abort return l:build_dir endif - return ale#path#Dirname(ale#c#FindCompileCommands(a:buffer)) -endfunction - + let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer) -function! ale#c#FindProjectRoot(buffer) abort - for l:project_filename in g:__ale_c_project_filenames - let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename) + return ale#path#Dirname(l:json_file) +endfunction - if !empty(l:full_path) - let l:path = fnamemodify(l:full_path, ':h') +function! ale#c#ShellSplit(line) abort + let l:stack = [] + let l:args = [''] + let l:prev = '' - " Correct .git path detection. - if fnamemodify(l:path, ':t') is# '.git' - let l:path = fnamemodify(l:path, ':h') + for l:char in split(a:line, '\zs') + if l:char is# '''' + if len(l:stack) > 0 && get(l:stack, -1) is# '''' + call remove(l:stack, -1) + elseif (len(l:stack) == 0 || get(l:stack, -1) isnot# '"') && l:prev isnot# '\' + call add(l:stack, l:char) + endif + elseif (l:char is# '"' || l:char is# '`') && l:prev isnot# '\' + if len(l:stack) > 0 && get(l:stack, -1) is# l:char + call remove(l:stack, -1) + elseif len(l:stack) == 0 || get(l:stack, -1) isnot# '''' + call add(l:stack, l:char) + endif + elseif (l:char is# '(' || l:char is# '[' || l:char is# '{') && l:prev isnot# '\' + if len(l:stack) == 0 || get(l:stack, -1) isnot# '''' + call add(l:stack, l:char) + endif + elseif (l:char is# ')' || l:char is# ']' || l:char is# '}') && l:prev isnot# '\' + if len(l:stack) > 0 && get(l:stack, -1) is# {')': '(', ']': '[', '}': '{'}[l:char] + call remove(l:stack, -1) + endif + elseif l:char is# ' ' && len(l:stack) == 0 + if len(get(l:args, -1)) > 0 + call add(l:args, '') endif - return l:path + continue endif + + let l:args[-1] = get(l:args, -1) . l:char endfor - return '' + return l:args endfunction -function! ale#c#AreSpecialCharsBalanced(option) abort - " Escape \" - let l:option_escaped = substitute(a:option, '\\"', '', 'g') +" Takes the path prefix and a list of cflags and expands @file arguments to +" the contents of the file. +" +" @file arguments are command line arguments recognised by gcc and clang. For +" instance, if @./path/to/file was given to gcc, it would load .path/to/file +" and use the contents of that file as arguments. +function! ale#c#ExpandAtArgs(path_prefix, raw_split_lines) abort + let l:out_lines = [] + + for l:option in a:raw_split_lines + if stridx(l:option, '@') == 0 + " This is an argument specifying a location of a file containing other arguments + let l:path = join(split(l:option, '\zs')[1:], '') + + " Make path absolute + if !ale#path#IsAbsolute(l:path) + let l:rel_path = substitute(l:path, '"', '', 'g') + let l:rel_path = substitute(l:rel_path, '''', '', 'g') + let l:path = ale#path#GetAbsPath(a:path_prefix, l:rel_path) + endif - " Retain special chars only - let l:special_chars = substitute(l:option_escaped, '[^"''()`]', '', 'g') - let l:special_chars = split(l:special_chars, '\zs') + " Read the file and add all the arguments + try + let l:additional_args = readfile(l:path) + catch + continue " All we can really do is skip this argument + endtry - " Check if they are balanced - let l:stack = [] + let l:file_lines = [] - for l:char in l:special_chars - if l:char is# ')' - if len(l:stack) == 0 || get(l:stack, -1) isnot# '(' - return 0 - endif + for l:line in l:additional_args + let l:file_lines += ale#c#ShellSplit(l:line) + endfor - call remove(l:stack, -1) - elseif l:char is# '(' - call add(l:stack, l:char) + " @file arguments can include other @file arguments, so we must + " recurse. + let l:out_lines += ale#c#ExpandAtArgs(a:path_prefix, l:file_lines) 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 + " This is not an @file argument, so don't touch it. + let l:out_lines += [l:option] endif endfor - return len(l:stack) == 0 + return l:out_lines endfunction -function! ale#c#ParseCFlags(path_prefix, cflag_line) abort - let l:cflags_list = [] - let l:previous_options = '' +" Quote C/C++ a compiler argument, if needed. +" +" Quoting arguments might cause issues with some systems/compilers, so we only +" quote them if we need to. +function! ale#c#QuoteArg(arg) abort + if a:arg !~# '\v[#$&*()\\|[\]{};''"<>/?! ^%]' + return a:arg + endif + + return ale#Escape(a:arg) +endfunction - let l:split_lines = split(a:cflag_line, ' ') +function! ale#c#ParseCFlags(path_prefix, should_quote, raw_arguments) abort + " Expand @file arguments now before parsing + let l:arguments = ale#c#ExpandAtArgs(a:path_prefix, a:raw_arguments) + " A list of [already_quoted, argument] + let l:items = [] let l:option_index = 0 - while l:option_index < len(l:split_lines) - let l:option = l:previous_options . l:split_lines[l:option_index] + while l:option_index < len(l:arguments) + let l:option = l:arguments[l:option_index] let l:option_index = l:option_index + 1 - " Check if cflag contained an unmatched special character and should not have been splitted - if ale#c#AreSpecialCharsBalanced(l:option) == 0 && l:option_index < len(l:split_lines) - let l:previous_options = l:option . ' ' - continue - endif - - " Check if there was spaces after -D/-I and the flag should not have been splitted - if l:option is# '-D' || l:option is# '-I' - let l:previous_options = l:option - continue - endif - - let l:previous_options = '' - + " Include options, that may need relative path fix + if stridx(l:option, '-I') == 0 + \ || stridx(l:option, '-iquote') == 0 + \ || stridx(l:option, '-isystem') == 0 + \ || stridx(l:option, '-idirafter') == 0 + \ || stridx(l:option, '-iframework') == 0 + if stridx(l:option, '-I') == 0 && l:option isnot# '-I' + let l:arg = join(split(l:option, '\zs')[2:], '') + let l:option = '-I' + else + let l:arg = l:arguments[l:option_index] + let l:option_index = l:option_index + 1 + endif - " Fix relative paths if needed - if stridx(l:option, '-I') >= 0 && - \ stridx(l:option, '-I' . s:sep) < 0 - let l:rel_path = join(split(l:option, '\zs')[2:], '') - let l:rel_path = substitute(l:rel_path, '"', '', 'g') - let l:rel_path = substitute(l:rel_path, '''', '', 'g') - let l:option = ale#Escape('-I' . a:path_prefix . - \ s:sep . l:rel_path) - endif + " Fix relative paths if needed + if !ale#path#IsAbsolute(l:arg) + let l:rel_path = substitute(l:arg, '"', '', 'g') + let l:rel_path = substitute(l:rel_path, '''', '', 'g') + let l:arg = ale#path#GetAbsPath(a:path_prefix, l:rel_path) + endif - " Parse the cflag - if stridx(l:option, '-I') >= 0 || - \ stridx(l:option, '-D') >= 0 - if index(l:cflags_list, l:option) < 0 - call add(l:cflags_list, l:option) + call add(l:items, [1, l:option]) + call add(l:items, [1, ale#Escape(l:arg)]) + " Options with arg that can be grouped with the option or separate + elseif stridx(l:option, '-D') == 0 || stridx(l:option, '-B') == 0 + if l:option is# '-D' || l:option is# '-B' + call add(l:items, [1, l:option]) + call add(l:items, [0, l:arguments[l:option_index]]) + let l:option_index = l:option_index + 1 + else + call add(l:items, [0, l:option]) endif + " Options that have an argument (always separate) + elseif l:option is# '-iprefix' || stridx(l:option, '-iwithprefix') == 0 + \ || l:option is# '-isysroot' || l:option is# '-imultilib' + \ || l:option is# '-include' || l:option is# '-imacros' + call add(l:items, [0, l:option]) + call add(l:items, [0, l:arguments[l:option_index]]) + let l:option_index = l:option_index + 1 + " Options without argument + elseif (stridx(l:option, '-W') == 0 && stridx(l:option, '-Wa,') != 0 && stridx(l:option, '-Wl,') != 0 && stridx(l:option, '-Wp,') != 0) + \ || l:option is# '-w' || stridx(l:option, '-pedantic') == 0 + \ || l:option is# '-ansi' || stridx(l:option, '-std=') == 0 + \ || stridx(l:option, '-f') == 0 && l:option !~# '\v^-f(dump|diagnostics|no-show-column|stack-usage)' + \ || stridx(l:option, '-O') == 0 + \ || l:option is# '-C' || l:option is# '-CC' || l:option is# '-trigraphs' + \ || stridx(l:option, '-nostdinc') == 0 || stridx(l:option, '-iplugindir=') == 0 + \ || stridx(l:option, '--sysroot=') == 0 || l:option is# '--no-sysroot-suffix' + \ || stridx(l:option, '-m') == 0 + call add(l:items, [0, l:option]) endif endwhile - return join(l:cflags_list, ' ') + if a:should_quote + " Quote C arguments that haven't already been quoted above. + " If and only if we've been asked to quote them. + call map(l:items, 'v:val[0] ? v:val[1] : ale#c#QuoteArg(v:val[1])') + else + call map(l:items, 'v:val[1]') + endif + + return join(l:items, ' ') endfunction function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort - if !g:ale_c_parse_makefile - return '' + if !s:CanParseMakefile(a:buffer) + return v:null endif let l:buffer_filename = expand('#' . a:buffer . ':t') @@ -145,17 +228,20 @@ function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort 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) + return ale#c#ParseCFlags(l:makefile_dir, 0, ale#c#ShellSplit(l:cflag_line)) endfunction -" Given a buffer number, find the build subdirectory with compile commands -" The subdirectory is returned without the trailing / +" 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 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. @@ -165,12 +251,42 @@ function! ale#c#FindCompileCommands(buffer) abort let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json' if filereadable(l:json_file) - return l:json_file + return [l:path, l:json_file] endif endfor endfor - return '' + 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 @@ -180,6 +296,10 @@ if !exists('s:compile_commands_cache') let s:compile_commands_cache = {} endif +function! ale#c#ResetCompileCommandsCache() abort + let s:compile_commands_cache = {} +endfunction + function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort let l:empty = [{}, {}] @@ -202,15 +322,30 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort 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 l:raw_data + for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : []) + let l:filename = ale#path#GetAbsPath(l:entry.directory, l:entry.file) + + " Store a key for lookups by the absolute path to the filename. + let l:file_lookup[l:filename] = get(l:file_lookup, l:filename, []) + [l:entry] + + " Store a key for fuzzy lookups by the absolute path to the directory. + let l:dirname = fnamemodify(l:filename, ':h') + let l:dir_lookup[l:dirname] = get(l:dir_lookup, l:dirname, []) + [l:entry] + + " Store a key for fuzzy lookups by just the basename of the file. let l:basename = tolower(fnamemodify(l:entry.file, ':t')) let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry] + " Store a key for fuzzy lookups by just the basename of the directory. let l:dirbasename = tolower(fnamemodify(l:entry.directory, ':p:h:t')) - let l:dir_lookup[l:dirbasename] = get(l:dir_lookup, l:basename, []) + [l:entry] + let l:dir_lookup[l:dirbasename] = get(l:dir_lookup, l:dirbasename, []) + [l:entry] endfor if !empty(l:file_lookup) && !empty(l:dir_lookup) @@ -223,26 +358,113 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort return l:empty endfunction +" Get [should_quote, arguments] from either 'command' or 'arguments' +" 'arguments' should be quoted later, the split 'command' strings should not. +function! s:GetArguments(json_item) abort + if has_key(a:json_item, 'arguments') + return [1, a:json_item.arguments] + elseif has_key(a:json_item, 'command') + return [0, ale#c#ShellSplit(a:json_item.command)] + endif + + return [0, []] +endfunction + function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort + let l:buffer_filename = ale#path#Simplify(expand('#' . a:buffer . ':p')) + let l:basename = tolower(fnamemodify(l:buffer_filename, ':t')) + " Look for any file in the same directory if we can't find an exact match. + let l:dir = fnamemodify(l:buffer_filename, ':h') + " 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, []) + let l:file_list = get(a:file_lookup, l:buffer_filename, []) + + " We may have to look for /foo/bar instead of C:\foo\bar + if empty(l:file_list) && has('win32') + let l:file_list = get( + \ a:file_lookup, + \ ale#path#RemoveDriveLetter(l:buffer_filename), + \ [] + \) + endif + + " Try the absolute path to the directory second. + let l:dir_list = get(a:dir_lookup, l:dir, []) + + if empty(l:dir_list) && has('win32') + let l:dir_list = get( + \ a:dir_lookup, + \ ale#path#RemoveDriveLetter(l:dir), + \ [] + \) + endif + + if empty(l:file_list) && empty(l:dir_list) + " If we can't find matches with the path to the file, try a + " case-insensitive match for any similarly-named file. + let l:file_list = get(a:file_lookup, l:basename, []) + + " If we can't find matches with the path to the directory, try a + " case-insensitive match for anything in similarly-named directory. + let l:dir_list = get(a:dir_lookup, tolower(fnamemodify(l:dir, ':t')), []) + endif + + " 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'] + " Try to find a source file by an absolute path first. + let l:key = fnamemodify(l:buffer_filename, ':r') . l:suffix + let l:file_list = get(a:file_lookup, l:key, []) + + if empty(l:file_list) && has('win32') + let l:file_list = get( + \ a:file_lookup, + \ ale#path#RemoveDriveLetter(l:key), + \ [] + \) + endif + + if empty(l:file_list) + " Look fuzzy matches on the basename second. + let l:key = fnamemodify(l:basename, ':r') . l:suffix + let l:file_list = get(a:file_lookup, l:key, []) + endif + + if !empty(l:file_list) + let l:source_file = l:key + break + endif + endfor + endif for l:item in l:file_list - if bufnr(l:item.file) is a:buffer - return ale#c#ParseCFlags(l:item.directory, l:item.command) + let l:filename = ale#path#GetAbsPath(l:item.directory, l:item.file) + + " Load the flags for this file, or for a source file matching the + " header file. + if ( + \ bufnr(l:filename) is a:buffer + \ || ( + \ !empty(l:source_file) + \ && l:filename[-len(l:source_file):] is? l:source_file + \ ) + \) + let [l:should_quote, l:args] = s:GetArguments(l:item) + + return ale#c#ParseCFlags(l:item.directory, l:should_quote, l:args) 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')) + for l:item in l:dir_list + let l:filename = ale#path#GetAbsPath(l:item.directory, l:item.file) - let l:dirbasename = tolower(expand('#' . a:buffer . ':p:h:t')) - let l:dir_list = get(a:dir_lookup, l:dirbasename, []) + if ale#path#RemoveDriveLetter(fnamemodify(l:filename, ':h')) + \ is? ale#path#RemoveDriveLetter(l:dir) + let [l:should_quote, l:args] = s:GetArguments(l:item) - for l:item in l:dir_list - if ale#path#Simplify(fnamemodify(l:item.file, ':h')) is? l:dir - return ale#c#ParseCFlags(l:item.directory, l:item.command) + return ale#c#ParseCFlags(l:item.directory, l:should_quote, l:args) endif endfor @@ -258,37 +480,61 @@ function! ale#c#FlagsFromCompileCommands(buffer, compile_commands_file) abort endfunction function! ale#c#GetCFlags(buffer, output) abort - let l:cflags = ' ' - - if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output) - let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output) - endif + let l:cflags = v:null if ale#Var(a:buffer, 'c_parse_compile_commands') - let l:json_file = ale#c#FindCompileCommands(a:buffer) + 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# ' ' + if empty(l:cflags) && s:CanParseMakefile(a:buffer) && !empty(a:output) + let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output) + endif + + if l:cflags is v:null let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer)) endif - return l:cflags + 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 s:CanParseMakefile(a:buffer) + let l:path = ale#path#FindNearestFile(a:buffer, 'Makefile') + + if empty(l:path) + let l:path = ale#path#FindNearestFile(a:buffer, 'GNUmakefile') + endif + + if !empty(l:path) + let l:always_make = ale#Var(a:buffer, 'c_always_make') - if !empty(l:makefile_path) - return 'cd '. fnamemodify(l:makefile_path, ':p:h') . ' && make -n' + return [ + \ fnamemodify(l:path, ':h'), + \ 'make -n' . (l:always_make ? ' --always-make' : ''), + \] endif endif - return '' + return ['', ''] +endfunction + +function! ale#c#RunMakeCommand(buffer, Callback) abort + let [l:cwd, 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)}, + \ {'cwd': l:cwd}, + \) endfunction " Given a buffer number, search for a project root, and output a List @@ -339,8 +585,3 @@ function! ale#c#IncludeOptions(include_paths) abort 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/vim-config/plugins/ale/autoload/ale/code_action.vim b/vim-config/plugins/ale/autoload/ale/code_action.vim new file mode 100644 index 00000000..917190be --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/code_action.vim @@ -0,0 +1,411 @@ +" Author: Jerko Steiner +" Description: Code action support for LSP / tsserver + +function! ale#code_action#ReloadBuffer() abort + let l:buffer = bufnr('') + + execute 'augroup ALECodeActionReloadGroup' . l:buffer + autocmd! + augroup END + + silent! execute 'augroup! ALECodeActionReloadGroup' . l:buffer + + call ale#util#Execute(':e!') +endfunction + +function! ale#code_action#HandleCodeAction(code_action, options) abort + let l:current_buffer = bufnr('') + let l:changes = a:code_action.changes + let l:should_save = get(a:options, 'should_save') + + for l:file_code_edit in l:changes + call ale#code_action#ApplyChanges( + \ l:file_code_edit.fileName, + \ l:file_code_edit.textChanges, + \ l:should_save, + \) + endfor +endfunction + +function! s:ChangeCmp(left, right) abort + if a:left.start.line < a:right.start.line + return -1 + endif + + if a:left.start.line > a:right.start.line + return 1 + endif + + if a:left.start.offset < a:right.start.offset + return -1 + endif + + if a:left.start.offset > a:right.start.offset + return 1 + endif + + if a:left.end.line < a:right.end.line + return -1 + endif + + if a:left.end.line > a:right.end.line + return 1 + endif + + if a:left.end.offset < a:right.end.offset + return -1 + endif + + if a:left.end.offset > a:right.end.offset + return 1 + endif + + return 0 +endfunction + +function! ale#code_action#ApplyChanges(filename, changes, should_save) abort + let l:current_buffer = bufnr('') + " The buffer is used to determine the fileformat, if available. + let l:buffer = bufnr(a:filename) + let l:is_current_buffer = l:buffer > 0 && l:buffer == l:current_buffer + + if l:buffer > 0 + let l:lines = getbufline(l:buffer, 1, '$') + + " Add empty line if there's trailing newline, like readfile() does. + if getbufvar(l:buffer, '&eol') + let l:lines += [''] + endif + else + let l:lines = readfile(a:filename, 'b') + endif + + if l:is_current_buffer + let l:pos = getpos('.')[1:2] + else + let l:pos = [1, 1] + endif + + " Changes have to be sorted so we apply them from bottom-to-top + for l:code_edit in reverse(sort(copy(a:changes), function('s:ChangeCmp'))) + let l:line = l:code_edit.start.line + let l:column = l:code_edit.start.offset + let l:end_line = l:code_edit.end.line + let l:end_column = l:code_edit.end.offset + let l:text = l:code_edit.newText + + let l:insertions = split(l:text, '\n', 1) + + " Fix invalid columns + let l:column = l:column > 0 ? l:column : 1 + let l:end_column = l:end_column > 0 ? l:end_column : 1 + + " Clamp start to BOF + if l:line < 1 + let [l:line, l:column] = [1, 1] + endif + + " Clamp start to EOF + if l:line > len(l:lines) || l:line == len(l:lines) && l:column > len(l:lines[-1]) + 1 + let [l:line, l:column] = [len(l:lines), len(l:lines[-1]) + 1] + " Special case when start is after EOL + elseif l:line < len(l:lines) && l:column > len(l:lines[l:line - 1]) + 1 + let [l:line, l:column] = [l:line + 1, 1] + endif + + " Adjust end: clamp if invalid and/or adjust if we moved start + if l:end_line < l:line || l:end_line == l:line && l:end_column < l:column + let [l:end_line, l:end_column] = [l:line, l:column] + endif + + " Clamp end to EOF + if l:end_line > len(l:lines) || l:end_line == len(l:lines) && l:end_column > len(l:lines[-1]) + 1 + let [l:end_line, l:end_column] = [len(l:lines), len(l:lines[-1]) + 1] + " Special case when end is after EOL + elseif l:end_line < len(l:lines) && l:end_column > len(l:lines[l:end_line - 1]) + 1 + let [l:end_line, l:end_column] = [l:end_line + 1, 1] + endif + + " Careful, [:-1] is not an empty list + let l:start = l:line is 1 ? [] : l:lines[: l:line - 2] + let l:middle = l:column is 1 ? [''] : [l:lines[l:line - 1][: l:column - 2]] + + let l:middle[-1] .= l:insertions[0] + let l:middle += l:insertions[1:] + let l:middle[-1] .= l:lines[l:end_line - 1][l:end_column - 1 :] + + let l:end_line_len = len(l:lines[l:end_line - 1]) + let l:lines_before_change = len(l:lines) + let l:lines = l:start + l:middle + l:lines[l:end_line :] + + let l:current_line_offset = len(l:lines) - l:lines_before_change + let l:column_offset = len(l:middle[-1]) - l:end_line_len + + " Keep cursor where it was (if outside of changes) or move it after + " the changed text (if inside), but don't touch it when the change + " spans the entire buffer, in which case we have no clue and it's + " better to not do anything. + if l:line isnot 1 || l:column isnot 1 + \|| l:end_line < l:lines_before_change + \|| l:end_line == l:lines_before_change && l:end_column <= l:end_line_len + let l:pos = s:UpdateCursor(l:pos, + \ [l:line, l:column], + \ [l:end_line, l:end_column], + \ [l:current_line_offset, l:column_offset]) + endif + endfor + + if l:buffer > 0 + " Make sure ale#util#{Writefile,SetBufferContents} add trailing + " newline if and only if it should be added. + if l:lines[-1] is# '' && getbufvar(l:buffer, '&eol') + call remove(l:lines, -1) + else + call setbufvar(l:buffer, '&eol', 0) + endif + elseif exists('+fixeol') && &fixeol && l:lines[-1] is# '' + " Not in buffer, ale#util#Writefile can't check &eol and always adds + " newline if &fixeol: remove to prevent double trailing newline. + call remove(l:lines, -1) + endif + + if a:should_save || l:buffer < 0 + call ale#util#Writefile(l:buffer, l:lines, a:filename) + else + call ale#util#SetBufferContents(l:buffer, l:lines) + endif + + if l:is_current_buffer + if a:should_save + call ale#util#Execute(':e!') + endif + + call setpos('.', [0, l:pos[0], l:pos[1], 0]) + endif + + if a:should_save && l:buffer > 0 && !l:is_current_buffer + " Set up a one-time use event that will delete itself to reload the + " buffer next time it's entered to view the changes made to it. + execute 'augroup ALECodeActionReloadGroup' . l:buffer + autocmd! + + execute printf( + \ 'autocmd BufEnter ' + \ . ' call ale#code_action#ReloadBuffer()', + \ l:buffer + \) + augroup END + endif +endfunction + +function! s:UpdateCursor(cursor, start, end, offset) abort + let l:cur_line = a:cursor[0] + let l:cur_column = a:cursor[1] + let l:line = a:start[0] + let l:column = a:start[1] + let l:end_line = a:end[0] + let l:end_column = a:end[1] + let l:line_offset = a:offset[0] + let l:column_offset = a:offset[1] + + if l:end_line < l:cur_line + " both start and end lines are before the cursor. only line offset + " needs to be updated + let l:cur_line += l:line_offset + elseif l:end_line == l:cur_line + " end line is at the same location as cursor, which means + " l:line <= l:cur_line + if l:line < l:cur_line || l:column <= l:cur_column + " updates are happening either before or around the cursor + if l:end_column < l:cur_column + " updates are happening before the cursor, update the + " column offset for cursor + let l:cur_line += l:line_offset + let l:cur_column += l:column_offset + else + " updates are happening around the cursor, move the cursor + " to the end of the changes + let l:cur_line += l:line_offset + let l:cur_column = l:end_column + l:column_offset + endif + " else is not necessary, it means modifications are happening + " after the cursor so no cursor updates need to be done + endif + else + " end line is after the cursor + if l:line < l:cur_line || l:line == l:cur_line && l:column <= l:cur_column + " changes are happening around the cursor, move the cursor + " to the end of the changes + let l:cur_line = l:end_line + l:line_offset + let l:cur_column = l:end_column + l:column_offset + " else is not necesary, it means modifications are happening + " after the cursor so no cursor updates need to be done + endif + endif + + return [l:cur_line, l:cur_column] +endfunction + +function! ale#code_action#GetChanges(workspace_edit) abort + if a:workspace_edit is v:null + return {} + endif + + let l:changes = {} + + if has_key(a:workspace_edit, 'changes') && !empty(a:workspace_edit.changes) + return a:workspace_edit.changes + elseif has_key(a:workspace_edit, 'documentChanges') + let l:document_changes = [] + + if type(a:workspace_edit.documentChanges) is v:t_dict + \ && has_key(a:workspace_edit.documentChanges, 'edits') + call add(l:document_changes, a:workspace_edit.documentChanges) + elseif type(a:workspace_edit.documentChanges) is v:t_list + let l:document_changes = a:workspace_edit.documentChanges + endif + + for l:text_document_edit in l:document_changes + let l:filename = l:text_document_edit.textDocument.uri + let l:edits = l:text_document_edit.edits + let l:changes[l:filename] = l:edits + endfor + endif + + return l:changes +endfunction + +function! ale#code_action#BuildChangesList(changes_map) abort + let l:changes = [] + + for l:file_name in keys(a:changes_map) + let l:text_edits = a:changes_map[l:file_name] + let l:text_changes = [] + + for l:edit in l:text_edits + let l:range = l:edit.range + let l:new_text = l:edit.newText + + call add(l:text_changes, { + \ 'start': { + \ 'line': l:range.start.line + 1, + \ 'offset': l:range.start.character + 1, + \ }, + \ 'end': { + \ 'line': l:range.end.line + 1, + \ 'offset': l:range.end.character + 1, + \ }, + \ 'newText': l:new_text, + \}) + endfor + + call add(l:changes, { + \ 'fileName': ale#path#FromURI(l:file_name), + \ 'textChanges': l:text_changes, + \}) + endfor + + return l:changes +endfunction + +function! s:EscapeMenuName(text) abort + return substitute(a:text, '\\\| \|\.\|&', '\\\0', 'g') +endfunction + +function! s:UpdateMenu(data, menu_items) abort + silent! aunmenu PopUp.Refactor\.\.\. + + if empty(a:data) + return + endif + + for [l:type, l:item] in a:menu_items + let l:name = l:type is# 'tsserver' ? l:item.name : l:item.title + let l:func_name = l:type is# 'tsserver' + \ ? 'ale#codefix#ApplyTSServerCodeAction' + \ : 'ale#codefix#ApplyLSPCodeAction' + + execute printf( + \ 'anoremenu PopUp.&Refactor\.\.\..%s' + \ . ' :call %s(%s, %s)', + \ s:EscapeMenuName(l:name), + \ l:func_name, + \ string(a:data), + \ string(l:item), + \) + endfor + + if empty(a:menu_items) + silent! anoremenu PopUp.Refactor\.\.\..(None) :silent + endif +endfunction + +function! s:GetCodeActions(linter, options) 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:location = { + \ 'buffer': l:buffer, + \ 'line': l:line, + \ 'column': l:column, + \ 'end_line': l:line, + \ 'end_column': l:column, + \} + let l:Callback = function('s:OnReady', [l:location, a:options]) + call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) +endfunction + +function! ale#code_action#GetCodeActions(options) abort + silent! aunmenu PopUp.Rename + silent! aunmenu PopUp.Refactor\.\.\. + + " Only display the menu items if there's an LSP server. + let l:has_lsp = 0 + + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + let l:has_lsp = 1 + + break + endif + endfor + + if l:has_lsp + if !empty(expand('')) + silent! anoremenu PopUp.Rename :ALERename + endif + + silent! anoremenu PopUp.Refactor\.\.\..(None) :silent + + call ale#codefix#Execute( + \ mode() is# 'v' || mode() is# "\", + \ function('s:UpdateMenu') + \) + endif +endfunction + +function! s:Setup(enabled) abort + augroup ALECodeActionsGroup + autocmd! + + if a:enabled + autocmd MenuPopup * :call ale#code_action#GetCodeActions({}) + endif + augroup END + + if !a:enabled + silent! augroup! ALECodeActionsGroup + + silent! aunmenu PopUp.Rename + silent! aunmenu PopUp.Refactor\.\.\. + endif +endfunction + +function! ale#code_action#EnablePopUpMenu() abort + call s:Setup(1) +endfunction + +function! ale#code_action#DisablePopUpMenu() abort + call s:Setup(0) +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/codefix.vim b/vim-config/plugins/ale/autoload/ale/codefix.vim new file mode 100644 index 00000000..853ee4e8 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/codefix.vim @@ -0,0 +1,497 @@ +" Author: Dalius Dobravolskas +" Description: Code Fix support for tsserver and LSP servers + +let s:codefix_map = {} + +" Used to get the codefix map in tests. +function! ale#codefix#GetMap() abort + return deepcopy(s:codefix_map) +endfunction + +" Used to set the codefix map in tests. +function! ale#codefix#SetMap(map) abort + let s:codefix_map = a:map +endfunction + +function! ale#codefix#ClearLSPData() abort + let s:codefix_map = {} +endfunction + +function! s:message(message) abort + call ale#util#Execute('echom ' . string(a:message)) +endfunction + +function! ale#codefix#ApplyTSServerCodeAction(data, item) abort + if has_key(a:item, 'changes') + let l:changes = a:item.changes + + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'codefix', + \ 'changes': l:changes, + \ }, + \ {}, + \) + else + let l:message = ale#lsp#tsserver_message#GetEditsForRefactor( + \ a:data.buffer, + \ a:data.line, + \ a:data.column, + \ a:data.end_line, + \ a:data.end_column, + \ a:item.id[0], + \ a:item.id[1], + \) + + let l:request_id = ale#lsp#Send(a:data.connection_id, l:message) + + let s:codefix_map[l:request_id] = a:data + endif +endfunction + +function! ale#codefix#HandleTSServerResponse(conn_id, response) abort + if !has_key(a:response, 'request_seq') + \ || !has_key(s:codefix_map, a:response.request_seq) + return + endif + + let l:data = remove(s:codefix_map, a:response.request_seq) + let l:MenuCallback = get(l:data, 'menu_callback', v:null) + + if get(a:response, 'command', '') is# 'getCodeFixes' + if get(a:response, 'success', v:false) is v:false + \&& l:MenuCallback is v:null + let l:message = get(a:response, 'message', 'unknown') + call s:message('Error while getting code fixes. Reason: ' . l:message) + + return + endif + + let l:result = get(a:response, 'body', []) + call filter(l:result, 'has_key(v:val, ''changes'')') + + if l:MenuCallback isnot v:null + call l:MenuCallback( + \ l:data, + \ map(copy(l:result), '[''tsserver'', v:val]') + \) + + return + endif + + if len(l:result) == 0 + call s:message('No code fixes available.') + + return + endif + + let l:code_fix_to_apply = 0 + + if len(l:result) == 1 + let l:code_fix_to_apply = 1 + else + let l:codefix_no = 1 + let l:codefixstring = "Code Fixes:\n" + + for l:codefix in l:result + let l:codefixstring .= l:codefix_no . ') ' + \ . l:codefix.description . "\n" + let l:codefix_no += 1 + endfor + + let l:codefixstring .= 'Type number and (empty cancels): ' + + let l:code_fix_to_apply = ale#util#Input(l:codefixstring, '') + let l:code_fix_to_apply = str2nr(l:code_fix_to_apply) + + if l:code_fix_to_apply == 0 + return + endif + endif + + call ale#codefix#ApplyTSServerCodeAction( + \ l:data, + \ l:result[l:code_fix_to_apply - 1], + \) + elseif get(a:response, 'command', '') is# 'getApplicableRefactors' + if get(a:response, 'success', v:false) is v:false + \&& l:MenuCallback is v:null + let l:message = get(a:response, 'message', 'unknown') + call s:message('Error while getting applicable refactors. Reason: ' . l:message) + + return + endif + + let l:result = get(a:response, 'body', []) + + if len(l:result) == 0 + call s:message('No applicable refactors available.') + + return + endif + + let l:refactors = [] + + for l:item in l:result + for l:action in l:item.actions + call add(l:refactors, { + \ 'name': l:action.description, + \ 'id': [l:item.name, l:action.name], + \}) + endfor + endfor + + if l:MenuCallback isnot v:null + call l:MenuCallback( + \ l:data, + \ map(copy(l:refactors), '[''tsserver'', v:val]') + \) + + return + endif + + let l:refactor_no = 1 + let l:refactorstring = "Applicable refactors:\n" + + for l:refactor in l:refactors + let l:refactorstring .= l:refactor_no . ') ' + \ . l:refactor.name . "\n" + let l:refactor_no += 1 + endfor + + let l:refactorstring .= 'Type number and (empty cancels): ' + + let l:refactor_to_apply = ale#util#Input(l:refactorstring, '') + let l:refactor_to_apply = str2nr(l:refactor_to_apply) + + if l:refactor_to_apply == 0 + return + endif + + let l:id = l:refactors[l:refactor_to_apply - 1].id + + call ale#codefix#ApplyTSServerCodeAction( + \ l:data, + \ l:refactors[l:refactor_to_apply - 1], + \) + elseif get(a:response, 'command', '') is# 'getEditsForRefactor' + if get(a:response, 'success', v:false) is v:false + let l:message = get(a:response, 'message', 'unknown') + call s:message('Error while getting edits for refactor. Reason: ' . l:message) + + return + endif + + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'editsForRefactor', + \ 'changes': a:response.body.edits, + \ }, + \ {}, + \) + endif +endfunction + +function! ale#codefix#ApplyLSPCodeAction(data, item) abort + if has_key(a:item, 'command') + \&& type(a:item.command) == v:t_dict + let l:command = a:item.command + let l:message = ale#lsp#message#ExecuteCommand( + \ l:command.command, + \ l:command.arguments, + \) + + let l:request_id = ale#lsp#Send(a:data.connection_id, l:message) + elseif has_key(a:item, 'command') && has_key(a:item, 'arguments') + \&& type(a:item.command) == v:t_string + let l:message = ale#lsp#message#ExecuteCommand( + \ a:item.command, + \ a:item.arguments, + \) + + let l:request_id = ale#lsp#Send(a:data.connection_id, l:message) + elseif has_key(a:item, 'edit') || has_key(a:item, 'arguments') + if has_key(a:item, 'edit') + let l:topass = a:item.edit + else + let l:topass = a:item.arguments[0] + endif + + let l:changes_map = ale#code_action#GetChanges(l:topass) + + if empty(l:changes_map) + return + endif + + let l:changes = ale#code_action#BuildChangesList(l:changes_map) + + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'codeaction', + \ 'changes': l:changes, + \ }, + \ {}, + \) + endif +endfunction + +function! ale#codefix#HandleLSPResponse(conn_id, response) abort + if has_key(a:response, 'method') + \ && a:response.method is# 'workspace/applyEdit' + \ && has_key(a:response, 'params') + let l:params = a:response.params + + let l:changes_map = ale#code_action#GetChanges(l:params.edit) + + if empty(l:changes_map) + return + endif + + let l:changes = ale#code_action#BuildChangesList(l:changes_map) + + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'applyEdit', + \ 'changes': l:changes, + \ }, + \ {} + \) + elseif has_key(a:response, 'id') + \&& has_key(s:codefix_map, a:response.id) + let l:data = remove(s:codefix_map, a:response.id) + let l:MenuCallback = get(l:data, 'menu_callback', v:null) + + let l:result = get(a:response, 'result') + + if type(l:result) != v:t_list + let l:result = [] + endif + + " Send the results to the menu callback, if set. + if l:MenuCallback isnot v:null + call l:MenuCallback( + \ l:data, + \ map(copy(l:result), '[''lsp'', v:val]') + \) + + return + endif + + if len(l:result) == 0 + call s:message('No code actions received from server') + + return + endif + + let l:codeaction_no = 1 + let l:codeactionstring = "Code Fixes:\n" + + for l:codeaction in l:result + let l:codeactionstring .= l:codeaction_no . ') ' + \ . l:codeaction.title . "\n" + let l:codeaction_no += 1 + endfor + + let l:codeactionstring .= 'Type number and (empty cancels): ' + + let l:codeaction_to_apply = ale#util#Input(l:codeactionstring, '') + let l:codeaction_to_apply = str2nr(l:codeaction_to_apply) + + if l:codeaction_to_apply == 0 + return + endif + + let l:item = l:result[l:codeaction_to_apply - 1] + + call ale#codefix#ApplyLSPCodeAction(l:data, l:item) + endif +endfunction + +function! s:FindError(buffer, line, column, end_line, end_column, linter_name) abort + let l:nearest_error = v:null + + if a:line == a:end_line + \&& a:column == a:end_column + \&& has_key(g:ale_buffer_info, a:buffer) + let l:nearest_error_diff = -1 + + for l:error in get(g:ale_buffer_info[a:buffer], 'loclist', []) + if has_key(l:error, 'code') + \ && (a:linter_name is v:null || l:error.linter_name is# a:linter_name) + \ && l:error.lnum == a:line + let l:diff = abs(l:error.col - a:column) + + if l:nearest_error_diff == -1 || l:diff < l:nearest_error_diff + let l:nearest_error_diff = l:diff + let l:nearest_error = l:error + endif + endif + endfor + endif + + return l:nearest_error +endfunction + +function! s:OnReady( +\ line, +\ column, +\ end_line, +\ end_column, +\ MenuCallback, +\ linter, +\ lsp_details, +\) abort + let l:id = a:lsp_details.connection_id + + if !ale#lsp#HasCapability(l:id, 'code_actions') + return + endif + + let l:buffer = a:lsp_details.buffer + + if a:linter.lsp is# 'tsserver' + let l:nearest_error = + \ s:FindError(l:buffer, a:line, a:column, a:end_line, a:end_column, a:linter.lsp) + + if l:nearest_error isnot v:null + let l:message = ale#lsp#tsserver_message#GetCodeFixes( + \ l:buffer, + \ a:line, + \ a:column, + \ a:line, + \ a:column, + \ [l:nearest_error.code], + \) + else + let l:message = ale#lsp#tsserver_message#GetApplicableRefactors( + \ l:buffer, + \ a:line, + \ a:column, + \ a:end_line, + \ a:end_column, + \) + endif + 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) + + let l:diagnostics = [] + let l:nearest_error = + \ s:FindError(l:buffer, a:line, a:column, a:end_line, a:end_column, v:null) + + if l:nearest_error isnot v:null + let l:diagnostics = [ + \ { + \ 'code': l:nearest_error.code, + \ 'message': l:nearest_error.text, + \ 'range': { + \ 'start': { + \ 'line': l:nearest_error.lnum - 1, + \ 'character': l:nearest_error.col - 1, + \ }, + \ 'end': { + \ 'line': l:nearest_error.end_lnum - 1, + \ 'character': l:nearest_error.end_col, + \ }, + \ }, + \ }, + \] + endif + + let l:message = ale#lsp#message#CodeAction( + \ l:buffer, + \ a:line, + \ a:column, + \ a:end_line, + \ a:end_column, + \ l:diagnostics, + \) + endif + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#codefix#HandleTSServerResponse') + \ : function('ale#codefix#HandleLSPResponse') + + call ale#lsp#RegisterCallback(l:id, l:Callback) + + let l:request_id = ale#lsp#Send(l:id, l:message) + + let s:codefix_map[l:request_id] = { + \ 'connection_id': l:id, + \ 'buffer': l:buffer, + \ 'line': a:line, + \ 'column': a:column, + \ 'end_line': a:end_line, + \ 'end_column': a:end_column, + \ 'menu_callback': a:MenuCallback, + \} +endfunction + +function! s:ExecuteGetCodeFix(linter, range, MenuCallback) abort + let l:buffer = bufnr('') + + if a:range == 0 + let [l:line, l:column] = getpos('.')[1:2] + let l:end_line = l:line + let l:end_column = l:column + + " Expand the range to cover the current word, if there is one. + let l:cword = expand('') + + if !empty(l:cword) + let l:search_pos = searchpos('\V' . l:cword, 'bn', l:line) + + if l:search_pos != [0, 0] + let l:column = l:search_pos[1] + let l:end_column = l:column + len(l:cword) - 1 + endif + endif + elseif mode() is# 'v' || mode() is# "\" + " You need to get the start and end in a different way when you're in + " visual mode. + let [l:line, l:column] = getpos('v')[1:2] + let [l:end_line, l:end_column] = getpos('.')[1:2] + else + let [l:line, l:column] = getpos("'<")[1:2] + let [l:end_line, l:end_column] = getpos("'>")[1:2] + endif + + let l:column = min([l:column, len(getline(l:line))]) + let l:end_column = min([l:end_column, len(getline(l:end_line))]) + + let l:Callback = function( + \ 's:OnReady', [l:line, l:column, l:end_line, l:end_column, a:MenuCallback] + \) + + call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) +endfunction + +function! ale#codefix#Execute(range, ...) abort + if a:0 > 1 + throw 'Too many arguments' + endif + + let l:MenuCallback = get(a:000, 0, v:null) + let l:lsp_linters = [] + + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + call add(l:lsp_linters, l:linter) + endif + endfor + + if empty(l:lsp_linters) + if l:MenuCallback is v:null + call s:message('No active LSPs') + else + call l:MenuCallback({}, []) + endif + + return + endif + + for l:lsp_linter in l:lsp_linters + call s:ExecuteGetCodeFix(l:lsp_linter, a:range, l:MenuCallback) + endfor +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/command.vim b/vim-config/plugins/ale/autoload/ale/command.vim old mode 100755 new mode 100644 index 6c56d518..c9dc8d94 --- a/vim-config/plugins/ale/autoload/ale/command.vim +++ b/vim-config/plugins/ale/autoload/ale/command.vim @@ -1,6 +1,133 @@ " Author: w0rp -" Description: Special command formatting for creating temporary files and -" passing buffer filenames easily. +" 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 + +" The regular expression used for formatting filenames with modifiers. +let s:path_format_regex = '\v\%s(%(:h|:t|:r|:e)*)' + +" 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 + +" Set the cwd for commands that are about to run. +" Used internally. +function! ale#command#SetCwd(buffer, cwd) abort + call ale#command#InitData(a:buffer) + let s:buffer_data[a:buffer].cwd = a:cwd +endfunction + +function! ale#command#ResetCwd(buffer) abort + if has_key(s:buffer_data, a:buffer) + let s:buffer_data[a:buffer].cwd = v:null + 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') @@ -16,14 +143,68 @@ function! s:TemporaryFilename(buffer) abort 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 + +" Format a filename, converting it with filename mappings, if non-empty, +" and escaping it for putting into a command string. +" +" The filename can be modified. +function! s:FormatFilename(filename, mappings, modifiers) abort + let l:filename = a:filename + + if !empty(a:mappings) + let l:filename = ale#filename_mapping#Map(l:filename, a:mappings) + endif + + if !empty(a:modifiers) + let l:filename = fnamemodify(l:filename, a:modifiers) + endif + + return ale#Escape(l:filename) +endfunction + +" Produce a command prefix to check to a particular directory for a command. +" %s format markers with filename-modifiers can be used as the directory, and +" will be returned verbatim for formatting in paths relative to files. +function! ale#command#CdString(directory) abort + let l:match = matchstrpos(a:directory, s:path_format_regex) + " Do not escape the directory here if it's a valid format string. + " This allows us to use sequences like %s:h, %s:h:h, etc. + let l:directory = l:match[1:] == [0, len(a:directory)] + \ ? a:directory + \ : ale#Escape(a:directory) + + if has('win32') + return 'cd /d ' . l:directory . ' && ' + endif + + return 'cd ' . l:directory . ' && ' +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, CreateTemporaryFileForJob) abort +function! ale#command#FormatCommand( +\ buffer, +\ executable, +\ command, +\ pipe_file_if_needed, +\ input, +\ cwd, +\ mappings, +\) abort let l:temporary_file = '' let l:command = a:command + if !empty(a:cwd) + let l:command = ale#command#CdString(a:cwd) . l:command + endif + " First replace all uses of %%, used for literal percent characters, " with an ugly string. let l:command = substitute(l:command, '%%', '<>', 'g') @@ -37,14 +218,24 @@ function! ale#command#FormatCommand(buffer, executable, command, pipe_file_if_ne " 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') + let l:command = substitute( + \ l:command, + \ s:path_format_regex, + \ '\=s:FormatFilename(l:filename, a:mappings, submatch(1))', + \ 'g' + \) endif - if l:command =~# '%t' + 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') + let l:command = substitute( + \ l:command, + \ '\v\%t(%(:h|:t|:r|:e)*)', + \ '\=s:FormatFilename(l:temporary_file, a:mappings, submatch(1))', + \ 'g' + \) endif " Finish formatting so %% becomes %. @@ -58,7 +249,225 @@ function! ale#command#FormatCommand(buffer, executable, command, pipe_file_if_ne let l:command = l:command . ' < ' . ale#Escape(l:temporary_file) endif - let l:file_created = a:CreateTemporaryFileForJob(a:buffer, l:temporary_file) + 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 + + " Set the default cwd for this buffer in this call stack. + call ale#command#SetCwd(a:buffer, l:result.cwd) + + try + if get(l:result, 'result_callback', v:null) isnot v:null + call call(l:result.result_callback, [l:value]) + endif + finally + call ale#command#ResetCwd(a:buffer) + endtry +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:cwd = get(l:options, 'cwd', v:null) + + if l:cwd is v:null + " Default the working directory to whatever it was for the last + " command run in the chain. + let l:cwd = get(get(s:buffer_data, a:buffer, {}), 'cwd', v:null) + endif + + 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), + \ l:cwd, + \ get(l:options, 'filename_mappings', []), + \) + 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 cwd is kept and used as the default value for the next command in + " the chain. + " + " The original command here is used in tests. + let l:result = { + \ '_deferred_job_id': l:job_id, + \ 'executable': get(l:options, 'executable', ''), + \ 'cwd': l:cwd, + \ '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/vim-config/plugins/ale/autoload/ale/completion.vim b/vim-config/plugins/ale/autoload/ale/completion.vim old mode 100755 new mode 100644 index 9baf29fd..e139feaa --- a/vim-config/plugins/ale/autoload/ale/completion.vim +++ b/vim-config/plugins/ale/autoload/ale/completion.vim @@ -1,10 +1,11 @@ " Author: w0rp " Description: Completion support for LSP linters +scriptencoding utf-8 " 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) +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() @@ -15,29 +16,111 @@ 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 g:ale_completion_autoimport = get(g:, 'ale_completion_autoimport', 0) +let g:ale_completion_tsserver_remove_warnings = get(g:, 'ale_completion_tsserver_remove_warnings', 0) 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 g:ale_lsp_types = { +\ 1: 'text', +\ 2: 'method', +\ 3: 'function', +\ 4: 'constructor', +\ 5: 'field', +\ 6: 'variable', +\ 7: 'class', +\ 8: 'interface', +\ 9: 'module', +\ 10: 'property', +\ 11: 'unit', +\ 12: 'value', +\ 13: 'enum', +\ 14: 'keyword', +\ 15: 'snippet', +\ 16: 'color', +\ 17: 'file', +\ 18: 'reference', +\ 19: 'folder', +\ 20: 'enum_member', +\ 21: 'constant', +\ 22: 'struct', +\ 23: 'event', +\ 24: 'operator', +\ 25: 'type_parameter', +\ } + +" from https://github.com/microsoft/TypeScript/blob/29becf05012bfa7ba20d50b0d16813971e46b8a6/lib/protocol.d.ts#L2472 +let g:ale_tsserver_types = { +\ 'warning': 'text', +\ 'keyword': 'keyword', +\ 'script': 'file', +\ 'module': 'module', +\ 'class': 'class', +\ 'local class': 'class', +\ 'interface': 'interface', +\ 'type': 'class', +\ 'enum': 'enum', +\ 'enum member': 'enum_member', +\ 'var': 'variable', +\ 'local var': 'variable', +\ 'function': 'function', +\ 'local function': 'function', +\ 'method': 'method', +\ 'getter': 'property', +\ 'setter': 'method', +\ 'property': 'property', +\ 'constructor': 'constructor', +\ 'call': 'method', +\ 'index': 'index', +\ 'construct': 'constructor', +\ 'parameter': 'parameter', +\ 'type parameter': 'type_parameter', +\ 'primitive type': 'unit', +\ 'label': 'text', +\ 'alias': 'class', +\ 'const': 'constant', +\ 'let': 'variable', +\ 'directory': 'folder', +\ 'external module name': 'text', +\ 'JSX attribute': 'parameter', +\ 'string': 'text' +\ } + +" For compatibility reasons, we only use built in VIM completion kinds +" See :help complete-items for Vim completion kinds +let g:ale_completion_symbols = get(g:, 'ale_completion_symbols', { +\ 'text': 'v', +\ 'method': 'f', +\ 'function': 'f', +\ 'constructor': 'f', +\ 'field': 'm', +\ 'variable': 'v', +\ 'class': 't', +\ 'interface': 't', +\ 'module': 'd', +\ 'property': 'm', +\ 'unit': 'v', +\ 'value': 'v', +\ 'enum': 't', +\ 'keyword': 'v', +\ 'snippet': 'v', +\ 'color': 'v', +\ 'file': 'v', +\ 'reference': 'v', +\ 'folder': 'v', +\ 'enum_member': 'm', +\ 'constant': 'm', +\ 'struct': 't', +\ 'event': 'v', +\ 'operator': 'f', +\ 'type_parameter': 'p', +\ '': 'v' +\ }) + +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]*$' @@ -49,6 +132,7 @@ let s:should_complete_map = { \ 'lisp': s:lisp_regex, \ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$', \ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$', +\ 'cpp': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$|-\>$', \} " Regular expressions for finding the start column to replace with completion. @@ -56,11 +140,13 @@ let s:omni_start_map = { \ '': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$', \} -" A map of exact characters for triggering LSP completions. +" A map of exact characters for triggering LSP completions. Do not forget to +" update self.input_patterns in ale.py in updating entries in this map. let s:trigger_character_map = { \ '': ['.'], \ 'typescript': ['.', '''', '"'], \ 'rust': ['.', '::'], +\ 'cpp': ['.', '::', '->'], \} function! s:GetFiletypeValue(map, filetype) abort @@ -102,7 +188,13 @@ function! ale#completion#GetTriggerCharacter(filetype, prefix) abort return '' endfunction -function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort +function! ale#completion#Filter( +\ buffer, +\ filetype, +\ suggestions, +\ prefix, +\ exact_prefix_match, +\) abort let l:excluded_words = ale#Var(a:buffer, 'completion_excluded_words') if empty(a:prefix) @@ -129,10 +221,17 @@ function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort " 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) + if a:exact_prefix_match + " Add suggestions if the word is an exact match. + if l:word is# a:prefix + call add(l:filtered_suggestions, l:item) + endif + else + " 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 endif endfor endif @@ -155,7 +254,7 @@ function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort return l:filtered_suggestions endfunction -function! s:ReplaceCompletionOptions() abort +function! s:ReplaceCompletionOptions(source) abort " Remember the old omnifunc value, if there is one. " If we don't store an old one, we'll just never reset the option. " This will stop some random exceptions from appearing. @@ -163,16 +262,26 @@ function! s:ReplaceCompletionOptions() abort let b:ale_old_omnifunc = &l:omnifunc endif - let &l:omnifunc = 'ale#completion#OmniFunc' + let &l:omnifunc = 'ale#completion#AutomaticOmniFunc' - if !exists('b:ale_old_completopt') - let b:ale_old_completopt = &l:completeopt - endif + if a: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' + let l:opt_list = split(&l:completeopt, ',') + " The menu and noinsert options must be set, or automatic completion + " will be annoying. + let l:new_opt_list = ['menu', 'menuone', 'noinsert'] + + " Permit some other completion options, provided users have set them. + for l:opt in ['preview', 'popup', 'noselect'] + if index(l:opt_list, l:opt) >= 0 + call add(l:new_opt_list, l:opt) + endif + endfor + + let &l:completeopt = join(l:new_opt_list, ',') endif endfunction @@ -186,70 +295,165 @@ function! ale#completion#RestoreCompletionOptions() abort unlet b:ale_old_omnifunc endif - if exists('b:ale_old_completopt') - let &l:completeopt = b:ale_old_completopt - unlet b:ale_old_completopt + if exists('b:ale_old_completeopt') + let &l:completeopt = b:ale_old_completeopt + unlet b:ale_old_completeopt endif endfunction -function! ale#completion#OmniFunc(findstart, base) abort - if a:findstart - let l:line = b:ale_completion_info.line - let l:column = b:ale_completion_info.column - let l:regex = s: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) +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 + return l:column - len(l:match) - 1 +endfunction + +function! ale#completion#GetCompletionPositionForDeoplete(input) abort + return match(a:input, '\k*$') +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 - " Parse a new response if there is one. - if exists('b:ale_completion_response') - \&& exists('b:ale_completion_parser') - let l:response = b:ale_completion_response - let l:parser = b:ale_completion_parser + let l:result = ale#completion#GetCompletionResult() - unlet b:ale_completion_response - unlet b:ale_completion_parser + let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '') - let b:ale_completion_result = function(l:parser)(l:response) + if l:source is# 'ale-automatic' || l:source is# 'ale-manual' + call s:ReplaceCompletionOptions(l:source) endif - call s:ReplaceCompletionOptions() + return l:result isnot v:null ? l:result : [] + endif +endfunction - return get(b:, 'ale_completion_result', []) +function! s:OpenCompletionMenu(...) abort + if !&l:paste + call ale#util#FeedKeys("\(ale_show_completion_menu)") endif endfunction -function! ale#completion#Show(response, completion_parser) abort - if ale#util#Mode() isnot# 'i' +function! ale#completion#Show(result) abort + let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '') + + if ale#util#Mode() isnot# 'i' && l:source isnot# 'ale-import' + return + endif + + " Set the list in the buffer. + 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) + if l:source is# 'ale-import' + " If we ran completion from :ALEImport, + " tell the user that nothing is going to happen. + call s:message('No possible imports found.') + endif + return endif - " Set the list in the buffer, temporarily replace omnifunc with our - " function, and then start omni-completion. - let b:ale_completion_response = a:response - let b:ale_completion_parser = a:completion_parser " Replace completion options shortly before opening the menu. - call s:ReplaceCompletionOptions() + if l:source is# 'ale-automatic' || l:source is# 'ale-manual' + call s:ReplaceCompletionOptions(l:source) + + call timer_start(0, function('s:OpenCompletionMenu')) + endif + + if l:source is# 'ale-callback' + call b:CompleteCallback(b:ale_completion_result) + endif + + if l:source is# 'ale-import' + call ale#completion#HandleUserData(b:ale_completion_result[0]) + + let l:text_changed = '' . g:ale_lint_on_text_changed + + " Check the buffer again right away, if linting is enabled. + if g:ale_enabled + \&& ( + \ l:text_changed is# '1' + \ || l:text_changed is# 'always' + \ || l:text_changed is# 'normal' + \ || l:text_changed is# 'insert' + \) + call ale#Queue(0, '') + endif + endif +endfunction + +function! ale#completion#GetAllTriggers() abort + return deepcopy(s:trigger_character_map) +endfunction + +function! ale#completion#GetCompletionKind(kind) abort + let l:lsp_symbol = get(g:ale_lsp_types, a:kind, '') - call timer_start(0, {-> ale#util#FeedKeys("\(ale_show_completion_menu)")}) + if !empty(l:lsp_symbol) + return l:lsp_symbol + endif + + return get(g:ale_tsserver_types, a:kind, '') +endfunction + +function! ale#completion#GetCompletionSymbols(kind) abort + let l:kind = ale#completion#GetCompletionKind(a:kind) + let l:symbol = get(g:ale_completion_symbols, l:kind, '') + + if !empty(l:symbol) + return l:symbol + endif + + return get(g:ale_completion_symbols, '', 'v') endfunction function! s:CompletionStillValid(request_id) abort - let [l:line, l:column] = getcurpos()[1:2] + let [l:line, l:column] = getpos('.')[1:2] - return ale#util#Mode() is# 'i' - \&& has_key(b:, 'ale_completion_info') + return has_key(b:, 'ale_completion_info') + \&& ( + \ ale#util#Mode() is# 'i' + \ || b:ale_completion_info.source is# 'ale-import' + \) \&& 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.column == l:column + \ || b:ale_completion_info.source is# 'ale-omnifunc' + \ || b:ale_completion_info.source is# 'ale-callback' + \ || b:ale_completion_info.source is# 'ale-import' + \) endfunction function! ale#completion#ParseTSServerCompletions(response) abort let l:names = [] for l:suggestion in a:response.body - call add(l:names, l:suggestion.name) + let l:kind = get(l:suggestion, 'kind', '') + + if g:ale_completion_tsserver_remove_warnings == 0 || l:kind isnot# 'warning' + call add(l:names, { + \ 'word': l:suggestion.name, + \ 'source': get(l:suggestion, 'source', ''), + \}) + endif endfor return l:names @@ -259,11 +463,26 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort let l:buffer = bufnr('') let l:results = [] let l:names_with_details = [] + let l:info = get(b:, 'ale_completion_info', {}) for l:suggestion in a:response.body let l:displayParts = [] + let l:local_name = v:null + + for l:action in get(l:suggestion, 'codeActions', []) + call add(l:displayParts, l:action.description . ' ') + endfor for l:part in l:suggestion.displayParts + " Stop on stop on line breaks for the menu. + if get(l:part, 'kind') is# 'lineBreak' + break + endif + + if get(l:part, 'kind') is# 'localName' + let l:local_name = l:part.text + endif + call add(l:displayParts, l:part.text) endfor @@ -274,22 +493,37 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort 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, + let l:result = { + \ 'word': ( + \ l:suggestion.name is# 'default' + \ && l:suggestion.kind is# 'alias' + \ && !empty(l:local_name) + \ ? l:local_name + \ : l:suggestion.name + \ ), + \ 'kind': ale#completion#GetCompletionSymbols(l:suggestion.kind), \ 'icase': 1, \ 'menu': join(l:displayParts, ''), + \ 'dup': get(l:info, 'additional_edits_only', 0) + \ || g:ale_completion_autoimport, \ 'info': join(l:documentationParts, ''), - \}) + \} + " This flag is used to tell if this completion came from ALE or not. + let l:user_data = {'_ale_completion_item': 1} + + if has_key(l:suggestion, 'codeActions') + let l:user_data.code_actions = l:suggestion.codeActions + endif + + let l:result.user_data = json_encode(l:user_data) + + " Include this item if we'll accept any items, + " or if we only want items with additional edits, and this has them. + if !get(l:info, 'additional_edits_only', 0) + \|| has_key(l:user_data, 'code_actions') + call add(l:results, l:result) + endif endfor let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', []) @@ -298,16 +532,17 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort 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', + \ 'index(l:names_with_details, v:val.word) < 0', \) for l:name in l:missing_names call add(l:results, { - \ 'word': l:name, + \ 'word': l:name.word, \ 'kind': 'v', \ 'icase': 1, \ 'menu': '', \ 'info': '', + \ 'user_data': json_encode({'_ale_completion_item': 1}), \}) endfor endif @@ -316,7 +551,7 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort endfunction function! ale#completion#NullFilter(buffer, item) abort - return 1 + return 1 endfunction function! ale#completion#ParseLSPCompletions(response) abort @@ -346,27 +581,29 @@ function! ale#completion#ParseLSPCompletions(response) abort continue endif - let l:word = matchstr(l:item.label, '\v^[^(]+') + 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' + " Don't use LSP items with additional text edits when autoimport for + " completions is turned off. + if !empty(get(l:item, 'additionalTextEdits')) + \&& !( + \ get(l:info, 'additional_edits_only', 0) + \ || g:ale_completion_autoimport + \) + continue endif let l:doc = get(l:item, 'documentation', '') @@ -375,20 +612,73 @@ function! ale#completion#ParseLSPCompletions(response) abort let l:doc = l:doc.value endif - call add(l:results, { + " Collapse whitespaces and line breaks into a single space. + let l:detail = substitute(get(l:item, 'detail', ''), '\_s\+', ' ', 'g') + + let l:result = { \ 'word': l:word, - \ 'kind': l:kind, + \ 'kind': ale#completion#GetCompletionSymbols(get(l:item, 'kind', '')), \ 'icase': 1, - \ 'menu': get(l:item, 'detail', ''), + \ 'menu': l:detail, + \ 'dup': get(l:info, 'additional_edits_only', 0) + \ || g:ale_completion_autoimport, \ 'info': (type(l:doc) is v:t_string ? l:doc : ''), - \}) + \} + " This flag is used to tell if this completion came from ALE or not. + let l:user_data = {'_ale_completion_item': 1} + + if has_key(l:item, 'additionalTextEdits') + \ && l:item.additionalTextEdits isnot v:null + let l:text_changes = [] + + for l:edit in l:item.additionalTextEdits + call add(l:text_changes, { + \ 'start': { + \ 'line': l:edit.range.start.line + 1, + \ 'offset': l:edit.range.start.character + 1, + \ }, + \ 'end': { + \ 'line': l:edit.range.end.line + 1, + \ 'offset': l:edit.range.end.character + 1, + \ }, + \ 'newText': l:edit.newText, + \}) + endfor + + if !empty(l:text_changes) + let l:user_data.code_actions = [{ + \ 'description': 'completion', + \ 'changes': [ + \ { + \ 'fileName': expand('#' . l:buffer . ':p'), + \ 'textChanges': l:text_changes, + \ }, + \ ], + \}] + endif + endif + + let l:result.user_data = json_encode(l:user_data) + + " Include this item if we'll accept any items, + " or if we only want items with additional edits, and this has them. + if !get(l:info, 'additional_edits_only', 0) + \|| has_key(l:user_data, 'code_actions') + call add(l:results, l:result) + endif endfor if has_key(l:info, 'prefix') - return ale#completion#Filter(l:buffer, &filetype, l:results, l:info.prefix) + let l:results = ale#completion#Filter( + \ l:buffer, + \ &filetype, + \ l:results, + \ l:info.prefix, + \ get(l:info, 'additional_edits_only', 0), + \) endif - return l:results + return l:results[: g:ale_completion_max_suggestions - 1] endfunction function! ale#completion#HandleTSServerResponse(conn_id, response) abort @@ -409,27 +699,47 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort \ &filetype, \ ale#completion#ParseTSServerCompletions(a:response), \ b:ale_completion_info.prefix, + \ get(b:ale_completion_info, 'additional_edits_only', 0), \)[: 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) + if empty(l:names) + " Response with no results now and skip making a redundant request + " for nothing. + call ale#completion#Show([]) + else + let l:identifiers = [] + + for l:name in l:names + let l:identifier = { + \ 'name': l:name.word, + \} + let l:source = get(l:name, 'source', '') + + " Empty source results in no details for the completed item + if !empty(l:source) + call extend(l:identifier, { 'source': l:source }) + endif + + call add(l:identifiers, l:identifier) + endfor + 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, + \ l:identifiers, \ ), \) endif elseif l:command is# 'completionEntryDetails' call ale#completion#Show( - \ a:response, - \ 'ale#completion#ParseTSServerCompletionEntryDetails', + \ ale#completion#ParseTSServerCompletionEntryDetails(a:response), \) endif endfunction @@ -441,15 +751,19 @@ function! ale#completion#HandleLSPResponse(conn_id, response) abort endif call ale#completion#Show( - \ a:response, - \ 'ale#completion#ParseLSPCompletions', + \ ale#completion#ParseLSPCompletions(a:response), \) endfunction -function! s:OnReady(linter, lsp_details, ...) abort - let l:buffer = a:lsp_details.buffer +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 @@ -461,11 +775,17 @@ function! s:OnReady(linter, lsp_details, ...) abort call ale#lsp#RegisterCallback(l:id, l:Callback) if a:linter.lsp is# 'tsserver' + if get(g:, 'ale_completion_tsserver_autoimport') is 1 + execute 'echom `g:ale_completion_tsserver_autoimport` is deprecated. Use `g:ale_completion_autoimport` instead.''' + endif + 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, + \ get(b:ale_completion_info, 'additional_edits_only', 0) + \ || g:ale_completion_autoimport, \) else " Send a message saying the buffer has changed first, otherwise @@ -478,10 +798,7 @@ function! s:OnReady(linter, lsp_details, ...) abort let l:message = ale#lsp#message#Completion( \ l:buffer, \ b:ale_completion_info.line, - \ min([ - \ b:ale_completion_info.line_length, - \ b:ale_completion_info.column + 1, - \ ]), + \ b:ale_completion_info.column, \ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix), \) endif @@ -498,38 +815,51 @@ function! s:OnReady(linter, lsp_details, ...) abort endif endfunction -function! s:GetLSPCompletions(linter) abort - let l:buffer = bufnr('') - let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter) +" 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 - if empty(l:lsp_details) - return 0 - endif + return 0 +endfunction - let l:id = l:lsp_details.connection_id +" This function can be used to manually trigger autocomplete, even when +" g:ale_completion_enabled is set to false +function! ale#completion#GetCompletions(...) abort + let l:source = get(a:000, 0, '') + let l:options = get(a:000, 1, {}) - let l:OnReady = function('s:OnReady', [a:linter, l:lsp_details]) + if len(a:000) > 2 + throw 'Too many arguments!' + endif - call ale#lsp#WaitForCapability(l:id, 'completion', l:OnReady) -endfunction + let l:CompleteCallback = get(l:options, 'callback', v:null) -function! ale#completion#GetCompletions() abort - if !g:ale_completion_enabled - return + if l:CompleteCallback isnot v:null + let b:CompleteCallback = l:CompleteCallback endif - call ale#completion#AlwaysGetCompletions(1) -endfunction - -" This function can be used to manually trigger autocomplete, even when -" g:ale_completion_enabled is set to false -function! ale#completion#AlwaysGetCompletions(need_prefix) abort - let [l:line, l:column] = getcurpos()[1:2] + if has_key(l:options, 'line') && has_key(l:options, 'column') + " Use a provided line and column, if given. + let l:line = l:options.line + let l:column = l:options.column + else + let [l:line, l:column] = getpos('.')[1:2] + endif - let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column) + if has_key(l:options, 'prefix') + let l:prefix = l:options.prefix + else + let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column) + endif - if a:need_prefix && empty(l:prefix) - return + if l:source is# 'ale-automatic' && empty(l:prefix) + return 0 endif let l:line_length = len(getline('.')) @@ -541,24 +871,98 @@ function! ale#completion#AlwaysGetCompletions(need_prefix) abort \ 'prefix': l:prefix, \ 'conn_id': 0, \ 'request_id': 0, + \ 'source': l:source, \} + unlet! b:ale_completion_result + + if has_key(l:options, 'additional_edits_only') + let b:ale_completion_info.additional_edits_only = + \ l:options.additional_edits_only + endif + + 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) - call s:GetLSPCompletions(l:linter) + if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) + let l:started = 1 + endif endif endfor + + return l:started +endfunction + +function! s:message(message) abort + call ale#util#Execute('echom ' . string(a:message)) +endfunction + +" This function implements the :ALEImport command. +function! ale#completion#Import() abort + let l:word = expand('') + + if empty(l:word) + call s:message('Nothing to complete at cursor!') + + return + endif + + let [l:line, l:column] = getpos('.')[1:2] + let l:column = searchpos('\V' . escape(l:word, '/\'), 'bn', l:line)[1] + + if l:column isnot 0 + let l:started = ale#completion#GetCompletions('ale-import', { + \ 'line': l:line, + \ 'column': l:column, + \ 'prefix': l:word, + \ 'additional_edits_only': 1, + \}) + + if !l:started + call s:message('No completion providers are available.') + endif + endif +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] = getcurpos()[1:2] + 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() + call ale#completion#GetCompletions('ale-automatic') endif endfunction @@ -572,11 +976,11 @@ function! ale#completion#StopTimer() abort endfunction function! ale#completion#Queue() abort - if !g:ale_completion_enabled + if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled) return endif - let s:timer_pos = getcurpos()[1:2] + 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 @@ -595,14 +999,45 @@ function! ale#completion#Queue() abort let s:timer_id = timer_start(g:ale_completion_delay, function('s:TimerHandler')) endfunction +function! ale#completion#HandleUserData(completed_item) abort + let l:user_data_json = get(a:completed_item, 'user_data', '') + let l:user_data = type(l:user_data_json) is v:t_dict + \ ? l:user_data_json + \ : ale#util#FuzzyJSONDecode(l:user_data_json, {}) + + if !has_key(l:user_data, '_ale_completion_item') + return + endif + + let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '') + + if l:source is# 'ale-automatic' + \|| l:source is# 'ale-manual' + \|| l:source is# 'ale-callback' + \|| l:source is# 'ale-import' + \|| l:source is# 'ale-omnifunc' + for l:code_action in get(l:user_data, 'code_actions', []) + call ale#code_action#HandleCodeAction(l:code_action, {}) + endfor + endif + + silent doautocmd User ALECompletePost +endfunction + function! ale#completion#Done() abort silent! pclose call ale#completion#RestoreCompletionOptions() - let s:last_done_pos = getcurpos()[1:2] + let s:last_done_pos = getpos('.')[1:2] endfunction +augroup ALECompletionActions + autocmd! + + autocmd CompleteDone * call ale#completion#HandleUserData(v:completed_item) +augroup END + function! s:Setup(enabled) abort augroup ALECompletionGroup autocmd! diff --git a/vim-config/plugins/ale/autoload/ale/completion/python.vim b/vim-config/plugins/ale/autoload/ale/completion/python.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/cursor.vim b/vim-config/plugins/ale/autoload/ale/cursor.vim old mode 100755 new mode 100644 index 6672c349..e8478e93 --- a/vim-config/plugins/ale/autoload/ale/cursor.vim +++ b/vim-config/plugins/ale/autoload/ale/cursor.vim @@ -9,7 +9,6 @@ let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10) 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 @@ -22,10 +21,10 @@ function! ale#cursor#TruncatedEcho(original_message) abort let l:shortmess_options = &l:shortmess try - let l:cursor_position = getcurpos() + let l:cursor_position = getpos('.') " The message is truncated and saved to the history. - setlocal shortmess+=T + silent! setlocal shortmess+=T try exec "norm! :echomsg l:message\n" @@ -39,12 +38,14 @@ function! ale#cursor#TruncatedEcho(original_message) abort endif exec 'echomsg l:message' + catch /E481/ + " Do nothing if running from a visual selection. 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 != getcurpos() + if l:cursor_position != getpos('.') call setpos('.', l:cursor_position) endif finally @@ -114,16 +115,20 @@ function! ale#cursor#EchoCursorWarningWithDelay() abort call s:StopCursorTimer() - let l:pos = getcurpos()[0:2] + let l:pos = getpos('.')[0:2] + + if !exists('w:last_pos') + let w:last_pos = [0, 0, 0] + endif " 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 + if l:pos != w:last_pos let l:delay = ale#Var(l:buffer, 'echo_delay') - let s:last_pos = l:pos + let w:last_pos = l:pos let s:cursor_timer = timer_start( \ l:delay, \ function('ale#cursor#EchoCursorWarning') @@ -137,11 +142,16 @@ function! s:ShowCursorDetailForItem(loc, options) abort 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' + if g:ale_floating_preview || g:ale_detail_to_floating_preview + call ale#floating_preview#Show(l:lines) + else + 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 endif endfunction diff --git a/vim-config/plugins/ale/autoload/ale/d.vim b/vim-config/plugins/ale/autoload/ale/d.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/debugging.vim b/vim-config/plugins/ale/autoload/ale/debugging.vim old mode 100755 new mode 100644 index 3aed38fe..efd52776 --- a/vim-config/plugins/ale/autoload/ale/debugging.vim +++ b/vim-config/plugins/ale/autoload/ale/debugging.vim @@ -8,6 +8,7 @@ let s:global_variable_list = [ \ 'ale_completion_delay', \ 'ale_completion_enabled', \ 'ale_completion_max_suggestions', +\ 'ale_disable_lsp', \ 'ale_echo_cursor', \ 'ale_echo_msg_error_str', \ 'ale_echo_msg_format', @@ -28,6 +29,7 @@ let s:global_variable_list = [ \ 'ale_linter_aliases', \ 'ale_linters', \ 'ale_linters_explicit', +\ 'ale_linters_ignore', \ 'ale_list_vertical', \ 'ale_list_window_size', \ 'ale_loclist_msg_format', @@ -37,6 +39,7 @@ let s:global_variable_list = [ \ 'ale_open_list', \ 'ale_pattern_options', \ 'ale_pattern_options_enabled', +\ 'ale_root', \ 'ale_set_balloons', \ 'ale_set_highlights', \ 'ale_set_loclist', @@ -49,6 +52,7 @@ let s:global_variable_list = [ \ 'ale_sign_style_error', \ 'ale_sign_style_warning', \ 'ale_sign_warning', +\ 'ale_sign_highlight_linenrs', \ 'ale_statusline_format', \ 'ale_type_map', \ 'ale_use_global_executables', @@ -61,7 +65,7 @@ function! s:Echo(message) abort execute 'echo a:message' endfunction -function! s:GetLinterVariables(filetype, linter_names) abort +function! s:GetLinterVariables(filetype, exclude_linter_names) abort let l:variable_list = [] let l:filetype_parts = split(a:filetype, '\.') @@ -72,7 +76,7 @@ function! s:GetLinterVariables(filetype, linter_names) abort " Include matching variables. if !empty(l:match) \&& index(l:filetype_parts, l:match[1]) >= 0 - \&& index(a:linter_names, l:match[2]) >= 0 + \&& index(a:exclude_linter_names, l:match[2]) == -1 call add(l:variable_list, l:key) endif endfor @@ -194,6 +198,7 @@ function! s:EchoLSPErrorMessages(all_linter_names) abort endfunction function! ale#debugging#Info() abort + let l:buffer = bufnr('') let l:filetype = &filetype " We get the list of enabled linters for free by the above function. @@ -210,19 +215,30 @@ function! ale#debugging#Info() abort let l:all_names = map(copy(l:all_linters), 'v:val[''name'']') let l:enabled_names = map(copy(l:enabled_linters), 'v:val[''name'']') + let l:exclude_names = filter(copy(l:all_names), 'index(l:enabled_names, v:val) == -1') " 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:variable_list = s:GetLinterVariables(l:filetype, l:exclude_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'), '') + let l:non_ignored_names = map( + \ copy(ale#linter#RemoveIgnored(l:buffer, l:filetype, l:enabled_linters)), + \ 'v:val[''name'']', + \) + let l:ignored_names = filter( + \ copy(l:enabled_names), + \ 'index(l:non_ignored_names, v:val) < 0' + \) + 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(' Ignored Linters: ' . string(l:ignored_names)) call s:Echo(' Suggested Fixers: ' . l:fixers_string) call s:Echo(' Linter Variables:') call s:Echo('') @@ -237,9 +253,13 @@ function! ale#debugging#Info() abort endfunction function! ale#debugging#InfoToClipboard() abort - redir => l:output - silent call ale#debugging#Info() - redir END + if !has('clipboard') + call s:Echo('clipboard not available. Try :ALEInfoToFile instead.') + + return + endif + + let l:output = execute('call ale#debugging#Info()') let @+ = l:output call s:Echo('ALEInfo copied to your clipboard') @@ -248,9 +268,7 @@ endfunction function! ale#debugging#InfoToFile(filename) abort let l:expanded_filename = expand(a:filename) - redir => l:output - silent call ale#debugging#Info() - redir END + let l:output = execute('call ale#debugging#Info()') call writefile(split(l:output, "\n"), l:expanded_filename) call s:Echo('ALEInfo written to ' . l:expanded_filename) diff --git a/vim-config/plugins/ale/autoload/ale/definition.vim b/vim-config/plugins/ale/autoload/ale/definition.vim old mode 100755 new mode 100644 index a732e501..9574017b --- a/vim-config/plugins/ale/autoload/ale/definition.vim +++ b/vim-config/plugins/ale/autoload/ale/definition.vim @@ -3,6 +3,10 @@ let s:go_to_definition_map = {} +" Enable automatic updates of the tagstack +let g:ale_update_tagstack = get(g:, 'ale_update_tagstack', 1) +let g:ale_default_navigation = get(g:, 'ale_default_navigation', 'buffer') + " Used to get the definition map in tests. function! ale#definition#GetMap() abort return deepcopy(s:go_to_definition_map) @@ -17,8 +21,22 @@ 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' + if has_key(a:response, 'request_seq') \&& has_key(s:go_to_definition_map, a:response.request_seq) let l:options = remove(s:go_to_definition_map, a:response.request_seq) @@ -27,6 +45,7 @@ function! ale#definition#HandleTSServerResponse(conn_id, response) abort 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 @@ -47,31 +66,53 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort 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 + if has_key(l:item, 'targetUri') + " LocationLink items use targetUri + let l:filename = ale#path#FromURI(l:item.targetUri) + let l:line = l:item.targetRange.start.line + 1 + let l:column = l:item.targetRange.start.character + 1 + else + " LocationLink items use uri + 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 + endif + call ale#definition#UpdateTagStack() call ale#util#Open(l:filename, l:line, l:column, l:options) break endfor endif endfunction -function! s:OnReady(linter, lsp_details, line, column, options, capability, ...) abort - let l:buffer = a:lsp_details.buffer +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 - \) + if a:capability is# 'definition' + let l:message = ale#lsp#tsserver_message#Definition( + \ l:buffer, + \ a:line, + \ a:column + \) + elseif a:capability is# 'typeDefinition' + let l:message = ale#lsp#tsserver_message#TypeDefinition( + \ l:buffer, + \ a:line, + \ a:column + \) + endif else " Send a message saying the buffer has changed first, or the " definition position probably won't make sense. @@ -99,22 +140,14 @@ endfunction function! s:GoToLSPDefinition(linter, options, capability) abort let l:buffer = bufnr('') - let [l:line, l:column] = getcurpos()[1:2] - let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter) - - if a:linter.lsp isnot# 'tsserver' - let l:column = min([l:column, len(getline(l:line))]) - endif - - if empty(l:lsp_details) - return 0 - endif - - let l:id = l:lsp_details.connection_id - - call ale#lsp#WaitForCapability(l:id, a:capability, function('s:OnReady', [ - \ a:linter, l:lsp_details, l:line, l:column, a:options, a:capability - \])) + 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 @@ -128,13 +161,37 @@ 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 + +function! ale#definition#GoToCommandHandler(command, ...) abort + let l:options = {} + + if len(a:000) > 0 + for l:option in a:000 + if l:option is? '-tab' + let l:options.open_in = 'tab' + elseif l:option is? '-split' + let l:options.open_in = 'split' + elseif l:option is? '-vsplit' + let l:options.open_in = 'vsplit' + endif + endfor + endif + + if !has_key(l:options, 'open_in') + let l:default_navigation = ale#Var(bufnr(''), 'default_navigation') + + if index(['tab', 'split', 'vsplit'], l:default_navigation) >= 0 + let l:options.open_in = l:default_navigation + endif + endif + + if a:command is# 'type' + call ale#definition#GoToType(l:options) + else + call ale#definition#GoTo(l:options) + endif +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/dhall.vim b/vim-config/plugins/ale/autoload/ale/dhall.vim new file mode 100644 index 00000000..cc54418f --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/dhall.vim @@ -0,0 +1,24 @@ +" Author: Pat Brisbin , toastal +" Description: Functions for working with Dhall’s executable + +call ale#Set('dhall_executable', 'dhall') +call ale#Set('dhall_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('dhall_options', '') + +function! ale#dhall#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'dhall_executable') + + " Dhall is written in Haskell and commonly installed with Stack + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'dhall') +endfunction + +function! ale#dhall#GetExecutableWithOptions(buffer) abort + let l:executable = ale#dhall#GetExecutable(a:buffer) + + return l:executable + \ . ale#Pad(ale#Var(a:buffer, 'dhall_options')) +endfunction + +function! ale#dhall#GetCommand(buffer) abort + return '%e ' . ale#Pad(ale#Var(a:buffer, 'dhall_options')) +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/engine.vim b/vim-config/plugins/ale/autoload/ale/engine.vim old mode 100755 new mode 100644 index ace123dc..5b9b1fca --- a/vim-config/plugins/ale/autoload/ale/engine.vim +++ b/vim-config/plugins/ale/autoload/ale/engine.vim @@ -4,21 +4,12 @@ " Remapping of linter problems. let g:ale_type_map = get(g:, 'ale_type_map', {}) - -" Stores information for each job including: -" -" linter: The linter dictionary for the job. -" buffer: The buffer number for the job. -" output: The array of lines for the output of the job. -if !has_key(s:, 'job_info_map') - let s:job_info_map = {} -endif +let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {}) 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 @@ -34,6 +25,25 @@ function! ale#engine#CleanupEveryBuffer() abort 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 @@ -71,18 +81,12 @@ endfunction function! ale#engine#InitBufferInfo(buffer) abort if !has_key(g:ale_buffer_info, a:buffer) - " job_list will hold the list of job IDs " active_linter_list will hold the list of active linter names " loclist holds the loclist items after all jobs have completed. - " temporary_file_list holds temporary files to be cleaned up - " temporary_directory_list holds temporary directories to be cleaned up let g:ale_buffer_info[a:buffer] = { - \ 'job_list': [], \ 'active_linter_list': [], \ 'active_other_sources_list': [], \ 'loclist': [], - \ 'temporary_file_list': [], - \ 'temporary_directory_list': [], \} return 1 @@ -101,84 +105,6 @@ function! ale#engine#IsCheckingBuffer(buffer) abort \ || !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 - call ale#engine#InitBufferInfo(a:buffer) - call add(g:ale_buffer_info[a:buffer].temporary_file_list, a:filename) -endfunction - -" Same as the above, but manage an entire directory. -function! ale#engine#ManageDirectory(buffer, directory) abort - call ale#engine#InitBufferInfo(a:buffer) - call add(g:ale_buffer_info[a:buffer].temporary_directory_list, a:directory) -endfunction - -function! ale#engine#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#engine#ManageFile(a:buffer, l:temporary_file) - - return l:temporary_file -endfunction - -" Create a new temporary directory and manage it in one go. -function! ale#engine#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#engine#ManageDirectory(a:buffer, l:temporary_directory) - - return l:temporary_directory -endfunction - -function! ale#engine#RemoveManagedFiles(buffer) abort - let l:info = get(g:ale_buffer_info, a:buffer, {}) - - " 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. - if has_key(l:info, 'temporary_file_list') - for l:filename in l:info.temporary_file_list - call delete(l:filename) - endfor - - let l:info.temporary_file_list = [] - endif - - " 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. - if has_key(l:info, 'temporary_directory_list') - for l:directory in l:info.temporary_directory_list - call delete(l:directory, 'rf') - endfor - - let l:info.temporary_directory_list = [] - endif -endfunction - -function! s:GatherOutput(job_id, line) abort - if has_key(s:job_info_map, a:job_id) - call add(s:job_info_map[a:job_id].output, a:line) - endif -endfunction - function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort let l:info = get(g:ale_buffer_info, a:buffer, {}) @@ -189,7 +115,7 @@ function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_sour 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 isnot# a:linter_name') + 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 @@ -222,27 +148,18 @@ function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_sour call ale#engine#SetResults(a:buffer, l:info.loclist) endfunction -function! s:HandleExit(job_id, exit_code) abort - if !has_key(s:job_info_map, a:job_id) +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:job_info = s:job_info_map[a:job_id] - let l:linter = l:job_info.linter - let l:output = l:job_info.output - let l:buffer = l:job_info.buffer - let l:executable = l:job_info.executable - let l:next_chain_index = l:job_info.next_chain_index - - if g:ale_history_enabled - call ale#history#SetExitCode(l:buffer, a:job_id, a:exit_code) - endif + let l:linter = a:job_info.linter + let l:executable = a:job_info.executable " Remove this job from the list. - call ale#job#Stop(a:job_id) - call remove(s:job_info_map, a:job_id) - call filter(g:ale_buffer_info[l:buffer].job_list, 'v:val isnot# a:job_id') - call filter(g:ale_buffer_info[l:buffer].active_linter_list, 'v:val isnot# l:linter.name') + 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. @@ -250,29 +167,18 @@ function! s:HandleExit(job_id, exit_code) abort return endif - if has('nvim') && !empty(l:output) && empty(l:output[-1]) - call remove(l:output, -1) - endif - - if l:next_chain_index < len(get(l:linter, 'command_chain', [])) - call s:InvokeChain(l:buffer, l:executable, l:linter, l:next_chain_index, l:output) - - return - endif - - " Log the output of the command for ALEInfo if we should. - if g:ale_history_enabled && g:ale_history_log_output - call ale#history#RememberOutput(l:buffer, a:job_id, l:output[:]) + if has('nvim') && !empty(a:output) && empty(a:output[-1]) + call remove(a:output, -1) endif try - let l:loclist = ale#util#GetFunction(l:linter.callback)(l:buffer, l:output) + 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, l:buffer, l:loclist, 0) + call ale#engine#HandleLoclist(l:linter.name, a:buffer, l:loclist, 0) endfunction function! ale#engine#SetResults(buffer, loclist) abort @@ -321,7 +227,7 @@ function! ale#engine#SetResults(buffer, loclist) abort " Automatically remove all managed temporary files and directories " now that all jobs have completed. - call ale#engine#RemoveManagedFiles(a:buffer) + call ale#command#RemoveManagedFiles(a:buffer) " Call user autocommands. This allows users to hook into ALE's lint cycle. silent doautocmd User ALELintPost @@ -351,6 +257,13 @@ function! s:RemapItemTypes(type_map, loclist) abort endfunction function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist) abort + let l:mappings = ale#GetFilenameMappings(a:buffer, a:linter_name) + + if !empty(l:mappings) + " We need to apply reverse filename mapping here. + let l:mappings = ale#filename_mapping#Invert(l:mappings) + endif + let l:bufnr_map = {} let l:new_loclist = [] @@ -391,13 +304,19 @@ function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist) let l:item.code = l:old_item.code endif - if has_key(l:old_item, 'filename') - \&& !ale#path#IsTempName(l:old_item.filename) + let l:old_name = get(l:old_item, 'filename', '') + + " Map parsed from output to local filesystem files. + if !empty(l:old_name) && !empty(l:mappings) + let l:old_name = ale#filename_mapping#Map(l:old_name, l:mappings) + endif + + if !empty(l:old_name) && !ale#path#IsTempName(l:old_name) " 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:filename = l:old_name let l:item.filename = l:filename if has_key(l:old_item, 'bufnr') @@ -472,231 +391,88 @@ 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 - return substitute(a:command_part, '%', '%%', 'g') -endfunction - -function! s:CreateTemporaryFileForJob(buffer, temporary_file) abort - if empty(a:temporary_file) - " There is no file, so we didn't create anything. - return 0 - endif - - 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#engine#ManageDirectory(a:buffer, l:temporary_directory) - " Write the buffer out to a file. - let l:lines = getbufline(a:buffer, 1, '$') - call ale#util#Writefile(a:buffer, l:lines, a:temporary_file) - - return 1 + " TODO: Emit deprecation warning here later. + return ale#command#EscapeCommandPart(a:command_part) endfunction " Run a job. " -" Returns 1 when the job was started successfully. -function! s:RunJob(options) abort - let l:command = a:options.command +" 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:cwd = a:options.cwd 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:read_buffer = a:options.read_buffer && !a:options.lint_file let l:info = g:ale_buffer_info[l:buffer] - let [l:temporary_file, l:command, l:file_created] = ale#command#FormatCommand( - \ l:buffer, - \ l:executable, - \ l:command, - \ l:read_buffer, - \ function('s:CreateTemporaryFileForJob'), - \) - - if l:file_created - " If a temporary filename has been formatted in to the command, then - " we do not need to send the Vim buffer to the command. - let l:read_buffer = 0 - endif - - let l:command = ale#job#PrepareCommand(l:buffer, l:command) - let l:job_options = { - \ 'mode': 'nl', - \ 'exit_cb': function('s:HandleExit'), - \} - - if l:output_stream is# 'stderr' - let l:job_options.err_cb = function('s:GatherOutput') - elseif l:output_stream is# 'both' - let l:job_options.out_cb = function('s:GatherOutput') - let l:job_options.err_cb = function('s:GatherOutput') - else - let l:job_options.out_cb = function('s:GatherOutput') - endif - - if get(g:, 'ale_run_synchronously') == 1 - " Find a unique Job value to use, which will be the same as the ID for - " running commands synchronously. This is only for test code. - let l:job_id = len(s:job_info_map) + 1 - - while has_key(s:job_info_map, l:job_id) - let l:job_id += 1 - endwhile - else - let l:job_id = ale#job#Start(l:command, l:job_options) - endif - - let l:status = 'failed' + let l:Callback = function('s:HandleExit', [{ + \ 'linter': l:linter, + \ 'executable': l:executable, + \}]) + let l:result = ale#command#Run(l:buffer, l:command, l:Callback, { + \ 'cwd': l:cwd, + \ 'output_stream': l:output_stream, + \ 'executable': l:executable, + \ 'read_buffer': l:read_buffer, + \ 'log_output': 1, + \ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:linter.name), + \}) " Only proceed if the job is being run. - if l:job_id - " Add the job to the list of jobs, so we can track them. - call add(l:info.job_list, l:job_id) - - if index(l:info.active_linter_list, l:linter.name) < 0 - call add(l:info.active_linter_list, l:linter.name) - endif - - let l:status = 'started' - " Store the ID for the job in the map to read back again. - let s:job_info_map[l:job_id] = { - \ 'linter': l:linter, - \ 'buffer': l:buffer, - \ 'executable': l:executable, - \ 'output': [], - \ 'next_chain_index': l:next_chain_index, - \} - - silent doautocmd User ALEJobStarted - endif - - if g:ale_history_enabled - call ale#history#Add(l:buffer, l:status, l:job_id, l:command) - endif - - if get(g:, 'ale_run_synchronously') == 1 - " Run a command synchronously if this test option is set. - let s:job_info_map[l:job_id].output = systemlist( - \ type(l:command) is v:t_list - \ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2]) - \ : l:command - \) - - call l:job_options.exit_cb(l:job_id, v:shell_error) - endif - - return l:job_id != 0 -endfunction - -" Determine which commands to run for a link in a command chain, or -" just a regular command. -function! ale#engine#ProcessChain(buffer, 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 - - if has_key(a:linter, 'command_chain') - 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 - else - let l:command = ale#linter#GetCommand(a:buffer, a:linter) + if empty(l:result) + return 0 endif - return { - \ 'command': l:command, - \ 'buffer': a:buffer, - \ 'linter': a:linter, - \ 'output_stream': l:output_stream, - \ 'next_chain_index': l:chain_index + 1, - \ 'read_buffer': l:read_buffer, - \} -endfunction + call ale#engine#MarkLinterActive(l:info, l:linter) -function! s:InvokeChain(buffer, executable, linter, chain_index, input) abort - let l:options = ale#engine#ProcessChain(a:buffer, a:linter, a:chain_index, a:input) - let l:options.executable = a:executable + silent doautocmd User ALEJobStarted - return s:RunJob(l:options) + return 1 endfunction -function! s:StopCurrentJobs(buffer, include_lint_file_jobs) abort +function! s:StopCurrentJobs(buffer, clear_lint_file_jobs, linter_slots) abort let l:info = get(g:ale_buffer_info, a:buffer, {}) - let l:new_job_list = [] - let l:new_active_linter_list = [] + call ale#command#StopJobs(a:buffer, 'linter') - for l:job_id in get(l:info, 'job_list', []) - let l:job_info = get(s:job_info_map, l:job_id, {}) + " 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 + let l:lint_file_map = {} - if !empty(l:job_info) - if a:include_lint_file_jobs || !l:job_info.linter.lint_file - call ale#job#Stop(l:job_id) - call remove(s:job_info_map, l:job_id) - else - call add(l:new_job_list, l:job_id) - " Linters with jobs still running are still active. - call add(l:new_active_linter_list, l:job_info.linter.name) + " Use a previously computed map of `lint_file` values to find + " linters that are used for linting files. + for [l:lint_file, l:linter] in a:linter_slots + if l:lint_file is 1 + let l:lint_file_map[l:linter.name] = 1 endif - endif - endfor - - " Remove duplicates from the active linter list. - call uniq(sort(l:new_active_linter_list)) + endfor - " Update the List, so it includes only the jobs we still need. - let l:info.job_list = l:new_job_list - " Update the active linter list, clearing out anything not running. - let l:info.active_linter_list = l:new_active_linter_list + " Keep jobs for linting files when we're only linting buffers. + call filter(l:info.active_linter_list, 'get(l:lint_file_map, v:val.name)') + endif endfunction +function! ale#engine#Stop(buffer) abort + call s:StopCurrentJobs(a:buffer, 1, []) +endfunction function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort " Figure out which linters are still enabled, and remove @@ -748,27 +524,125 @@ function! s:AddProblemsFromOtherBuffers(buffer, linters) abort endif endfunction +function! s:RunIfExecutable(buffer, linter, lint_file, executable) abort + if ale#command#IsDeferred(a:executable) + let a:executable.result_callback = { + \ executable -> s:RunIfExecutable( + \ a:buffer, + \ a:linter, + \ a:lint_file, + \ 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:lint_file ? 'file_linter' : 'linter' + call setbufvar(a:buffer, 'ale_job_type', l:job_type) + + " Get the cwd for the linter and set it before we call GetCommand. + " This will ensure that ale#command#Run uses it by default. + let l:cwd = ale#linter#GetCwd(a:buffer, a:linter) + + if l:cwd isnot v:null + call ale#command#SetCwd(a:buffer, l:cwd) + endif + + let l:command = ale#linter#GetCommand(a:buffer, a:linter) + + if l:cwd isnot v:null + call ale#command#ResetCwd(a:buffer) + endif + + let l:options = { + \ 'cwd': l:cwd, + \ 'executable': a:executable, + \ 'buffer': a:buffer, + \ 'linter': a:linter, + \ 'output_stream': get(a:linter, 'output_stream', 'stdout'), + \ 'read_buffer': a:linter.read_buffer, + \ 'lint_file': a:lint_file, + \} + + 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 +function! s:RunLinter(buffer, linter, lint_file) 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) - if ale#engine#IsExecutable(a:buffer, l:executable) - return s:InvokeChain(a:buffer, l:executable, a:linter, 0, []) - endif + return s:RunIfExecutable(a:buffer, a:linter, a:lint_file, 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) +function! s:GetLintFileSlots(buffer, linters) abort + let l:linter_slots = [] + + for l:linter in a:linters + let l:LintFile = l:linter.lint_file + + if type(l:LintFile) is v:t_func + let l:LintFile = l:LintFile(a:buffer) + endif + + call add(l:linter_slots, [l:LintFile, l:linter]) + endfor + + return l:linter_slots +endfunction + +function! s:GetLintFileValues(slots, Callback) abort + let l:deferred_list = [] + let l:new_slots = [] + + for [l:lint_file, l:linter] in a:slots + while ale#command#IsDeferred(l:lint_file) && has_key(l:lint_file, 'value') + " If we've already computed the return value, use it. + let l:lint_file = l:lint_file.value + endwhile + + if ale#command#IsDeferred(l:lint_file) + " If we are going to return the result later, wait for it. + call add(l:deferred_list, l:lint_file) + else + " If we have the value now, coerce it to 0 or 1. + let l:lint_file = l:lint_file is 1 + endif + + call add(l:new_slots, [l:lint_file, l:linter]) + endfor + + if !empty(l:deferred_list) + for l:deferred in l:deferred_list + let l:deferred.result_callback = + \ {-> s:GetLintFileValues(l:new_slots, a:Callback)} + endfor + else + call a:Callback(l:new_slots) + endif +endfunction + +function! s:RunLinters( +\ buffer, +\ linters, +\ slots, +\ should_lint_file, +\ new_buffer, +\) abort + call s:StopCurrentJobs(a:buffer, a:should_lint_file, a:slots) call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters) " We can only clear the results if we aren't checking the buffer. @@ -776,10 +650,10 @@ function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort silent doautocmd User ALELintPre - for l:linter in a:linters + for [l:lint_file, l:linter] in a:slots " 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 !l:lint_file || a:should_lint_file + if s:RunLinter(a:buffer, l:linter, l:lint_file) " If a single linter ran, we shouldn't clear everything. let l:can_clear_results = 0 endif @@ -794,11 +668,32 @@ function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort " 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) + elseif a:new_buffer + call s:AddProblemsFromOtherBuffers( + \ a:buffer, + \ map(copy(a:slots), 'v:val[1]') + \) endif 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:GetLintFileValues( + \ s:GetLintFileSlots(a:buffer, a:linters), + \ { + \ slots -> s:RunLinters( + \ a:buffer, + \ a:linters, + \ slots, + \ a:should_lint_file, + \ l:new_buffer, + \ ) + \ } + \) +endfunction + " Clean up a buffer. " " This function will stop all current jobs for the buffer, @@ -810,6 +705,10 @@ function! ale#engine#Cleanup(buffer) abort 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 @@ -827,90 +726,3 @@ function! ale#engine#GetLoclist(buffer) abort return g:ale_buffer_info[a:buffer].loclist 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#engine#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:info in values(g:ale_buffer_info) - call extend(l:job_list, get(l:info, 'job_list', [])) - 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 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#engine#WaitForJobs(l:new_deadline) - endif -endfunction diff --git a/vim-config/plugins/ale/autoload/ale/engine/ignore.vim b/vim-config/plugins/ale/autoload/ale/engine/ignore.vim old mode 100755 new mode 100644 index 2db2c6c1..80574656 --- a/vim-config/plugins/ale/autoload/ale/engine/ignore.vim +++ b/vim-config/plugins/ale/autoload/ale/engine/ignore.vim @@ -22,7 +22,7 @@ function! ale#engine#ignore#GetList(filetype, config) abort endfunction " Given a List of linter descriptions, exclude the linters to be ignored. -function! ale#engine#ignore#Exclude(filetype, all_linters, config) abort +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 = [] @@ -37,6 +37,10 @@ function! ale#engine#ignore#Exclude(filetype, all_linters, config) abort 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 diff --git a/vim-config/plugins/ale/autoload/ale/events.vim b/vim-config/plugins/ale/autoload/ale/events.vim old mode 100755 new mode 100644 index c3dbd378..3568c117 --- a/vim-config/plugins/ale/autoload/ale/events.vim +++ b/vim-config/plugins/ale/autoload/ale/events.vim @@ -105,11 +105,11 @@ function! ale#events#Init() abort 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) + autocmd TextChanged,TextChangedI * call ale#Queue(ale#Var(str2nr(expand('')), 'lint_delay')) elseif l:text_changed is? 'normal' - autocmd TextChanged * call ale#Queue(g:ale_lint_delay) + autocmd TextChanged * call ale#Queue(ale#Var(str2nr(expand('')), 'lint_delay')) elseif l:text_changed is? 'insert' - autocmd TextChangedI * call ale#Queue(g:ale_lint_delay) + autocmd TextChangedI * call ale#Queue(ale#Var(str2nr(expand('')), 'lint_delay')) endif if g:ale_lint_on_enter @@ -128,7 +128,7 @@ function! ale#events#Init() abort endif if g:ale_lint_on_insert_leave - autocmd InsertLeave * call ale#Queue(0) + 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 @@ -147,6 +147,10 @@ function! ale#events#Init() abort autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarning() | endif endif + if g:ale_hover_cursor + autocmd CursorHold * if exists('*ale#lsp#Send') | call ale#hover#ShowTruncatedMessageAtCursor() | endif + endif + if g:ale_close_preview_on_insert autocmd InsertEnter * if exists('*ale#preview#CloseIfTypeMatches') | call ale#preview#CloseIfTypeMatches('ale-preview') | endif endif diff --git a/vim-config/plugins/ale/autoload/ale/filename_mapping.vim b/vim-config/plugins/ale/autoload/ale/filename_mapping.vim new file mode 100644 index 00000000..76d47acc --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/filename_mapping.vim @@ -0,0 +1,22 @@ +" Author: w0rp +" Description: Logic for handling mappings between files + +" Invert filesystem mappings so they can be mapped in reverse. +function! ale#filename_mapping#Invert(filename_mappings) abort + return map(copy(a:filename_mappings), '[v:val[1], v:val[0]]') +endfunction + +" Given a filename and some filename_mappings, map a filename. +function! ale#filename_mapping#Map(filename, filename_mappings) abort + let l:simplified_filename = ale#path#Simplify(a:filename) + + for [l:mapping_from, l:mapping_to] in a:filename_mappings + let l:mapping_from = ale#path#Simplify(l:mapping_from) + + if l:simplified_filename[:len(l:mapping_from) - 1] is# l:mapping_from + return l:mapping_to . l:simplified_filename[len(l:mapping_from):] + endif + endfor + + return a:filename +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/filetypes.vim b/vim-config/plugins/ale/autoload/ale/filetypes.vim old mode 100755 new mode 100644 index 6174aa0e..340a9c4e --- a/vim-config/plugins/ale/autoload/ale/filetypes.vim +++ b/vim-config/plugins/ale/autoload/ale/filetypes.vim @@ -4,9 +4,7 @@ function! ale#filetypes#LoadExtensionMap() abort " Output includes: " '*.erl setf erlang' - redir => l:output - silent exec 'autocmd' - redir end + let l:output = execute('exec "autocmd"') let l:map = {} diff --git a/vim-config/plugins/ale/autoload/ale/fix.vim b/vim-config/plugins/ale/autoload/ale/fix.vim old mode 100755 new mode 100644 index 59502933..8ebba9fe --- a/vim-config/plugins/ale/autoload/ale/fix.vim +++ b/vim-config/plugins/ale/autoload/ale/fix.vim @@ -1,55 +1,47 @@ -if !has_key(s:, 'job_info_map') - let s:job_info_map = {} -endif +" Author: w0rp +" Description: Functions for fixing code with programs, or other means. -function! s:GatherOutput(job_id, line) abort - if has_key(s:job_info_map, a:job_id) - call add(s:job_info_map[a:job_id].output, a:line) - endif -endfunction +let g:ale_fix_on_save_ignore = get(g:, 'ale_fix_on_save_ignore', {}) +let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {}) " Apply fixes queued up for buffers which may be hidden. " Vim doesn't let you modify hidden buffers. -function! ale#fix#ApplyQueuedFixes() abort - let l:buffer = bufnr('') - let l:data = get(g:ale_fix_buffer_data, l:buffer, {'done': 0}) +function! ale#fix#ApplyQueuedFixes(buffer) abort + let l:data = get(g:ale_fix_buffer_data, a:buffer, {'done': 0}) - if !l:data.done + if !l:data.done || (!ale#util#HasBuflineApi() && a:buffer isnot bufnr('')) return endif - call remove(g:ale_fix_buffer_data, l:buffer) - - if l:data.changes_made - let l:start_line = len(l:data.output) + 1 - let l:end_line = len(l:data.lines_before) - - if l:end_line >= l:start_line - let l:save = winsaveview() - silent execute l:start_line . ',' . l:end_line . 'd_' - call winrestview(l:save) - endif - - " 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:lines_to_set = getbufvar(l:buffer, '&fileformat') is# 'dos' - \ ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')') - \ : l:data.output + call remove(g:ale_fix_buffer_data, a:buffer) - call setline(1, l:lines_to_set) - - if l:data.should_save - if empty(&buftype) - noautocmd :w! - else - set nomodified + try + if l:data.changes_made + let l:new_lines = ale#util#SetBufferContents(a:buffer, l:data.output) + + 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 - endif + catch /E21/ + " If we cannot modify the buffer now, try again later. + let g:ale_fix_buffer_data[a:buffer] = l:data + + return + endtry if l:data.should_save - let l:should_lint = g:ale_fix_on_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 @@ -60,302 +52,187 @@ function! ale#fix#ApplyQueuedFixes() abort " fixing problems. if g:ale_enabled \&& l:should_lint - \&& !ale#events#QuitRecently(l:buffer) + \&& !ale#events#QuitRecently(a:buffer) call ale#Queue(0, l:data.should_save ? 'lint_file' : '') endif endfunction function! ale#fix#ApplyFixes(buffer, output) abort - call ale#fix#RemoveManagedFiles(a:buffer) - 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.changes_made = l:data.lines_before !=# l:data.output " no-custom-checks + 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''' + + if !l:data.ignore_file_changed_errors + execute 'echoerr ''The file was changed before fixing finished''' + endif return endif endif - if !bufexists(a:buffer) - " Remove the buffer data when it doesn't exist. - call remove(g:ale_fix_buffer_data, a:buffer) - endif - - let l:data.done = 1 - " 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() + call ale#fix#ApplyQueuedFixes(a:buffer) endfunction -function! s:HandleExit(job_id, exit_code) abort - if !has_key(s:job_info_map, a:job_id) - return - endif +function! s:HandleExit(job_info, buffer, job_output, data) abort + let l:buffer_info = get(g:ale_fix_buffer_data, a:buffer, {}) - let l:job_info = remove(s:job_info_map, a:job_id) - let l:buffer = l:job_info.buffer - - if g:ale_history_enabled - call ale#history#SetExitCode(l:buffer, a:job_id, a:exit_code) + if empty(l:buffer_info) + return endif - if has_key(l:job_info, 'file_to_read') - let l:job_info.output = readfile(l:job_info.file_to_read) + 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(l:job_info, 'chain_with', v:null) - let l:ProcessWith = get(l:job_info, 'process_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:job_info.output = call( - \ ale#util#GetFunction(l:ProcessWith), - \ [l:buffer, l:job_info.output] - \) + 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:job_info.output))) - let l:input = l:job_info.output + if !empty(split(join(l:output))) + let l:input = l:output else - let l:input = l:job_info.input + let l:input = a:job_info.input endif - let l:next_index = l:ChainCallback is v:null - \ ? l:job_info.callback_index + 1 - \ : l:job_info.callback_index - call s:RunFixer({ - \ 'buffer': l:buffer, + \ 'buffer': a:buffer, \ 'input': l:input, - \ 'output': l:job_info.output, - \ 'callback_list': l:job_info.callback_list, - \ 'callback_index': l:next_index, - \ 'chain_callback': l:ChainCallback, + \ 'callback_list': a:job_info.callback_list, + \ 'callback_index': a:job_info.callback_index + 1, \}) endfunction -function! ale#fix#ManageDirectory(buffer, directory) abort - call add(g:ale_fix_buffer_data[a:buffer].temporary_directory_list, a:directory) -endfunction +function! s:RunJob(result, options) abort + if ale#command#IsDeferred(a:result) + let a:result.result_callback = {x -> s:RunJob(x, a:options)} -function! ale#fix#RemoveManagedFiles(buffer) abort - if !has_key(g:ale_fix_buffer_data, a:buffer) return endif - " 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 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 g:ale_fix_buffer_data[a:buffer].temporary_directory_list - call delete(l:directory, 'rf') - endfor - - let g:ale_fix_buffer_data[a:buffer].temporary_directory_list = [] -endfunction - -function! s:CreateTemporaryFileForJob(input, buffer, temporary_file) abort - if empty(a:temporary_file) - " There is no file, so we didn't create anything. - return 0 - endif - - 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#fix#ManageDirectory(a:buffer, l:temporary_directory) - " Write the buffer out to a file. - call ale#util#Writefile(a:buffer, a:input, a:temporary_file) - - return 1 -endfunction - -function! s:RunJob(options) abort let l:buffer = a:options.buffer - let l:command = a:options.command let l:input = a:options.input - let l:output_stream = a:options.output_stream - let l:read_temporary_file = a:options.read_temporary_file - let l:ChainWith = a:options.chain_with - let l:read_buffer = a:options.read_buffer + let l:fixer_name = a:options.fixer_name - if empty(l:command) - " If there's nothing further to chain the command with, stop here. - if l:ChainWith is v:null - return 0 + 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 - " If there's another chained callback to run, then run that. call s:RunFixer({ \ 'buffer': l:buffer, \ 'input': l:input, - \ 'callback_index': a:options.callback_index, + \ 'callback_index': a:options.callback_index + 1, \ 'callback_list': a:options.callback_list, - \ 'chain_callback': l:ChainWith, - \ 'output': [], \}) - return 1 + return endif - let [l:temporary_file, l:command, l:file_created] = ale#command#FormatCommand( - \ l:buffer, - \ '', - \ l:command, - \ l:read_buffer, - \ function('s:CreateTemporaryFileForJob', [l:input]), - \) - - let l:command = ale#job#PrepareCommand(l:buffer, l:command) - let l:job_options = { - \ 'mode': 'nl', - \ 'exit_cb': function('s:HandleExit'), - \} + let l:command = get(a:result, 'command', '') - let l:job_info = { - \ 'buffer': l:buffer, - \ 'input': l:input, - \ 'output': [], - \ 'chain_with': l:ChainWith, - \ 'callback_index': a:options.callback_index, - \ 'callback_list': a:options.callback_list, - \ 'process_with': a:options.process_with, - \} - - if l:read_temporary_file - " TODO: Check that a temporary file is set here. - let l:job_info.file_to_read = l:temporary_file - elseif l:output_stream is# 'stderr' - let l:job_options.err_cb = function('s:GatherOutput') - elseif l:output_stream is# 'both' - let l:job_options.out_cb = function('s:GatherOutput') - let l:job_options.err_cb = function('s:GatherOutput') - else - let l:job_options.out_cb = function('s:GatherOutput') - endif - - if get(g:, 'ale_emulate_job_failure') == 1 - let l:job_id = 0 - elseif get(g:, 'ale_run_synchronously') == 1 - " Find a unique Job value to use, which will be the same as the ID for - " running commands synchronously. This is only for test code. - let l:job_id = len(s:job_info_map) + 1 + if empty(l:command) + " If the command is empty, skip to the next item. + call s:RunFixer({ + \ 'buffer': l:buffer, + \ 'input': l:input, + \ 'callback_index': a:options.callback_index, + \ 'callback_list': a:options.callback_list, + \}) - while has_key(s:job_info_map, l:job_id) - let l:job_id += 1 - endwhile - else - let l:job_id = ale#job#Start(l:command, l:job_options) + return endif - let l:status = l:job_id ? 'started' : 'failed' - - if g:ale_history_enabled - call ale#history#Add(l:buffer, l:status, l:job_id, l:command) - endif + let l:read_temporary_file = get(a:result, 'read_temporary_file', 0) + let l:read_buffer = get(a:result, 'read_buffer', 1) + let l:output_stream = get(a:result, 'output_stream', 'stdout') + let l:cwd = get(a:result, 'cwd', v:null) - if l:job_id == 0 - return 0 + if l:read_temporary_file + let l:output_stream = 'none' endif - let s:job_info_map[l:job_id] = l:job_info - - if get(g:, 'ale_run_synchronously') == 1 - " Run a command synchronously if this test option is set. - let l:output = systemlist( - \ type(l:command) is v:t_list - \ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2]) - \ : l:command - \) - - if !l:read_temporary_file - let s:job_info_map[l:job_id].output = l:output - endif + let l:Callback = function('s:HandleExit', [{ + \ 'input': l:input, + \ '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, + \ 'cwd': l:cwd, + \ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:fixer_name), + \}) - call l:job_options.exit_cb(l:job_id, v:shell_error) + 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 - - return 1 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 - let l:ChainCallback = get(a:options, 'chain_callback', v:null) - - while len(a:options.callback_list) > l:index - let l:Function = l:ChainCallback isnot v:null - \ ? ale#util#GetFunction(l:ChainCallback) - \ : a:options.callback_list[l:index] - - 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 - " Chained commands accept (buffer, [done, input]) - let l:result = ale#util#FunctionArgCount(l:Function) == 1 - \ ? call(l:Function, [l:buffer]) - \ : call(l:Function, [l:buffer, v:null, copy(l:input)]) - endif - if type(l:result) is v:t_number && l:result == 0 - " When `0` is returned, skip this item. - let l:index += 1 - elseif type(l:result) is v:t_list - let l:input = l:result - let l:index += 1 - else - let l:ChainWith = get(l:result, 'chain_with', v:null) - " Default to piping the buffer for the last fixer in the chain. - let l:read_buffer = get(l:result, 'read_buffer', l:ChainWith is v:null) - - let l:job_ran = s:RunJob({ - \ 'buffer': l:buffer, - \ 'command': l:result.command, - \ 'input': l:input, - \ 'output_stream': get(l:result, 'output_stream', 'stdout'), - \ 'read_temporary_file': get(l:result, 'read_temporary_file', 0), - \ 'read_buffer': l:read_buffer, - \ 'chain_with': l:ChainWith, - \ 'callback_list': a:options.callback_list, - \ 'callback_index': l:index, - \ 'process_with': get(l:result, 'process_with', v:null), - \}) - - if !l:job_ran - " The job failed to run, so skip to the next item. - let l:index += 1 - else - " Stop here, we will handle exit later on. - return - endif - endif - endwhile + if len(a:options.callback_list) <= l:index + call ale#fix#ApplyFixes(l:buffer, l:input) - call ale#fix#ApplyFixes(l:buffer, l:input) + return + endif + + let [l:fixer_name, l:Function] = a:options.callback_list[l:index] + + " Record new jobs started as fixer jobs. + call setbufvar(l:buffer, 'ale_job_type', 'fixer') + + " 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)]) + + call s:RunJob(l:result, { + \ 'buffer': l:buffer, + \ 'input': l:input, + \ 'callback_list': a:options.callback_list, + \ 'callback_index': l:index, + \ 'fixer_name': l:fixer_name, + \}) endfunction function! s:AddSubCallbacks(full_list, callbacks) abort @@ -370,7 +247,21 @@ function! s:AddSubCallbacks(full_list, callbacks) abort return 1 endfunction -function! s:GetCallbacks(buffer, fixers) abort +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 @@ -395,8 +286,12 @@ function! s:GetCallbacks(buffer, fixers) abort endif endif - if empty(l:callback_list) - return [] + 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 = [] @@ -404,16 +299,24 @@ function! s:GetCallbacks(buffer, fixers) abort " Variables with capital characters are needed, or Vim will complain about " funcref variables. for l:Item in l:callback_list + " Try to capture the names of registered fixer names, so we can use + " them for filename mapping or other purposes later. + let l:fixer_name = v:null + if type(l:Item) is v:t_string let l:Func = ale#fix#registry#GetFunc(l:Item) if !empty(l:Func) + let l:fixer_name = l:Item let l:Item = l:Func endif endif try - call add(l:corrected_list, ale#util#GetFunction(l:Item)) + call add(l:corrected_list, [ + \ l:fixer_name, + \ ale#util#GetFunction(l:Item) + \]) catch /E475/ " Rethrow exceptions for failing to get a function so we can print " a friendly message about it. @@ -431,6 +334,7 @@ function! ale#fix#InitBufferData(buffer, fixing_flag) abort \ 'lines_before': getbufline(a:buffer, 1, '$'), \ 'done': 0, \ 'should_save': a:fixing_flag is# 'save_file', + \ 'ignore_file_changed_errors': a:fixing_flag is# '!', \ 'temporary_directory_list': [], \} endfunction @@ -439,19 +343,23 @@ endfunction " " 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'" + if a:fixing_flag isnot# '' + \&& a:fixing_flag isnot# '!' + \&& a:fixing_flag isnot# 'save_file' + throw "fixing_flag must be '', '!', or 'save_file'" endif try - let l:callback_list = s:GetCallbacks(a:buffer, a:000) + 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' + if a:fixing_flag isnot# '!' + 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' + endif return 0 endtry @@ -464,13 +372,9 @@ function! ale#fix#Fix(buffer, fixing_flag, ...) abort return 0 endif - for l:job_id in keys(s:job_info_map) - call remove(s:job_info_map, l:job_id) - call ale#job#Stop(l:job_id) - endfor - + call ale#command#StopJobs(a:buffer, 'fixer') " Clean up any files we might have left behind from a previous run. - call ale#fix#RemoveManagedFiles(a:buffer) + call ale#command#RemoveManagedFiles(a:buffer) call ale#fix#InitBufferData(a:buffer, a:fixing_flag) silent doautocmd User ALEFixPre @@ -488,5 +392,5 @@ endfunction " Set up an autocmd command to try and apply buffer fixes when available. augroup ALEBufferFixGroup autocmd! - autocmd BufEnter * call ale#fix#ApplyQueuedFixes() + autocmd BufEnter * call ale#fix#ApplyQueuedFixes(str2nr(expand(''))) augroup END diff --git a/vim-config/plugins/ale/autoload/ale/fix/registry.vim b/vim-config/plugins/ale/autoload/ale/fix/registry.vim old mode 100755 new mode 100644 index a7422f22..c6764daf --- a/vim-config/plugins/ale/autoload/ale/fix/registry.vim +++ b/vim-config/plugins/ale/autoload/ale/fix/registry.vim @@ -12,6 +12,16 @@ let s:default_registry = { \ 'suggested_filetypes': ['help'], \ 'description': 'Align help tags to the right margin', \ }, +\ 'autoimport': { +\ 'function': 'ale#fixers#autoimport#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Fix import issues with autoimport.', +\ }, +\ 'autoflake': { +\ 'function': 'ale#fixers#autoflake#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Fix flake issues with autoflake.', +\ }, \ 'autopep8': { \ 'function': 'ale#fixers#autopep8#Fix', \ 'suggested_filetypes': ['python'], @@ -27,6 +37,47 @@ let s:default_registry = { \ 'suggested_filetypes': ['python'], \ 'description': 'Fix PEP8 issues with black.', \ }, +\ 'buildifier': { +\ 'function': 'ale#fixers#buildifier#Fix', +\ 'suggested_filetypes': ['bzl'], +\ 'description': 'Format BUILD and .bzl files with buildifier.', +\ }, +\ 'deno': { +\ 'function': 'ale#fixers#deno#Fix', +\ 'suggested_filetypes': ['typescript'], +\ 'description': 'Fix TypeScript using deno fmt.', +\ }, +\ 'dfmt': { +\ 'function': 'ale#fixers#dfmt#Fix', +\ 'suggested_filetypes': ['d'], +\ 'description': 'Fix D files with dfmt.', +\ }, +\ 'dhall': { +\ 'function': 'ale#fixers#dhall#Fix', +\ 'suggested_filetypes': ['dhall'], +\ 'description': 'Fix Dhall files with dhall-format.', +\ }, +\ 'dhall-format': { +\ 'function': 'ale#fixers#dhall_format#Fix', +\ 'suggested_filetypes': ['dhall'], +\ 'description': 'Standard code formatter for the Dhall language', +\ 'aliases': ['dhall'], +\ }, +\ 'dhall-freeze': { +\ 'function': 'ale#fixers#dhall_freeze#Freeze', +\ 'suggested_filetypes': ['dhall'], +\ 'description': 'Add integrity checks to remote import statements of an expression for the Dhall language', +\ }, +\ 'dhall-lint': { +\ 'function': 'ale#fixers#dhall_lint#Fix', +\ 'suggested_filetypes': ['dhall'], +\ 'description': 'Standard code formatter for the Dhall language and removing dead code', +\ }, +\ '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'], @@ -44,6 +95,16 @@ let s:default_registry = { \ 'description': 'Apply elm-format to a file.', \ 'aliases': ['format'], \ }, +\ 'nimpretty': { +\ 'function': 'ale#fixers#nimpretty#Fix', +\ 'suggested_filetypes': ['nim'], +\ 'description': 'Apply nimpretty to a file.', +\ }, +\ 'erblint': { +\ 'function': 'ale#fixers#erblint#Fix', +\ 'suggested_filetypes': ['eruby'], +\ 'description': 'Apply erblint --autocorrect to a file.', +\ }, \ 'eslint': { \ 'function': 'ale#fixers#eslint#Fix', \ 'suggested_filetypes': ['javascript', 'typescript'], @@ -61,7 +122,7 @@ let s:default_registry = { \ }, \ 'prettier': { \ 'function': 'ale#fixers#prettier#Fix', -\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'html', 'yaml'], +\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'svelte', 'html', 'yaml', 'openapi', 'ruby'], \ 'description': 'Apply prettier to a file.', \ }, \ 'prettier_eslint': { @@ -90,6 +151,11 @@ let s:default_registry = { \ 'suggested_filetypes': [], \ 'description': 'Remove all trailing whitespace characters at the end of every line.', \ }, +\ 'yamlfix': { +\ 'function': 'ale#fixers#yamlfix#Fix', +\ 'suggested_filetypes': ['yaml'], +\ 'description': 'Fix yaml files with yamlfix.', +\ }, \ 'yapf': { \ 'function': 'ale#fixers#yapf#Fix', \ 'suggested_filetypes': ['python'], @@ -107,9 +173,14 @@ let s:default_registry = { \ }, \ 'scalafmt': { \ 'function': 'ale#fixers#scalafmt#Fix', -\ 'suggested_filetypes': ['scala'], +\ 'suggested_filetypes': ['sbt', 'scala'], \ 'description': 'Fix Scala files using scalafmt', \ }, +\ 'sorbet': { +\ 'function': 'ale#fixers#sorbet#Fix', +\ 'suggested_filetypes': ['ruby'], +\ 'description': 'Fix ruby files with srb tc --autocorrect.', +\ }, \ 'standard': { \ 'function': 'ale#fixers#standard#Fix', \ 'suggested_filetypes': ['javascript'], @@ -122,7 +193,7 @@ let s:default_registry = { \ }, \ 'stylelint': { \ 'function': 'ale#fixers#stylelint#Fix', -\ 'suggested_filetypes': ['css', 'sass', 'scss', 'stylus'], +\ 'suggested_filetypes': ['css', 'sass', 'scss', 'sugarss', 'stylus'], \ 'description': 'Fix stylesheet files using stylelint --fix.', \ }, \ 'swiftformat': { @@ -130,6 +201,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['swift'], \ 'description': 'Apply SwiftFormat to a file.', \ }, +\ 'apple-swift-format': { +\ 'function': 'ale#fixers#appleswiftformat#Fix', +\ 'suggested_filetypes': ['swift'], +\ 'description': 'Apply apple/swift-format to a file.', +\ }, \ 'phpcbf': { \ 'function': 'ale#fixers#phpcbf#Fix', \ 'suggested_filetypes': ['php'], @@ -140,10 +216,30 @@ let s:default_registry = { \ 'suggested_filetypes': ['php'], \ 'description': 'Fix PHP files with php-cs-fixer.', \ }, +\ 'astyle': { +\ 'function': 'ale#fixers#astyle#Fix', +\ 'suggested_filetypes': ['c', 'cpp'], +\ 'description': 'Fix C/C++ with astyle.', +\ }, +\ 'clangtidy': { +\ 'function': 'ale#fixers#clangtidy#Fix', +\ 'suggested_filetypes': ['c', 'cpp', 'objc'], +\ 'description': 'Fix C/C++ and ObjectiveC files with clang-tidy.', +\ }, \ 'clang-format': { \ 'function': 'ale#fixers#clangformat#Fix', -\ 'suggested_filetypes': ['c', 'cpp'], -\ 'description': 'Fix C/C++ files with clang-format.', +\ '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.', +\ }, +\ 'fish_indent': { +\ 'function': 'ale#fixers#fish_indent#Fix', +\ 'suggested_filetypes': ['fish'], +\ 'description': 'Format fish scripts using fish_indent.', \ }, \ 'gofmt': { \ 'function': 'ale#fixers#gofmt#Fix', @@ -155,6 +251,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['go'], \ 'description': 'Fix Go files imports with goimports.', \ }, +\ 'golines': { +\ 'function': 'ale#fixers#golines#Fix', +\ 'suggested_filetypes': ['go'], +\ 'description': 'Fix Go file long lines with golines', +\ }, \ 'gomod': { \ 'function': 'ale#fixers#gomod#Fix', \ 'suggested_filetypes': ['gomod'], @@ -172,7 +273,7 @@ let s:default_registry = { \ }, \ 'textlint': { \ 'function': 'ale#fixers#textlint#Fix', -\ 'suggested_filetypes': ['text','markdown','asciidoc'], +\ 'suggested_filetypes': ['text','markdown','asciidoc','tex'], \ 'description': 'Fix text files with textlint --fix', \ }, \ 'hackfmt': { @@ -180,6 +281,11 @@ let s:default_registry = { \ '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'], @@ -190,6 +296,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['haskell'], \ 'description': 'Fix Haskell files with brittany.', \ }, +\ 'hindent': { +\ 'function': 'ale#fixers#hindent#Fix', +\ 'suggested_filetypes': ['haskell'], +\ 'description': 'Fix Haskell files with hindent.', +\ }, \ 'hlint': { \ 'function': 'ale#fixers#hlint#Fix', \ 'suggested_filetypes': ['haskell'], @@ -200,16 +311,36 @@ let s:default_registry = { \ 'suggested_filetypes': ['haskell'], \ 'description': 'Refactor Haskell files with stylish-haskell.', \ }, +\ 'purs-tidy': { +\ 'function': 'ale#fixers#purs_tidy#Fix', +\ 'suggested_filetypes': ['purescript'], +\ 'description': 'Format PureScript files with purs-tidy.', +\ }, +\ 'purty': { +\ 'function': 'ale#fixers#purty#Fix', +\ 'suggested_filetypes': ['purescript'], +\ 'description': 'Format PureScript files with purty.', +\ }, \ 'ocamlformat': { \ 'function': 'ale#fixers#ocamlformat#Fix', -\ 'suggested_filetypes': ['ocaml'], +\ 'suggested_filetypes': ['ocaml', 'ocamlinterface'], \ 'description': 'Fix OCaml files with ocamlformat.', \ }, +\ 'ocp-indent': { +\ 'function': 'ale#fixers#ocp_indent#Fix', +\ 'suggested_filetypes': ['ocaml', 'ocamlinterface'], +\ 'description': 'Fix OCaml files with ocp-indent.', +\ }, \ 'refmt': { \ 'function': 'ale#fixers#refmt#Fix', \ 'suggested_filetypes': ['reason'], \ 'description': 'Fix ReasonML files with refmt.', \ }, +\ 'pandoc': { +\ 'function': 'ale#fixers#pandoc#Fix', +\ 'suggested_filetypes': ['markdown'], +\ 'description': 'Fix markdown files with pandoc.', +\ }, \ 'shfmt': { \ 'function': 'ale#fixers#shfmt#Fix', \ 'suggested_filetypes': ['sh'], @@ -220,6 +351,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['sql'], \ 'description': 'Fix SQL files with sqlfmt.', \ }, +\ 'sqlformat': { +\ 'function': 'ale#fixers#sqlformat#Fix', +\ 'suggested_filetypes': ['sql'], +\ 'description': 'Fix SQL files with sqlformat.', +\ }, \ 'google_java_format': { \ 'function': 'ale#fixers#google_java_format#Fix', \ 'suggested_filetypes': ['java'], @@ -235,6 +371,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['json'], \ 'description': 'Fix JSON files with jq.', \ }, +\ 'protolint': { +\ 'function': 'ale#fixers#protolint#Fix', +\ 'suggested_filetypes': ['proto'], +\ 'description': 'Fix Protocol Buffer files with protolint.', +\ }, \ 'perltidy': { \ 'function': 'ale#fixers#perltidy#Fix', \ 'suggested_filetypes': ['perl'], @@ -242,8 +383,8 @@ let s:default_registry = { \ }, \ 'xo': { \ 'function': 'ale#fixers#xo#Fix', -\ 'suggested_filetypes': ['javascript'], -\ 'description': 'Fix JavaScript files using xo --fix.', +\ 'suggested_filetypes': ['javascript', 'typescript'], +\ 'description': 'Fix JavaScript/TypeScript files using xo --fix.', \ }, \ 'qmlfmt': { \ 'function': 'ale#fixers#qmlfmt#Fix', @@ -255,6 +396,16 @@ let s:default_registry = { \ 'suggested_filetypes': ['dart'], \ 'description': 'Fix Dart files with dartfmt.', \ }, +\ 'dart-format': { +\ 'function': 'ale#fixers#dart_format#Fix', +\ 'suggested_filetypes': ['dart'], +\ 'description': 'Fix Dart files with dart format.', +\ }, +\ 'dotnet-format': { +\ 'function': 'ale#fixers#dotnet_format#Fix', +\ 'suggested_filetypes': ['cs'], +\ 'description': 'Fix C# files with dotnet format.', +\ }, \ 'xmllint': { \ 'function': 'ale#fixers#xmllint#Fix', \ 'suggested_filetypes': ['xml'], @@ -270,6 +421,91 @@ let s:default_registry = { \ 'suggested_filetypes': ['hcl', 'terraform'], \ 'description': 'Fix tf and hcl files with terraform fmt.', \ }, +\ 'ktlint': { +\ 'function': 'ale#fixers#ktlint#Fix', +\ 'suggested_filetypes': ['kt', 'kotlin'], +\ 'description': 'Fix Kotlin files with ktlint.', +\ }, +\ 'styler': { +\ 'function': 'ale#fixers#styler#Fix', +\ 'suggested_filetypes': ['r', 'rmarkdown', 'rmd'], +\ '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.', +\ }, +\ 'gnatpp': { +\ 'function': 'ale#fixers#gnatpp#Fix', +\ 'suggested_filetypes': ['ada'], +\ 'description': 'Format Ada files with gnatpp.', +\ }, +\ 'nixfmt': { +\ 'function': 'ale#fixers#nixfmt#Fix', +\ 'suggested_filetypes': ['nix'], +\ 'description': 'A nix formatter written in Haskell.', +\ }, +\ 'nixpkgs-fmt': { +\ 'function': 'ale#fixers#nixpkgsfmt#Fix', +\ 'suggested_filetypes': ['nix'], +\ 'description': 'A formatter for Nix code', +\ }, +\ 'remark-lint': { +\ 'function': 'ale#fixers#remark_lint#Fix', +\ 'suggested_filetypes': ['markdown'], +\ 'description': 'Fix markdown files with remark-lint', +\ }, +\ 'html-beautify': { +\ 'function': 'ale#fixers#html_beautify#Fix', +\ 'suggested_filetypes': ['html', 'htmldjango'], +\ 'description': 'Fix HTML files with html-beautify.', +\ }, +\ 'lua-format': { +\ 'function': 'ale#fixers#lua_format#Fix', +\ 'suggested_filetypes': ['lua'], +\ 'description': 'Fix Lua files with lua-format.', +\ }, +\ 'luafmt': { +\ 'function': 'ale#fixers#luafmt#Fix', +\ 'suggested_filetypes': ['lua'], +\ 'description': 'Fix Lua files with luafmt.', +\ }, +\ 'stylua': { +\ 'function': 'ale#fixers#stylua#Fix', +\ 'suggested_filetypes': ['lua'], +\ 'description': 'Fix Lua files with stylua.', +\ }, +\ 'ormolu': { +\ 'function': 'ale#fixers#ormolu#Fix', +\ 'suggested_filetypes': ['haskell'], +\ 'description': 'A formatter for Haskell source code.', +\ }, +\ 'jsonnetfmt': { +\ 'function': 'ale#fixers#jsonnetfmt#Fix', +\ 'suggested_filetypes': ['jsonnet'], +\ 'description': 'Fix jsonnet files with jsonnetfmt', +\ }, +\ 'ptop': { +\ 'function': 'ale#fixers#ptop#Fix', +\ 'suggested_filetypes': ['pascal'], +\ 'description': 'Fix Pascal files with ptop.', +\ }, +\ 'vfmt': { +\ 'function': 'ale#fixers#vfmt#Fix', +\ 'suggested_filetypes': ['v'], +\ 'description': 'A formatter for V source code.', +\ } \} " Reset the function registry to the default entries. diff --git a/vim-config/plugins/ale/autoload/ale/fixers/appleswiftformat.vim b/vim-config/plugins/ale/autoload/ale/fixers/appleswiftformat.vim new file mode 100644 index 00000000..ca27e82c --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/appleswiftformat.vim @@ -0,0 +1,16 @@ +" Author: (bosr) +" Description: Integration of apple/swift-format formatter with ALE. + +function! ale#fixers#appleswiftformat#Fix(buffer) abort + let l:command_args = ale#swift#GetAppleSwiftFormatCommand(a:buffer) . ' format --in-place %t' + let l:config_args = ale#swift#GetAppleSwiftFormatConfigArgs(a:buffer) + + if l:config_args isnot# '' + let l:command_args = l:command_args . ' ' . l:config_args + endif + + return { + \ 'read_temporary_file': 1, + \ 'command': l:command_args, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/astyle.vim b/vim-config/plugins/ale/autoload/ale/fixers/astyle.vim new file mode 100644 index 00000000..3a5a70a1 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/astyle.vim @@ -0,0 +1,59 @@ +" Author: James Kim +" Description: Fix C/C++ files with astyle. + +function! s:set_variables() abort + for l:ft in ['c', 'cpp'] + call ale#Set(l:ft . '_astyle_executable', 'astyle') + call ale#Set(l:ft . '_astyle_project_options', '') + endfor +endfunction + +call s:set_variables() + + +function! ale#fixers#astyle#Var(buffer, name) abort + let l:ft = getbufvar(str2nr(a:buffer), '&filetype') + let l:ft = l:ft =~# 'cpp' ? 'cpp' : 'c' + + return ale#Var(a:buffer, l:ft . '_astyle_' . a:name) +endfunction + +" Try to find a project options file. +function! ale#fixers#astyle#FindProjectOptions(buffer) abort + let l:proj_options = ale#fixers#astyle#Var(a:buffer, 'project_options') + + " If user has set project options variable then use it and skip any searching. + " This would allow users to use project files named differently than .astylerc. + if !empty(l:proj_options) + return l:proj_options + endif + + " Try to find nearest .astylerc file. + let l:proj_options = fnamemodify(ale#path#FindNearestFile(a:buffer, '.astylerc'), ':t') + + if !empty(l:proj_options) + return l:proj_options + endif + + " Try to find nearest _astylerc file. + let l:proj_options = fnamemodify(ale#path#FindNearestFile(a:buffer, '_astylerc'), ':t') + + if !empty(l:proj_options) + return l:proj_options + endif + + " If no project options file is found return an empty string. + return '' +endfunction + +function! ale#fixers#astyle#Fix(buffer) abort + let l:executable = ale#fixers#astyle#Var(a:buffer, 'executable') + let l:proj_options = ale#fixers#astyle#FindProjectOptions(a:buffer) + let l:command = ' --stdin=' . ale#Escape(expand('#' . a:buffer)) + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:proj_options) ? '' : ' --project=' . l:proj_options) + \ . l:command + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/autoflake.vim b/vim-config/plugins/ale/autoload/ale/fixers/autoflake.vim new file mode 100644 index 00000000..e2ad6536 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/autoflake.vim @@ -0,0 +1,28 @@ +" Author: circld +" Description: Fixing files with autoflake. + +call ale#Set('python_autoflake_executable', 'autoflake') +call ale#Set('python_autoflake_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_autoflake_options', '') + +function! ale#fixers#autoflake#Fix(buffer) abort + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'python_autoflake', + \ ['autoflake'], + \) + + if !executable(l:executable) + return 0 + endif + + let l:options = ale#Var(a:buffer, 'python_autoflake_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --in-place ' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/autoimport.vim b/vim-config/plugins/ale/autoload/ale/fixers/autoimport.vim new file mode 100644 index 00000000..700d36b5 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/autoimport.vim @@ -0,0 +1,27 @@ +" Author: lyz-code +" Description: Fixing Python imports with autoimport. + +call ale#Set('python_autoimport_executable', 'autoimport') +call ale#Set('python_autoimport_options', '') +call ale#Set('python_autoimport_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#autoimport#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'python_autoimport_options') + + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'python_autoimport', + \ ['autoimport'], + \) + + if !executable(l:executable) + return 0 + endif + + return { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -', + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/autopep8.vim b/vim-config/plugins/ale/autoload/ale/fixers/autopep8.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/bibclean.vim b/vim-config/plugins/ale/autoload/ale/fixers/bibclean.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/black.vim b/vim-config/plugins/ale/autoload/ale/fixers/black.vim old mode 100755 new mode 100644 index 27249c55..4a88c5cd --- a/vim-config/plugins/ale/autoload/ale/fixers/black.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/black.vim @@ -5,6 +5,8 @@ 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_auto_poetry', 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')) @@ -12,21 +14,39 @@ function! ale#fixers#black#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_black_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + return ale#python#FindExecutable(a:buffer, 'python_black', ['black']) endfunction function! ale#fixers#black#Fix(buffer) abort let l:executable = ale#fixers#black#GetExecutable(a:buffer) + let l:cmd = [ale#Escape(l:executable)] - let l:exec_args = l:executable =~? 'pipenv$' - \ ? ' run black' - \ : '' + if l:executable =~? 'pipenv\|poetry$' + call extend(l:cmd, ['run', 'black']) + endif let l:options = ale#Var(a:buffer, 'python_black_options') - return { - \ 'command': ale#Escape(l:executable) . l:exec_args - \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' -', - \} + if !empty(l:options) + call add(l:cmd, l:options) + endif + + if expand('#' . a:buffer . ':e') is? 'pyi' + call add(l:cmd, '--pyi') + endif + + call add(l:cmd, '-') + + let l:result = {'command': join(l:cmd, ' ')} + + if ale#Var(a:buffer, 'python_black_change_directory') + let l:result.cwd = '%s:h' + endif + + return l:result endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/brittany.vim b/vim-config/plugins/ale/autoload/ale/fixers/brittany.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/buildifier.vim b/vim-config/plugins/ale/autoload/ale/fixers/buildifier.vim new file mode 100644 index 00000000..48103b2e --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/buildifier.vim @@ -0,0 +1,26 @@ +" Author: Jon Parise +" Description: Format Bazel BUILD and .bzl files with buildifier. +" +call ale#Set('bazel_buildifier_executable', 'buildifier') +call ale#Set('bazel_buildifier_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('bazel_buildifier_options', '') + +function! ale#fixers#buildifier#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'bazel_buildifier', [ + \ 'buildifier', + \]) +endfunction + +function! ale#fixers#buildifier#Fix(buffer) abort + let l:executable = ale#Escape(ale#fixers#buildifier#GetExecutable(a:buffer)) + let l:options = ale#Var(a:buffer, 'bazel_buildifier_options') + let l:filename = ale#Escape(bufname(a:buffer)) + + let l:command = l:executable . ' -mode fix -lint fix -path ' . l:filename + + if l:options isnot# '' + let l:command .= ' ' . l:options + endif + + return {'command': l:command . ' -'} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/clangformat.vim b/vim-config/plugins/ale/autoload/ale/fixers/clangformat.vim old mode 100755 new mode 100644 index eae1a7b4..81498ebd --- a/vim-config/plugins/ale/autoload/ale/fixers/clangformat.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/clangformat.vim @@ -5,18 +5,43 @@ scriptencoding utf-8 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', '') +call ale#Set('c_clangformat_style_option', '') +call ale#Set('c_clangformat_use_local_file', 0) function! ale#fixers#clangformat#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'c_clangformat', [ + return ale#path#FindExecutable(a:buffer, 'c_clangformat', [ \ 'clang-format', \]) endfunction function! ale#fixers#clangformat#Fix(buffer) abort + let l:executable = ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer)) + let l:filename = ale#Escape(bufname(a:buffer)) let l:options = ale#Var(a:buffer, 'c_clangformat_options') + let l:style_option = ale#Var(a:buffer, 'c_clangformat_style_option') + let l:use_local_file = ale#Var(a:buffer, 'c_clangformat_use_local_file') - return { - \ 'command': ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer)) - \ . ' ' . l:options, - \} + if l:style_option isnot# '' + let l:style_option = '-style=' . "'" . l:style_option . "'" + endif + + if l:use_local_file + let l:config = ale#path#FindNearestFile(a:buffer, '.clang-format') + + if !empty(l:config) + let l:style_option = '-style=file' + endif + endif + + if l:style_option isnot# '' + let l:options .= ' ' . l:style_option + endif + + let l:command = l:executable . ' --assume-filename=' . l:filename + + if l:options isnot# '' + let l:command .= ' ' . l:options + endif + + return {'command': l:command} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/clangtidy.vim b/vim-config/plugins/ale/autoload/ale/fixers/clangtidy.vim new file mode 100644 index 00000000..b37360a7 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/clangtidy.vim @@ -0,0 +1,52 @@ +scriptencoding utf-8 +" Author: ObserverOfTime +" Description: Fixing C/C++ files with clang-tidy. + +function! s:set_variables() abort + let l:use_global = get(g:, 'ale_use_global_executables', 0) + + for l:ft in ['c', 'cpp'] + call ale#Set(l:ft . '_clangtidy_executable', 'clang-tidy') + call ale#Set(l:ft . '_clangtidy_use_global', l:use_global) + call ale#Set(l:ft . '_clangtidy_checks', []) + call ale#Set(l:ft . '_clangtidy_options', '') + call ale#Set(l:ft . '_clangtidy_extra_options', '') + call ale#Set(l:ft . '_clangtidy_fix_errors', 1) + endfor + + call ale#Set('c_build_dir', '') +endfunction + +call s:set_variables() + +function! ale#fixers#clangtidy#Var(buffer, name) abort + let l:ft = getbufvar(str2nr(a:buffer), '&filetype') + let l:ft = l:ft =~# 'cpp' ? 'cpp' : 'c' + + return ale#Var(a:buffer, l:ft . '_clangtidy_' . a:name) +endfunction + +function! ale#fixers#clangtidy#GetCommand(buffer) abort + let l:checks = join(ale#fixers#clangtidy#Var(a:buffer, 'checks'), ',') + let l:extra_options = ale#fixers#clangtidy#Var(a:buffer, 'extra_options') + let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + let l:options = empty(l:build_dir) + \ ? ale#fixers#clangtidy#Var(a:buffer, 'options') : '' + let l:fix_errors = ale#fixers#clangtidy#Var(a:buffer, 'fix_errors') + + return ' -fix' . (l:fix_errors ? ' -fix-errors' : '') + \ . (empty(l:checks) ? '' : ' -checks=' . ale#Escape(l:checks)) + \ . (empty(l:extra_options) ? '' : ' ' . l:extra_options) + \ . (empty(l:build_dir) ? '' : ' -p ' . ale#Escape(l:build_dir)) + \ . ' %t' . (empty(l:options) ? '' : ' -- ' . l:options) +endfunction + +function! ale#fixers#clangtidy#Fix(buffer) abort + let l:executable = ale#fixers#clangtidy#Var(a:buffer, 'executable') + let l:command = ale#fixers#clangtidy#GetCommand(a:buffer) + + return { + \ 'command': ale#Escape(l:executable) . l:command, + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/cmakeformat.vim b/vim-config/plugins/ale/autoload/ale/fixers/cmakeformat.vim new file mode 100644 index 00000000..dcc29cf3 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/cmakeformat.vim @@ -0,0 +1,16 @@ +" 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) + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' -' + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/dart_format.vim b/vim-config/plugins/ale/autoload/ale/fixers/dart_format.vim new file mode 100644 index 00000000..4b8f730b --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/dart_format.vim @@ -0,0 +1,18 @@ +" Author: ghsang +" Description: Integration of dart format with ALE. + +call ale#Set('dart_format_executable', 'dart') +call ale#Set('dart_format_options', '') + +function! ale#fixers#dart_format#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'dart_format_executable') + let l:options = ale#Var(a:buffer, 'dart_format_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' format' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/dartfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/dartfmt.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/deno.vim b/vim-config/plugins/ale/autoload/ale/fixers/deno.vim new file mode 100644 index 00000000..7154c6ee --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/deno.vim @@ -0,0 +1,17 @@ +function! ale#fixers#deno#Fix(buffer) abort + let l:executable = ale#handlers#deno#GetExecutable(a:buffer) + + if !executable(l:executable) + return 0 + endif + + let l:options = ' fmt -' + + if ale#Var(a:buffer, 'deno_unstable') + let l:options = l:options . ' --unstable' + endif + + return { + \ 'command': ale#Escape(l:executable) . l:options + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/dfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/dfmt.vim new file mode 100644 index 00000000..0072e045 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/dfmt.vim @@ -0,0 +1,18 @@ +" Author: theoldmoon0602 +" Description: Integration of dfmt with ALE. + +call ale#Set('d_dfmt_executable', 'dfmt') +call ale#Set('d_dfmt_options', '') + +function! ale#fixers#dfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'd_dfmt_executable') + let l:options = ale#Var(a:buffer, 'd_dfmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -i' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/dhall_format.vim b/vim-config/plugins/ale/autoload/ale/fixers/dhall_format.vim new file mode 100644 index 00000000..4f12abc8 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/dhall_format.vim @@ -0,0 +1,11 @@ +" Author: toastal +" Description: Dhall’s built-in formatter +" +function! ale#fixers#dhall_format#Fix(buffer) abort + let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer) + + return { + \ 'command': l:executable + \ . ' format' + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/dhall_freeze.vim b/vim-config/plugins/ale/autoload/ale/fixers/dhall_freeze.vim new file mode 100644 index 00000000..ff54482d --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/dhall_freeze.vim @@ -0,0 +1,14 @@ +" Author: toastal +" Description: Dhall’s package freezing + +call ale#Set('dhall_freeze_options', '') + +function! ale#fixers#dhall_freeze#Freeze(buffer) abort + let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer) + + return { + \ 'command': l:executable + \ . ' freeze' + \ . ale#Pad(ale#Var(a:buffer, 'dhall_freeze_options')) + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/dhall_lint.vim b/vim-config/plugins/ale/autoload/ale/fixers/dhall_lint.vim new file mode 100644 index 00000000..149a6581 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/dhall_lint.vim @@ -0,0 +1,11 @@ +" Author: toastal +" Description: Dhall’s built-in linter/formatter + +function! ale#fixers#dhall_lint#Fix(buffer) abort + let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer) + + return { + \ 'command': l:executable + \ . ' lint' + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/dotnet_format.vim b/vim-config/plugins/ale/autoload/ale/fixers/dotnet_format.vim new file mode 100644 index 00000000..b44a28bd --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/dotnet_format.vim @@ -0,0 +1,18 @@ +" Author: ghsang +" Description: Integration of dotnet format with ALE. + +call ale#Set('cs_dotnet_format_executable', 'dotnet') +call ale#Set('cs_dotnet_format_options', '') + +function! ale#fixers#dotnet_format#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'cs_dotnet_format_executable') + let l:options = ale#Var(a:buffer, 'cs_dotnet_format_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' format' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' --folder --include %t "$(dirname %t)"', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/elm_format.vim b/vim-config/plugins/ale/autoload/ale/fixers/elm_format.vim old mode 100755 new mode 100644 index cd2be2c3..a4740db4 --- a/vim-config/plugins/ale/autoload/ale/fixers/elm_format.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/elm_format.vim @@ -6,7 +6,7 @@ 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', [ + return ale#path#FindExecutable(a:buffer, 'elm_format', [ \ 'node_modules/.bin/elm-format', \]) endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/erblint.vim b/vim-config/plugins/ale/autoload/ale/fixers/erblint.vim new file mode 100644 index 00000000..41aca0c8 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/erblint.vim @@ -0,0 +1,40 @@ +" Author: Roeland Moors - https://github.com/roelandmoors +" Description: ERB Lint, support for https://github.com/Shopify/erb-lint + +call ale#Set('eruby_erblint_executable', 'erblint') +call ale#Set('eruby_erblint_options', '') + + +" Erblint fixer outputs diagnostics first and then the fixed +" output. These are delimited by something like this: +" ================ /path/to/demo.html.erb ================== +" We only need the output after this +function! ale#fixers#erblint#PostProcess(buffer, output) abort + let l:line = 0 + + for l:output in a:output + let l:line = l:line + 1 + + if l:output =~# "^=\\+.*=\\+$" + break + endif + endfor + + return a:output[l:line :] +endfunction + +function! ale#fixers#erblint#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'eruby_erblint_executable') + let l:options = ale#Var(a:buffer, 'eruby_erblint_options') + + return ale#ruby#EscapeExecutable(l:executable, 'erblint') + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --autocorrect --stdin %s' +endfunction + +function! ale#fixers#erblint#Fix(buffer) abort + return { + \ 'command': ale#fixers#erblint#GetCommand(a:buffer), + \ 'process_with': 'ale#fixers#erblint#PostProcess' + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/erlfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/erlfmt.vim new file mode 100644 index 00000000..f9951e9d --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/erlfmt.vim @@ -0,0 +1,21 @@ +" Author: AntoineGagne - https://github.com/AntoineGagne +" Description: Integration of erlfmt with ALE. + +call ale#Set('erlang_erlfmt_executable', 'erlfmt') +call ale#Set('erlang_erlfmt_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('erlang_erlfmt_options', '') + +function! ale#fixers#erlfmt#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'erlang_erlfmt', ['erlfmt']) +endfunction + +function! ale#fixers#erlfmt#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'erlang_erlfmt_options') + let l:executable = ale#fixers#erlfmt#GetExecutable(a:buffer) + + let l:command = ale#Escape(l:executable) . (empty(l:options) ? '' : ' ' . l:options) . ' %s' + + return { + \ 'command': l:command + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/eslint.vim b/vim-config/plugins/ale/autoload/ale/fixers/eslint.vim old mode 100755 new mode 100644 index ea5b2a63..c9535cb0 --- a/vim-config/plugins/ale/autoload/ale/fixers/eslint.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/eslint.vim @@ -3,15 +3,15 @@ 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' - let l:command = ale#semver#HasVersion(l:executable) - \ ? '' - \ : ale#node#Executable(a:buffer, l:executable) . ' --version' - - return { - \ 'command': l:command, - \ 'chain_with': 'ale#fixers#eslint#ApplyFixForVersion', - \} + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ l:executable, + \ l:command, + \ function('ale#fixers#eslint#ApplyFixForVersion'), + \) endfunction function! ale#fixers#eslint#ProcessFixDryRunOutput(buffer, output) abort @@ -33,37 +33,50 @@ function! ale#fixers#eslint#ProcessEslintDOutput(buffer, output) abort return a:output endfunction -function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort +function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) - let l:version = ale#semver#GetVersion(l:executable, a:version_output) + let l:options = ale#Var(a:buffer, 'javascript_eslint_options') - let l:config = ale#handlers#eslint#FindConfig(a:buffer) + " 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 empty(l:config) + if !l:has_config return 0 endif " Use --fix-to-stdout with eslint_d - if l:executable =~# 'eslint_d$' && ale#semver#GTE(l:version, [3, 19, 0]) + if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0]) return { + \ 'cwd': ale#handlers#eslint#GetCwd(a:buffer), \ '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(l:version, [4, 9, 0]) + if ale#semver#GTE(a:version, [4, 9, 0]) return { + \ 'cwd': ale#handlers#eslint#GetCwd(a:buffer), \ '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 { + \ 'cwd': ale#handlers#eslint#GetCwd(a:buffer), \ 'command': ale#node#Executable(a:buffer, l:executable) - \ . ' -c ' . ale#Escape(l:config) + \ . ale#Pad(l:options) + \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') \ . ' --fix %t', \ 'read_temporary_file': 1, \} diff --git a/vim-config/plugins/ale/autoload/ale/fixers/fecs.vim b/vim-config/plugins/ale/autoload/ale/fixers/fecs.vim new file mode 100644 index 00000000..d692bc97 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/autoload/ale/fixers/fish_indent.vim b/vim-config/plugins/ale/autoload/ale/fixers/fish_indent.vim new file mode 100644 index 00000000..ebf17c5a --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/fish_indent.vim @@ -0,0 +1,19 @@ +" Author: Chen YuanYuan +" Description: Integration of fish_indent with ALE. + +call ale#Set('fish_fish_indent_executable', 'fish_indent') +call ale#Set('fish_fish_indent_options', '') + +function! ale#fixers#fish_indent#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'fish_fish_indent_executable') + let l:options = ale#Var(a:buffer, 'fish_fish_indent_options') + let l:filename = ale#Escape(bufname(a:buffer)) + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -w ' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/fixjson.vim b/vim-config/plugins/ale/autoload/ale/fixers/fixjson.vim old mode 100755 new mode 100644 index 33ce0af3..4bad8f9b --- a/vim-config/plugins/ale/autoload/ale/fixers/fixjson.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/fixjson.vim @@ -6,7 +6,7 @@ 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', [ + return ale#path#FindExecutable(a:buffer, 'json_fixjson', [ \ 'node_modules/.bin/fixjson', \]) endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/floskell.vim b/vim-config/plugins/ale/autoload/ale/fixers/floskell.vim new file mode 100644 index 00000000..f0015db7 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/autoload/ale/fixers/generic.vim b/vim-config/plugins/ale/autoload/ale/fixers/generic.vim old mode 100755 new mode 100644 index 1d88553e..cb8865b4 --- a/vim-config/plugins/ale/autoload/ale/fixers/generic.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/generic.vim @@ -1,7 +1,7 @@ " Author: w0rp " Description: Generic functions for fixing files with. -function! ale#fixers#generic#RemoveTrailingBlankLines(buffer, done, lines) abort +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]) @@ -12,7 +12,7 @@ function! ale#fixers#generic#RemoveTrailingBlankLines(buffer, done, lines) abort endfunction " Remove all whitespaces at the end of lines -function! ale#fixers#generic#TrimWhitespace(buffer, done, lines) abort +function! ale#fixers#generic#TrimWhitespace(buffer, lines) abort let l:index = 0 let l:lines_new = range(len(a:lines)) diff --git a/vim-config/plugins/ale/autoload/ale/fixers/generic_python.vim b/vim-config/plugins/ale/autoload/ale/fixers/generic_python.vim old mode 100755 new mode 100644 index 9a929b96..d55a23c3 --- a/vim-config/plugins/ale/autoload/ale/fixers/generic_python.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/generic_python.vim @@ -2,7 +2,7 @@ " Description: Generic fixer functions for Python. " Add blank lines before control statements. -function! ale#fixers#generic_python#AddLinesBeforeControlStatements(buffer, done, lines) abort +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 @@ -41,7 +41,7 @@ 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, done, lines) abort +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') diff --git a/vim-config/plugins/ale/autoload/ale/fixers/gnatpp.vim b/vim-config/plugins/ale/autoload/ale/fixers/gnatpp.vim new file mode 100644 index 00000000..bf3d484e --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/gnatpp.vim @@ -0,0 +1,17 @@ +" Author: tim +" Description: Fix files with gnatpp. + +call ale#Set('ada_gnatpp_executable', 'gnatpp') +call ale#Set('ada_gnatpp_options', '') + +function! ale#fixers#gnatpp#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'ada_gnatpp_executable') + let l:options = ale#Var(a:buffer, 'ada_gnatpp_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/gofmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/gofmt.vim old mode 100755 new mode 100644 index 66b67a9e..b9cfbb58 --- a/vim-config/plugins/ale/autoload/ale/fixers/gofmt.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/gofmt.vim @@ -7,12 +7,10 @@ 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') + let l:env = ale#go#EnvString(a:buffer) return { - \ 'command': ale#Escape(l:executable) - \ . ' -l -w' + \ 'command': l:env . ale#Escape(l:executable) \ . (empty(l:options) ? '' : ' ' . l:options) - \ . ' %t', - \ 'read_temporary_file': 1, \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/goimports.vim b/vim-config/plugins/ale/autoload/ale/fixers/goimports.vim old mode 100755 new mode 100644 index 783d0206..65f0fd98 --- a/vim-config/plugins/ale/autoload/ale/fixers/goimports.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/goimports.vim @@ -7,13 +7,14 @@ 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') + let l:env = ale#go#EnvString(a:buffer) if !executable(l:executable) return 0 endif return { - \ 'command': ale#Escape(l:executable) + \ 'command': l:env . ale#Escape(l:executable) \ . ' -l -w -srcdir %s' \ . (empty(l:options) ? '' : ' ' . l:options) \ . ' %t', diff --git a/vim-config/plugins/ale/autoload/ale/fixers/golines.vim b/vim-config/plugins/ale/autoload/ale/fixers/golines.vim new file mode 100644 index 00000000..9326f482 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/golines.vim @@ -0,0 +1,21 @@ +" Author Pig Frown +" Description: Fix Go files long lines with golines" + +call ale#Set('go_golines_executable', 'golines') + +call ale#Set('go_golines_options', '') + +function! ale#fixers#golines#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'go_golines_executable') + let l:options = ale#Var(a:buffer, 'go_golines_options') + let l:env = ale#go#EnvString(a:buffer) + + if !executable(l:executable) + return 0 + endif + + return { + \ 'command': l:env . ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options) + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/gomod.vim b/vim-config/plugins/ale/autoload/ale/fixers/gomod.vim old mode 100755 new mode 100644 index 68895f9b..ee8c46c9 --- a/vim-config/plugins/ale/autoload/ale/fixers/gomod.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/gomod.vim @@ -2,9 +2,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') + let l:env = ale#go#EnvString(a:buffer) return { - \ 'command': ale#Escape(l:executable) . ' mod edit -fmt %t', + \ 'command': l:env . ale#Escape(l:executable) . ' mod edit -fmt %t', \ 'read_temporary_file': 1, \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/google_java_format.vim b/vim-config/plugins/ale/autoload/ale/fixers/google_java_format.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/hackfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/hackfmt.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/help.vim b/vim-config/plugins/ale/autoload/ale/fixers/help.vim old mode 100755 new mode 100644 index 9fb0717b..b20740fe --- a/vim-config/plugins/ale/autoload/ale/fixers/help.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/help.vim @@ -1,7 +1,7 @@ " Author: w0rp " Description: Generic fixer functions for Vim help documents. -function! ale#fixers#help#AlignTags(buffer, done, lines) abort +function! ale#fixers#help#AlignTags(buffer, lines) abort let l:new_lines = [] for l:line in a:lines diff --git a/vim-config/plugins/ale/autoload/ale/fixers/hfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/hfmt.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/hindent.vim b/vim-config/plugins/ale/autoload/ale/fixers/hindent.vim new file mode 100644 index 00000000..b6009a2c --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/hindent.vim @@ -0,0 +1,20 @@ +" Author: AlexeiDrake +" Description: Integration of hindent formatting with ALE. +" +call ale#Set('haskell_hindent_executable', 'hindent') + +function! ale#fixers#hindent#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_hindent_executable') + + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hindent') +endfunction + +function! ale#fixers#hindent#Fix(buffer) abort + let l:executable = ale#fixers#hindent#GetExecutable(a:buffer) + + return { + \ 'command': l:executable + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/hlint.vim b/vim-config/plugins/ale/autoload/ale/fixers/hlint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/html_beautify.vim b/vim-config/plugins/ale/autoload/ale/fixers/html_beautify.vim new file mode 100644 index 00000000..236cb6ec --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/html_beautify.vim @@ -0,0 +1,21 @@ +" Author: WhyNotHugo +" Description: Lint HTML files with html-beautify. +" +call ale#Set('html_beautify_executable', 'html-beautify') +call ale#Set('html_beautify_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('html_beautify_options', '') +call ale#Set('html_beautify_change_directory', 1) + +function! ale#fixers#html_beautify#Fix(buffer) abort + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'html_beautify', + \ ['html-beautify'] + \) + + let l:options = ale#Var(a:buffer, 'html_beautify_options') + + return { + \ 'command': ale#Escape(l:executable). ' ' . l:options . ' -', + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/importjs.vim b/vim-config/plugins/ale/autoload/ale/fixers/importjs.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/isort.vim b/vim-config/plugins/ale/autoload/ale/fixers/isort.vim old mode 100755 new mode 100644 index 9070fb27..6eb6a67c --- a/vim-config/plugins/ale/autoload/ale/fixers/isort.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/isort.vim @@ -2,24 +2,70 @@ " 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)) +call ale#Set('python_isort_options', '') +call ale#Set('python_isort_auto_pipenv', 0) +call ale#Set('python_isort_auto_poetry', 0) -function! ale#fixers#isort#Fix(buffer) abort - let l:options = ale#Var(a:buffer, 'python_isort_options') +function! ale#fixers#isort#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_isort_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif - let l:executable = ale#python#FindExecutable( - \ a:buffer, - \ 'python_isort', - \ ['isort'], - \) + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_isort_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif - if !executable(l:executable) - return 0 + return ale#python#FindExecutable(a:buffer, 'python_isort', ['isort']) +endfunction + +function! ale#fixers#isort#GetCmd(buffer) abort + let l:executable = ale#fixers#isort#GetExecutable(a:buffer) + let l:cmd = [ale#Escape(l:executable)] + + if l:executable =~? 'pipenv\|poetry$' + call extend(l:cmd, ['run', 'isort']) endif + return join(l:cmd, ' ') +endfunction + +function! ale#fixers#isort#FixForVersion(buffer, version) abort + let l:executable = ale#fixers#isort#GetExecutable(a:buffer) + let l:cmd = [ale#Escape(l:executable)] + + if l:executable =~? 'pipenv\|poetry$' + call extend(l:cmd, ['run', 'isort']) + endif + + if ale#semver#GTE(a:version, [5, 7, 0]) + call add(l:cmd, '--filename %s') + endif + + let l:options = ale#Var(a:buffer, 'python_isort_options') + + if !empty(l:options) + call add(l:cmd, l:options) + endif + + call add(l:cmd, '-') + return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -', + \ 'cwd': '%s:h', + \ 'command': join(l:cmd, ' '), \} endfunction + +function! ale#fixers#isort#Fix(buffer) abort + let l:executable = ale#fixers#isort#GetExecutable(a:buffer) + let l:command = ale#fixers#isort#GetCmd(a:buffer) . ale#Pad('--version') + + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ l:executable, + \ l:command, + \ function('ale#fixers#isort#FixForVersion'), + \) +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/jq.vim b/vim-config/plugins/ale/autoload/ale/fixers/jq.vim old mode 100755 new mode 100644 index 1b743e49..cd9b9138 --- a/vim-config/plugins/ale/autoload/ale/fixers/jq.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/jq.vim @@ -7,16 +7,16 @@ function! ale#fixers#jq#GetExecutable(buffer) abort 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') + 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 + if empty(l:filters) + return 0 + endif - return { - \ 'command': ale#Escape(ale#fixers#jq#GetExecutable(a:buffer)) - \ . ' ' . l:filters . ' ' - \ . l:options, - \} + return { + \ 'command': ale#Escape(ale#fixers#jq#GetExecutable(a:buffer)) + \ . ' ' . l:filters . ' ' + \ . l:options, + \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/jsonnetfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/jsonnetfmt.vim new file mode 100644 index 00000000..f1e41cd5 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/jsonnetfmt.vim @@ -0,0 +1,18 @@ +" Authors: Trevor Whitney and Takuya Kosugiyama +" Description: Integration of jsonnetfmt with ALE. + +call ale#Set('jsonnet_jsonnetfmt_executable', 'jsonnetfmt') +call ale#Set('jsonnet_jsonnetfmt_options', '') + +function! ale#fixers#jsonnetfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'jsonnet_jsonnetfmt_executable') + let l:options = ale#Var(a:buffer, 'jsonnet_jsonnetfmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -i' + \ . ale#Pad(l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/ktlint.vim b/vim-config/plugins/ale/autoload/ale/fixers/ktlint.vim new file mode 100644 index 00000000..64d1340d --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/ktlint.vim @@ -0,0 +1,8 @@ +" 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' + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/latexindent.vim b/vim-config/plugins/ale/autoload/ale/fixers/latexindent.vim new file mode 100644 index 00000000..54f1231e --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/latexindent.vim @@ -0,0 +1,16 @@ +" 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' + \ . (empty(l:options) ? '' : ' ' . l:options) + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/lua_format.vim b/vim-config/plugins/ale/autoload/ale/fixers/lua_format.vim new file mode 100644 index 00000000..98b155c0 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/lua_format.vim @@ -0,0 +1,16 @@ +" Author: Mathias Jean Johansen +" Description: Integration of LuaFormatter with ALE. + +call ale#Set('lua_lua_format_executable', 'lua-format') +call ale#Set('lua_lua_format_options', '') + +function! ale#fixers#lua_format#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'lua_lua_format_executable') + let l:options = ale#Var(a:buffer, 'lua_lua_format_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ale#Pad(l:options) + \ . ' -i', + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/luafmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/luafmt.vim new file mode 100644 index 00000000..6cb9ef4a --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/luafmt.vim @@ -0,0 +1,13 @@ +call ale#Set('lua_luafmt_executable', 'luafmt') +call ale#Set('lua_luafmt_options', '') + +function! ale#fixers#luafmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'lua_luafmt_executable') + let l:options = ale#Var(a:buffer, 'lua_luafmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' --stdin', + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/mix_format.vim b/vim-config/plugins/ale/autoload/ale/fixers/mix_format.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/nimpretty.vim b/vim-config/plugins/ale/autoload/ale/fixers/nimpretty.vim new file mode 100644 index 00000000..fe2e7136 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/nimpretty.vim @@ -0,0 +1,15 @@ +" Author: Nhan +" Description: Integration of nimpretty with ALE. + +call ale#Set('nim_nimpretty_executable', 'nimpretty') +call ale#Set('nim_nimpretty_options', '--maxLineLen:80') + +function! ale#fixers#nimpretty#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'nim_nimpretty_executable') + let l:options = ale#Var(a:buffer, 'nim_nimpretty_options') + + return { + \ 'command': ale#Escape(l:executable) . ' %t' . ale#Pad(l:options), + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/nixfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/nixfmt.vim new file mode 100644 index 00000000..4a548b23 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/nixfmt.vim @@ -0,0 +1,15 @@ +scriptencoding utf-8 +" Author: houstdav000 +" Description: Fix files with nixfmt + +call ale#Set('nix_nixfmt_executable', 'nixfmt') +call ale#Set('nix_nixfmt_options', '') + +function! ale#fixers#nixfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'nix_nixfmt_executable') + let l:options = ale#Var(a:buffer, 'nix_nixfmt_options') + + return { + \ 'command': ale#Escape(l:executable) . ale#Pad(l:options), + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/nixpkgsfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/nixpkgsfmt.vim new file mode 100644 index 00000000..403ce798 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/nixpkgsfmt.vim @@ -0,0 +1,12 @@ +call ale#Set('nix_nixpkgsfmt_executable', 'nixpkgs-fmt') +call ale#Set('nix_nixpkgsfmt_options', '') + +function! ale#fixers#nixpkgsfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'nix_nixpkgsfmt_executable') + let l:options = ale#Var(a:buffer, 'nix_nixpkgsfmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options), + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/ocamlformat.vim b/vim-config/plugins/ale/autoload/ale/fixers/ocamlformat.vim old mode 100755 new mode 100644 index 9b7c3e12..b12d2eb9 --- a/vim-config/plugins/ale/autoload/ale/fixers/ocamlformat.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/ocamlformat.vim @@ -5,14 +5,13 @@ 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) + \ . ' --name=%s' \ . ' -' \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/ocp_indent.vim b/vim-config/plugins/ale/autoload/ale/fixers/ocp_indent.vim new file mode 100644 index 00000000..e1b047b3 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/autoload/ale/fixers/ormolu.vim b/vim-config/plugins/ale/autoload/ale/fixers/ormolu.vim new file mode 100644 index 00000000..69b55c1f --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/ormolu.vim @@ -0,0 +1,12 @@ +call ale#Set('haskell_ormolu_executable', 'ormolu') +call ale#Set('haskell_ormolu_options', '') + +function! ale#fixers#ormolu#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_ormolu_executable') + let l:options = ale#Var(a:buffer, 'haskell_ormolu_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options), + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/pandoc.vim b/vim-config/plugins/ale/autoload/ale/fixers/pandoc.vim new file mode 100644 index 00000000..d704c8a2 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/pandoc.vim @@ -0,0 +1,16 @@ +scriptencoding utf-8 +" Author: Jesse Hathaway +" Description: Fix markdown files with pandoc. + +call ale#Set('markdown_pandoc_executable', 'pandoc') +call ale#Set('markdown_pandoc_options', '-f gfm -t gfm -s -') + +function! ale#fixers#pandoc#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'markdown_pandoc_executable') + let l:options = ale#Var(a:buffer, 'markdown_pandoc_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' ' . l:options, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/perltidy.vim b/vim-config/plugins/ale/autoload/ale/fixers/perltidy.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/pgformatter.vim b/vim-config/plugins/ale/autoload/ale/fixers/pgformatter.vim new file mode 100644 index 00000000..9ea08ec6 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/autoload/ale/fixers/php_cs_fixer.vim b/vim-config/plugins/ale/autoload/ale/fixers/php_cs_fixer.vim old mode 100755 new mode 100644 index 5c59e262..c8f9c7b0 --- a/vim-config/plugins/ale/autoload/ale/fixers/php_cs_fixer.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/php_cs_fixer.vim @@ -6,7 +6,7 @@ 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', [ + return ale#path#FindExecutable(a:buffer, 'php_cs_fixer', [ \ 'vendor/bin/php-cs-fixer', \ 'php-cs-fixer' \]) diff --git a/vim-config/plugins/ale/autoload/ale/fixers/phpcbf.vim b/vim-config/plugins/ale/autoload/ale/fixers/phpcbf.vim old mode 100755 new mode 100644 index f14b8406..494bf346 --- a/vim-config/plugins/ale/autoload/ale/fixers/phpcbf.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/phpcbf.vim @@ -2,11 +2,12 @@ " Description: Fixing files with phpcbf. call ale#Set('php_phpcbf_standard', '') +call ale#Set('php_phpcbf_options', '') 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', [ + return ale#path#FindExecutable(a:buffer, 'php_phpcbf', [ \ 'vendor/bin/phpcbf', \ 'phpcbf' \]) @@ -20,6 +21,6 @@ function! ale#fixers#phpcbf#Fix(buffer) abort \ : '' return { - \ 'command': ale#Escape(l:executable) . ' --stdin-path=%s ' . l:standard_option . ' -' + \ 'command': ale#Escape(l:executable) . ' --stdin-path=%s ' . l:standard_option . ale#Pad(ale#Var(a:buffer, 'php_phpcbf_options')) . ' -' \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/prettier.vim b/vim-config/plugins/ale/autoload/ale/fixers/prettier.vim old mode 100755 new mode 100644 index 95932474..8a67e2ff --- a/vim-config/plugins/ale/autoload/ale/fixers/prettier.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/prettier.vim @@ -7,7 +7,7 @@ call ale#Set('javascript_prettier_use_global', get(g:, 'ale_use_global_executabl call ale#Set('javascript_prettier_options', '') function! ale#fixers#prettier#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'javascript_prettier', [ + return ale#path#FindExecutable(a:buffer, 'javascript_prettier', [ \ 'node_modules/.bin/prettier_d', \ 'node_modules/prettier-cli/index.js', \ 'node_modules/.bin/prettier', @@ -15,16 +15,12 @@ function! ale#fixers#prettier#GetExecutable(buffer) abort endfunction function! ale#fixers#prettier#Fix(buffer) abort - let l:executable = ale#fixers#prettier#GetExecutable(a:buffer) - - let l:command = ale#semver#HasVersion(l:executable) - \ ? '' - \ : ale#Escape(l:executable) . ' --version' - - return { - \ 'command': l:command, - \ 'chain_with': 'ale#fixers#prettier#ApplyFixForVersion', - \} + 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 @@ -38,22 +34,34 @@ function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort return a:output endfunction -function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort +function! ale#fixers#prettier#GetCwd(buffer) abort + let l:config = ale#path#FindNearestFile(a:buffer, '.prettierignore') + + " Fall back to the directory of the buffer + return !empty(l:config) ? fnamemodify(l:config, ':h') : '%s:h' +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:version = ale#semver#GetVersion(l:executable, a:version_output) let l:parser = '' + let l:filetypes = split(getbufvar(a:buffer, '&filetype'), '\.') + + if index(l:filetypes, 'handlebars') > -1 + let l:parser = 'glimmer' + endif + " 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 + if empty(expand('#' . a:buffer . ':e')) && l:parser is# '' && 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(l:version, [1, 16, 0]) - let l:parser = 'babel' + if ale#semver#GTE(a:version, [1, 16, 0]) + let l:parser = 'babel' else - let l:parser = 'babylon' + let l:parser = 'babylon' endif let l:prettier_parsers = { @@ -66,11 +74,14 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort \ 'graphql': 'graphql', \ 'markdown': 'markdown', \ 'vue': 'vue', + \ 'svelte': 'svelte', \ 'yaml': 'yaml', + \ 'openapi': 'yaml', \ 'html': 'html', + \ 'ruby': 'ruby', \} - for l:filetype in split(getbufvar(a:buffer, '&filetype'), '\.') + for l:filetype in l:filetypes if has_key(l:prettier_parsers, l:filetype) let l:parser = l:prettier_parsers[l:filetype] break @@ -85,8 +96,8 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort " Special error handling needed for prettier_d if l:executable =~# 'prettier_d$' return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) + \ 'cwd': '%s:h', + \ 'command':ale#Escape(l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --stdin-filepath %s --stdin', \ 'process_with': 'ale#fixers#prettier#ProcessPrettierDOutput', @@ -94,10 +105,10 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort endif " 1.4.0 is the first version with --stdin-filepath - if ale#semver#GTE(l:version, [1, 4, 0]) + if ale#semver#GTE(a:version, [1, 4, 0]) return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) + \ 'cwd': ale#fixers#prettier#GetCwd(a:buffer), + \ 'command': ale#Escape(l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --stdin-filepath %s --stdin', \} diff --git a/vim-config/plugins/ale/autoload/ale/fixers/prettier_eslint.vim b/vim-config/plugins/ale/autoload/ale/fixers/prettier_eslint.vim old mode 100755 new mode 100644 index bc0caadd..0b9c88b7 --- a/vim-config/plugins/ale/autoload/ale/fixers/prettier_eslint.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/prettier_eslint.vim @@ -2,42 +2,32 @@ " w0rp , morhetz (Pavel Pertsev) " Description: Integration between Prettier and ESLint. -function! ale#fixers#prettier_eslint#SetOptionDefaults() abort - 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', '') -endfunction - -call ale#fixers#prettier_eslint#SetOptionDefaults() +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', [ + return ale#path#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 - let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer) - - let l:command = ale#semver#HasVersion(l:executable) - \ ? '' - \ : ale#Escape(l:executable) . ' --version' - - return { - \ 'command': l:command, - \ 'chain_with': 'ale#fixers#prettier_eslint#ApplyFixForVersion', - \} + 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_output) abort +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) - let l:version = ale#semver#GetVersion(l:executable, a:version_output) - " 4.2.0 is the first version with --eslint-config-path - let l:config = ale#semver#GTE(l:version, [4, 2, 0]) + 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) @@ -45,10 +35,10 @@ function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version_output) \ : '' " 4.4.0 is the first version with --stdin-filepath - if ale#semver#GTE(l:version, [4, 4, 0]) + if ale#semver#GTE(a:version, [4, 4, 0]) return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(l:executable) \ . l:eslint_config_option \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --stdin-filepath %s --stdin', diff --git a/vim-config/plugins/ale/autoload/ale/fixers/prettier_standard.vim b/vim-config/plugins/ale/autoload/ale/fixers/prettier_standard.vim old mode 100755 new mode 100644 index b6e0a6f9..c8c09e31 --- a/vim-config/plugins/ale/autoload/ale/fixers/prettier_standard.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/prettier_standard.vim @@ -6,7 +6,7 @@ call ale#Set('javascript_prettier_standard_use_global', get(g:, 'ale_use_global_ call ale#Set('javascript_prettier_standard_options', '') function! ale#fixers#prettier_standard#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'javascript_prettier_standard', [ + return ale#path#FindExecutable(a:buffer, 'javascript_prettier_standard', [ \ 'node_modules/prettier-standard/lib/index.js', \ 'node_modules/.bin/prettier-standard', \]) @@ -17,8 +17,8 @@ function! ale#fixers#prettier_standard#Fix(buffer) abort return { \ 'command': ale#Escape(ale#fixers#prettier_standard#GetExecutable(a:buffer)) - \ . ' %t' + \ . ' --stdin' + \ . ' --stdin-filepath=%s' \ . ' ' . l:options, - \ 'read_temporary_file': 1, \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/protolint.vim b/vim-config/plugins/ale/autoload/ale/fixers/protolint.vim new file mode 100644 index 00000000..9b8e72f1 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/protolint.vim @@ -0,0 +1,26 @@ +" Author: Yohei Yoshimuta +" Description: Integration of protolint with ALE. + +call ale#Set('proto_protolint_executable', 'protolint') +call ale#Set('proto_protolint_config', '') + +function! ale#fixers#protolint#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'proto_protolint_executable') + + return ale#Escape(l:executable) +endfunction + +function! ale#fixers#protolint#Fix(buffer) abort + let l:executable = ale#fixers#protolint#GetExecutable(a:buffer) + let l:config = ale#Var(a:buffer, 'proto_protolint_config') + + return { + \ 'command': l:executable + \ . (!empty(l:config) ? ' -config_path=' . ale#Escape(l:config) : '') + \ . ' -fix' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction + + diff --git a/vim-config/plugins/ale/autoload/ale/fixers/ptop.vim b/vim-config/plugins/ale/autoload/ale/fixers/ptop.vim new file mode 100644 index 00000000..98345226 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/ptop.vim @@ -0,0 +1,17 @@ +" Author: BarrOff https://github.com/BarrOff +" Description: Integration of ptop with ALE. + +call ale#Set('pascal_ptop_executable', 'ptop') +call ale#Set('pascal_ptop_options', '') + +function! ale#fixers#ptop#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'pascal_ptop_executable') + let l:options = ale#Var(a:buffer, 'pascal_ptop_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %s %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/puppetlint.vim b/vim-config/plugins/ale/autoload/ale/fixers/puppetlint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/purs_tidy.vim b/vim-config/plugins/ale/autoload/ale/fixers/purs_tidy.vim new file mode 100644 index 00000000..09fa631b --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/purs_tidy.vim @@ -0,0 +1,24 @@ +" Author: toastal +" Description: Integration of purs-tidy with ALE. + +call ale#Set('purescript_tidy_executable', 'purs-tidy') +call ale#Set('purescript_tidy_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('purescript_tidy_options', '') + +function! ale#fixers#purs_tidy#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'purescript_tidy', [ + \ 'node_modules/purescript-tidy/bin/index.js', + \ 'node_modules/.bin/purs-tidy', + \]) +endfunction + +function! ale#fixers#purs_tidy#Fix(buffer) abort + let l:executable = ale#fixers#purs_tidy#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'purescript_tidy_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' format' + \ . ale#Pad(l:options) + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/purty.vim b/vim-config/plugins/ale/autoload/ale/fixers/purty.vim new file mode 100644 index 00000000..46d2cacd --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/purty.vim @@ -0,0 +1,22 @@ +" Author: iclanzan +" Description: Integration of purty with ALE. + +call ale#Set('purescript_purty_executable', 'purty') + +function! ale#fixers#purty#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'purescript_purty_executable') + + return ale#Escape(l:executable) +endfunction + +function! ale#fixers#purty#Fix(buffer) abort + let l:executable = ale#fixers#purty#GetExecutable(a:buffer) + + return { + \ 'command': l:executable + \ . ' --write' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction + diff --git a/vim-config/plugins/ale/autoload/ale/fixers/qmlfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/qmlfmt.vim old mode 100755 new mode 100644 index d750d1c4..90b25679 --- a/vim-config/plugins/ale/autoload/ale/fixers/qmlfmt.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/qmlfmt.vim @@ -5,7 +5,7 @@ function! ale#fixers#qmlfmt#GetExecutable(buffer) abort endfunction function! ale#fixers#qmlfmt#Fix(buffer) abort - return { - \ 'command': ale#Escape(ale#fixers#qmlfmt#GetExecutable(a:buffer)), - \} + return { + \ 'command': ale#Escape(ale#fixers#qmlfmt#GetExecutable(a:buffer)), + \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/refmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/refmt.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/remark_lint.vim b/vim-config/plugins/ale/autoload/ale/fixers/remark_lint.vim new file mode 100644 index 00000000..85593b44 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/remark_lint.vim @@ -0,0 +1,24 @@ +" Author: blyoa +" Description: Fixing files with remark-lint. + +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#fixers#remark_lint#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'markdown_remark_lint', [ + \ 'node_modules/remark-cli/cli.js', + \ 'node_modules/.bin/remark', + \]) +endfunction + +function! ale#fixers#remark_lint#Fix(buffer) abort + let l:executable = ale#fixers#remark_lint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'markdown_remark_lint_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : ''), + \} +endfunction + diff --git a/vim-config/plugins/ale/autoload/ale/fixers/reorder_python_imports.vim b/vim-config/plugins/ale/autoload/ale/fixers/reorder_python_imports.vim new file mode 100644 index 00000000..42a0a6e2 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/autoload/ale/fixers/rubocop.vim b/vim-config/plugins/ale/autoload/ale/fixers/rubocop.vim old mode 100755 new mode 100644 index 33ba6887..5a1b7959 --- a/vim-config/plugins/ale/autoload/ale/fixers/rubocop.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/rubocop.vim @@ -1,20 +1,38 @@ call ale#Set('ruby_rubocop_options', '') +call ale#Set('ruby_rubocop_auto_correct_all', 0) call ale#Set('ruby_rubocop_executable', 'rubocop') +" Rubocop fixer outputs diagnostics first and then the fixed +" output. These are delimited by a "=======" string that we +" look for to remove everything before it. +function! ale#fixers#rubocop#PostProcess(buffer, output) abort + let l:line = 0 + + for l:output in a:output + let l:line = l:line + 1 + + if l:output =~# "^=\\+$" + break + endif + endfor + + return a:output[l:line :] +endfunction + 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') + let l:auto_correct_all = ale#Var(a:buffer, 'ruby_rubocop_auto_correct_all') - return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop') - \ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '') + return ale#ruby#EscapeExecutable(l:executable, 'rubocop') \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' --auto-correct --force-exclusion %t' + \ . (l:auto_correct_all ? ' --auto-correct-all' : ' --auto-correct') + \ . ' --force-exclusion --stdin %s' endfunction function! ale#fixers#rubocop#Fix(buffer) abort return { \ 'command': ale#fixers#rubocop#GetCommand(a:buffer), - \ 'read_temporary_file': 1, + \ 'process_with': 'ale#fixers#rubocop#PostProcess' \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/rufo.vim b/vim-config/plugins/ale/autoload/ale/fixers/rufo.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/rustfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/rustfmt.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/scalafmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/scalafmt.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/shfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/shfmt.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/sorbet.vim b/vim-config/plugins/ale/autoload/ale/fixers/sorbet.vim new file mode 100644 index 00000000..7c12fa1e --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/sorbet.vim @@ -0,0 +1,19 @@ +call ale#Set('ruby_sorbet_executable', 'srb') +call ale#Set('ruby_sorbet_options', '') + +function! ale#fixers#sorbet#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable') + let l:options = ale#Var(a:buffer, 'ruby_sorbet_options') + + return ale#ruby#EscapeExecutable(l:executable, 'srb') + \ . ' tc' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --autocorrect --file %t' +endfunction + +function! ale#fixers#sorbet#Fix(buffer) abort + return { + \ 'command': ale#fixers#sorbet#GetCommand(a:buffer), + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/sqlfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/sqlfmt.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/sqlformat.vim b/vim-config/plugins/ale/autoload/ale/fixers/sqlformat.vim new file mode 100644 index 00000000..6319c1ac --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/sqlformat.vim @@ -0,0 +1,16 @@ +" Author: Cluas +" Description: Fixing files with sqlformat. + +call ale#Set('sql_sqlformat_executable', 'sqlformat') +call ale#Set('sql_sqlformat_options', '') + +function! ale#fixers#sqlformat#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'sql_sqlformat_executable') + let l:options = ale#Var(a:buffer, 'sql_sqlformat_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -' + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/standard.vim b/vim-config/plugins/ale/autoload/ale/fixers/standard.vim old mode 100755 new mode 100644 index 77712d40..b9d60ebb --- a/vim-config/plugins/ale/autoload/ale/fixers/standard.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/standard.vim @@ -6,7 +6,8 @@ call ale#Set('javascript_standard_use_global', get(g:, 'ale_use_global_executabl call ale#Set('javascript_standard_options', '') function! ale#fixers#standard#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'javascript_standard', [ + return ale#path#FindExecutable(a:buffer, 'javascript_standard', [ + \ 'node_modules/standardx/bin/cmd.js', \ 'node_modules/standard/bin/cmd.js', \ 'node_modules/.bin/standard', \]) @@ -14,12 +15,19 @@ 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') + let l:filetype = getbufvar(a:buffer, '&filetype') + let l:options_type = 'javascript_standard_options' + + if l:filetype =~# 'typescript' + let l:options_type = 'typescript_standard_options' + endif + + let l:options = ale#Var(a:buffer, l:options_type) return { \ 'command': ale#node#Executable(a:buffer, l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' --fix %t', + \ . ' --fix --stdin < %s > %t', \ 'read_temporary_file': 1, \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/standardrb.vim b/vim-config/plugins/ale/autoload/ale/fixers/standardrb.vim old mode 100755 new mode 100644 index fab1e2bc..acb310c6 --- a/vim-config/plugins/ale/autoload/ale/fixers/standardrb.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/standardrb.vim @@ -9,15 +9,15 @@ function! ale#fixers#standardrb#GetCommand(buffer) abort 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') + return ale#ruby#EscapeExecutable(l:executable, 'standardrb') \ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '') \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' --fix --force-exclusion %t' + \ . ' --fix --force-exclusion --stdin %s' endfunction function! ale#fixers#standardrb#Fix(buffer) abort return { \ 'command': ale#fixers#standardrb#GetCommand(a:buffer), - \ 'read_temporary_file': 1, + \ 'process_with': 'ale#fixers#rubocop#PostProcess' \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/stylelint.vim b/vim-config/plugins/ale/autoload/ale/fixers/stylelint.vim old mode 100755 new mode 100644 index 30309c7e..650b9c4a --- a/vim-config/plugins/ale/autoload/ale/fixers/stylelint.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/stylelint.vim @@ -3,21 +3,24 @@ call ale#Set('stylelint_executable', 'stylelint') call ale#Set('stylelint_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('stylelint_options', '') function! ale#fixers#stylelint#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'stylelint', [ - \ 'node_modules/stylelint/bin/stylelint.js', - \ 'node_modules/.bin/stylelint', - \]) + return ale#path#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) + let l:options = ale#Var(a:buffer, 'stylelint_options') return { + \ 'cwd': '%s:h', \ 'command': ale#node#Executable(a:buffer, l:executable) - \ . ' --fix %t', - \ 'read_temporary_file': 1, + \ . ale#Pad(l:options) + \ . ' --fix --stdin --stdin-filename %s', + \ 'read_temporary_file': 0, \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/styler.vim b/vim-config/plugins/ale/autoload/ale/fixers/styler.vim new file mode 100644 index 00000000..1c7607bd --- /dev/null +++ b/vim-config/plugins/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), transformers = ' + \ . ale#Var(a:buffer, 'r_styler_options') . ')"' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/stylish_haskell.vim b/vim-config/plugins/ale/autoload/ale/fixers/stylish_haskell.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/stylua.vim b/vim-config/plugins/ale/autoload/ale/fixers/stylua.vim new file mode 100644 index 00000000..3521c935 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/stylua.vim @@ -0,0 +1,14 @@ +" Author: Robert Liebowitz +" Description: https://github.com/johnnymorganz/stylua + +call ale#Set('lua_stylua_executable', 'stylua') +call ale#Set('lua_stylua_options', '') + +function! ale#fixers#stylua#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'lua_stylua_executable') + let l:options = ale#Var(a:buffer, 'lua_stylua_options') + + return { + \ 'command': ale#Escape(l:executable) . ale#Pad(l:options) . ' -', + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/swiftformat.vim b/vim-config/plugins/ale/autoload/ale/fixers/swiftformat.vim old mode 100755 new mode 100644 index 304182b2..cc553b7d --- a/vim-config/plugins/ale/autoload/ale/fixers/swiftformat.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/swiftformat.vim @@ -6,7 +6,7 @@ call ale#Set('swift_swiftformat_use_global', get(g:, 'ale_use_global_executables call ale#Set('swift_swiftformat_options', '') function! ale#fixers#swiftformat#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'swift_swiftformat', [ + return ale#path#FindExecutable(a:buffer, 'swift_swiftformat', [ \ 'Pods/SwiftFormat/CommandLineTool/swiftformat', \ 'ios/Pods/SwiftFormat/CommandLineTool/swiftformat', \ 'swiftformat', diff --git a/vim-config/plugins/ale/autoload/ale/fixers/terraform.vim b/vim-config/plugins/ale/autoload/ale/fixers/terraform.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/textlint.vim b/vim-config/plugins/ale/autoload/ale/fixers/textlint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/tidy.vim b/vim-config/plugins/ale/autoload/ale/fixers/tidy.vim old mode 100755 new mode 100644 index 1af4120b..2c79e73a --- a/vim-config/plugins/ale/autoload/ale/fixers/tidy.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/tidy.vim @@ -5,7 +5,7 @@ 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( + let l:executable = ale#path#FindExecutable( \ a:buffer, \ 'html_tidy', \ ['tidy'], diff --git a/vim-config/plugins/ale/autoload/ale/fixers/tslint.vim b/vim-config/plugins/ale/autoload/ale/fixers/tslint.vim old mode 100755 new mode 100644 index b352af3a..15768fd5 --- a/vim-config/plugins/ale/autoload/ale/fixers/tslint.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/tslint.vim @@ -16,7 +16,7 @@ function! ale#fixers#tslint#Fix(buffer) abort return { \ 'command': ale#node#Executable(a:buffer, l:executable) \ . l:tslint_config_option - \ . ' --fix %t', + \ . ' --outputAbsolutePaths --fix %t', \ 'read_temporary_file': 1, \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/uncrustify.vim b/vim-config/plugins/ale/autoload/ale/fixers/uncrustify.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/vfmt.vim b/vim-config/plugins/ale/autoload/ale/fixers/vfmt.vim new file mode 100644 index 00000000..2e780318 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/vfmt.vim @@ -0,0 +1,13 @@ +" Author: fiatjaf +" Description: Integration of `v fmt` with ALE. + +call ale#Set('v_vfmt_options', '') + +function! ale#fixers#vfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'v_v_executable') + let l:options = ale#Var(a:buffer, 'v_vfmt_options') + + return { + \ 'command': ale#Escape(l:executable) . ' fmt' . ale#Pad(l:options) + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/xmllint.vim b/vim-config/plugins/ale/autoload/ale/fixers/xmllint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/fixers/xo.vim b/vim-config/plugins/ale/autoload/ale/fixers/xo.vim old mode 100755 new mode 100644 index 882350be..dcf4c737 --- a/vim-config/plugins/ale/autoload/ale/fixers/xo.vim +++ b/vim-config/plugins/ale/autoload/ale/fixers/xo.vim @@ -1,23 +1,36 @@ " 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#Fix(buffer) abort + let l:executable = ale#handlers#xo#GetExecutable(a:buffer) + let l:options = ale#handlers#xo#GetOptions(a:buffer) -function! ale#fixers#xo#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'javascript_xo', [ - \ 'node_modules/xo/cli.js', - \ 'node_modules/.bin/xo', - \]) + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ l:executable, + \ '%e --version', + \ {b, v -> ale#fixers#xo#ApplyFixForVersion(b, v, l:executable, l:options)} + \) endfunction -function! ale#fixers#xo#Fix(buffer) abort - let l:executable = ale#fixers#xo#GetExecutable(a:buffer) +function! ale#fixers#xo#ApplyFixForVersion(buffer, version, executable, options) abort + let l:executable = ale#node#Executable(a:buffer, a:executable) + let l:options = ale#Pad(a:options) + + " 0.30.0 is the first version with a working --stdin --fix + if ale#semver#GTE(a:version, [0, 30, 0]) + return { + \ 'command': l:executable + \ . ' --stdin --stdin-filename %s' + \ . ' --fix' + \ . l:options, + \} + endif return { - \ 'command': ale#node#Executable(a:buffer, l:executable) - \ . ' --fix %t', + \ 'command': l:executable + \ . ' --fix %t' + \ . l:options, \ 'read_temporary_file': 1, \} endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/yamlfix.vim b/vim-config/plugins/ale/autoload/ale/fixers/yamlfix.vim new file mode 100644 index 00000000..6654a25c --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/fixers/yamlfix.vim @@ -0,0 +1,25 @@ +" Author: lyz-code +" Description: Fixing yaml files with yamlfix. + +call ale#Set('yaml_yamlfix_executable', 'yamlfix') +call ale#Set('yaml_yamlfix_options', '') +call ale#Set('yaml_yamlfix_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#yamlfix#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'yaml_yamlfix_options') + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'yaml_yamlfix', + \ ['yamlfix'], + \) + + if !executable(l:executable) + return 0 + endif + + return { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') . ' -', + \} +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/fixers/yapf.vim b/vim-config/plugins/ale/autoload/ale/fixers/yapf.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/floating_preview.vim b/vim-config/plugins/ale/autoload/ale/floating_preview.vim new file mode 100644 index 00000000..f0bc8f80 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/floating_preview.vim @@ -0,0 +1,203 @@ +" Author: Jan-Grimo Sobez +" Author: Kevin Clark +" Author: D. Ben Knoble +" Description: Floating preview window for showing whatever information in. + +" Precondition: exists('*nvim_open_win') || has('popupwin') + +function! ale#floating_preview#Show(lines, ...) abort + if !exists('*nvim_open_win') && !has('popupwin') + execute 'echom ''Floating windows not supported in this vim instance.''' + + return + endif + + let l:options = get(a:000, 0, {}) + + if has('nvim') + call s:NvimShow(a:lines, l:options) + else + call s:VimShow(a:lines, l:options) + endif +endfunction + +function! s:NvimShow(lines, options) abort + " Remove the close autocmd so it doesn't happen mid update + augroup ale_floating_preview_window + autocmd! + augroup END + + " Only create a new window if we need it + if !exists('w:preview') || index(nvim_list_wins(), w:preview['id']) is# -1 + call s:NvimCreate(a:options) + else + call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:true) + endif + + " Execute commands in window context + let l:parent_window = nvim_get_current_win() + + call nvim_set_current_win(w:preview['id']) + + for l:command in get(a:options, 'commands', []) + call execute(l:command) + endfor + + call nvim_set_current_win(l:parent_window) + + " Return to parent context on move + augroup ale_floating_preview_window + autocmd! + + if g:ale_close_preview_on_insert + autocmd CursorMoved,TabLeave,WinLeave,InsertEnter ++once call s:NvimClose() + else + autocmd CursorMoved,TabLeave,WinLeave ++once call s:NvimClose() + endif + augroup END + + let [l:lines, l:width, l:height] = s:NvimPrepareWindowContent(a:lines) + + call nvim_win_set_width(w:preview['id'], l:width) + call nvim_win_set_height(w:preview['id'], l:height) + call nvim_buf_set_lines(w:preview['buffer'], 0, -1, v:false, l:lines) + call nvim_buf_set_option(w:preview['buffer'], 'modified', v:false) + call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:false) +endfunction + +function! s:VimShow(lines, options) abort + if g:ale_close_preview_on_insert + " Remove the close autocmd so it doesn't happen mid update + silent! autocmd! ale_floating_preview_window + endif + + " Only create a new window if we need it + if !exists('w:preview') || index(popup_list(), w:preview['id']) is# -1 + call s:VimCreate(a:options) + endif + + " Execute commands in window context + for l:command in get(a:options, 'commands', []) + call win_execute(w:preview['id'], l:command) + endfor + + call popup_settext(w:preview['id'], a:lines) + + if g:ale_close_preview_on_insert + augroup ale_floating_preview_window + autocmd! + autocmd InsertEnter * ++once call s:VimClose() + augroup END + endif +endfunction + +function! s:NvimPrepareWindowContent(lines) abort + let l:max_height = 10 + + let l:width = max(map(copy(a:lines), 'strdisplaywidth(v:val)')) + let l:height = min([len(a:lines), l:max_height]) + + if empty(g:ale_floating_window_border) + return [a:lines, l:width, l:height] + endif + + " Add the size of borders + let l:width += 2 + let l:height += 2 + + let l:hor = g:ale_floating_window_border[0] + let l:top = g:ale_floating_window_border[1] + let l:top_left = g:ale_floating_window_border[2] + let l:top_right = g:ale_floating_window_border[3] + let l:bottom_right = g:ale_floating_window_border[4] + let l:bottom_left = g:ale_floating_window_border[5] + + let l:lines = [l:top_left . repeat(l:top, l:width - 2) . l:top_right] + + for l:line in a:lines + let l:line_width = strchars(l:line) + let l:lines = add(l:lines, l:hor . l:line . repeat(' ', l:width - l:line_width - 2). l:hor) + endfor + + " Truncate the lines + if len(l:lines) > l:max_height + 1 + let l:lines = l:lines[0:l:max_height] + endif + + let l:lines = add(l:lines, l:bottom_left . repeat(l:top, l:width - 2) . l:bottom_right) + + return [l:lines, l:width, l:height] +endfunction + +function! s:NvimCreate(options) abort + let l:buffer = nvim_create_buf(v:false, v:false) + let l:winid = nvim_open_win(l:buffer, v:false, { + \ 'relative': 'cursor', + \ 'row': 1, + \ 'col': 0, + \ 'width': 42, + \ 'height': 4, + \ 'style': 'minimal' + \ }) + call nvim_buf_set_option(l:buffer, 'buftype', 'acwrite') + call nvim_buf_set_option(l:buffer, 'bufhidden', 'delete') + call nvim_buf_set_option(l:buffer, 'swapfile', v:false) + call nvim_buf_set_option(l:buffer, 'filetype', get(a:options, 'filetype', 'ale-preview')) + + let w:preview = {'id': l:winid, 'buffer': l:buffer} +endfunction + +function! s:VimCreate(options) abort + let l:popup_id = popup_create([], { + \ 'line': 'cursor+1', + \ 'col': 'cursor', + \ 'drag': v:true, + \ 'resize': v:true, + \ 'close': 'button', + \ 'padding': [0, 1, 0, 1], + \ 'border': [], + \ 'borderchars': empty(g:ale_floating_window_border) ? [' '] : [ + \ g:ale_floating_window_border[1], + \ g:ale_floating_window_border[0], + \ g:ale_floating_window_border[1], + \ g:ale_floating_window_border[0], + \ g:ale_floating_window_border[2], + \ g:ale_floating_window_border[3], + \ g:ale_floating_window_border[4], + \ g:ale_floating_window_border[5], + \ ], + \ 'moved': 'any', + \ }) + call setbufvar(winbufnr(l:popup_id), '&filetype', get(a:options, 'filetype', 'ale-preview')) + let w:preview = {'id': l:popup_id} +endfunction + +function! s:NvimClose() abort + let l:mode = mode() + let l:restore_visual = l:mode is# 'v' || l:mode is# 'V' || l:mode is# "\" + + if !exists('w:preview') + return + endif + + call setbufvar(w:preview['buffer'], '&modified', 0) + + if win_id2win(w:preview['id']) > 0 + execute win_id2win(w:preview['id']).'wincmd c' + endif + + unlet w:preview + + if l:restore_visual + normal! gv + endif +endfunction + +function! s:VimClose() abort + if !exists('w:preview') + return + endif + + call popup_close(w:preview['id']) + unlet w:preview +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/go.vim b/vim-config/plugins/ale/autoload/ale/go.vim old mode 100755 new mode 100644 index a166480a..bce85a87 --- a/vim-config/plugins/ale/autoload/ale/go.vim +++ b/vim-config/plugins/ale/autoload/ale/go.vim @@ -9,19 +9,50 @@ function! ale#go#FindProjectRoot(buffer) abort 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) + 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 + " 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 + return l:default_go_path endif return '' endfunction + + +call ale#Set('go_go111module', '') + +" Return a string setting Go-specific environment variables +function! ale#go#EnvString(buffer) abort + let l:env = '' + + " GO111MODULE - turn go modules behavior on/off + let l:go111module = ale#Var(a:buffer, 'go_go111module') + + if !empty(l:go111module) + let l:env = ale#Env('GO111MODULE', l:go111module) . l:env + endif + + return l:env +endfunction + +function! ale#go#GetGoPathExecutable(suffix) abort + let l:prefix = $GOPATH + + if !empty($GOPATH) + let l:prefix = $GOPATH + elseif has('win32') + let l:prefix = $USERPROFILE . '/go' + else + let l:prefix = $HOME . '/go' + endif + + return ale#path#Simplify(l:prefix . '/' . a:suffix) +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/gradle.vim b/vim-config/plugins/ale/autoload/ale/gradle.vim old mode 100755 new mode 100644 index dc377fb9..ba1add4d --- a/vim-config/plugins/ale/autoload/ale/gradle.vim +++ b/vim-config/plugins/ale/autoload/ale/gradle.vim @@ -50,18 +50,25 @@ function! ale#gradle#FindExecutable(buffer) abort 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. +" Given a buffer number, get a working directory and command to print the +" classpath of the root project. +" +" Returns an empty string for the command if Gradle is not detected. 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' + if !empty(l:executable) + let l:project_root = ale#gradle#FindProjectRoot(a:buffer) + + if !empty(l:project_root) + return [ + \ l:project_root, + \ ale#Escape(l:executable) + \ . ' -I ' . ale#Escape(s:init_path) + \ . ' -q printClasspath' + \] + endif endif - return '' + return ['', ''] endfunction diff --git a/vim-config/plugins/ale/autoload/ale/gradle/init.gradle b/vim-config/plugins/ale/autoload/ale/gradle/init.gradle old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/alex.vim b/vim-config/plugins/ale/autoload/ale/handlers/alex.vim old mode 100755 new mode 100644 index 853d3137..6ef4867f --- a/vim-config/plugins/ale/autoload/ale/handlers/alex.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/alex.vim @@ -1,10 +1,24 @@ +scriptencoding utf-8 " Author: Johannes Wienke " Description: Error handling for errors in alex output format +function! ale#handlers#alex#GetExecutable(buffer) abort + return ale#path#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 = '^ *\(\d\+\):\(\d\+\)-\(\d\+\):\(\d\+\) \+warning \+\(.\{-\}\) \+\(.\{-\}\) \+\(.\{-\}\)$' + let l:pattern = '\v^ *(\d+):(\d+)-(\d+):(\d+) +warning +(.{-}) +(.{-}) +(.{-})$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) @@ -20,3 +34,21 @@ function! ale#handlers#alex#Handle(buffer, lines) abort 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/vim-config/plugins/ale/autoload/ale/handlers/atools.vim b/vim-config/plugins/ale/autoload/ale/handlers/atools.vim new file mode 100644 index 00000000..c273fc40 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/atools.vim @@ -0,0 +1,41 @@ +" Author: Leo +" Description: Handlers for output expected from atools + +function! ale#handlers#atools#Handle(buffer, lines) abort + " Format: SEVERITY:[TAG]:PATH:LINENUM:MSG + " Example: MC:[AL5]:./APKBUILD:12:variable set to empty string: install= + let l:pattern = '\([^:]\+\):\([^:]\+\):\([^:]\+\):\(\d\+\):\(.\+\)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + " We are expected to receive 2 characters, the first character + " can be 'S', 'I', 'M' 'T', which are respectively: + " Serious (Error) + " Important (Error) + " Minor (Warning) + " Style (Warning) + " + " The second character can be either 'C' or 'P', which are respectively: + " Certain (Error) + " Possible (Warning) + let l:severity = matchstr(l:match[1], '^.') + let l:certainty = matchstr(l:match[1], '.$') + + let l:type = 'E' + " If the tag returns 'Minor' or 'Style' or is 'Possible' + " then return a warning + + if l:severity is# 'M' || l:severity is# 'T' || l:certainty is# 'P' + let l:type = 'W' + endif + + call add(l:output, { + \ 'lnum': l:match[4] + 0, + \ 'text': l:match[5], + \ 'type': l:type, + \ 'code': matchstr(l:match[2], 'AL[0-9]*'), + \}) + endfor + + return l:output +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/ccls.vim b/vim-config/plugins/ale/autoload/ale/handlers/ccls.vim old mode 100755 new mode 100644 index 29dd6aed..290f5852 --- a/vim-config/plugins/ale/autoload/ale/handlers/ccls.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/ccls.vim @@ -3,15 +3,24 @@ scriptencoding utf-8 " Description: Utilities for ccls function! ale#handlers#ccls#GetProjectRoot(buffer) abort - let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls-root') + " Try to find ccls configuration files first. + let l:config = ale#path#FindNearestFile(a:buffer, '.ccls-root') - if empty(l:project_root) - let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') + if empty(l:config) + let l:config = ale#path#FindNearestFile(a:buffer, '.ccls') endif - if empty(l:project_root) - let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls') + if !empty(l:config) + return fnamemodify(l:config, ':h') endif - return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' + " Fall back on default project root detection. + return ale#c#FindProjectRoot(a:buffer) +endfunction + +function! ale#handlers#ccls#GetInitOpts(buffer, init_options_var) abort + let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + let l:init_options = empty(l:build_dir) ? {} : {'compilationDatabaseDirectory': l:build_dir} + + return extend(l:init_options, ale#Var(a:buffer, a:init_options_var)) endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/cppcheck.vim b/vim-config/plugins/ale/autoload/ale/handlers/cppcheck.vim old mode 100755 new mode 100644 index dc56cd0b..a07d0aed --- a/vim-config/plugins/ale/autoload/ale/handlers/cppcheck.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/cppcheck.vim @@ -1,18 +1,67 @@ " Description: Handle errors for cppcheck. +function! ale#handlers#cppcheck#GetCwd(buffer) abort + let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer) + + return !empty(l:dir) ? l:dir : '' +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]+)\) (.+)$' + "test.cpp:974:6: error:inconclusive Array 'n[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\ + " n[3]=3; + " ^ + "" OR if cppcheck doesn't support {column} or {inconclusive:text}: + "test.cpp:974:{column}: error:{inconclusive:inconclusive} Array 'n[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\ + " n[3]=3; + " ^ + let l:pattern = '\v(\f+):(\d+):(\d+|\{column\}): (\w+):(\{inconclusive:inconclusive\})? ?(.*) \[(\w+)\]\' 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], + \ 'lnum': str2nr(l:match[2]), + \ 'col': match(l:match[3],'{column}') >= 0 ? 1 : str2nr(l:match[3]), + \ 'type': l:match[4] is# 'error' ? 'E' : 'W', + \ 'sub_type': l:match[4] is# 'style' ? 'style' : '', + \ 'text': l:match[6], + \ 'code': l:match[7] \}) endif endfor diff --git a/vim-config/plugins/ale/autoload/ale/handlers/cpplint.vim b/vim-config/plugins/ale/autoload/ale/handlers/cpplint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/css.vim b/vim-config/plugins/ale/autoload/ale/handlers/css.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/deno.vim b/vim-config/plugins/ale/autoload/ale/handlers/deno.vim new file mode 100644 index 00000000..1b5e1718 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/deno.vim @@ -0,0 +1,74 @@ +" Author: Mohammed Chelouti - https://github.com/motato1 +" Arnold Chand +" Description: Handler functions for Deno. + +call ale#Set('deno_executable', 'deno') +call ale#Set('deno_unstable', 0) +call ale#Set('deno_importMap', 'import_map.json') +call ale#Set('deno_lsp_project_root', '') + +function! ale#handlers#deno#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'deno_executable') +endfunction + +" Find project root for Deno's language server. +" +" Deno projects do not require a project or configuration file at the project root. +" This means the root directory has to be guessed, +" unless it is explicitly specified by the user. +" +" The project root is determined by ... +" 1. using a user-specified value from deno_lsp_project_root +" 2. looking for common top-level files/dirs +" 3. using the buffer's directory +function! ale#handlers#deno#GetProjectRoot(buffer) abort + let l:project_root = ale#Var(a:buffer, 'deno_lsp_project_root') + + if !empty(l:project_root) + return l:project_root + endif + + let l:possible_project_roots = [ + \ 'tsconfig.json', + \ '.git', + \ bufname(a:buffer), + \] + + for l:possible_root in l:possible_project_roots + let l:project_root = ale#path#FindNearestFile(a:buffer, l:possible_root) + + if empty(l:project_root) + let l:project_root = ale#path#FindNearestDirectory(a:buffer, l:possible_root) + endif + + if !empty(l:project_root) + " dir:p expands to /full/path/to/dir/ whereas + " file:p expands to /full/path/to/file (no trailing slash) + " Appending '/' ensures that :h:h removes the path's last segment + " regardless of whether it is a directory or not. + return fnamemodify(l:project_root . '/', ':p:h:h') + endif + endfor + + return '' +endfunction + +" Initialization Options for deno, for javascript and typescript +function! ale#handlers#deno#GetInitializationOptions(buffer) abort + let l:options = { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false, + \ 'importMap': ale#path#FindNearestFile(a:buffer, 'import_map.json'), + \ } + + if ale#Var(a:buffer, 'deno_unstable') + let l:options.unstable = v:true + endif + + if ale#Var(a:buffer, 'deno_importMap') isnot# '' + let l:options.importMap = ale#path#FindNearestFile(a:buffer, ale#Var(a:buffer, 'deno_importMap')) + endif + + return l:options +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/elixir.vim b/vim-config/plugins/ale/autoload/ale/handlers/elixir.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/eslint.vim b/vim-config/plugins/ale/autoload/ale/handlers/eslint.vim old mode 100755 new mode 100644 index eda033e4..374460bc --- a/vim-config/plugins/ale/autoload/ale/handlers/eslint.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/eslint.vim @@ -1,6 +1,12 @@ " Author: w0rp " Description: Functions for working with eslint, for checking or fixing files. +let s:executables = [ +\ '.yarn/sdks/eslint/bin/eslint.js', +\ 'node_modules/.bin/eslint_d', +\ 'node_modules/eslint/bin/eslint.js', +\ 'node_modules/.bin/eslint', +\] let s:sep = has('win32') ? '\' : '/' call ale#Set('javascript_eslint_options', '') @@ -30,11 +36,36 @@ function! ale#handlers#eslint#FindConfig(buffer) abort 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', - \]) + return ale#path#FindExecutable(a:buffer, 'javascript_eslint', s:executables) +endfunction + +" Given a buffer, return an appropriate working directory for ESLint. +function! ale#handlers#eslint#GetCwd(buffer) abort + " ESLint 6 loads plugins/configs/parsers from the project root + " By default, the project root is simply the CWD of the running process. + " https://github.com/eslint/rfcs/blob/master/designs/2018-simplified-package-loading/README.md + " https://github.com/dense-analysis/ale/issues/2787 + " + " If eslint is installed in a directory which contains the buffer, assume + " it is the ESLint project root. Otherwise, use nearest node_modules. + " Note: If node_modules not present yet, can't load local deps anyway. + let l:executable = ale#path#FindNearestExecutable(a:buffer, s:executables) + + if !empty(l:executable) + let l:modules_index = strridx(l:executable, 'node_modules') + let l:modules_root = l:modules_index > -1 ? l:executable[0:l:modules_index - 2] : '' + + let l:sdks_index = strridx(l:executable, ale#path#Simplify('.yarn/sdks')) + let l:sdks_root = l:sdks_index > -1 ? l:executable[0:l:sdks_index - 2] : '' + else + let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules') + let l:modules_root = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : '' + + let l:sdks_dir = ale#path#FindNearestDirectory(a:buffer, ale#path#Simplify('.yarn/sdks')) + let l:sdks_root = !empty(l:sdks_dir) ? fnamemodify(l:sdks_dir, ':h:h:h') : '' + endif + + return strlen(l:modules_root) > strlen(l:sdks_root) ? l:modules_root : l:sdks_root endfunction function! ale#handlers#eslint#GetCommand(buffer) abort @@ -44,16 +75,9 @@ function! ale#handlers#eslint#GetCommand(buffer) abort return ale#node#Executable(a:buffer, l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' -f unix --stdin --stdin-filename %s' + \ . ' -f json --stdin --stdin-filename %s' endfunction -let s:col_end_patterns = [ -\ '\vParsing error: Unexpected token (.+) ?', -\ '\v''(.+)'' is not defined.', -\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]', -\ '\vUnexpected (console) statement', -\] - function! s:AddHintsForTypeScriptParsingErrors(output) abort for l:item in a:output let l:item.text = substitute( @@ -90,22 +114,74 @@ function! s:CheckForBadConfig(buffer, lines) abort return 0 endfunction -function! ale#handlers#eslint#Handle(buffer, lines) 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"), - \}] +function! s:parseJSON(buffer, lines) abort + let l:parsed = [] + + for l:line in a:lines + try + let l:parsed = extend(l:parsed, json_decode(l:line)) + catch + endtry + endfor + + if type(l:parsed) != v:t_list || empty(l:parsed) + return [] endif - if a:lines == ['Could not connect'] - return [{ - \ 'lnum': 1, - \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.', - \}] + 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] @@ -120,12 +196,6 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern]) let l:text = l:match[3] - if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore') - if l:text is# 'File ignored because of a matching ignore pattern. Use "--no-ignore" to override.' - continue - endif - endif - let l:obj = { \ 'lnum': l:match[1] + 0, \ 'col': l:match[2] + 0, @@ -152,9 +222,59 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort 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/vim-config/plugins/ale/autoload/ale/handlers/fecs.vim b/vim-config/plugins/ale/autoload/ale/handlers/fecs.vim new file mode 100644 index 00000000..064b927e --- /dev/null +++ b/vim-config/plugins/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#path#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/vim-config/plugins/ale/autoload/ale/handlers/flawfinder.vim b/vim-config/plugins/ale/autoload/ale/handlers/flawfinder.vim old mode 100755 new mode 100644 index a650d6dd..b7d2bec3 --- a/vim-config/plugins/ale/autoload/ale/handlers/flawfinder.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/flawfinder.vim @@ -1,3 +1,4 @@ +scriptencoding utf-8 " Author: Christian Gibbons " Description: This file defines a handler function that should work for the " flawfinder format with the -CDQS flags. @@ -30,7 +31,7 @@ function! ale#handlers#flawfinder#HandleFlawfinderFormat(buffer, lines) abort \ 'lnum': str2nr(l:match[2]), \ 'col': str2nr(l:match[3]), \ 'type': (l:severity < ale#Var(a:buffer, 'c_flawfinder_error_severity')) - \ ? 'W' : 'E', + \ ? 'W' : 'E', \ 'text': s:RemoveUnicodeQuotes(join(split(l:match[4])[1:]) . ': ' . l:match[5]), \} diff --git a/vim-config/plugins/ale/autoload/ale/handlers/gawk.vim b/vim-config/plugins/ale/autoload/ale/handlers/gawk.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/gcc.vim b/vim-config/plugins/ale/autoload/ale/handlers/gcc.vim old mode 100755 new mode 100644 index 72d639da..0b37c98a --- a/vim-config/plugins/ale/autoload/ale/handlers/gcc.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/gcc.vim @@ -10,7 +10,8 @@ let s:pragma_error = '#pragma once in main file' " :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: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)$' @@ -25,6 +26,28 @@ function! s:RemoveUnicodeQuotes(text) abort 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 = [] @@ -94,6 +117,23 @@ function! ale#handlers#gcc#HandleGCCFormat(buffer, lines) abort if !empty(l:output) if !has_key(l:output[-1], 'detail') let l:output[-1].detail = l:output[-1].text + + " handle macro expansion errors/notes + if l:match[5] =~? '^in expansion of macro ‘\w*\w’$' + " if the macro expansion is in the file we're in, add + " the lnum and col keys to the previous error + if l:match[1] is# '' + \ && !has_key(l:output[-1], 'col') + let l:output[-1].lnum = str2nr(l:match[2]) + let l:output[-1].col = str2nr(l:match[3]) + else + " the error is not in the current file, and since + " macro expansion errors don't show the full path to + " the error from the current file, we have to just + " give out a generic error message + let l:output[-1].text = 'Error found in macro expansion. See :ALEDetail' + endif + endif endif let l:output[-1].detail = l:output[-1].detail . "\n" @@ -129,6 +169,7 @@ endfunction 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 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/go.vim b/vim-config/plugins/ale/autoload/ale/handlers/go.vim old mode 100755 new mode 100644 index f17cd862..c969669d --- a/vim-config/plugins/ale/autoload/ale/handlers/go.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/go.vim @@ -6,9 +6,12 @@ " " Author: Ben Paxton " Description: moved to generic Golang file from govet +" +" Author: mostfunkyduck +" Description: updated to work with go 1.14 function! ale#handlers#go#Handler(buffer, lines) abort - let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? ?(.+)$' + let l:pattern = '\v^%(vet: )?([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? ?(.+)$' let l:output = [] let l:dir = expand('#' . a:buffer . ':p:h') diff --git a/vim-config/plugins/ale/autoload/ale/handlers/haskell.vim b/vim-config/plugins/ale/autoload/ale/handlers/haskell.vim old mode 100755 new mode 100644 index 9e495b36..3613b1bb --- a/vim-config/plugins/ale/autoload/ale/handlers/haskell.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/haskell.vim @@ -66,11 +66,11 @@ function! ale#handlers#haskell#HandleGHCFormat(buffer, lines) abort 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] + 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] + 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' diff --git a/vim-config/plugins/ale/autoload/ale/handlers/haskell_stack.vim b/vim-config/plugins/ale/autoload/ale/handlers/haskell_stack.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/hdl_checker.vim b/vim-config/plugins/ale/autoload/ale/handlers/hdl_checker.vim new file mode 100644 index 00000000..e11c5377 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/hdl_checker.vim @@ -0,0 +1,73 @@ +" Author: suoto +" Description: Adds support for HDL Code Checker, which wraps vcom/vlog, ghdl +" or xvhdl. More info on https://github.com/suoto/hdl_checker + +call ale#Set('hdl_checker_executable', 'hdl_checker') +call ale#Set('hdl_checker_config_file', has('unix') ? '.hdl_checker.config' : '_hdl_checker.config') +call ale#Set('hdl_checker_options', '') + +" Use this as a function so we can mock it on testing. Need to do this because +" test files are inside /testplugin (which refers to the ale repo), which will +" always have a .git folder +function! ale#handlers#hdl_checker#IsDotGit(path) abort + return ! empty(a:path) && isdirectory(a:path) +endfunction + +" Sould return (in order of preference) +" 1. Nearest config file +" 2. Nearest .git directory +" 3. The current path +function! ale#handlers#hdl_checker#GetProjectRoot(buffer) abort + let l:project_root = ale#path#FindNearestFile( + \ a:buffer, + \ ale#Var(a:buffer, 'hdl_checker_config_file')) + + if !empty(l:project_root) + return fnamemodify(l:project_root, ':h') + endif + + " Search for .git to use as root + let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git') + + if ale#handlers#hdl_checker#IsDotGit(l:project_root) + return fnamemodify(l:project_root, ':h:h') + endif + + return '' +endfunction + +function! ale#handlers#hdl_checker#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'hdl_checker_executable') +endfunction + +function! ale#handlers#hdl_checker#GetCommand(buffer) abort + let l:command = ale#Escape(ale#handlers#hdl_checker#GetExecutable(a:buffer)) . ' --lsp' + + " Add extra parameters only if config has been set + let l:options = ale#Var(a:buffer, 'hdl_checker_options') + + if ! empty(l:options) + let l:command = l:command . ' ' . l:options + endif + + return l:command +endfunction + +" To allow testing +function! ale#handlers#hdl_checker#GetInitOptions(buffer) abort + return {'project_file': ale#Var(a:buffer, 'hdl_checker_config_file')} +endfunction + +" Define the hdl_checker linter for a given filetype. +function! ale#handlers#hdl_checker#DefineLinter(filetype) abort + call ale#linter#Define(a:filetype, { + \ 'name': 'hdl-checker', + \ 'lsp': 'stdio', + \ 'language': a:filetype, + \ 'executable': function('ale#handlers#hdl_checker#GetExecutable'), + \ 'command': function('ale#handlers#hdl_checker#GetCommand'), + \ 'project_root': function('ale#handlers#hdl_checker#GetProjectRoot'), + \ 'initialization_options': function('ale#handlers#hdl_checker#GetInitOptions'), + \ }) +endfunction + diff --git a/vim-config/plugins/ale/autoload/ale/handlers/hlint.vim b/vim-config/plugins/ale/autoload/ale/handlers/hlint.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/inko.vim b/vim-config/plugins/ale/autoload/ale/handlers/inko.vim new file mode 100644 index 00000000..73f06871 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/inko.vim @@ -0,0 +1,37 @@ +" Author: Yorick Peterse +" Description: output handlers for the Inko JSON format + +function! ale#handlers#inko#GetType(severity) abort + if a:severity is? 'warning' + return 'W' + endif + + return 'E' +endfunction + +function! ale#handlers#inko#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 = [] + let l:dir = expand('#' . a:buffer . ':p:h') + + for l:error in l:errors + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:error['file']), + \ 'lnum': l:error['line'], + \ 'col': l:error['column'], + \ 'text': l:error['message'], + \ 'type': ale#handlers#inko#GetType(l:error['level']), + \}) + endfor + + return l:output +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/ktlint.vim b/vim-config/plugins/ale/autoload/ale/handlers/ktlint.vim new file mode 100644 index 00000000..77e7ab66 --- /dev/null +++ b/vim-config/plugins/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) + \ . ' --stdin' +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/vim-config/plugins/ale/autoload/ale/handlers/languagetool.vim b/vim-config/plugins/ale/autoload/ale/handlers/languagetool.vim new file mode 100644 index 00000000..73974ceb --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/languagetool.vim @@ -0,0 +1,77 @@ +" Author: Vincent (wahrwolf [at] wolfpit.net) +" Description: languagetool for markdown files +" +call ale#Set('languagetool_executable', 'languagetool') +call ale#Set('languagetool_options', '--autoDetect') + +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) + let l:options = ale#Var(a:buffer, 'languagetool_options') + + return ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options) . ' %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/vim-config/plugins/ale/autoload/ale/handlers/markdownlint.vim b/vim-config/plugins/ale/autoload/ale/handlers/markdownlint.vim old mode 100755 new mode 100644 index 12fc501c..6c273bd0 --- a/vim-config/plugins/ale/autoload/ale/handlers/markdownlint.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/markdownlint.vim @@ -2,15 +2,22 @@ " 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:pattern=': \?\(\d\+\)\(:\(\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', - \ }) + let l:result = ({ + \ 'lnum': l:match[1] + 0, + \ 'code': l:match[4], + \ 'text': l:match[5], + \ 'type': 'W', + \}) + + if len(l:match[3]) > 0 + let l:result.col = (l:match[3] + 0) + endif + + call add(l:output, l:result) endfor return l:output diff --git a/vim-config/plugins/ale/autoload/ale/handlers/ocamllsp.vim b/vim-config/plugins/ale/autoload/ale/handlers/ocamllsp.vim new file mode 100644 index 00000000..2738ea2b --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/ocamllsp.vim @@ -0,0 +1,30 @@ +" Author: Risto Stevcev +" Description: Handlers for the official OCaml language server + +let s:language_id_of_filetype = { +\ 'menhir': 'ocaml.menhir', +\ 'ocaml': 'ocaml', +\ 'ocamlinterface': 'ocaml.interface', +\ 'ocamllex': 'ocaml.lex' +\} + +function! ale#handlers#ocamllsp#GetExecutable(buffer) abort + return 'ocamllsp' +endfunction + +function! ale#handlers#ocamllsp#GetCommand(buffer) abort + let l:executable = ale#handlers#ocamllsp#GetExecutable(a:buffer) + let l:ocaml_ocamllsp_use_opam = ale#Var(a:buffer, 'ocaml_ocamllsp_use_opam') + + return l:ocaml_ocamllsp_use_opam ? 'opam config exec -- ' . l:executable : l:executable +endfunction + +function! ale#handlers#ocamllsp#GetLanguage(buffer) abort + return s:language_id_of_filetype[getbufvar(a:buffer, '&filetype')] +endfunction + +function! ale#handlers#ocamllsp#GetProjectRoot(buffer) abort + let l:dune_project_file = ale#path#FindNearestFile(a:buffer, 'dune-project') + + return !empty(l:dune_project_file) ? fnamemodify(l:dune_project_file, ':h') : '' +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/ols.vim b/vim-config/plugins/ale/autoload/ale/handlers/ols.vim old mode 100755 new mode 100644 index 74130a26..c292c6d9 --- a/vim-config/plugins/ale/autoload/ale/handlers/ols.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/ols.vim @@ -4,7 +4,7 @@ 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, [ + return ale#path#FindExecutable(a:buffer, l:ols_setting, [ \ 'node_modules/.bin/ocaml-language-server', \]) endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/pony.vim b/vim-config/plugins/ale/autoload/ale/handlers/pony.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/redpen.vim b/vim-config/plugins/ale/autoload/ale/handlers/redpen.vim old mode 100755 new mode 100644 index 84e331ed..195057ca --- a/vim-config/plugins/ale/autoload/ale/handlers/redpen.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/redpen.vim @@ -4,10 +4,10 @@ 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 = json_decode(join(a:lines))[0] + let l:res = get(ale#util#FuzzyJSONDecode(a:lines, []), 0, {}) let l:output = [] - for l:err in l:res.errors + for l:err in get(l:res, 'errors', []) let l:item = { \ 'text': l:err.message, \ 'type': 'W', diff --git a/vim-config/plugins/ale/autoload/ale/handlers/ruby.vim b/vim-config/plugins/ale/autoload/ale/handlers/ruby.vim old mode 100755 new mode 100644 index c28b8b75..7a1c5765 --- a/vim-config/plugins/ale/autoload/ale/handlers/ruby.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/ruby.vim @@ -36,11 +36,3 @@ 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/vim-config/plugins/ale/autoload/ale/handlers/rust.vim b/vim-config/plugins/ale/autoload/ale/handlers/rust.vim old mode 100755 new mode 100644 index c6a4b670..a7fac464 --- a/vim-config/plugins/ale/autoload/ale/handlers/rust.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/rust.vim @@ -56,14 +56,20 @@ function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort endif if !empty(l:span) - call add(l:output, { + 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, + \ '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 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/scala.vim b/vim-config/plugins/ale/autoload/ale/handlers/scala.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/sh.vim b/vim-config/plugins/ale/autoload/ale/handlers/sh.vim old mode 100755 new mode 100644 index e96dd3ce..6ed9fea3 --- a/vim-config/plugins/ale/autoload/ale/handlers/sh.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/sh.vim @@ -1,20 +1,37 @@ " 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, '') + let l:shebang = get(getbufline(a:buffer, 1), 0, '') - " Take the shell executable from the hashbang, if we can. - if l:bang_line[:1] is# '#!' + let l:command = '' + + " Take the shell executable from the shebang, if we can. + if l:shebang[:1] is# '#!' " Remove options like -e, etc. - let l:command = substitute(l:bang_line, ' --\?[a-zA-Z0-9]\+', '', 'g') + let l:command = substitute(l:shebang, ' --\?[a-zA-Z0-9]\+', '', 'g') + endif - for l:possible_shell in ['bash', 'dash', 'ash', 'tcsh', 'csh', 'zsh', 'sh'] - if l:command =~# l:possible_shell . '\s*$' - return l:possible_shell - endif - endfor + " With no shebang line, attempt to use Vim's buffer-local variables. + if l:command is# '' + if getbufvar(a:buffer, 'is_bash', 0) + let l:command = 'bash' + elseif getbufvar(a:buffer, 'is_sh', 0) + let l:command = 'sh' + elseif getbufvar(a:buffer, 'is_kornshell', 0) + let l:command = 'ksh' + endif endif + " If we couldn't find a shebang, try the filetype + if l:command is# '' + let l:command = &filetype + endif + + 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 + return '' endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/shellcheck.vim b/vim-config/plugins/ale/autoload/ale/handlers/shellcheck.vim new file mode 100644 index 00000000..17de2912 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/shellcheck.vim @@ -0,0 +1,123 @@ +" Author: w0rp +" Description: This file adds support for using the shellcheck linter + +" Shellcheck supports shell directives to define the shell dialect for scripts +" that do not have a shebang for some reason. +" https://github.com/koalaman/shellcheck/wiki/Directive#shell +function! ale#handlers#shellcheck#GetShellcheckDialectDirective(buffer) abort + let l:linenr = 0 + let l:pattern = '\s\{-}#\s\{-}shellcheck\s\{-}shell=\(.*\)' + let l:possible_shell = ['bash', 'dash', 'ash', 'tcsh', 'csh', 'zsh', 'ksh', 'sh'] + + while l:linenr < min([50, line('$')]) + let l:linenr += 1 + let l:match = matchlist(getline(l:linenr), l:pattern) + + if len(l:match) > 1 && index(l:possible_shell, l:match[1]) >= 0 + return l:match[1] + endif + endwhile + + return '' +endfunction + +function! ale#handlers#shellcheck#GetDialectArgument(buffer) abort + let l:shell_type = ale#handlers#shellcheck#GetShellcheckDialectDirective(a:buffer) + + if empty(l:shell_type) + let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) + endif + + 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 + + return '' +endfunction + +function! ale#handlers#shellcheck#GetCwd(buffer) abort + return ale#Var(a:buffer, 'sh_shellcheck_change_directory') ? '%s:h' : '' +endfunction + +function! ale#handlers#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' : '' + + if l:dialect is# 'auto' + let l:dialect = ale#handlers#shellcheck#GetDialectArgument(a:buffer) + endif + + return '%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#handlers#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 + +function! ale#handlers#shellcheck#DefineLinter(filetype) abort + " 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) + + call ale#linter#Define(a:filetype, { + \ 'name': 'shellcheck', + \ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')}, + \ 'cwd': function('ale#handlers#shellcheck#GetCwd'), + \ 'command': {buffer -> ale#semver#RunWithVersionCheck( + \ buffer, + \ ale#Var(buffer, 'sh_shellcheck_executable'), + \ '%e --version', + \ function('ale#handlers#shellcheck#GetCommand'), + \ )}, + \ 'callback': 'ale#handlers#shellcheck#Handle', + \}) +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/sml.vim b/vim-config/plugins/ale/autoload/ale/handlers/sml.vim old mode 100755 new mode 100644 index 92c5f83b..f5365dd6 --- a/vim-config/plugins/ale/autoload/ale/handlers/sml.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/sml.vim @@ -26,7 +26,6 @@ function! ale#handlers#sml#GetCmFile(buffer) abort endfunction " Only one of smlnj or smlnj-cm can be enabled at a time. -" executable_callback is called before *every* lint attempt 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 @@ -57,33 +56,34 @@ 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\): .*\)' + 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 + call add(l:out, { + \ 'filename': l:match2[1], + \ 'lnum': l:match2[2] + 0, + \ 'col' : l:match2[3] - 1, + \ 'text': l:match2[4], + \ 'type': l:match2[4] =~# '^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 + call add(l:out, { + \ 'filename': l:match[1], + \ 'lnum': l:match[2] + 0, + \ 'text': l:match[3] . ': ' . l:match[4], + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \}) + continue endif endfor diff --git a/vim-config/plugins/ale/autoload/ale/handlers/solhint.vim b/vim-config/plugins/ale/autoload/ale/handlers/solhint.vim new file mode 100644 index 00000000..611aa7bd --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/solhint.vim @@ -0,0 +1,98 @@ +" Author: Henrique Barcelos <@hbarcelos> +" Description: Functions for working with local solhint for checking *.sol files. + +let s:executables = [ +\ 'node_modules/.bin/solhint', +\ 'node_modules/solhint/solhint.js', +\ 'solhint', +\] + +let s:sep = has('win32') ? '\' : '/' + +call ale#Set('solidity_solhint_options', '') +call ale#Set('solidity_solhint_executable', 'solhint') +call ale#Set('solidity_solhint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#handlers#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:output = [] + + let l:lint_pattern = '\v^[^:]+: line (\d+), col (\d+), (Error|Warning) - (.*) \((.*)\)$' + + for l:match in ale#util#GetMatches(a:lines, l:lint_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 + + let l:syntax_pattern = '\v^[^:]+: line (\d+), col (\d+), (Error|Warning) - (Parse error): (.*)$' + + for l:match in ale#util#GetMatches(a:lines, l:syntax_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[5], + \ 'code': l:match[4], + \ 'type': l:isError ? 'E' : 'W', + \}) + endfor + + return l:output +endfunction + +function! ale#handlers#solhint#FindConfig(buffer) abort + for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) + for l:basename in [ + \ '.solhintrc.js', + \ '.solhintrc.json', + \ '.solhintrc', + \] + 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#solhint#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'solidity_solhint', s:executables) +endfunction + +" Given a buffer, return an appropriate working directory for solhint. +function! ale#handlers#solhint#GetCwd(buffer) abort + " If solhint is installed in a directory which contains the buffer, assume + " it is the solhint project root. Otherwise, use nearest node_modules. + " Note: If node_modules not present yet, can't load local deps anyway. + let l:executable = ale#path#FindNearestExecutable(a:buffer, s:executables) + + if !empty(l:executable) + let l:nmi = strridx(l:executable, 'node_modules') + let l:project_dir = l:executable[0:l:nmi - 2] + else + let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules') + let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : '' + endif + + return !empty(l:project_dir) ? l:project_dir : '' +endfunction + +function! ale#handlers#solhint#GetCommand(buffer) abort + let l:executable = ale#handlers#solhint#GetExecutable(a:buffer) + + let l:options = ale#Var(a:buffer, 'solidity_solhint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --formatter compact %s' +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/spectral.vim b/vim-config/plugins/ale/autoload/ale/handlers/spectral.vim new file mode 100644 index 00000000..1eb4a5de --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/spectral.vim @@ -0,0 +1,31 @@ +" Author: t2h5 +" Description: Integration of Stoplight Spectral CLI with ALE. + +function! ale#handlers#spectral#HandleSpectralOutput(buffer, lines) abort + " Matches patterns like the following: + " openapi.yml:1:1 error oas3-schema "Object should have required property `info`." + " openapi.yml:1:1 warning oas3-api-servers "OpenAPI `servers` must be present and non-empty array." + let l:pattern = '\v^.*:(\d+):(\d+) (error|warning) (.*)$' + 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, + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \ 'text': l:match[4], + \} + + let l:code_match = matchlist(l:obj.text, '\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 + diff --git a/vim-config/plugins/ale/autoload/ale/handlers/textlint.vim b/vim-config/plugins/ale/autoload/ale/handlers/textlint.vim old mode 100755 new mode 100644 index 6d495b0d..7a648617 --- a/vim-config/plugins/ale/autoload/ale/handlers/textlint.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/textlint.vim @@ -6,7 +6,7 @@ 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', [ + return ale#path#FindExecutable(a:buffer, 'textlint', [ \ 'node_modules/.bin/textlint', \ 'node_modules/textlint/bin/textlint.js', \]) diff --git a/vim-config/plugins/ale/autoload/ale/handlers/tslint.vim b/vim-config/plugins/ale/autoload/ale/handlers/tslint.vim old mode 100755 new mode 100644 index 90579344..ee091d24 --- a/vim-config/plugins/ale/autoload/ale/handlers/tslint.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/tslint.vim @@ -7,7 +7,7 @@ function! ale#handlers#tslint#InitVariables() abort endfunction function! ale#handlers#tslint#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'typescript_tslint', [ + return ale#path#FindExecutable(a:buffer, 'typescript_tslint', [ \ 'node_modules/.bin/tslint', \]) endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/tsserver.vim b/vim-config/plugins/ale/autoload/ale/handlers/tsserver.vim new file mode 100644 index 00000000..f78499ac --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/autoload/ale/handlers/unix.vim b/vim-config/plugins/ale/autoload/ale/handlers/unix.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/vale.vim b/vim-config/plugins/ale/autoload/ale/handlers/vale.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/handlers/writegood.vim b/vim-config/plugins/ale/autoload/ale/handlers/writegood.vim old mode 100755 new mode 100644 index aff66d5f..b5b91b3f --- a/vim-config/plugins/ale/autoload/ale/handlers/writegood.vim +++ b/vim-config/plugins/ale/autoload/ale/handlers/writegood.vim @@ -11,7 +11,7 @@ endfunction call ale#handlers#writegood#ResetOptions() function! ale#handlers#writegood#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'writegood', [ + return ale#path#FindExecutable(a:buffer, 'writegood', [ \ 'node_modules/.bin/write-good', \ 'node_modules/write-good/bin/write-good.js', \]) @@ -65,8 +65,8 @@ function! ale#handlers#writegood#DefineLinter(filetype) abort call ale#linter#Define(a:filetype, { \ 'name': 'writegood', \ 'aliases': ['write-good'], - \ 'executable_callback': 'ale#handlers#writegood#GetExecutable', - \ 'command_callback': 'ale#handlers#writegood#GetCommand', + \ 'executable': function('ale#handlers#writegood#GetExecutable'), + \ 'command': function('ale#handlers#writegood#GetCommand'), \ 'callback': 'ale#handlers#writegood#Handle', \}) endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/xo.vim b/vim-config/plugins/ale/autoload/ale/handlers/xo.vim new file mode 100644 index 00000000..a87c6d8f --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/xo.vim @@ -0,0 +1,44 @@ +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', '') + +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#handlers#xo#GetExecutable(buffer) abort + let l:type = ale#handlers#xo#GetType(a:buffer) + + return ale#path#FindExecutable(a:buffer, l:type . '_xo', [ + \ 'node_modules/xo/cli.js', + \ 'node_modules/.bin/xo', + \]) +endfunction + +function! ale#handlers#xo#GetLintCommand(buffer) abort + return ale#Escape(ale#handlers#xo#GetExecutable(a:buffer)) + \ . ale#Pad(ale#handlers#xo#GetOptions(a:buffer)) + \ . ' --reporter json --stdin --stdin-filename %s' +endfunction + +function! ale#handlers#xo#GetOptions(buffer) abort + let l:type = ale#handlers#xo#GetType(a:buffer) + + return ale#Var(a:buffer, l:type . '_xo_options') +endfunction + +" xo uses eslint and the output format is the same +function! ale#handlers#xo#HandleJSON(buffer, lines) abort + return ale#handlers#eslint#HandleJSON(a:buffer, a:lines) +endfunction + +function! ale#handlers#xo#GetType(buffer) abort + let l:filetype = getbufvar(a:buffer, '&filetype') + let l:type = 'javascript' + + if l:filetype =~# 'typescript' + let l:type = 'typescript' + endif + + return l:type +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/handlers/yamllint.vim b/vim-config/plugins/ale/autoload/ale/handlers/yamllint.vim new file mode 100644 index 00000000..5e04577d --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/handlers/yamllint.vim @@ -0,0 +1,39 @@ +function! ale#handlers#yamllint#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'yaml_yamllint_options')) + \ . ' -f parsable %t' +endfunction + +function! ale#handlers#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 + diff --git a/vim-config/plugins/ale/autoload/ale/highlight.vim b/vim-config/plugins/ale/autoload/ale/highlight.vim old mode 100755 new mode 100644 index ae1f3e7d..473ad354 --- a/vim-config/plugins/ale/autoload/ale/highlight.vim +++ b/vim-config/plugins/ale/autoload/ale/highlight.vim @@ -26,6 +26,25 @@ endif let s:MAX_POS_VALUES = 8 let s:MAX_COL_SIZE = 1073741824 " pow(2, 30) +let s:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace') + +if s:has_nvim_highlight + let s:ns_id = nvim_create_namespace('ale_highlight') +endif + +" Wrappers are necessary to test this functionality by faking the calls in tests. +function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort + " Ignore all errors for adding highlights. + try + call nvim_buf_add_highlight(a:buffer, a:ns_id, a:hl_group, a:line, a:col_start, a:col_end) + catch + endtry +endfunction + +function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort + call nvim_buf_clear_namespace(a:buffer, a:ns_id, a:line_start, a:line_end) +endfunction + 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. @@ -49,12 +68,69 @@ 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 =~# '^ALE' - call matchdelete(l:match.id) - endif - endfor + if s:has_nvim_highlight + call ale#highlight#nvim_buf_clear_namespace(bufnr(''), s:ns_id, 0, -1) + else + for l:match in getmatches() + if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$' + call matchdelete(l:match.id) + endif + endfor + endif +endfunction + +" Same semantics of matchaddpos but will use nvim_buf_add_highlight if +" available. This involves iterating over the position list, switching from +" 1-based indexing to 0-based indexing, and translating the multiple ways +" that position can be specified for matchaddpos into line + col_start + +" col_end. +function! s:matchaddpos(group, pos_list) abort + if s:has_nvim_highlight + for l:pos in a:pos_list + let l:line = type(l:pos) == v:t_number + \ ? l:pos - 1 + \ : l:pos[0] - 1 + + if type(l:pos) == v:t_number || len(l:pos) == 1 + let l:col_start = 0 + let l:col_end = s:MAX_COL_SIZE + else + let l:col_start = l:pos[1] - 1 + let l:col_end = l:col_start + get(l:pos, 2, 1) + endif + + call ale#highlight#nvim_buf_add_highlight( + \ bufnr(''), + \ s:ns_id, + \ a:group, + \ l:line, + \ l:col_start, + \ l:col_end, + \) + endfor + else + call matchaddpos(a:group, a:pos_list) + endif +endfunction + +function! s:highlight_line(bufnr, lnum, group) abort + call s: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 + \ ), + \ 's:matchaddpos(a:group, v:val)' + \) endfunction function! ale#highlight#UpdateHighlights() abort @@ -79,17 +155,14 @@ function! ale#highlight#UpdateHighlights() abort let l:group = 'ALEError' endif - let l:line = l:item.lnum - let l:col = l:item.col - let l:end_line = get(l:item, 'end_lnum', l:line) - let l:end_col = get(l:item, 'end_col', l:col) - - " 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(l:line, l:col, l:end_line, l:end_col), - \ 'matchaddpos(l:group, v:val)' - \) + 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 @@ -111,7 +184,7 @@ function! ale#highlight#UpdateHighlights() abort endif if l:available_groups[l:group] - call matchaddpos(l:group, [l:item.lnum]) + call s:highlight_line(l:item.bufnr, l:item.lnum, l:group) endif endfor endif @@ -137,6 +210,12 @@ function! ale#highlight#SetHighlights(buffer, loclist) abort " Set the list in the buffer variable. call setbufvar(str2nr(a:buffer), 'ale_highlight_items', l:new_list) + let l:exclude_list = ale#Var(a:buffer, 'exclude_highlights') + + if !empty(l:exclude_list) + call filter(l:new_list, 'empty(ale#util#GetMatches(v:val.text, l:exclude_list))') + endif + " Update highlights for the current buffer, which may or may not " be the buffer we just set highlights for. call ale#highlight#UpdateHighlights() diff --git a/vim-config/plugins/ale/autoload/ale/history.vim b/vim-config/plugins/ale/autoload/ale/history.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/hover.vim b/vim-config/plugins/ale/autoload/ale/hover.vim old mode 100755 new mode 100644 index 490cc406..4513c6ad --- a/vim-config/plugins/ale/autoload/ale/hover.vim +++ b/vim-config/plugins/ale/autoload/ale/hover.vim @@ -24,6 +24,8 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort if get(a:response, 'success', v:false) is v:true \&& get(a:response, 'body', v:null) isnot v:null + let l:set_balloons = ale#Var(l:options.buffer, 'set_balloons') + " 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) @@ -40,8 +42,21 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort endif elseif get(l:options, 'hover_from_balloonexpr', 0) \&& exists('*balloon_show') - \&& ale#Var(l:options.buffer, 'set_balloons') + \&& (l:set_balloons is 1 || l:set_balloons is# 'hover') call balloon_show(a:response.body.displayString) + elseif get(l:options, 'truncated_echo', 0) + if !empty(a:response.body.displayString) + call ale#cursor#TruncatedEcho(split(a:response.body.displayString, "\n")[0]) + endif + elseif g:ale_hover_to_floating_preview || g:ale_floating_preview + call ale#floating_preview#Show(split(a:response.body.displayString, "\n"), { + \ 'filetype': 'ale-preview.message', + \}) + elseif g:ale_hover_to_preview + call ale#preview#Show(split(a:response.body.displayString, "\n"), { + \ 'filetype': 'ale-preview.message', + \ 'stay_here': 1, + \}) else call ale#util#ShowMessage(a:response.body.displayString) endif @@ -49,6 +64,137 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort endif endfunction +" Convert a language name to another one. +" The language name could be an empty string or v:null +function! s:ConvertLanguageName(language) abort + return a:language +endfunction + +function! ale#hover#ParseLSPResult(contents) abort + let l:includes = {} + let l:highlights = [] + let l:lines = [] + let l:list = type(a:contents) is v:t_list ? a:contents : [a:contents] + let l:region_index = 0 + + for l:item in l:list + if !empty(l:lines) + call add(l:lines, '') + endif + + if type(l:item) is v:t_dict && has_key(l:item, 'kind') + if l:item.kind is# 'markdown' + " Handle markdown values as we handle strings below. + let l:item = get(l:item, 'value', '') + elseif l:item.kind is# 'plaintext' + " We shouldn't try to parse plaintext as markdown. + " Pass the lines on and skip parsing them. + call extend(l:lines, split(get(l:item, 'value', ''), "\n")) + + continue + endif + endif + + let l:marked_list = [] + + " If the item is a string, then we should parse it as Markdown text. + if type(l:item) is v:t_string + let l:fence_language = v:null + let l:fence_lines = [] + + for l:line in split(l:item, "\n") + if l:fence_language is v:null + " Look for the start of a code fence. (```python, etc.) + let l:match = matchlist(l:line, '^```\(.*\)$') + + if !empty(l:match) + let l:fence_language = l:match[1] + + if !empty(l:marked_list) + call add(l:fence_lines, '') + endif + else + if !empty(l:marked_list) + \&& l:marked_list[-1][0] isnot v:null + call add(l:marked_list, [v:null, ['']]) + endif + + call add(l:marked_list, [v:null, [l:line]]) + endif + elseif l:line =~# '^```$' + " When we hit the end of a code fence, pass the fenced + " lines on to the next steps below. + call add(l:marked_list, [l:fence_language, l:fence_lines]) + let l:fence_language = v:null + let l:fence_lines = [] + else + " Gather lines inside of a code fence. + call add(l:fence_lines, l:line) + endif + endfor + " If the result from the LSP server is a {language: ..., value: ...} + " Dictionary, then that should be interpreted as if it was: + " + " ```${language} + " ${value} + " ``` + elseif type(l:item) is v:t_dict + \&& has_key(l:item, 'language') + \&& type(l:item.language) is v:t_string + \&& has_key(l:item, 'value') + \&& type(l:item.value) is v:t_string + call add( + \ l:marked_list, + \ [l:item.language, split(l:item.value, "\n")], + \) + endif + + for [l:language, l:marked_lines] in l:marked_list + if l:language is v:null + " NOTE: We could handle other Markdown formatting here. + call map( + \ l:marked_lines, + \ 'substitute(v:val, ''\\_'', ''_'', ''g'')', + \) + else + let l:language = s:ConvertLanguageName(l:language) + + if !empty(l:language) + let l:includes[l:language] = printf( + \ 'syntax/%s.vim', + \ l:language, + \) + + let l:start = len(l:lines) + 1 + let l:end = l:start + len(l:marked_lines) + let l:region_index += 1 + + call add(l:highlights, 'syntax region' + \ . ' ALE_hover_' . l:region_index + \ . ' start=/\%' . l:start . 'l/' + \ . ' end=/\%' . l:end . 'l/' + \ . ' contains=@ALE_hover_' . l:language + \) + endif + endif + + call extend(l:lines, l:marked_lines) + endfor + endfor + + let l:include_commands = [] + + for [l:language, l:lang_path] in sort(items(l:includes)) + call add(l:include_commands, 'unlet! b:current_syntax') + call add( + \ l:include_commands, + \ printf('syntax include @ALE_hover_%s %s', l:language, l:lang_path), + \) + endfor + + return [l:include_commands + l:highlights, l:lines] +endfunction + function! ale#hover#HandleLSPResponse(conn_id, response) abort if has_key(a:response, 'id') \&& has_key(s:hover_map, a:response.id) @@ -57,7 +203,7 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort " 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] = getcurpos()[1:2] + let [l:line, l:column] = getpos('.')[1:2] let l:end = len(getline(l:line)) if l:buffer isnot l:options.buffer @@ -75,41 +221,46 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort 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 + let [l:commands, l:lines] = ale#hover#ParseLSPResult(l:result.contents) - 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 !empty(l:lines) + let l:set_balloons = ale#Var(l:options.buffer, 'set_balloons') - 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 + if get(l:options, 'hover_from_balloonexpr', 0) + \&& exists('*balloon_show') + \&& (l:set_balloons is 1 || l:set_balloons is# 'hover') + call balloon_show(join(l:lines, "\n")) + elseif get(l:options, 'truncated_echo', 0) + call ale#cursor#TruncatedEcho(l:lines[0]) + elseif g:ale_hover_to_floating_preview || g:ale_floating_preview + call ale#floating_preview#Show(l:lines, { + \ 'filetype': 'ale-preview.message', + \ 'commands': l:commands, + \}) + elseif g:ale_hover_to_preview + call ale#preview#Show(l:lines, { + \ 'filetype': 'ale-preview.message', + \ 'stay_here': 1, + \ 'commands': l:commands, + \}) + else + call ale#util#ShowMessage(join(l:lines, "\n"), { + \ 'commands': l:commands, + \}) endif endif endif endfunction -function! s:OnReady(linter, lsp_details, line, column, opt, ...) abort - let l:buffer = a:lsp_details.buffer +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') @@ -128,7 +279,10 @@ function! s:OnReady(linter, lsp_details, line, column, opt, ...) abort " 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:column = max([ + \ min([a:column, len(getbufline(l:buffer, a:line)[0])]), + \ 1, + \]) let l:message = ale#lsp#message#Hover(l:buffer, a:line, l:column) endif @@ -141,23 +295,10 @@ function! s:OnReady(linter, lsp_details, line, column, opt, ...) abort \ 'column': l:column, \ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0), \ 'show_documentation': get(a:opt, 'show_documentation', 0), + \ 'truncated_echo': get(a:opt, 'truncated_echo', 0), \} endfunction -function! s:ShowDetails(linter, buffer, line, column, opt, ...) abort - let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter) - - if empty(l:lsp_details) - return 0 - endif - - let l:id = l:lsp_details.connection_id - - call ale#lsp#WaitForCapability(l:id, 'hover', function('s:OnReady', [ - \ a:linter, l:lsp_details, a:line, a:column, a:opt - \])) -endfunction - " Obtain Hover information for the specified position " Pass optional arguments in the dictionary opt. " Currently, only one key/value is useful: @@ -169,28 +310,50 @@ endfunction " - 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 s:ShowDetails(l:linter, a:buffer, a:line, a:col, a:opt) + call ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback) endif endfor endfunction +let s:last_pos = [0, 0, 0] + " This function implements the :ALEHover command. function! ale#hover#ShowAtCursor() abort let l:buffer = bufnr('') - let l:pos = getcurpos() + let l:pos = getpos('.') call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], {}) endfunction +function! ale#hover#ShowTruncatedMessageAtCursor() abort + let l:buffer = bufnr('') + let l:pos = getpos('.')[0:2] + + if l:pos != s:last_pos + let s:last_pos = l:pos + let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer) + + if empty(l:loc) + call ale#hover#Show( + \ l:buffer, + \ l:pos[1], + \ l:pos[2], + \ {'truncated_echo': 1}, + \) + endif + endif +endfunction + " This function implements the :ALEDocumentation command. function! ale#hover#ShowDocumentationAtCursor() abort let l:buffer = bufnr('') - let l:pos = getcurpos() + let l:pos = getpos('.') let l:options = {'show_documentation': 1} call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], l:options) diff --git a/vim-config/plugins/ale/autoload/ale/java.vim b/vim-config/plugins/ale/autoload/ale/java.vim old mode 100755 new mode 100644 index b7fd10bd..e641ac6c --- a/vim-config/plugins/ale/autoload/ale/java.vim +++ b/vim-config/plugins/ale/autoload/ale/java.vim @@ -16,5 +16,11 @@ function! ale#java#FindProjectRoot(buffer) abort 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/vim-config/plugins/ale/autoload/ale/job.vim b/vim-config/plugins/ale/autoload/ale/job.vim old mode 100755 new mode 100644 index f9a917e1..14b3e484 --- a/vim-config/plugins/ale/autoload/ale/job.vim +++ b/vim-config/plugins/ale/autoload/ale/job.vim @@ -99,7 +99,8 @@ function! s:VimCloseCallback(channel) abort if job_status(l:job) is# 'dead' try if !empty(l:info) && has_key(l:info, 'exit_cb') - call ale#util#GetFunction(l:info.exit_cb)(l:job_id, get(l:info, 'exit_code', 1)) + " 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. @@ -124,7 +125,8 @@ function! s:VimExitCallback(job, exit_code) abort if ch_status(job_getchannel(a:job)) is# 'closed' try if !empty(l:info) && has_key(l:info, 'exit_cb') - call ale#util#GetFunction(l:info.exit_cb)(l:job_id, a:exit_code) + " 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. @@ -274,12 +276,34 @@ function! ale#job#Start(command, options) abort 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 - call ch_sendraw(job_getchannel(s:job_map[a:job_id].job), a:string) + 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 @@ -303,6 +327,20 @@ function! ale#job#IsRunning(job_id) abort 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 diff --git a/vim-config/plugins/ale/autoload/ale/julia.vim b/vim-config/plugins/ale/autoload/ale/julia.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/linter.vim b/vim-config/plugins/ale/autoload/ale/linter.vim old mode 100755 new mode 100644 index 0b61bad1..cbc79064 --- a/vim-config/plugins/ale/autoload/ale/linter.vim +++ b/vim-config/plugins/ale/autoload/ale/linter.vim @@ -12,11 +12,18 @@ let s:linters = {} let s:default_ale_linter_aliases = { \ 'Dockerfile': 'dockerfile', \ 'csh': 'sh', +\ 'javascriptreact': ['javascript', 'jsx'], \ 'plaintex': 'tex', +\ 'ps1': 'powershell', +\ 'rmarkdown': 'r', +\ 'rmd': 'r', \ 'systemverilog': 'verilog', +\ 'typescriptreact': ['typescript', 'tsx'], \ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], \ 'vimwiki': 'markdown', \ 'vue': ['vue', 'javascript'], +\ 'xsd': ['xsd', 'xml'], +\ 'xslt': ['xslt', 'xml'], \ 'zsh': 'sh', \} @@ -25,25 +32,28 @@ let s:default_ale_linter_aliases = { " " No linters are used for plaintext files by default. " -" Only cargo is enabled for Rust by default. +" Only cargo and rls are 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 = { +\ 'apkbuild': ['apkbuild_lint', 'secfixes_check'], \ 'csh': ['shell'], -\ 'elixir': ['credo', 'dialyxir', 'dogma', 'elixir-ls'], -\ 'go': ['gofmt', 'golint', 'go vet'], +\ 'elixir': ['credo', 'dialyxir', 'dogma'], +\ 'go': ['gofmt', 'golint', 'gopls', 'govet'], \ 'hack': ['hack'], \ 'help': [], +\ 'inko': ['inko'], \ 'perl': ['perlcritic'], \ 'perl6': [], -\ 'python': ['flake8', 'mypy', 'pylint'], -\ 'rust': ['cargo'], +\ 'python': ['flake8', 'mypy', 'pylint', 'pyright'], +\ 'rust': ['cargo', 'rls'], \ 'spec': [], \ 'text': [], \ 'vue': ['eslint', 'vls'], \ 'zsh': ['shell'], +\ 'v': ['v'], \} " Testing/debugging helper to unload all linters. @@ -70,10 +80,6 @@ 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' @@ -107,133 +113,80 @@ function! ale#linter#PreProcess(filetype, linter) abort 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' + throw '`executable` cannot be used when lsp == ''socket''' endif elseif has_key(a:linter, 'executable') let l:obj.executable = a:linter.executable if type(l:obj.executable) isnot v:t_string - throw '`executable` must be a string if defined' + \&& 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' + throw '`executable` 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' + throw '`command` cannot be used when lsp == ''socket''' endif elseif has_key(a:linter, 'command') let l:obj.command = a:linter.command if type(l:obj.command) isnot v:t_string - throw '`command` must be a string if defined' + \&& 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' + throw '`command` must be defined' endif if !l:needs_address - if has_key(a:linter, 'address_callback') - throw '`address_callback` cannot be used when lsp != ''socket''' + if has_key(a:linter, 'address') + throw '`address` cannot be used when lsp != ''socket''' endif - elseif has_key(a:linter, 'address_callback') - let l:obj.address_callback = a:linter.address_callback + 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 - if !s:IsCallback(l:obj.address_callback) - throw '`address_callback` must be a callback if defined' + if has_key(a:linter, 'cwd') + throw '`cwd` makes no sense for socket LSP connections' endif else - throw '`address_callback` must be defined for getting the LSP address' + throw '`address` 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 + if has_key(a:linter, 'cwd') + let l:obj.cwd = a:linter.cwd - 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:obj.language = get(a:linter, 'language', a:filetype) + if type(l:obj.cwd) isnot v:t_string + \&& type(l:obj.cwd) isnot v:t_func + throw '`cwd` must be a String or Function if defined' + endif + endif - if type(l:obj.language) isnot v:t_string - throw '`language` must be a string' - endif + if l:needs_lsp_details + " Default to using the filetype as the language. + let l:obj.language = get(a:linter, 'language', a:filetype) - " Make 'language_callback' return the 'language' value. - let l:obj.language_callback = function('s:LanguageGetter') + if type(l:obj.language) isnot v:t_string + \&& type(l:obj.language) isnot v:t_func + throw '`language` must be a String or Function if defined' endif - let l:obj.project_root_callback = get(a:linter, 'project_root_callback') + if has_key(a:linter, 'project_root') + let l:obj.project_root = a:linter.project_root - if !s:IsCallback(l:obj.project_root_callback) - throw '`project_root_callback` must be a callback for LSP linters' + 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' + endif + else + throw '`project_root` must be defined for LSP linters' endif if has_key(a:linter, 'completion_filter') @@ -244,34 +197,19 @@ function! ale#linter#PreProcess(filetype, linter) abort 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') + if has_key(a:linter, 'initialization_options') let l:obj.initialization_options = a:linter.initialization_options - 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' + 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 Dictionary or Function if defined' endif + 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 has_key(a:linter, 'lsp_config') if type(a:linter.lsp_config) isnot v:t_dict - throw '`lsp_config` must be a Dictionary' + \&& 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 @@ -289,21 +227,17 @@ function! ale#linter#PreProcess(filetype, linter) abort " 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`' + if !s:IsBoolean(l:obj.lint_file) && type(l:obj.lint_file) isnot v:t_func + throw '`lint_file` must be `0`, `1`, or a Function' endif " An option indicating that the buffer should be read. - let l:obj.read_buffer = get(a:linter, 'read_buffer', !l:obj.lint_file) + let l:obj.read_buffer = get(a:linter, 'read_buffer', 1) 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 @@ -318,12 +252,14 @@ 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 - let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter) - + " 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 @@ -474,24 +410,47 @@ function! ale#linter#Get(original_filetypes) abort return reverse(l:combined_linters) endfunction +function! ale#linter#RemoveIgnored(buffer, filetype, linters) abort + " 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') + + return !empty(l:ignore_config) || l:disable_lsp + \ ? ale#engine#ignore#Exclude(a:filetype, a:linters, l:ignore_config, l:disable_lsp) + \ : a:linters +endfunction + " Given a buffer and linter, get the executable String for the linter. function! ale#linter#GetExecutable(buffer, linter) abort - return has_key(a:linter, 'executable_callback') - \ ? ale#util#GetFunction(a:linter.executable_callback)(a:buffer) - \ : a:linter.executable + let l:Executable = a:linter.executable + + return type(l:Executable) is v:t_func + \ ? l:Executable(a:buffer) + \ : l:Executable +endfunction + +function! ale#linter#GetCwd(buffer, linter) abort + let l:Cwd = get(a:linter, 'cwd', v:null) + + return type(l:Cwd) is v:t_func ? l:Cwd(a:buffer) : l:Cwd 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 - return has_key(a:linter, 'command_callback') - \ ? ale#util#GetFunction(a:linter.command_callback)(a:buffer) - \ : a:linter.command + let l:Command = 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 - return has_key(a:linter, 'address_callback') - \ ? ale#util#GetFunction(a:linter.address_callback)(a:buffer) - \ : a:linter.address + let l:Address = a:linter.address + + return type(l:Address) is v:t_func ? l:Address(a:buffer) : l:Address +endfunction + +function! ale#linter#GetLanguage(buffer, linter) abort + let l:Language = a:linter.language + + return type(l:Language) is v:t_func ? l:Language(a:buffer) : l:Language endfunction diff --git a/vim-config/plugins/ale/autoload/ale/list.vim b/vim-config/plugins/ale/autoload/ale/list.vim old mode 100755 new mode 100644 index 3417575c..089aa2c0 --- a/vim-config/plugins/ale/autoload/ale/list.vim +++ b/vim-config/plugins/ale/autoload/ale/list.vim @@ -20,11 +20,17 @@ 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 + let l:res = getqflist({ 'winid' : winnr() }) + + if has_key(l:res, 'winid') && l:res.winid > 0 + return 1 + endif + + let l:res = getloclist(0, { 'winid' : winnr() }) + + if has_key(l:res, 'winid') && l:res.winid > 0 + return 1 + endif return 0 endfunction @@ -38,6 +44,15 @@ function! s:ShouldOpen(buffer) abort return l:val is 1 || (l:val is# 'on_save' && l:saved) endfunction +function! s:Deduplicate(list) abort + let l:list = a:list + + call sort(l:list, function('ale#util#LocItemCompareWithText')) + call uniq(l:list, function('ale#util#LocItemCompareWithText')) + + return l:list +endfunction + function! ale#list#GetCombinedList() abort let l:list = [] @@ -45,10 +60,7 @@ function! ale#list#GetCombinedList() abort 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 + return s:Deduplicate(l:list) endfunction function! s:FixList(buffer, list) abort @@ -71,8 +83,8 @@ function! s:FixList(buffer, list) abort return l:new_list endfunction -function! s:BufWinId(buffer) abort - return exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0 +function! s:WinFindBuf(buffer) abort + return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0] endfunction function! s:SetListsImpl(timer_id, buffer, loclist) abort @@ -88,19 +100,26 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort call setqflist([], 'r', {'title': l:title}) endif elseif g:ale_set_loclist - " If windows support is off, bufwinid() may not exist. + " 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:id = s:BufWinId(a:buffer) + let l:ids = s:WinFindBuf(a:buffer) - 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 + let l:loclist = s:Deduplicate(a:loclist) + + for l:id in l:ids + if has('nvim') + call setloclist(l:id, s:FixList(a:buffer, l:loclist), ' ', l:title) + else + call setloclist(l:id, s:FixList(a:buffer, l:loclist)) + call setloclist(l:id, [], 'r', {'title': l:title}) + endif + endfor endif + " Save the current view before opening/closing any window + call setbufvar(a:buffer, 'ale_winview', winsaveview()) + " 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 @@ -108,14 +127,12 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort 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 ' + let l:open_type = 'vert rightbelow ' endif if g:ale_set_quickfix @@ -131,15 +148,18 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort 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. + " Return to original mode when applicable + if mode() != l:mode + if l:mode is? 'v' || l:mode is# "\" + " Reset our last visual selection + normal! gv + elseif l:mode is? 's' || l:mode is# "\" + " Reset our last character selection normal! "\" endif endif + + call s:RestoreViewIfNeeded(a:buffer) endif " If ALE isn't currently checking for more problems, close the window if @@ -150,6 +170,30 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort endif endfunction +" Try to restore the window view after closing any of the lists to avoid making +" the it moving around, especially useful when on insert mode +function! s:RestoreViewIfNeeded(buffer) abort + let l:saved_view = getbufvar(a:buffer, 'ale_winview', {}) + + " Saved view is empty, can't do anything + if empty(l:saved_view) + return + endif + + " Check wether the cursor has moved since linting was actually requested. If + " the user has indeed moved lines, do nothing + let l:current_view = winsaveview() + + if l:current_view['lnum'] != l:saved_view['lnum'] + return + endif + + " Anchor view by topline if the list is set to open horizontally + if ale#Var(a:buffer, 'list_vertical') == 0 + call winrestview({'topline': l:saved_view['topline']}) + 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) @@ -173,21 +217,31 @@ function! s:CloseWindowIfNeeded(buffer) abort return endif + let l:did_close_any_list = 0 + 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 + let l:did_close_any_list = 1 endif else - let l:win_id = s:BufWinId(a:buffer) - - if g:ale_set_loclist && empty(getloclist(l:win_id)) - lclose - endif + 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 + let l:did_close_any_list = 1 + endif + endfor endif " Ignore 'Cannot close last window' errors. catch /E444/ endtry + + if l:did_close_any_list + call s:RestoreViewIfNeeded(a:buffer) + endif endfunction diff --git a/vim-config/plugins/ale/autoload/ale/loclist_jumping.vim b/vim-config/plugins/ale/autoload/ale/loclist_jumping.vim old mode 100755 new mode 100644 index fd5ff922..55097d12 --- a/vim-config/plugins/ale/autoload/ale/loclist_jumping.vim +++ b/vim-config/plugins/ale/autoload/ale/loclist_jumping.vim @@ -9,14 +9,26 @@ " 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 +function! ale#loclist_jumping#FindNearest(direction, wrap, ...) abort let l:buffer = bufnr('') - let l:pos = getcurpos() + 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) @@ -41,34 +53,96 @@ function! ale#loclist_jumping#FindNearest(direction, wrap) abort \ l:search_item \) - if a:direction is# 'before' && l:cmp_value < 0 - return [l:item.lnum, l:item.col] - endif + 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# 'after' && l:cmp_value > 0 - return [l:item.lnum, l:item.col] + 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 && !empty(l:loclist) - let l:item = l:loclist[0] - - return [l:item.lnum, l:item.col] + 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, wrap) abort - let l:nearest = ale#loclist_jumping#FindNearest(a:direction, a:wrap) +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) + 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 diff --git a/vim-config/plugins/ale/autoload/ale/lsp.vim b/vim-config/plugins/ale/autoload/ale/lsp.vim old mode 100755 new mode 100644 index 95ab83cf..75d81525 --- a/vim-config/plugins/ale/autoload/ale/lsp.vim +++ b/vim-config/plugins/ale/autoload/ale/lsp.vim @@ -21,7 +21,6 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort " 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. - " message_queue: Messages queued for sending to callbacks. " capabilities_queue: The list of callbacks to call with capabilities. " capabilities: Features the server supports. let s:connections[l:conn_id] = { @@ -35,16 +34,19 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort \ 'init_options': a:init_options, \ 'config': {}, \ 'callback_list': [], - \ 'message_queue': [], - \ 'capabilities_queue': [], + \ 'init_queue': [], \ 'capabilities': { \ 'hover': 0, + \ 'rename': 0, \ 'references': 0, \ 'completion': 0, \ 'completion_trigger_characters': [], \ 'definition': 0, \ 'typeDefinition': 0, \ 'symbol_search': 0, + \ 'code_actions': 0, + \ 'did_save': 0, + \ 'includeText': 0, \ }, \} endif @@ -59,6 +61,18 @@ function! ale#lsp#RemoveConnectionWithID(id) abort endif endfunction +function! ale#lsp#ResetConnections() abort + let s:connections = {} +endfunction + +" Used only in tests. +function! ale#lsp#GetConnections() abort + " This command will throw from the sandbox. + let &l:equalprg=&l:equalprg + + 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, {}) @@ -188,10 +202,34 @@ function! s:UpdateCapabilities(conn, capabilities) abort let a:conn.capabilities.hover = 1 endif + if type(get(a:capabilities, 'hoverProvider')) is v:t_dict + let a:conn.capabilities.hover = 1 + endif + if get(a:capabilities, 'referencesProvider') is v:true let a:conn.capabilities.references = 1 endif + if type(get(a:capabilities, 'referencesProvider')) is v:t_dict + let a:conn.capabilities.references = 1 + endif + + if get(a:capabilities, 'renameProvider') is v:true + let a:conn.capabilities.rename = 1 + endif + + if type(get(a:capabilities, 'renameProvider')) is v:t_dict + let a:conn.capabilities.rename = 1 + endif + + if get(a:capabilities, 'codeActionProvider') is v:true + let a:conn.capabilities.code_actions = 1 + endif + + if type(get(a:capabilities, 'codeActionProvider')) is v:t_dict + let a:conn.capabilities.code_actions = 1 + endif + if !empty(get(a:capabilities, 'completionProvider')) let a:conn.capabilities.completion = 1 endif @@ -208,13 +246,43 @@ function! s:UpdateCapabilities(conn, capabilities) abort let a:conn.capabilities.definition = 1 endif + if type(get(a:capabilities, 'definitionProvider')) is v:t_dict + let a:conn.capabilities.definition = 1 + endif + if get(a:capabilities, 'typeDefinitionProvider') is v:true let a:conn.capabilities.typeDefinition = 1 endif + if type(get(a:capabilities, 'typeDefinitionProvider')) is v:t_dict + let a:conn.capabilities.typeDefinition = 1 + endif + if get(a:capabilities, 'workspaceSymbolProvider') is v:true let a:conn.capabilities.symbol_search = 1 endif + + if type(get(a:capabilities, 'workspaceSymbolProvider')) is v:t_dict + let a:conn.capabilities.symbol_search = 1 + endif + + if type(get(a:capabilities, 'textDocumentSync')) is v:t_dict + let l:syncOptions = get(a:capabilities, 'textDocumentSync') + + if get(l:syncOptions, 'save') is v:true + let a:conn.capabilities.did_save = 1 + endif + + if type(get(l:syncOptions, 'save')) is v:t_dict + let a:conn.capabilities.did_save = 1 + + let l:saveOptions = get(l:syncOptions, 'save') + + if get(l:saveOptions, 'includeText') is v:true + let a:conn.capabilities.includeText = 1 + endif + endif + endif endfunction " Update a connection's configuration dictionary and notify LSP servers @@ -250,22 +318,15 @@ function! ale#lsp#HandleInitResponse(conn, response) abort return endif - " After the server starts, send messages we had queued previously. - for l:message_data in a:conn.message_queue - call s:SendMessageData(a:conn, l:message_data) - endfor - - " Remove the messages now. - let a:conn.message_queue = [] + " 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:capability, l:Callback] in a:conn.capabilities_queue - if a:conn.capabilities[l:capability] - call call(l:Callback, [a:conn.id]) - endif + for l:Callback in a:conn.init_queue + call l:Callback() endfor - let a:conn.capabilities_queue = [] + let a:conn.init_queue = [] endfunction function! ale#lsp#HandleMessage(conn_id, message) abort @@ -316,7 +377,80 @@ function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort let l:conn.capabilities.completion = 1 let l:conn.capabilities.completion_trigger_characters = ['.'] let l:conn.capabilities.definition = 1 + let l:conn.capabilities.typeDefinition = 1 let l:conn.capabilities.symbol_search = 1 + let l:conn.capabilities.rename = 1 + let l:conn.capabilities.code_actions = 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. @@ -325,13 +459,21 @@ endfunction " 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#IsRunning(l:conn.job_id) + 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)}, \} - let l:job_id = ale#job#Start(a:command, l:options) + + 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 @@ -340,6 +482,11 @@ function! ale#lsp#StartProgram(conn_id, executable, command) abort let l:conn.job_id = l:job_id endif + if l:started && !l:conn.is_tsserver + let l:conn.initialized = 0 + call s:SendInitMessage(l:conn) + endif + return l:job_id > 0 endfunction @@ -349,11 +496,14 @@ endfunction " 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 @@ -362,6 +512,10 @@ function! ale#lsp#ConnectToAddress(conn_id, address) abort let l:conn.channel_id = l:channel_id endif + if l:started + call s:SendInitMessage(l:conn) + endif + return l:channel_id >= 0 endfunction @@ -426,26 +580,12 @@ function! ale#lsp#Send(conn_id, message) abort return 0 endif - " If we haven't initialized the server yet, then send the message for it. - if !l:conn.initialized && !l:conn.init_request_id - let [l:init_id, l:init_data] = ale#lsp#CreateMessageData( - \ ale#lsp#message#Initialize(l:conn.root, l:conn.init_options), - \) - - let l:conn.init_request_id = l:init_id - - call s:SendMessageData(l:conn, l:init_data) + if !l:conn.initialized + throw 'LSP server not initialized yet!' endif let [l:id, l:data] = ale#lsp#CreateMessageData(a:message) - - if l:conn.initialized - " Send the message now. - call s:SendMessageData(l:conn, l:data) - else - " Add the message we wanted to send to a List to send later. - call add(l:conn.message_queue, l:data) - endif + call s:SendMessageData(l:conn, l:data) return l:id == 0 ? -1 : l:id endfunction @@ -471,6 +611,35 @@ function! ale#lsp#OpenDocument(conn_id, buffer, language_id) abort 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 @@ -496,26 +665,32 @@ function! ale#lsp#NotifyForChanges(conn_id, buffer) abort return l:notified endfunction -" Given some LSP details that must contain at least `connection_id` and -" `project_root` keys, -function! ale#lsp#WaitForCapability(conn_id, capability, callback) abort +" 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 - if l:conn.initialized - if l:conn.capabilities[a:capability] - " The project has been initialized, so call the callback now. - call call(a:callback, [a:conn_id]) - endif - else - " Call the callback later, once we have the information we need. - call add(l:conn.capabilities_queue, [a:capability, a:callback]) - endif + return l:conn.capabilities[a:capability] endfunction diff --git a/vim-config/plugins/ale/autoload/ale/lsp/message.vim b/vim-config/plugins/ale/autoload/ale/lsp/message.vim old mode 100755 new mode 100644 index cc0b2227..b40c4407 --- a/vim-config/plugins/ale/autoload/ale/lsp/message.vim +++ b/vim-config/plugins/ale/autoload/ale/lsp/message.vim @@ -5,7 +5,7 @@ " [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 getcurpos() and friends), those then +" (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 @@ -28,20 +28,19 @@ function! ale#lsp#message#GetNextVersionID() abort return l:id endfunction -function! ale#lsp#message#Initialize(root_path, initialization_options) abort - " TODO: Define needed capabilities. +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': {}, - \ 'initializationOptions': a:initialization_options, + \ 'capabilities': a:capabilities, + \ 'initializationOptions': a:options, \ 'rootUri': ale#path#ToURI(a:root_path), \}] endfunction function! ale#lsp#message#Initialized() abort - return [1, 'initialized'] + return [1, 'initialized', {}] endfunction function! ale#lsp#message#Shutdown() abort @@ -78,12 +77,19 @@ function! ale#lsp#message#DidChange(buffer) abort \}] endfunction -function! ale#lsp#message#DidSave(buffer) abort - return [1, 'textDocument/didSave', { +function! ale#lsp#message#DidSave(buffer, includeText) abort + let l:response = [1, 'textDocument/didSave', { \ 'textDocument': { \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), \ }, \}] + + if a:includeText + let l:response[2].textDocument.version = ale#lsp#message#GetNextVersionID() + let l:response[2].text = ale#util#GetBufferContents(a:buffer) + endif + + return l:response endfunction function! ale#lsp#message#DidClose(buffer) abort @@ -159,7 +165,39 @@ function! ale#lsp#message#Hover(buffer, line, column) abort endfunction function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort - return [0, 'workspace/didChangeConfiguration', { + return [1, 'workspace/didChangeConfiguration', { \ 'settings': a:config, \}] endfunction + +function! ale#lsp#message#Rename(buffer, line, column, new_name) abort + return [0, 'textDocument/rename', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \ 'position': {'line': a:line - 1, 'character': a:column - 1}, + \ 'newName': a:new_name, + \}] +endfunction + +function! ale#lsp#message#CodeAction(buffer, line, column, end_line, end_column, diagnostics) abort + return [0, 'textDocument/codeAction', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \ 'range': { + \ 'start': {'line': a:line - 1, 'character': a:column - 1}, + \ 'end': {'line': a:end_line - 1, 'character': a:end_column}, + \ }, + \ 'context': { + \ 'diagnostics': a:diagnostics + \ }, + \}] +endfunction + +function! ale#lsp#message#ExecuteCommand(command, arguments) abort + return [0, 'workspace/executeCommand', { + \ 'command': a:command, + \ 'arguments': a:arguments, + \}] +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/lsp/reset.vim b/vim-config/plugins/ale/autoload/ale/lsp/reset.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/lsp/response.vim b/vim-config/plugins/ale/autoload/ale/lsp/response.vim old mode 100755 new mode 100644 index 5e62a29a..a4f80980 --- a/vim-config/plugins/ale/autoload/ale/lsp/response.vim +++ b/vim-config/plugins/ale/autoload/ale/lsp/response.vim @@ -28,7 +28,7 @@ function! ale#lsp#response#ReadDiagnostics(response) abort for l:diagnostic in a:response.params.diagnostics let l:severity = get(l:diagnostic, 'severity', 0) let l:loclist_item = { - \ 'text': l:diagnostic.message, + \ '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, @@ -56,18 +56,23 @@ function! ale#lsp#response#ReadDiagnostics(response) abort endif if has_key(l:diagnostic, 'relatedInformation') + \ && l:diagnostic.relatedInformation isnot v:null 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 - \ }) + \ 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) + let l:loclist_item.detail = printf( + \ '[%s] %s', + \ l:diagnostic.source, + \ l:diagnostic.message + \) endif call add(l:loclist, l:loclist_item) @@ -86,7 +91,7 @@ function! ale#lsp#response#ReadTSServerDiagnostics(response) abort \ 'lnum': l:diagnostic.start.line, \ 'col': l:diagnostic.start.offset, \ 'end_lnum': l:diagnostic.end.line, - \ 'end_col': l:diagnostic.end.offset, + \ 'end_col': l:diagnostic.end.offset - 1, \} if has_key(l:diagnostic, 'code') diff --git a/vim-config/plugins/ale/autoload/ale/lsp/tsserver_message.vim b/vim-config/plugins/ale/autoload/ale/lsp/tsserver_message.vim old mode 100755 new mode 100644 index d6919516..00213a75 --- a/vim-config/plugins/ale/autoload/ale/lsp/tsserver_message.vim +++ b/vim-config/plugins/ale/autoload/ale/lsp/tsserver_message.vim @@ -36,12 +36,14 @@ 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 +function! ale#lsp#tsserver_message#Completions( +\ buffer, line, column, prefix, include_external) abort return [0, 'ts@completions', { \ 'line': a:line, \ 'offset': a:column, \ 'file': expand('#' . a:buffer . ':p'), \ 'prefix': a:prefix, + \ 'includeExternalModuleExports': a:include_external, \}] endfunction @@ -62,6 +64,14 @@ function! ale#lsp#tsserver_message#Definition(buffer, line, column) abort \}] endfunction +function! ale#lsp#tsserver_message#TypeDefinition(buffer, line, column) abort + return [0, 'ts@typeDefinition', { + \ '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, @@ -77,3 +87,63 @@ function! ale#lsp#tsserver_message#Quickinfo(buffer, line, column) abort \ 'file': expand('#' . a:buffer . ':p'), \}] endfunction + +function! ale#lsp#tsserver_message#Rename( +\ buffer, line, column, find_in_comments, find_in_strings) abort + return [0, 'ts@rename', { + \ 'line': a:line, + \ 'offset': a:column, + \ 'file': expand('#' . a:buffer . ':p'), + \ 'arguments': { + \ 'findInComments': a:find_in_comments, + \ 'findInStrings': a:find_in_strings, + \ } + \}] +endfunction + +function! ale#lsp#tsserver_message#OrganizeImports(buffer) abort + return [0, 'ts@organizeImports', { + \ 'scope': { + \ 'type': 'file', + \ 'args': { + \ 'file': expand('#' . a:buffer . ':p'), + \ }, + \ }, + \}] +endfunction + +function! ale#lsp#tsserver_message#GetCodeFixes(buffer, line, column, end_line, end_column, error_codes) abort + " The lines and columns are 1-based. + " The errors codes must be a list of tsserver error codes to fix. + return [0, 'ts@getCodeFixes', { + \ 'startLine': a:line, + \ 'startOffset': a:column, + \ 'endLine': a:end_line, + \ 'endOffset': a:end_column + 1, + \ 'file': expand('#' . a:buffer . ':p'), + \ 'errorCodes': a:error_codes, + \}] +endfunction + +function! ale#lsp#tsserver_message#GetApplicableRefactors(buffer, line, column, end_line, end_column) abort + " The arguments for this request can also be just 'line' and 'offset' + return [0, 'ts@getApplicableRefactors', { + \ 'startLine': a:line, + \ 'startOffset': a:column, + \ 'endLine': a:end_line, + \ 'endOffset': a:end_column + 1, + \ 'file': expand('#' . a:buffer . ':p'), + \}] +endfunction + +function! ale#lsp#tsserver_message#GetEditsForRefactor(buffer, line, column, end_line, end_column, refactor, action) abort + return [0, 'ts@getEditsForRefactor', { + \ 'startLine': a:line, + \ 'startOffset': a:column, + \ 'endLine': a:end_line, + \ 'endOffset': a:end_column + 1, + \ 'file': expand('#' . a:buffer . ':p'), + \ 'refactor': a:refactor, + \ 'action': a:action, + \}] +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/lsp_linter.vim b/vim-config/plugins/ale/autoload/ale/lsp_linter.vim old mode 100755 new mode 100644 index d92dae7e..230b3141 --- a/vim-config/plugins/ale/autoload/ale/lsp_linter.vim +++ b/vim-config/plugins/ale/autoload/ale/lsp_linter.vim @@ -8,8 +8,16 @@ 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. @@ -26,13 +34,18 @@ 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:escaped_name = escape( + \ fnameescape(l:filename), + \ has('win32') ? '^' : '^,}]' + \) + let l:buffer = bufnr('^' . l:escaped_name . '$') + let l:info = get(g:ale_buffer_info, l:buffer, {}) - if s:ShouldIgnore(l:buffer, l:linter_name) + if empty(l:info) return endif - if l:buffer <= 0 + if s:ShouldIgnore(l:buffer, l:linter_name) return endif @@ -43,13 +56,19 @@ endfunction function! s:HandleTSServerDiagnostics(response, error_type) abort let l:linter_name = 'tsserver' - let l:buffer = bufnr(a:response.body.file) + let l:escaped_name = escape( + \ fnameescape(a:response.body.file), + \ has('win32') ? '^' : '^,}]' + \) + let l:buffer = bufnr('^' . l:escaped_name . '$') 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 @@ -66,12 +85,18 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort endif let l:info.syntax_loclist = l:thislist - else + elseif a:error_type is# 'semantic' 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 + else + if len(l:thislist) is 0 && len(get(l:info, 'suggestion_loclist', [])) is 0 + let l:no_changes = 1 + endif + + let l:info.suggestion_loclist = l:thislist endif if l:no_changes @@ -79,6 +104,7 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort endif let l:loclist = get(l:info, 'semantic_loclist', []) + \ + get(l:info, 'suggestion_loclist', []) \ + get(l:info, 'syntax_loclist', []) call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0) @@ -119,123 +145,305 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort call s:HandleLSPErrorMessage(l:linter_name, a:response) elseif l:method is# 'textDocument/publishDiagnostics' call s:HandleLSPDiagnostics(a:conn_id, a:response) + elseif l:method is# 'window/showMessage' + call ale#lsp_window#HandleShowMessage( + \ s:lsp_linter_map[a:conn_id], + \ g:ale_lsp_show_message_format, + \ a:response.params + \) 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') + elseif get(a:response, 'type', '') is# 'event' + \&& get(a:response, 'event', '') is# 'suggestionDiag' + \&& get(g:, 'ale_lsp_suggestions', '1') == 1 + call s:HandleTSServerDiagnostics(a:response, 'suggestion') endif endfunction function! ale#lsp_linter#GetOptions(buffer, linter) abort - let l:initialization_options = {} - if has_key(a:linter, 'initialization_options_callback') - let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer) - elseif has_key(a:linter, 'initialization_options') - let l:initialization_options = a:linter.initialization_options + return ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer) endif - return l:initialization_options + 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 - let l:config = {} - if has_key(a:linter, 'lsp_config_callback') - let l:config = ale#util#GetFunction(a:linter.lsp_config_callback)(a:buffer) - elseif has_key(a:linter, 'lsp_config') - let l:config = a:linter.lsp_config + return ale#util#GetFunction(a:linter.lsp_config_callback)(a:buffer) endif - return l:config + 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 -" 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) abort - let l:command = '' - let l:address = '' - let l:root = ale#util#GetFunction(a:linter.project_root_callback)(a:buffer) +function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort + let l:buffer_ale_root = getbufvar( + \ a:buffer, + \ 'ale_root', + \ getbufvar(a:buffer, 'ale_lsp_root', {}) + \) - 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 {} + if type(l:buffer_ale_root) is v:t_string + return l:buffer_ale_root endif - let l:init_options = ale#lsp_linter#GetOptions(a:buffer, a:linter) + " 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 a:linter.lsp is# 'socket' - let l:address = ale#linter#GetAddress(a:buffer, a:linter) - let l:conn_id = ale#lsp#Register(l:address, l:root, l:init_options) - let l:ready = ale#lsp#ConnectToAddress(l:conn_id, l:address) - else - let l:executable = ale#linter#GetExecutable(a:buffer, a:linter) + if type(l:Root) is v:t_func + return l:Root(a:buffer) + else + return l:Root + endif + endif + + let l:global_root = g:ale_root + + if empty(g:ale_root) && exists('g:ale_lsp_root') + let l:global_root = g:ale_lsp_root + endif + + " Try to get a global setting for the root + if has_key(l:global_root, a:linter.name) + let l:Root = l:global_root[a:linter.name] - if empty(l:executable) || !executable(l:executable) - return {} + if type(l:Root) is v:t_func + return l:Root(a:buffer) + else + return l:Root endif + endif - let l:conn_id = ale#lsp#Register(l:executable, l:root, l:init_options) + " Fall back to the linter-specific configuration + if has_key(a:linter, 'project_root') + let l:Root = a:linter.project_root - let l:command = ale#linter#GetCommand(a:buffer, a:linter) - " Format the command, so %e can be formatted into it. - let l:command = ale#command#FormatCommand(a:buffer, l:executable, l:command, 0, {-> 0})[1] - let l:command = ale#job#PrepareCommand(a:buffer, l:command) - let l:ready = ale#lsp#StartProgram(l:conn_id, l:executable, l:command) + return type(l:Root) is v:t_func ? l:Root(a:buffer) : l:Root endif - if !l:ready + 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#linter#GetLanguage(l:buffer, a:linter) + + 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(a:buffer, 'failed', l:conn_id, l:command) + call ale#history#Add(l:buffer, 'started', l:conn_id, l:command) endif - - return {} endif - " tsserver behaves differently, so tell the LSP API that it is tsserver. + " The change message needs to be sent for tsserver before doing anything. if a:linter.lsp is# 'tsserver' - call ale#lsp#MarkConnectionAsTsserver(l:conn_id) + call ale#lsp#NotifyForChanges(l:conn_id, l:buffer) + endif + + " Tell the relevant buffer that the LSP has started via an autocmd. + if l:buffer > 0 + if l:buffer == bufnr('') + silent doautocmd User ALELSPStarted + else + execute 'augroup ALELSPStartedGroup' . l:buffer + autocmd! + + execute printf( + \ 'autocmd BufEnter ' + \ . ' doautocmd User ALELSPStarted', + \ l:buffer + \) + + " Replicate ++once behavior for backwards compatibility. + execute printf( + \ 'autocmd BufEnter ' + \ . ' autocmd! ALELSPStartedGroup%d', + \ l:buffer, l:buffer + \) + augroup END + endif + 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:cwd = ale#linter#GetCwd(l:buffer, l:linter) + let l:command = ale#command#FormatCommand( + \ l:buffer, + \ a:executable, + \ a:command, + \ 0, + \ v:false, + \ l:cwd, + \ ale#GetFilenameMappings(l:buffer, l:linter.name), + \)[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 - let l:config = ale#lsp_linter#GetConfig(a:buffer, a:linter) - let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer) + 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': a:buffer, + \ 'buffer': l:buffer, \ 'connection_id': l:conn_id, \ 'command': l:command, \ 'project_root': l:root, - \ 'language_id': l:language_id, \} - call ale#lsp#UpdateConfig(l:conn_id, a:buffer, l:config) + call ale#lsp#OnInit(l:conn_id, {-> + \ ale#lsp_linter#OnInit(l:linter, l:details, l:Callback) + \}) - if ale#lsp#OpenDocument(l:conn_id, a:buffer, l:language_id) - if g:ale_history_enabled && !empty(l:command) - call ale#history#Add(a:buffer, 'started', l:conn_id, l:command) - endif + 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 - " 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, a:buffer) + if empty(a:address) + return 0 endif - return l:details + return s:StartLSP(a:options, a:address, '', '') endfunction -function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort - let l:info = g:ale_buffer_info[a:buffer] - let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter) +function! 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:lsp_details) + 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:id = l:lsp_details.connection_id + 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') @@ -245,34 +453,84 @@ function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort let s:lsp_linter_map[l:id] = a:linter.name if a:linter.lsp is# 'tsserver' - let l:message = ale#lsp#tsserver_message#Geterr(a:buffer) + let l: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, a:buffer) + 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(a:buffer, 'ale_save_event_fired', 0) - let l:save_message = ale#lsp#message#DidSave(a:buffer) + \&& getbufvar(l:buffer, 'ale_save_event_fired', 0) + \&& ale#lsp#HasCapability(l:buffer, 'did_save') + let l:include_text = ale#lsp#HasCapability(l:buffer, 'includeText') + let l:save_message = ale#lsp#message#DidSave(l:buffer, l:include_text) let l:notified = ale#lsp#Send(l:id, l:save_message) != 0 endif +endfunction - if l:notified - if index(l:info.active_linter_list, a:linter.name) < 0 - call add(l:info.active_linter_list, a:linter.name) - endif - endif - - return l:notified +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/vim-config/plugins/ale/autoload/ale/lsp_window.vim b/vim-config/plugins/ale/autoload/ale/lsp_window.vim new file mode 100644 index 00000000..9a27f2f1 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/lsp_window.vim @@ -0,0 +1,58 @@ +" Author: suoto +" Description: Handling of window/* LSP methods, although right now only +" handles window/showMessage + +" Constants for message type codes +let s:LSP_MESSAGE_TYPE_DISABLED = 0 +let s:LSP_MESSAGE_TYPE_ERROR = 1 +let s:LSP_MESSAGE_TYPE_WARNING = 2 +let s:LSP_MESSAGE_TYPE_INFORMATION = 3 +let s:LSP_MESSAGE_TYPE_LOG = 4 + +" Translate strings from the user config to a number so we can check +" severities +let s:CFG_TO_LSP_SEVERITY = { +\ 'disabled': s:LSP_MESSAGE_TYPE_DISABLED, +\ 'error': s:LSP_MESSAGE_TYPE_ERROR, +\ 'warning': s:LSP_MESSAGE_TYPE_WARNING, +\ 'information': s:LSP_MESSAGE_TYPE_INFORMATION, +\ 'info': s:LSP_MESSAGE_TYPE_INFORMATION, +\ 'log': s:LSP_MESSAGE_TYPE_LOG +\} + +" Handle window/showMessage response. +" - details: dict containing linter name and format (g:ale_lsp_show_message_format) +" - params: dict with the params for the call in the form of {type: number, message: string} +function! ale#lsp_window#HandleShowMessage(linter_name, format, params) abort + let l:message = a:params.message + let l:type = a:params.type + + " Get the configured severity level threshold and check if the message + " should be displayed or not + let l:configured_severity = tolower(get(g:, 'ale_lsp_show_message_severity', 'error')) + " If the user has configured with a value we can't find on the conversion + " dict, fall back to warning + let l:cfg_severity_threshold = get(s:CFG_TO_LSP_SEVERITY, l:configured_severity, s:LSP_MESSAGE_TYPE_WARNING) + + if l:type > l:cfg_severity_threshold + return + endif + + " Severity will depend on the message type + if l:type is# s:LSP_MESSAGE_TYPE_ERROR + let l:severity = g:ale_echo_msg_error_str + elseif l:type is# s:LSP_MESSAGE_TYPE_INFORMATION + let l:severity = g:ale_echo_msg_info_str + elseif l:type is# s:LSP_MESSAGE_TYPE_LOG + let l:severity = g:ale_echo_msg_log_str + else + " Default to warning just in case + let l:severity = g:ale_echo_msg_warning_str + endif + + let l:string = substitute(a:format, '\V%severity%', l:severity, 'g') + let l:string = substitute(l:string, '\V%linter%', a:linter_name, 'g') + let l:string = substitute(l:string, '\V%s\>', l:message, 'g') + + call ale#util#ShowMessage(l:string) +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/maven.vim b/vim-config/plugins/ale/autoload/ale/maven.vim new file mode 100644 index 00000000..4f87ebb7 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/maven.vim @@ -0,0 +1,57 @@ +" Description: Functions for working with Maven projects. +" +" Given a buffer number, find a Maven project root. +function! ale#maven#FindProjectRoot(buffer) abort + let l:wrapper_path = ale#path#FindNearestFile(a:buffer, 'mvnw') + + if !empty(l:wrapper_path) + return fnamemodify(l:wrapper_path, ':h') + endif + + let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml') + + if !empty(l:pom_path) + return fnamemodify(l:pom_path, ':h') + endif + + return '' +endfunction + +" Given a buffer number, find the path to the executable. +" First search on the path for 'mvnw' (mvnw.cmd on Windows), if nothing is found, +" try the global command. Returns an empty string if cannot find the executable. +function! ale#maven#FindExecutable(buffer) abort + let l:wrapper_cmd = has('unix') ? 'mvnw' : 'mvnw.cmd' + let l:wrapper_path = ale#path#FindNearestFile(a:buffer, l:wrapper_cmd) + + if !empty(l:wrapper_path) && executable(l:wrapper_path) + return l:wrapper_path + endif + + if executable('mvn') + return 'mvn' + endif + + return '' +endfunction + +" Given a buffer number, get a working directory and command to print the +" classpath of the root project. +" +" Returns an empty string for the command if Maven is not detected. +function! ale#maven#BuildClasspathCommand(buffer) abort + let l:executable = ale#maven#FindExecutable(a:buffer) + + if !empty(l:executable) + let l:project_root = ale#maven#FindProjectRoot(a:buffer) + + if !empty(l:project_root) + return [ + \ l:project_root, + \ ale#Escape(l:executable) . ' dependency:build-classpath' + \] + endif + endif + + return ['', ''] +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/node.vim b/vim-config/plugins/ale/autoload/ale/node.vim old mode 100755 new mode 100644 index 5c579c75..9e11ca7e --- a/vim-config/plugins/ale/autoload/ale/node.vim +++ b/vim-config/plugins/ale/autoload/ale/node.vim @@ -3,31 +3,6 @@ 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 - -" As above, but curry the arguments so only the buffer number is required. -function! ale#node#FindExecutableFunc(base_var_name, path_list) abort - return {buf -> ale#node#FindExecutable(buf, a:base_var_name, a:path_list)} -endfunction - " Create a executable string which executes a Node.js script command with a " Node.js executable if needed. " @@ -37,7 +12,7 @@ endfunction " " The executable is only prefixed for Windows machines function! ale#node#Executable(buffer, executable) abort - if ale#Has('win32') && a:executable =~? '\.js$' + 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) diff --git a/vim-config/plugins/ale/autoload/ale/organize_imports.vim b/vim-config/plugins/ale/autoload/ale/organize_imports.vim new file mode 100644 index 00000000..e2b1c0d2 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/organize_imports.vim @@ -0,0 +1,62 @@ +" Author: Jerko Steiner +" Description: Organize imports support for tsserver +" +function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort + if get(a:response, 'command', '') isnot# 'organizeImports' + return + endif + + if get(a:response, 'success', v:false) isnot v:true + return + endif + + let l:file_code_edits = a:response.body + + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'Organize Imports', + \ 'changes': l:file_code_edits, + \ }, + \ {} + \) +endfunction + +function! s:OnReady(linter, lsp_details) abort + let l:id = a:lsp_details.connection_id + + if a:linter.lsp isnot# 'tsserver' + call ale#util#Execute('echom ''OrganizeImports currently only works with tsserver''') + + return + endif + + let l:buffer = a:lsp_details.buffer + + let l:Callback = function('ale#organize_imports#HandleTSServerResponse') + + call ale#lsp#RegisterCallback(l:id, l:Callback) + + let l:message = ale#lsp#tsserver_message#OrganizeImports(l:buffer) + + let l:request_id = ale#lsp#Send(l:id, l:message) +endfunction + +function! s:OrganizeImports(linter) abort + let l:buffer = bufnr('') + let [l:line, l:column] = getpos('.')[1:2] + + if a:linter.lsp isnot# 'tsserver' + let l:column = min([l:column, len(getline(l:line))]) + endif + + let l:Callback = function('s:OnReady') + call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) +endfunction + +function! ale#organize_imports#Execute() abort + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + call s:OrganizeImports(l:linter) + endif + endfor +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/other_source.vim b/vim-config/plugins/ale/autoload/ale/other_source.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/path.vim b/vim-config/plugins/ale/autoload/ale/path.vim old mode 100755 new mode 100644 index 89b119f4..c7bfd47e --- a/vim-config/plugins/ale/autoload/ale/path.vim +++ b/vim-config/plugins/ale/autoload/ale/path.vim @@ -3,13 +3,20 @@ " simplify a path, and fix annoying issues with paths on Windows. " -" Forward slashes are changed to back slashes so path equality works better. +" 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') - return substitute(simplify(a:path), '^//\+', '/', 'g') " no-custom-checks + 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') @@ -17,6 +24,14 @@ function! ale#path#Simplify(path) abort return substitute(simplify(l:win_path), '^\\\+', '\', 'g') " no-custom-checks endfunction +" Simplify a path without a Windows drive letter. +" This function can be used for checking if paths are equal. +function! ale#path#RemoveDriveLetter(path) abort + return has('win32') && a:path[1:2] is# ':\' + \ ? ale#path#Simplify(a:path[2:]) + \ : ale#path#Simplify(a:path) +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 @@ -47,14 +62,14 @@ function! ale#path#FindNearestDirectory(buffer, directory_name) abort return '' endfunction -" Given a buffer, a string to search for, an a global fallback for when +" Given a buffer, a string to search for, and 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 the search fails, try the global executable instead. if empty(l:path) let l:path = a:global_fallback endif @@ -62,20 +77,40 @@ function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abor 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 +" 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 program. +function! ale#path#FindNearestExecutable(buffer, path_list) abort + for l:path in a:path_list + if ale#path#IsAbsolute(l:path) + let l:executable = filereadable(l:path) ? l:path : '' + else + let l:executable = ale#path#FindNearestFile(a:buffer, l:path) + endif + + if !empty(l:executable) + return l:executable + endif + endfor + + return '' 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')) +" 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 program. +" +" The use_global and executable options for the relevant program will be used. +function! ale#path#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:nearest = ale#path#FindNearestExecutable(a:buffer, a:path_list) + + if !empty(l:nearest) + return l:nearest + endif + + return ale#Var(a:buffer, a:base_var_name . '_executable') endfunction " Return 1 if a path is an absolute path. @@ -88,7 +123,7 @@ function! ale#path#IsAbsolute(filename) abort return a:filename[:0] is# '/' || a:filename[1:2] is# ':\' endfunction -let s:temp_dir = ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h')) +let s:temp_dir = ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h:h')) " Given a filename, return 1 if the file represents some temporary file " created by Vim. @@ -117,7 +152,7 @@ function! ale#path#Dirname(path) abort endif " For /foo/bar/ we need :h:h to get /foo - if a:path[-1:] is# '/' + if a:path[-1:] is# '/' || (has('win32') && a:path[-1:] is# '\') return fnamemodify(a:path, ':h:h') endif @@ -197,14 +232,20 @@ function! ale#path#ToURI(path) abort endfunction function! ale#path#FromURI(uri) abort - let l:i = len('file://') - let l:encoded_path = a:uri[: l:i - 1] is# 'file://' ? a:uri[l:i :] : a:uri + 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 l:path =~# '^/[a-zA-Z]:' + 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 diff --git a/vim-config/plugins/ale/autoload/ale/pattern_options.vim b/vim-config/plugins/ale/autoload/ale/pattern_options.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/autoload/ale/powershell.vim b/vim-config/plugins/ale/autoload/ale/powershell.vim new file mode 100644 index 00000000..8c163206 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/autoload/ale/preview.vim b/vim-config/plugins/ale/autoload/ale/preview.vim old mode 100755 new mode 100644 index 1f50e0ad..1aca03ea --- a/vim-config/plugins/ale/autoload/ale/preview.vim +++ b/vim-config/plugins/ale/autoload/ale/preview.vim @@ -1,6 +1,22 @@ " Author: w0rp " Description: Preview windows for showing whatever information in. +if !has_key(s:, 'last_list') + let s:last_list = [] +endif + +if !has_key(s:, 'last_options') + let s:last_options = {} +endif + +function! ale#preview#SetLastSelection(item_list, options) abort + let s:last_list = a:item_list + let s:last_options = { + \ 'open_in': get(a:options, 'open_in', 'current-buffer'), + \ 'use_relative_paths': get(a:options, 'use_relative_paths', 0), + \} +endfunction + " Open a preview window and show some lines in it. " A second argument can be passed as a Dictionary with options. They are... " @@ -23,6 +39,10 @@ function! ale#preview#Show(lines, ...) abort setlocal readonly let &l:filetype = get(l:options, 'filetype', 'ale-preview') + for l:command in get(l:options, 'commands', []) + call execute(l:command) + endfor + if get(l:options, 'stay_here') wincmd p endif @@ -41,16 +61,24 @@ 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 +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:item.filename + \ l:filename \ . ':' . l:item.line \ . ':' . l:item.column \ . (!empty(l:match) ? ' ' . l:match : ''), @@ -59,32 +87,51 @@ function! ale#preview#ShowSelection(item_list) abort call ale#preview#Show(l:lines, {'filetype': 'ale-preview-selection'}) let b:ale_preview_item_list = a:item_list + let b:ale_preview_item_open_in = get(l:options, 'open_in', 'current-buffer') + + " Jump to an index for a previous selection, if set. + if has_key(l:options, 'jump_to_index') + let l:pos = getpos('.') + let l:pos[1] = l:options.jump_to_index + 1 + call setpos('.', l:pos) + endif + + " Remember preview state, so we can repeat it later. + call ale#preview#SetLastSelection(a:item_list, l:options) endfunction -function! s:Open(open_in_tab) abort +function! ale#preview#RepeatSelection() abort + if !empty(s:last_list) + call ale#preview#ShowSelection(s:last_list, s:last_options) + endif +endfunction + +function! s:Open(open_in) abort let l:item_list = get(b:, 'ale_preview_item_list', []) - let l:item = get(l:item_list, getcurpos()[1] - 1, {}) + let l:index = getpos('.')[1] - 1 + let l:item = get(l:item_list, l:index, {}) if empty(l:item) return endif - if !a:open_in_tab - :q! - endif + " Remember an index to jump to when repeating a selection. + let s:last_options.jump_to_index = l:index + + :q! call ale#util#Open( \ l:item.filename, \ l:item.line, \ l:item.column, - \ {'open_in_tab': a:open_in_tab}, + \ {'open_in': a:open_in}, \) endfunction -function! ale#preview#OpenSelectionInBuffer() abort - call s:Open(0) +function! ale#preview#OpenSelection() abort + call s:Open(b:ale_preview_item_open_in) endfunction function! ale#preview#OpenSelectionInTab() abort - call s:Open(1) + call s:Open('tab') endfunction diff --git a/vim-config/plugins/ale/autoload/ale/python.vim b/vim-config/plugins/ale/autoload/ale/python.vim old mode 100755 new mode 100644 index 8d6bf1f0..81cb06e0 --- a/vim-config/plugins/ale/autoload/ale/python.vim +++ b/vim-config/plugins/ale/autoload/ale/python.vim @@ -2,6 +2,7 @@ " Description: Functions for integrating with Python linters. call ale#Set('python_auto_pipenv', '0') +call ale#Set('python_auto_poetry', '0') let s:sep = has('win32') ? '\' : '/' " bin is used for Unix virtualenv directories, and Scripts is for Windows. @@ -23,12 +24,19 @@ function! ale#python#FindProjectRootIni(buffer) abort \|| filereadable(l:path . '/setup.cfg') \|| filereadable(l:path . '/pytest.ini') \|| filereadable(l:path . '/tox.ini') + \|| filereadable(l:path . '/.pyre_configuration.local') \|| filereadable(l:path . '/mypy.ini') \|| filereadable(l:path . '/pycodestyle.cfg') - \|| filereadable(l:path . '/flake8.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') + \|| filereadable(l:path . '/poetry.lock') + \|| filereadable(l:path . '/pyproject.toml') + \|| filereadable(l:path . '/.tool-versions') return l:path endif endfor @@ -48,7 +56,7 @@ function! ale#python#FindProjectRoot(buffer) abort let l:ini_root = ale#python#FindProjectRootIni(a:buffer) if !empty(l:ini_root) - return l:ini_root + return l:ini_root endif for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) @@ -110,7 +118,50 @@ function! ale#python#FindExecutable(buffer, base_var_name, path_list) abort 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 + +" Detects whether a poetry environment is present. +function! ale#python#PoetryPresent(buffer) abort + return findfile('poetry.lock', expand('#' . a:buffer . ':p:h') . ';') isnot# '' +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/racket.vim b/vim-config/plugins/ale/autoload/ale/racket.vim new file mode 100644 index 00000000..ff896108 --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/racket.vim @@ -0,0 +1,12 @@ +function! ale#racket#FindProjectRoot(buffer) abort + let l:cwd = expand('#' . a:buffer . ':p:h') + let l:highest_init = l:cwd + + for l:path in ale#path#Upwards(l:cwd) + if filereadable(l:path.'/init.rkt') + let l:highest_init = l:path + endif + endfor + + return l:highest_init +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/references.vim b/vim-config/plugins/ale/autoload/ale/references.vim old mode 100755 new mode 100644 index 24267bb4..38ff0d3d --- a/vim-config/plugins/ale/autoload/ale/references.vim +++ b/vim-config/plugins/ale/autoload/ale/references.vim @@ -1,3 +1,5 @@ +let g:ale_default_navigation = get(g:, 'ale_default_navigation', 'buffer') + let s:references_map = {} " Used to get the references map in tests. @@ -17,7 +19,7 @@ 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) - call remove(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 = [] @@ -34,7 +36,7 @@ function! ale#references#HandleTSServerResponse(conn_id, response) abort if empty(l:item_list) call ale#util#Execute('echom ''No references found.''') else - call ale#preview#ShowSelection(l:item_list) + call ale#preview#ShowSelection(l:item_list, l:options) endif endif endif @@ -43,32 +45,39 @@ endfunction function! ale#references#HandleLSPResponse(conn_id, response) abort if has_key(a:response, 'id') \&& has_key(s:references_map, a:response.id) - call remove(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 = [] - 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 + 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) + call ale#preview#ShowSelection(l:item_list, l:options) endif endif endfunction -function! s:OnReady(linter, lsp_details, line, column, ...) abort - let l:buffer = a:lsp_details.buffer +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') @@ -91,34 +100,45 @@ function! s:OnReady(linter, lsp_details, line, column, ...) abort let l:request_id = ale#lsp#Send(l:id, l:message) - let s:references_map[l:request_id] = {} + let s:references_map[l:request_id] = { + \ 'use_relative_paths': has_key(a:options, 'use_relative_paths') ? a:options.use_relative_paths : 0, + \ 'open_in': get(a:options, 'open_in', 'current-buffer'), + \} endfunction -function! s:FindReferences(linter) abort - let l:buffer = bufnr('') - let [l:line, l:column] = getcurpos()[1:2] - - if a:linter.lsp isnot# 'tsserver' - let l:column = min([l:column, len(getline(l:line))]) +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 + elseif l:option is? '-tab' + let l:options.open_in = 'tab' + elseif l:option is? '-split' + let l:options.open_in = 'split' + elseif l:option is? '-vsplit' + let l:options.open_in = 'vsplit' + endif + endfor endif - let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter) + if !has_key(l:options, 'open_in') + let l:default_navigation = ale#Var(bufnr(''), 'default_navigation') - if empty(l:lsp_details) - return 0 + if index(['tab', 'split', 'vsplit'], l:default_navigation) >= 0 + let l:options.open_in = l:default_navigation + endif endif - let l:id = l:lsp_details.connection_id - - call ale#lsp#WaitForCapability(l:id, 'references', function('s:OnReady', [ - \ a:linter, l:lsp_details, l:line, l:column - \])) -endfunction + 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]) -function! ale#references#Find() abort for l:linter in ale#linter#Get(&filetype) if !empty(l:linter.lsp) - call s:FindReferences(l:linter) + call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) endif endfor endfunction diff --git a/vim-config/plugins/ale/autoload/ale/rename.vim b/vim-config/plugins/ale/autoload/ale/rename.vim new file mode 100644 index 00000000..9030618e --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/rename.vim @@ -0,0 +1,208 @@ +" Author: Jerko Steiner +" Description: Rename symbol support for LSP / tsserver + +let s:rename_map = {} + +" Used to get the rename map in tests. +function! ale#rename#GetMap() abort + return deepcopy(s:rename_map) +endfunction + +" Used to set the rename map in tests. +function! ale#rename#SetMap(map) abort + let s:rename_map = a:map +endfunction + +function! ale#rename#ClearLSPData() abort + let s:rename_map = {} +endfunction + +let g:ale_rename_tsserver_find_in_comments = get(g:, 'ale_rename_tsserver_find_in_comments') +let g:ale_rename_tsserver_find_in_strings = get(g:, 'ale_rename_tsserver_find_in_strings') + +function! s:message(message) abort + call ale#util#Execute('echom ' . string(a:message)) +endfunction + +function! ale#rename#HandleTSServerResponse(conn_id, response) abort + if get(a:response, 'command', '') isnot# 'rename' + return + endif + + if !has_key(s:rename_map, a:response.request_seq) + return + endif + + let l:options = remove(s:rename_map, a:response.request_seq) + + let l:old_name = l:options.old_name + let l:new_name = l:options.new_name + + if get(a:response, 'success', v:false) is v:false + let l:message = get(a:response, 'message', 'unknown') + call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name + \ . '". Reason: ' . l:message) + + return + endif + + let l:changes = [] + + for l:response_item in a:response.body.locs + let l:filename = l:response_item.file + let l:text_changes = [] + + for l:loc in l:response_item.locs + call add(l:text_changes, { + \ 'start': { + \ 'line': l:loc.start.line, + \ 'offset': l:loc.start.offset, + \ }, + \ 'end': { + \ 'line': l:loc.end.line, + \ 'offset': l:loc.end.offset, + \ }, + \ 'newText': l:new_name, + \}) + endfor + + call add(l:changes, { + \ 'fileName': l:filename, + \ 'textChanges': l:text_changes, + \}) + endfor + + if empty(l:changes) + call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name . '"') + + return + endif + + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'rename', + \ 'changes': l:changes, + \ }, + \ { + \ 'should_save': 1, + \ }, + \) +endfunction + +function! ale#rename#HandleLSPResponse(conn_id, response) abort + if has_key(a:response, 'id') + \&& has_key(s:rename_map, a:response.id) + let l:options = remove(s:rename_map, a:response.id) + + if !has_key(a:response, 'result') + call s:message('No rename result received from server') + + return + endif + + let l:changes_map = ale#code_action#GetChanges(a:response.result) + + if empty(l:changes_map) + call s:message('No changes received from server') + + return + endif + + let l:changes = ale#code_action#BuildChangesList(l:changes_map) + + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'rename', + \ 'changes': l:changes, + \ }, + \ { + \ 'should_save': 1, + \ }, + \) + 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, 'rename') + return + endif + + let l:buffer = a:lsp_details.buffer + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#rename#HandleTSServerResponse') + \ : function('ale#rename#HandleLSPResponse') + + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#Rename( + \ l:buffer, + \ a:line, + \ a:column, + \ g:ale_rename_tsserver_find_in_comments, + \ g:ale_rename_tsserver_find_in_strings, + \) + else + " Send a message saying the buffer has changed first, or the + " rename position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:buffer) + + let l:message = ale#lsp#message#Rename( + \ l:buffer, + \ a:line, + \ a:column, + \ a:options.new_name + \) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message) + + let s:rename_map[l:request_id] = a:options +endfunction + +function! s:ExecuteRename(linter, options) abort + let l:buffer = bufnr('') + let [l:line, l:column] = getpos('.')[1:2] + + if a:linter.lsp isnot# 'tsserver' + let l:column = min([l:column, len(getline(l:line))]) + endif + + let l:Callback = function('s:OnReady', [l:line, l:column, a:options]) + call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) +endfunction + +function! ale#rename#Execute() abort + let l:lsp_linters = [] + + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + call add(l:lsp_linters, l:linter) + endif + endfor + + if empty(l:lsp_linters) + call s:message('No active LSPs') + + return + endif + + let l:old_name = expand('') + let l:new_name = ale#util#Input('New name: ', l:old_name) + + if empty(l:new_name) + call s:message('New name cannot be empty!') + + return + endif + + for l:lsp_linter in l:lsp_linters + call s:ExecuteRename(l:lsp_linter, { + \ 'old_name': l:old_name, + \ 'new_name': l:new_name, + \}) + endfor +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/ruby.vim b/vim-config/plugins/ale/autoload/ale/ruby.vim old mode 100755 new mode 100644 index 3d9c5a51..d941bb2c --- a/vim-config/plugins/ale/autoload/ale/ruby.vim +++ b/vim-config/plugins/ale/autoload/ale/ruby.vim @@ -1,7 +1,7 @@ " Author: Eddie Lebow https://github.com/elebow " Description: Functions for integrating with Ruby tools -" Find the nearest dir contining "app", "db", and "config", and assume it is +" 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'] @@ -26,7 +26,7 @@ function! ale#ruby#FindProjectRoot(buffer) abort let l:dir = ale#ruby#FindRailsRoot(a:buffer) if isdirectory(l:dir) - return l:dir + return l:dir endif for l:name in ['.solargraph.yml', 'Rakefile', 'Gemfile'] @@ -74,3 +74,10 @@ function! ale#ruby#HandleRubocopOutput(buffer, lines) abort return l:output endfunction +function! ale#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/vim-config/plugins/ale/autoload/ale/semver.vim b/vim-config/plugins/ale/autoload/ale/semver.vim old mode 100755 new mode 100644 index 6b0fd34a..e3eb49c0 --- a/vim-config/plugins/ale/autoload/ale/semver.vim +++ b/vim-config/plugins/ale/autoload/ale/semver.vim @@ -5,31 +5,52 @@ 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! ale#semver#GetVersion(executable, version_lines) abort +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) - for l:line in a:version_lines - let l:match = matchlist(l:line, '\v(\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 + if !empty(l:parsed_version) + let l:version = l:parsed_version + let s:version_cache[a:executable] = l:version + endif return l:version endfunction -" Return 1 if the semver version has been cached for a given executable. -function! ale#semver#HasVersion(executable) abort - return has_key(s:version_cache, a:executable) +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 diff --git a/vim-config/plugins/ale/autoload/ale/sign.vim b/vim-config/plugins/ale/autoload/ale/sign.vim old mode 100755 new mode 100644 index af863682..21e06313 --- a/vim-config/plugins/ale/autoload/ale/sign.vim +++ b/vim-config/plugins/ale/autoload/ale/sign.vim @@ -14,12 +14,16 @@ 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) +let g:ale_sign_priority = get(g:, 'ale_sign_priority', 30) " 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) +let g:ale_sign_highlight_linenrs = get(g:, 'ale_sign_highlight_linenrs', 0) + +let s:supports_sign_groups = has('nvim-0.4.2') || has('patch-8.1.614') if !hlexists('ALEErrorSign') highlight link ALEErrorSign error @@ -46,9 +50,10 @@ if !hlexists('ALESignColumnWithErrors') endif function! ale#sign#SetUpDefaultColumnWithoutErrorsHighlight() abort - redir => l:output - 0verbose silent highlight SignColumn - redir end + let l:verbose = &verbose + set verbose=0 + let l:output = execute('highlight SignColumn', 'silent') + let &verbose = l:verbose let l:highlight_syntax = join(split(l:output)[2:]) let l:match = matchlist(l:highlight_syntax, '\vlinks to (.+)$') @@ -64,18 +69,51 @@ 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=' . g:ale_sign_error +execute 'sign define ALEErrorSign text=' . s:EscapeSignText(g:ale_sign_error) \ . ' texthl=ALEErrorSign linehl=ALEErrorLine' -execute 'sign define ALEStyleErrorSign text=' . g:ale_sign_style_error +execute 'sign define ALEStyleErrorSign text=' . s:EscapeSignText(g:ale_sign_style_error) \ . ' texthl=ALEStyleErrorSign linehl=ALEErrorLine' -execute 'sign define ALEWarningSign text=' . g:ale_sign_warning +execute 'sign define ALEWarningSign text=' . s:EscapeSignText(g:ale_sign_warning) \ . ' texthl=ALEWarningSign linehl=ALEWarningLine' -execute 'sign define ALEStyleWarningSign text=' . g:ale_sign_style_warning +execute 'sign define ALEStyleWarningSign text=' . s:EscapeSignText(g:ale_sign_style_warning) \ . ' texthl=ALEStyleWarningSign linehl=ALEWarningLine' -execute 'sign define ALEInfoSign text=' . g:ale_sign_info +execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info) \ . ' texthl=ALEInfoSign linehl=ALEInfoLine' -sign define ALEDummySign +sign define ALEDummySign text=\ texthl=SignColumn + +if g:ale_sign_highlight_linenrs && has('nvim-0.3.2') + if !hlexists('ALEErrorSignLineNr') + highlight link ALEErrorSignLineNr CursorLineNr + endif + + if !hlexists('ALEStyleErrorSignLineNr') + highlight link ALEStyleErrorSignLineNr CursorLineNr + endif + + if !hlexists('ALEWarningSignLineNr') + highlight link ALEWarningSignLineNr CursorLineNr + endif + + if !hlexists('ALEStyleWarningSignLineNr') + highlight link ALEStyleWarningSignLineNr CursorLineNr + endif + + if !hlexists('ALEInfoSignLineNr') + highlight link ALEInfoSignLineNr CursorLineNr + endif + + sign define ALEErrorSign numhl=ALEErrorSignLineNr + sign define ALEStyleErrorSign numhl=ALEStyleErrorSignLineNr + sign define ALEWarningSign numhl=ALEWarningSignLineNr + sign define ALEStyleWarningSign numhl=ALEStyleWarningSignLineNr + sign define ALEInfoSign numhl=ALEInfoSignLineNr +endif function! ale#sign#GetSignName(sublist) abort let l:priority = g:ale#util#style_warning_priority @@ -113,24 +151,80 @@ function! ale#sign#GetSignName(sublist) abort return 'ALEErrorSign' endfunction +function! s:PriorityCmd() abort + if s:supports_sign_groups + return ' priority=' . g:ale_sign_priority . ' ' + else + return '' + endif +endfunction + +function! s:GroupCmd() abort + if s:supports_sign_groups + return ' group=ale ' + else + return ' ' + endif +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 + let l:output = execute( + \ 'sign place ' . s:GroupCmd() . s:PriorityCmd() + \ . ' buffer=' . a:buffer + \ ) return split(l:output, "\n") endfunction +function! ale#sign#ParsePattern() abort + if s:supports_sign_groups + " Matches output like : + " line=4 id=1 group=ale name=ALEErrorSign + " строка=1 id=1000001 группа=ale имя=ALEErrorSign + " 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign + " línea=12 id=1000001 grupo=ale nombre=ALEWarningSign + " riga=1 id=1000001 gruppo=ale nome=ALEWarningSign + " Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign + let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale>.*\=(ALE[a-zA-Z]+Sign)' + else + " 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 + " Zeile=235 id=1000001 Name=ALEErrorSign + let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)' + endif + + return l:pattern +endfunction + +" Given a buffer number, return a List of placed signs [line, id, group] +function! ale#sign#ParseSignsWithGetPlaced(buffer) abort + let l:signs = sign_getplaced(a:buffer, { 'group': s:supports_sign_groups ? 'ale' : '' })[0].signs + let l:result = [] + let l:is_dummy_sign_set = 0 + + for l:sign in l:signs + if l:sign['name'] is# 'ALEDummySign' + let l:is_dummy_sign_set = 1 + else + call add(l:result, [ + \ str2nr(l:sign['lnum']), + \ str2nr(l:sign['id']), + \ l:sign['name'], + \]) + endif + endfor + + return [l:is_dummy_sign_set, l:result] +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:pattern =ale#sign#ParsePattern() let l:result = [] let l:is_dummy_sign_set = 0 @@ -154,9 +248,13 @@ function! ale#sign#ParseSigns(line_list) abort endfunction function! ale#sign#FindCurrentSigns(buffer) abort - let l:line_list = ale#sign#ReadSigns(a:buffer) + if exists('*sign_getplaced') + return ale#sign#ParseSignsWithGetPlaced(a:buffer) + else + let l:line_list = ale#sign#ReadSigns(a:buffer) - return ale#sign#ParseSigns(l:line_list) + return ale#sign#ParseSigns(l:line_list) + endif endfunction " Given a loclist, group the List into with one List per line. @@ -285,8 +383,10 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort 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 + \ . s:GroupCmd() + \ . s:PriorityCmd() + \ . ' line=1 name=ALEDummySign ' + \ . ' buffer=' . a:buffer \) let l:is_dummy_sign_set = 1 endif @@ -303,6 +403,8 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort if index(l:info.current_id_list, l:info.new_id) < 0 call add(l:command_list, 'sign place ' \ . (l:info.new_id) + \ . s:GroupCmd() + \ . s:PriorityCmd() \ . ' line=' . l:line_str \ . ' name=' . (l:info.new_name) \ . ' buffer=' . a:buffer @@ -317,6 +419,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort if l:current_id isnot l:info.new_id call add(l:command_list, 'sign unplace ' \ . l:current_id + \ . s:GroupCmd() \ . ' buffer=' . a:buffer \) endif @@ -327,6 +430,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort if l:is_dummy_sign_set && !g:ale_sign_column_always call add(l:command_list, 'sign unplace ' \ . g:ale_sign_offset + \ . s:GroupCmd() \ . ' buffer=' . a:buffer \) endif @@ -381,3 +485,12 @@ function! ale#sign#SetSigns(buffer, loclist) abort highlight link SignColumn ALESignColumnWithoutErrors endif endfunction + +" Remove all signs. +function! ale#sign#Clear() abort + if s:supports_sign_groups + sign unplace group=ale * + else + sign unplace * + endif +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/socket.vim b/vim-config/plugins/ale/autoload/ale/socket.vim old mode 100755 new mode 100644 index 7e069fb5..61f11e70 --- a/vim-config/plugins/ale/autoload/ale/socket.vim +++ b/vim-config/plugins/ale/autoload/ale/socket.vim @@ -72,9 +72,8 @@ function! ale#socket#Open(address, options) abort 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_id = sockconnect(stridx(a:address, ':') != -1 ? 'tcp' : 'pipe', + \ a:address, {'on_data': function('s:NeoVimOutputCallback')}) let l:channel_info.last_line = '' catch /connection failed/ let l:channel_id = -1 diff --git a/vim-config/plugins/ale/autoload/ale/statusline.vim b/vim-config/plugins/ale/autoload/ale/statusline.vim old mode 100755 new mode 100644 index 94fbd6c9..6b93ba51 --- a/vim-config/plugins/ale/autoload/ale/statusline.vim +++ b/vim-config/plugins/ale/autoload/ale/statusline.vim @@ -1,4 +1,5 @@ " Author: KabbAmine +" Additions by: petpetpetpet " Description: Statusline related function(s) function! s:CreateCountDict() abort @@ -26,19 +27,42 @@ function! ale#statusline#Update(buffer, loclist) abort 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 @@ -47,24 +71,65 @@ function! ale#statusline#Update(buffer, loclist) abort 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:GetCounts(buffer) abort +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 s:CreateCountDict() + return 0 endif - " 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) + 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/vim-config/plugins/ale/autoload/ale/swift.vim b/vim-config/plugins/ale/autoload/ale/swift.vim new file mode 100644 index 00000000..3232d42a --- /dev/null +++ b/vim-config/plugins/ale/autoload/ale/swift.vim @@ -0,0 +1,70 @@ +" 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 + +" Support Apple Swift Format {{{1 + +call ale#Set('swift_appleswiftformat_executable', 'swift-format') +call ale#Set('swift_appleswiftformat_use_swiftpm', 0) + +" Return the executable depending on whether or not to use Swift Package Manager. +" +" If not asked to use Swift Package Manager (use_swiftpm = 0), the returned +" value is the global executable, else the returned value is 'swift' because +" the final command line will be `swift run swift-format ...`. +" +" Failure is expected if use_swiftpm is `1` but no Package.swift can be located. +function! ale#swift#GetAppleSwiftFormatExecutable(buffer) abort + if !ale#Var(a:buffer, 'swift_appleswiftformat_use_swiftpm') + return ale#Var(a:buffer, 'swift_appleswiftformat_executable') + endif + + if ale#path#FindNearestFile(a:buffer, 'Package.swift') is# '' + " If there is no Package.swift file, we don't use swift-format even if it exists, + " so we return '' to indicate failure. + return '' + endif + + return 'swift' +endfunction + +" Return the command depending on whether or not to use Swift Package Manager. +" +" If asked to use Swift Package Manager (use_swiftpm = 1), the command +" arguments are prefixed with 'swift run'. +" +" In either case, the configuration file is located and added to the command. +function! ale#swift#GetAppleSwiftFormatCommand(buffer) abort + let l:executable = ale#swift#GetAppleSwiftFormatExecutable(a:buffer) + let l:command_args = '' + + if ale#Var(a:buffer, 'swift_appleswiftformat_use_swiftpm') + let l:command_args = ' ' . 'run swift-format' + endif + + return ale#Escape(l:executable) . l:command_args +endfunction + +" Locate the nearest '.swift-format' configuration file, and return the +" arguments, else return an empty string. +function! ale#swift#GetAppleSwiftFormatConfigArgs(buffer) abort + let l:config_filepath = ale#path#FindNearestFile(a:buffer, '.swift-format') + + if l:config_filepath isnot# '' + return '--configuration' . ' ' . l:config_filepath + endif + + return '' +endfunction + +" }}} diff --git a/vim-config/plugins/ale/autoload/ale/symbol.vim b/vim-config/plugins/ale/autoload/ale/symbol.vim old mode 100755 new mode 100644 index 5180cb86..ae4151ab --- a/vim-config/plugins/ale/autoload/ale/symbol.vim +++ b/vim-config/plugins/ale/autoload/ale/symbol.vim @@ -52,12 +52,18 @@ function! ale#symbol#HandleLSPResponse(conn_id, response) abort if empty(l:item_list) call ale#util#Execute('echom ''No symbols found.''') else - call ale#preview#ShowSelection(l:item_list) + call ale#preview#ShowSelection(l:item_list, l:options) endif endif endfunction -function! s:OnReady(linter, lsp_details, query, ...) abort +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. @@ -65,8 +71,6 @@ function! s:OnReady(linter, lsp_details, query, ...) abort return endif - let l:id = a:lsp_details.connection_id - let l:Callback = function('ale#symbol#HandleLSPResponse') call ale#lsp#RegisterCallback(l:id, l:Callback) @@ -76,34 +80,31 @@ function! s:OnReady(linter, lsp_details, query, ...) abort 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! s:Search(linter, buffer, query) abort - let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter) - - if !empty(l:lsp_details) - call ale#lsp#WaitForCapability( - \ l:lsp_details.connection_id, - \ 'symbol_search', - \ function('s:OnReady', [a:linter, l:lsp_details, a:query]), - \) - endif -endfunction +function! ale#symbol#Search(args) abort + let [l:opts, l:query] = ale#args#Parse(['relative'], a:args) -function! ale#symbol#Search(query) abort - if type(a:query) isnot v:t_string || empty(a:query) + 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 s:Search(l:linter, l:buffer, a:query) + call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) endif endfor endfunction diff --git a/vim-config/plugins/ale/autoload/ale/test.vim b/vim-config/plugins/ale/autoload/ale/test.vim old mode 100755 new mode 100644 index e6ec70dc..4d75d515 --- a/vim-config/plugins/ale/autoload/ale/test.vim +++ b/vim-config/plugins/ale/autoload/ale/test.vim @@ -34,12 +34,11 @@ function! ale#test#RestoreDirectory() abort unlet! g:dir endfunction -" Change the filename for the current buffer using a relative path to -" the script without running autocmd commands. +" Get a filename for the current buffer using a relative path to the script. " " 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 +function! ale#test#GetFilename(path) abort let l:dir = get(g:, 'dir', '') if empty(l:dir) @@ -50,14 +49,24 @@ function! ale#test#SetFilename(path) abort \ ? a:path \ : l:dir . '/' . a:path - silent! noautocmd execute 'file ' . fnameescape(ale#path#Simplify(l:full_path)) + return ale#path#Simplify(l:full_path) +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:full_path = ale#test#GetFilename(a:path) + silent! noautocmd execute 'file ' . fnameescape(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 + if has_key(l:item, 'module') + call remove(l:item, 'module') + endif endfor endfunction @@ -85,3 +94,103 @@ function! ale#test#GetPreviewWindowText() abort 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 + " linters with chained commands. + 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/vim-config/plugins/ale/autoload/ale/toggle.vim b/vim-config/plugins/ale/autoload/ale/toggle.vim old mode 100755 new mode 100644 index 8e642b3f..1311e527 --- a/vim-config/plugins/ale/autoload/ale/toggle.vim +++ b/vim-config/plugins/ale/autoload/ale/toggle.vim @@ -13,6 +13,10 @@ function! s:DisablePostamble() abort 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 diff --git a/vim-config/plugins/ale/autoload/ale/uri.vim b/vim-config/plugins/ale/autoload/ale/uri.vim old mode 100755 new mode 100644 index 934637d9..e71c6340 --- a/vim-config/plugins/ale/autoload/ale/uri.vim +++ b/vim-config/plugins/ale/autoload/ale/uri.vim @@ -1,9 +1,18 @@ -" This probably doesn't handle Unicode characters well. +function! s:EncodeChar(char) abort + let l:result = '' + + for l:index in range(strlen(a:char)) + let l:result .= printf('%%%02x', char2nr(a:char[l:index])) + endfor + + return l:result +endfunction + function! ale#uri#Encode(value) abort return substitute( \ a:value, \ '\([^a-zA-Z0-9\\/$\-_.!*''(),]\)', - \ '\=printf(''%%%02x'', char2nr(submatch(1)))', + \ '\=s:EncodeChar(submatch(1))', \ 'g' \) endfunction @@ -12,7 +21,7 @@ function! ale#uri#Decode(value) abort return substitute( \ a:value, \ '%\(\x\x\)', - \ '\=nr2char(''0x'' . submatch(1))', + \ '\=printf("%c", str2nr(submatch(1), 16))', \ 'g' \) endfunction diff --git a/vim-config/plugins/ale/autoload/ale/util.vim b/vim-config/plugins/ale/autoload/ale/util.vim old mode 100755 new mode 100644 index ee9359f8..ec9383ac --- a/vim-config/plugins/ale/autoload/ale/util.vim +++ b/vim-config/plugins/ale/autoload/ale/util.vim @@ -16,7 +16,9 @@ endfunction " 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 +function! ale#util#ShowMessage(string, ...) abort + let l:options = get(a:000, 0, {}) + if !has('nvim') call ale#preview#CloseIfTypeMatches('ale-preview.message') endif @@ -25,10 +27,13 @@ function! ale#util#ShowMessage(string) abort 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, - \}) + call ale#preview#Show(split(a:string, "\n"), extend( + \ { + \ 'filetype': 'ale-preview.message', + \ 'stay_here': 1, + \ }, + \ l:options, + \)) endif endfunction @@ -91,17 +96,17 @@ endfunction " options['open_in'] can be: " current-buffer (default) " tab -" vertical-split -" horizontal-split +" split +" vsplit 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' + elseif l:open_in is# 'split' call ale#util#Execute('split ' . l:args_to_open) - elseif l:open_in is# 'vertical-split' + elseif l:open_in is# 'vsplit' call ale#util#Execute('vsplit ' . l:args_to_open) elseif bufnr(a:filename) isnot bufnr('') " Open another file only if we need to. @@ -111,6 +116,7 @@ function! ale#util#Open(filename, line, column, options) abort endif call cursor(a:line, a:column) + normal! zz endfunction let g:ale#util#error_priority = 5 @@ -334,16 +340,22 @@ function! ale#util#GetMatches(lines, patterns) abort return l:matches endfunction -function! s:LoadArgCount(function) abort - let l:Function = a:function - - redir => l:output - silent! function Function - redir END +" Given a single line, or a List of lines, and a single pattern, or a List of +" patterns, and a callback function for mapping the items matches, return the +" result of mapping all of the matches for the lines from the given patterns, +" using matchlist() +" +" Only the first pattern which matches a line will be returned. +function! ale#util#MapMatches(lines, patterns, Callback) abort + return map(ale#util#GetMatches(a:lines, a:patterns), 'a:Callback(v:val)') +endfunction - if !exists('l:output') +function! s:LoadArgCount(function) abort + try + let l:output = execute('function a:function') + catch /E123/ return 0 - endif + endtry let l:match = matchstr(split(l:output, "\n")[0], '\v\([^)]+\)')[1:-2] let l:arg_list = filter(split(l:match, ', '), 'v:val isnot# ''...''') @@ -407,7 +419,7 @@ function! ale#util#FuzzyJSONDecode(data, default) abort endif return l:result - catch /E474/ + catch /E474\|E491/ return a:default endtry endfunction @@ -421,7 +433,10 @@ function! ale#util#Writefile(buffer, lines, filename) abort \ ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')') \ : a:lines - call writefile(l:corrected_lines, a:filename) " no-custom-checks + " Set binary flag if buffer doesn't have eol and nofixeol to avoid appending newline + let l:flags = !getbufvar(a:buffer, '&eol') && exists('+fixeol') && !&fixeol ? 'bS' : 'S' + + call writefile(l:corrected_lines, a:filename, l:flags) " no-custom-checks endfunction if !exists('s:patial_timers') @@ -469,10 +484,58 @@ 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 = getcurpos() + 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 +function! ale#util#Input(message, value) abort + return input(a:message, a:value) +endfunction + +function! ale#util#HasBuflineApi() abort + return exists('*deletebufline') && exists('*setbufline') +endfunction + +" Sets buffer contents to lines +function! ale#util#SetBufferContents(buffer, lines) abort + let l:has_bufline_api = ale#util#HasBuflineApi() + + if !l:has_bufline_api && a:buffer isnot bufnr('') + return + endif + + " 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(a:lines), 'substitute(v:val, ''\r\+$'', '''', '''')') + \ : a:lines + 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 = line('$') + + 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 + + return l:new_lines +endfunction + +function! ale#util#GetBufferContents(buffer) abort + return join(getbufline(a:buffer, 1, '$'), '\n') . '\n' +endfunction diff --git a/vim-config/plugins/ale/autoload/ale/virtualtext.vim b/vim-config/plugins/ale/autoload/ale/virtualtext.vim old mode 100755 new mode 100644 index c4ce37dd..598bc1bf --- a/vim-config/plugins/ale/autoload/ale/virtualtext.vim +++ b/vim-config/plugins/ale/autoload/ale/virtualtext.vim @@ -7,9 +7,15 @@ scriptencoding utf-8 let g:ale_virtualtext_delay = get(g:, 'ale_virtualtext_delay', 10) let s:cursor_timer = -1 let s:last_pos = [0, 0, 0] +let s:has_virt_text = 0 if has('nvim-0.3.2') let s:ns_id = nvim_create_namespace('ale') + let s:has_virt_text = 1 +elseif has('textprop') && has('popupwin') + call prop_type_add('ale', {}) + let s:last_popup = -1 + let s:has_virt_text = 1 endif if !hlexists('ALEVirtualTextError') @@ -33,26 +39,51 @@ if !hlexists('ALEVirtualTextInfo') endif function! ale#virtualtext#Clear() abort - if !has('nvim-0.3.2') + if !s:has_virt_text return endif let l:buffer = bufnr('') - call nvim_buf_clear_highlight(l:buffer, s:ns_id, 0, -1) + if has('nvim') + call nvim_buf_clear_highlight(l:buffer, s:ns_id, 0, -1) + else + if s:last_popup != -1 + call prop_remove({'type': 'ale'}) + call popup_close(s:last_popup) + let s:last_popup = -1 + endif + endif endfunction function! ale#virtualtext#ShowMessage(message, hl_group) abort - if !has('nvim-0.3.2') + if !s:has_virt_text return endif - let l:cursor_position = getcurpos() 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]], {}) + let l:msg = l:prefix.trim(substitute(a:message, '\n', ' ', 'g')) + + if has('nvim') + call nvim_buf_set_virtual_text(l:buffer, s:ns_id, l:line-1, [[l:msg, a:hl_group]], {}) + else + let l:left_pad = col('$') + call prop_add(l:line, l:left_pad, { + \ 'type': 'ale', + \}) + let s:last_popup = popup_create(l:msg, { + \ 'line': -1, + \ 'padding': [0, 0, 0, 1], + \ 'mask': [[1, 1, 1, 1]], + \ 'textprop': 'ale', + \ 'highlight': a:hl_group, + \ 'fixed': 1, + \ 'wrap': 0, + \ 'zindex': 2 + \}) + endif endfunction function! s:StopCursorTimer() abort @@ -82,7 +113,7 @@ function! ale#virtualtext#ShowCursorWarning(...) abort call ale#virtualtext#Clear() if !empty(l:loc) - let l:msg = get(l:loc, 'detail', l:loc.text) + let l:msg = l:loc.text let l:hl_group = 'ALEVirtualTextInfo' let l:type = get(l:loc, 'type', 'E') @@ -117,7 +148,7 @@ function! ale#virtualtext#ShowCursorWarningWithDelay() abort call s:StopCursorTimer() - let l:pos = getcurpos()[0:2] + 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* diff --git a/vim-config/plugins/ale/autoload/asyncomplete/sources/ale.vim b/vim-config/plugins/ale/autoload/asyncomplete/sources/ale.vim new file mode 100644 index 00000000..ce793773 --- /dev/null +++ b/vim-config/plugins/ale/autoload/asyncomplete/sources/ale.vim @@ -0,0 +1,26 @@ +function! asyncomplete#sources#ale#get_source_options(...) abort + let l:default = extend({ + \ 'name': 'ale', + \ 'completor': function('asyncomplete#sources#ale#completor'), + \ 'whitelist': ['*'], + \ 'triggers': asyncomplete#sources#ale#get_triggers(), + \ }, a:0 >= 1 ? a:1 : {}) + + return extend(l:default, {'refresh_pattern': '\k\+$'}) +endfunction + +function! asyncomplete#sources#ale#get_triggers() abort + let l:triggers = ale#completion#GetAllTriggers() + let l:triggers['*'] = l:triggers[''] + + return l:triggers +endfunction + +function! asyncomplete#sources#ale#completor(options, context) abort + let l:keyword = matchstr(a:context.typed, '\w\+$') + let l:startcol = a:context.col - len(l:keyword) + + call ale#completion#GetCompletions('ale-callback', { 'callback': {completions -> + \ asyncomplete#complete(a:options.name, a:context, l:startcol, completions) + \ }}) +endfunction diff --git a/vim-config/plugins/ale/doc/ale-ada.txt b/vim-config/plugins/ale/doc/ale-ada.txt old mode 100755 new mode 100644 index 93e3261a..0fc55a9c --- a/vim-config/plugins/ale/doc/ale-ada.txt +++ b/vim-config/plugins/ale/doc/ale-ada.txt @@ -21,5 +21,46 @@ g:ale_ada_gcc_options *g:ale_ada_gcc_options* This variable can be set to pass additional options to gcc. +=============================================================================== +gnatpp *ale-ada-gnatpp* + +g:ale_ada_gnatpp_options *g:ale_ada_gnatpp_options* + *b:ale_ada_gnatpp_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to the gnatpp fixer. + + +=============================================================================== +ada-language-server *ale-ada-language-server* + +g:ale_ada_adals_executable *g:ale_ada_adals_executable* + *b:ale_ada_adals_executable* + Type: |String| + Default: `'ada_language_server'` + + This variable can be changed to use a different executable for Ada Language + Server. + + +g:ale_ada_adals_project *g:ale_ada_adals_project* + *b:ale_ada_adals_project* + Type: |String| + Default: `'default.gpr'` + +This variable can be changed to use a different GPR file for +Ada Language Server. + + +g:ale_ada_adals_encoding *g:ale_ada_adals_encoding* + *b:ale_ada_adals_encoding* + Type: |String| + Default: `'utf-8'` + +This variable can be changed to use a different file encoding for +Ada Language Server. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-ansible.txt b/vim-config/plugins/ale/doc/ale-ansible.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-apkbuild.txt b/vim-config/plugins/ale/doc/ale-apkbuild.txt new file mode 100644 index 00000000..05261400 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-apkbuild.txt @@ -0,0 +1,30 @@ +=============================================================================== +ALE APKBUILD Integration *ale-apkbuild-options* + + +=============================================================================== +apkbuild-lint *ale-apkbuild-apkbuild-lint* + +g:ale_apkbuild_apkbuild_lint_executable + *g:ale_apkbuild_apkbuild_lint_executable* + *b:ale_apkbuild_apkbuild_lint_executable* + + Type: |String| + Default: `'apkbuild-lint'` + + This variable can be set to change the path to apkbuild-lint + +=============================================================================== +secfixes-check *ale-apkbuild-secfixes-check* + +g:ale_apkbuild_secfixes_check_executable + *g:ale_apkbuild_secfixes_check_executable* + *b:ale_apkbuild_secfixes_check_executable* + + Type: |String| + Default: `'secfixes-check'` + + This variable can be set to change the path to secfixes-check + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-asciidoc.txt b/vim-config/plugins/ale/doc/ale-asciidoc.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-asm.txt b/vim-config/plugins/ale/doc/ale-asm.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-awk.txt b/vim-config/plugins/ale/doc/ale-awk.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-bats.txt b/vim-config/plugins/ale/doc/ale-bats.txt new file mode 100644 index 00000000..cf2199ec --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-bats.txt @@ -0,0 +1,13 @@ +=============================================================================== +ALE Bats Integration *ale-bats-options* + + +=============================================================================== +shellcheck *ale-bats-shellcheck* + +The `shellcheck` linter for Bats uses the sh options for `shellcheck`; see: +|ale-sh-shellcheck|. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-bazel.txt b/vim-config/plugins/ale/doc/ale-bazel.txt new file mode 100644 index 00000000..e2922aaf --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-bazel.txt @@ -0,0 +1,28 @@ +=============================================================================== +ALE Bazel Integration *ale-bazel-options* + +=============================================================================== +buildifier *ale-bazel-buildifier* + +g:ale_bazel_buildifier_executable *g:ale_bazel_buildifier_executable* + *b:ale_bazel_buildifier_executable* + Type: |String| + Default: `'buildifier'` + + See |ale-integrations-local-executables| + + +g:ale_bazel_buildifier_options *g:ale_bazel_buildifier_options* + *b:ale_bazel_buildifier_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to buildifier. + + +g:ale_bazel_buildifier_use_global *g:ale_bazel_buildifier_use_global* + *b:ale_bazel_buildifier_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| diff --git a/vim-config/plugins/ale/doc/ale-bib.txt b/vim-config/plugins/ale/doc/ale-bib.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-c.txt b/vim-config/plugins/ale/doc/ale-c.txt old mode 100755 new mode 100644 index be0a3d77..3b9fbc44 --- a/vim-config/plugins/ale/doc/ale-c.txt +++ b/vim-config/plugins/ale/doc/ale-c.txt @@ -1,22 +1,36 @@ =============================================================================== ALE C Integration *ale-c-options* +For basic checking of problems with C files, ALE offers the `cc` linter, which +runs either `clang`, or `gcc`. See |ale-c-cc|. + =============================================================================== Global Options +g:ale_c_always_make *g:ale_c_always_make* + *b:ale_c_always_make* + Type: |Number| + Default: `has('unix') && !has('macunix')` + + If set to `1`, use `--always-make` for `make`, which means that output will + always be parsed from `make` dry runs with GNU make. BSD `make` does not + support this option, so you probably want to turn this option off when using + a BSD variant. + + 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) + 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* @@ -37,7 +51,7 @@ g:ale_c_build_dir *g:ale_c_build_dir* g:ale_c_parse_compile_commands *g:ale_c_parse_compile_commands* *b:ale_c_parse_compile_commands* Type: |Number| - Default: `0` + Default: `1` 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 @@ -45,9 +59,6 @@ g:ale_c_parse_compile_commands *g:ale_c_parse_compile_commands* `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* @@ -58,24 +69,102 @@ g:ale_c_parse_makefile *g:ale_c_parse_makefile* set for C or C++ compilers. This can make it easier to determine the correct build flags to use for different files. + NOTE: When using this option on BSD, you may need to set + |g:ale_c_always_make| to `0`, and `make -n` will not provide consistent + results if binaries have already been built, so use `make clean` when + editing your files. + + WARNING: Running `make -n` automatically can execute arbitrary code, even + though it's supposed to be a dry run, so enable this option with care. You + might prefer to use the buffer-local version of the option instead with + |g:ale_pattern_options|, or you own code for checking which project you're + in. + + You might want to disable this option if `make -n` takes too long to run for + projects you work on. + + If |g:ale_c_parse_compile_commands| or |b:ale_c_parse_compile_commands| is + set to `1`, flags taken from `compile_commands.json` will be preferred over + `make -n` output. + + +=============================================================================== +astyle *ale-c-astyle* + +g:ale_c_astyle_executable *g:ale_c_astyle_executable* + *b:ale_c_astyle_executable* + Type: |String| + Default: `'astyle'` + + This variable can be changed to use a different executable for astyle. + + +g:ale_c_astyle_project_options *g:ale_c_astyle_project_options* + *b:ale_c_astyle_project_options* + Type: |String| + Default: `''` + + This variable can be changed to use an option file for project level + configurations. Provide only the filename of the option file that should be + present at the project's root directory. + + For example, if .astylrc is specified, the file is searched in the parent + directories of the source file's directory. + =============================================================================== -clang *ale-c-clang* +cc *ale-c-cc* + *ale-c-gcc* + *ale-c-clang* -g:ale_c_clang_executable *g:ale_c_clang_executable* - *b:ale_c_clang_executable* +g:ale_c_cc_executable *g:ale_c_cc_executable* + *b:ale_c_cc_executable* Type: |String| - Default: `'clang'` + Default: `''` - This variable can be changed to use a different executable for clang. + This variable can be changed to use a different executable for a C compiler. + ALE will try to use `clang` if Clang is available, otherwise ALE will + default to checking C code with `gcc`. -g:ale_c_clang_options *g:ale_c_clang_options* - *b:ale_c_clang_options* + +g:ale_c_cc_options *g:ale_c_cc_options* + *b:ale_c_cc_options* Type: |String| Default: `'-std=c11 -Wall'` - This variable can be changed to modify flags given to clang. + This variable can be change to modify flags given to the C compiler. + + +=============================================================================== +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. =============================================================================== @@ -113,7 +202,45 @@ g:ale_c_clangformat_options *g:ale_c_clangformat_options* Type: |String| Default: `''` - This variable can be change to modify flags given to clang-format. + This variable can be changed to modify flags given to clang-format. + + +g:ale_c_clangformat_style_option *g:ale_c_clangformat_style_option* + *b:ale_c_clangformat_style_option* + Type: |String| + Default: `''` + + This variable can be changed to modify only the style flag given to + clang-format. The contents of the variable are passed directly to the -style + flag of clang-format. + + Example: > + { + \ BasedOnStyle: Microsoft, + \ ColumnLimit: 80, + \ AllowShortBlocksOnASingleLine: Always, + \ AllowShortFunctionsOnASingleLine: Inline, + \ } +< + If you set this variable, ensure you don't modify -style in + |g:ale_c_clangformat_options|, as this will cause clang-format to error. + + +g:ale_c_clangformat_use_local_file *g:ale_c_clangformat_use_local_file* + *b:ale_c_clangformat_use_local_file* + Type: |Number| + Default: `0` + + This variable can be changed to modify whether to use a local .clang-format + file. If the file is found, the flag '-style=file' is passed to clang-format + and any options configured via |g:ale_c_clangformat_style_option| are not + passed. + + If this option is enabled but no .clang-format file is found, default back to + |g:ale_c_clangformat_style_option|, if it set. + + If you set this variable, ensure you don't modify -style in + |g:ale_c_clangformat_options|, as this will cause clang-format to error. =============================================================================== @@ -156,7 +283,7 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options* Type: |String| Default: `''` - This variable can be changed to modify flags given to clang-tidy. + 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 @@ -169,6 +296,23 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options* 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. + + +g:ale_c_clangtidy_fix_errors *g:ale_c_clangtidy_fix_errors* + *b:ale_c_clangtidy_fix_errors* + Type: |Number| + Default: `1` + + This variable can be changed to disable the `-fix-errors` option for the + |clangtidy| fixer. + + =============================================================================== cppcheck *ale-c-cppcheck* @@ -243,25 +387,6 @@ g:ale_c_flawfinder_error_severity *g:ale_c_flawfinder_error_severity* 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* @@ -281,36 +406,5 @@ g:ale_c_uncrustify_options *g:ale_c_uncrustify_options* 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/vim-config/plugins/ale/doc/ale-chef.txt b/vim-config/plugins/ale/doc/ale-chef.txt old mode 100755 new mode 100644 index 5024e279..75e144ec --- a/vim-config/plugins/ale/doc/ale-chef.txt +++ b/vim-config/plugins/ale/doc/ale-chef.txt @@ -2,6 +2,26 @@ 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* diff --git a/vim-config/plugins/ale/doc/ale-clojure.txt b/vim-config/plugins/ale/doc/ale-clojure.txt old mode 100755 new mode 100644 index a83e336f..3ff367f6 --- a/vim-config/plugins/ale/doc/ale-clojure.txt +++ b/vim-config/plugins/ale/doc/ale-clojure.txt @@ -2,6 +2,21 @@ 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 + +g:ale_clojure_clj_kondo_options *g:ale_clojure_clj_kondo_options* + *b:ale_clojure_clj_kondo_options* + Type: |String| + Default: `'--cache'` + + This variable can be changed to modify options passed to clj-kondo. + + =============================================================================== joker *ale-clojure-joker* diff --git a/vim-config/plugins/ale/doc/ale-cloudformation.txt b/vim-config/plugins/ale/doc/ale-cloudformation.txt old mode 100755 new mode 100644 index 59c6af06..9724403b --- a/vim-config/plugins/ale/doc/ale-cloudformation.txt +++ b/vim-config/plugins/ale/doc/ale-cloudformation.txt @@ -7,8 +7,40 @@ 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 +Website: https://github.com/awslabs/cfn-python-lint +Installation +------------------------------------------------------------------------------- + + +Install cfn-python-lint using either pip or brew: > + +`pip install cfn-lint`. If pip is not available, run +`python setup.py clean --all` then `python setup.py install`. + + Homebrew (macOS): + +`brew install cfn-lint` + +< +Configuration +------------------------------------------------------------------------------- + +To get cloudformation linter to work on only CloudFormation files we must set +the buffer |filetype| to yaml.cloudformation. +This causes ALE to lint the file with linters configured for cloudformation and +yaml files. + +Just put: + +> + + au BufRead,BufNewFile *.template.yaml set filetype=yaml.cloudformation + +< + +on `ftdetect/cloudformation.vim` + +This will get both cloudformation and yaml linters to work on any file with `.template.yaml` ext. =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: - diff --git a/vim-config/plugins/ale/doc/ale-cmake.txt b/vim-config/plugins/ale/doc/ale-cmake.txt old mode 100755 new mode 100644 index fb46336f..602637b1 --- a/vim-config/plugins/ale/doc/ale-cmake.txt +++ b/vim-config/plugins/ale/doc/ale-cmake.txt @@ -21,5 +21,23 @@ g:ale_cmake_cmakelint_options *g:ale_cmake_cmakelint_options* 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/vim-config/plugins/ale/doc/ale-cpp.txt b/vim-config/plugins/ale/doc/ale-cpp.txt old mode 100755 new mode 100644 index e1f64ab5..17894e6e --- a/vim-config/plugins/ale/doc/ale-cpp.txt +++ b/vim-config/plugins/ale/doc/ale-cpp.txt @@ -1,12 +1,16 @@ =============================================================================== ALE C++ Integration *ale-cpp-options* +For basic checking of problems with C++ files, ALE offers the `cc` linter, +which runs either `clang++`, or `gcc`. See |ale-cpp-cc|. + =============================================================================== Global Options The following C options also apply to some C++ linters too. +* |g:ale_c_always_make| * |g:ale_c_build_dir_names| * |g:ale_c_build_dir| * |g:ale_c_parse_makefile| @@ -14,41 +18,82 @@ The following C options also apply to some C++ linters too. =============================================================================== -clang *ale-cpp-clang* +astyle *ale-cpp-astyle* -g:ale_cpp_clang_executable *g:ale_cpp_clang_executable* - *b:ale_cpp_clang_executable* +g:ale_cpp_astyle_executable *g:ale_cpp_astyle_executable* + *b:ale_cpp_astyle_executable* Type: |String| - Default: `'clang++'` + Default: `'astyle'` - This variable can be changed to use a different executable for clang. + This variable can be changed to use a different executable for astyle. -g:ale_cpp_clang_options *g:ale_cpp_clang_options* - *b:ale_cpp_clang_options* +g:ale_cpp_astyle_project_options *g:ale_cpp_astyle_project_options* + *b:ale_cpp_astyle_project_options* Type: |String| - Default: `'-std=c++14 -Wall'` + Default: `''` + + This variable can be changed to use an option file for project level + configurations. Provide only the filename of the option file that should be + present at the project's root directory. - This variable can be changed to modify flags given to clang. + For example, if .astylrc is specified, the file is searched in the parent + directories of the source file's directory. =============================================================================== -clangd *ale-cpp-clangd* +cc *ale-cpp-cc* + *ale-cpp-gcc* + *ale-cpp-clang* -g:ale_cpp_clangd_executable *g:ale_cpp_clangd_executable* - *b:ale_cpp_clangd_executable* +g:ale_cpp_cc_executable *g:ale_cpp_cc_executable* + *b:ale_cpp_cc_executable* Type: |String| - Default: `'clangd'` + Default: `''` - This variable can be changed to use a different executable for clangd. + This variable can be changed to use a different executable for a C++ compiler. + ALE will try to use `clang++` if Clang is available, otherwise ALE will + default to checking C++ code with `gcc`. -g:ale_cpp_clangd_options *g:ale_cpp_clangd_options* - *b:ale_cpp_clangd_options* + +g:ale_cpp_cc_options *g:ale_cpp_cc_options* + *b:ale_cpp_cc_options* Type: |String| - Default: `''` + Default: `'-std=c++14 -Wall'` - This variable can be changed to modify flags given to clangd. + This variable can be change to modify flags given to the C++ compiler. + + +=============================================================================== +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. =============================================================================== @@ -82,6 +127,25 @@ g:ale_cpp_clangcheck_options *g:ale_cpp_clangcheck_options* option. +=============================================================================== +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. + + =============================================================================== clang-format *ale-cpp-clangformat* @@ -125,7 +189,7 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options* Type: |String| Default: `''` - This variable can be changed to modify flags given to clang-tidy. + 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 @@ -138,6 +202,23 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options* 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. + + +g:ale_cpp_clangtidy_fix_errors *g:ale_cpp_clangtidy_fix_errors* + *b:ale_cpp_clangtidy_fix_errors* + Type: |Number| + Default: `1` + + This variable can be changed to disable the `-fix-errors` option for the + |clangtidy| fixer. + + =============================================================================== clazy *ale-cpp-clazy* @@ -254,61 +335,11 @@ g:ale_cpp_flawfinder_options *g:ale-cpp-flawfinder* 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/vim-config/plugins/ale/doc/ale-cs.txt b/vim-config/plugins/ale/doc/ale-cs.txt old mode 100755 new mode 100644 index 01e6348f..bef495b9 --- a/vim-config/plugins/ale/doc/ale-cs.txt +++ b/vim-config/plugins/ale/doc/ale-cs.txt @@ -6,11 +6,129 @@ 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 +=============================================================================== +csc *ale-cs-csc* + + The |ale-cs-csc| 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 csc linter uses the mono csc compiler, providing full C# 7 and newer + support, to generate a temporary module target file (/t:module). The module + includes all '*.cs' files contained in the directory tree rooted at the path + defined by the |g:ale_cs_csc_source| or |b:ale_cs_csc_source| variable and + all sub directories. + + It will in future replace the |ale-cs-mcs| and |ale-cs-mcsc| linters as both + utilize the mcsc compiler which, according to the mono project, is no longer + actively developed, and only receives maintenance updates. However, because + the csc compiler does not support the -syntax option, this linter does not + offer any as-you-type syntax checking, similar to the |ale-cs-mcsc| linter. + + The paths to search for additional assembly files can be specified using the + |g:ale_cs_csc_assembly_path| or |b:ale_cs_csc_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_csc_options *g:ale_cs_csc_options* + *b:ale_cs_csc_options* + Type: |String| + Default: `''` + + This option can be set to pass additional arguments to the `csc` compiler. + + For example, to add the dotnet package which is not added per default: > + + let g:ale_cs_mcs_options = ' /warn:4 /langversion:7.2' +< + NOTE: the `/unsafe` option is always passed to `csc`. + + +g:ale_cs_csc_source *g:ale_cs_csc_source* + *b:ale_cs_csc_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_csc_assembly_path *g:ale_cs_csc_assembly_path* + *b:ale_cs_csc_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 csc compiler using the `/lib:` + flag. + + +g:ale_cs_csc_assemblies *g:ale_cs_csc_assemblies* + *b:ale_cs_csc_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 csc 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', + \] +< + +=============================================================================== +dotnet-format *ale-cs-dotnet-format* + +Installation +------------------------------------------------------------------------------- + +Installing .NET SDK should probably ensure that `dotnet` is in your `$PATH`. +For .NET 6 the `dotnet format` tool is already included in the .NET SDK. For +.NET 5 or below you will have to manually install it using the instructions +from listed in this repository: https://github.com/dotnet/format + + +Options +------------------------------------------------------------------------------- + +g:ale_cs_dotnet_format_executable *g:ale_cs_dotnet_format_executable* + *b:ale_cs_dotnet_format_executable* + Type: |String| + Default: `'dotnet'` + + This variable can be set to specify an absolute path to the + `dotnet` executable (or to specify an alternate executable). + + +g:ale_cs_dotnet_format_options *g:ale_cs_dotnet_format_options* + *b:ale_cs_dotnet_format_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the `dotnet format` + fixer. + + =============================================================================== 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. + 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* diff --git a/vim-config/plugins/ale/doc/ale-css.txt b/vim-config/plugins/ale/doc/ale-css.txt old mode 100755 new mode 100644 index f3cae385..ff74b263 --- a/vim-config/plugins/ale/doc/ale-css.txt +++ b/vim-config/plugins/ale/doc/ale-css.txt @@ -2,6 +2,14 @@ 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* diff --git a/vim-config/plugins/ale/doc/ale-cuda.txt b/vim-config/plugins/ale/doc/ale-cuda.txt old mode 100755 new mode 100644 index 052b3363..06aa48ce --- a/vim-config/plugins/ale/doc/ale-cuda.txt +++ b/vim-config/plugins/ale/doc/ale-cuda.txt @@ -21,5 +21,30 @@ g:ale_cuda_nvcc_options *g:ale_cuda_nvcc_options* This variable can be changed to modify flags given to nvcc. +=============================================================================== +clangd *ale-cuda-clangd* + +g:ale_cuda_clangd_executable *g:ale_cuda_clangd_executable* + *b:ale_cuda_clangd_executable* + Type: |String| + Default: `'clangd'` + + This variable can be changed to use a different executable for clangd. + + +g:ale_cuda_clangd_options *g:ale_cuda_clangd_options* + *b:ale_cuda_clangd_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clangd. + +=============================================================================== +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/vim-config/plugins/ale/doc/ale-d.txt b/vim-config/plugins/ale/doc/ale-d.txt old mode 100755 new mode 100644 index 55596062..72349a20 --- a/vim-config/plugins/ale/doc/ale-d.txt +++ b/vim-config/plugins/ale/doc/ale-d.txt @@ -1,6 +1,15 @@ =============================================================================== ALE D Integration *ale-d-options* +=============================================================================== +dfmt *ale-d-dfmt* + +g:ale_d_dfmt_options *g:ale_d_dfmt_options* + *b:ale_d_dfmt_options* + Type: |String| + Default: `''` + +This variable can be set to pass additional options to the dfmt fixer. =============================================================================== dls *ale-d-dls* diff --git a/vim-config/plugins/ale/doc/ale-dafny.txt b/vim-config/plugins/ale/doc/ale-dafny.txt new file mode 100644 index 00000000..005170ad --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-dafny.txt @@ -0,0 +1,16 @@ +=============================================================================== +ALE Dafny Integration *ale-dafny-options* + + +=============================================================================== +dafny *ale-dafny-dafny* + +g:ale_dafny_dafny_timelimit *g:ale_dafny_dafny_timelimit* + *b:ale_dafny_dafny_timelimit* + Type: |Number| + Default: `10` + + This variable sets the `/timeLimit` used for dafny. + + + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-dart.txt b/vim-config/plugins/ale/doc/ale-dart.txt old mode 100755 new mode 100644 index a6d88dd8..a046808b --- a/vim-config/plugins/ale/doc/ale-dart.txt +++ b/vim-config/plugins/ale/doc/ale-dart.txt @@ -2,6 +2,92 @@ ALE Dart Integration *ale-dart-options* +=============================================================================== +analysis_server *ale-dart-analysis_server* + +Installation +------------------------------------------------------------------------------- + +Install Dart via whatever means. `analysis_server` will be included in the SDK. + +In case that `dart` is not in your path, try to set the executable option to +its absolute path. : > + " Set the executable path for dart to the absolute path to it. + let g:ale_dart_analysis_server_executable = '/usr/local/bin/dart' +< + +Options +------------------------------------------------------------------------------- + +g:ale_dart_analysis_server_executable *g:ale_dart_analysis_server_executable* + *b:ale_dart_analysis_server_executable* + Type: |String| + Default: `'dart'` + + This variable can be set to change the path of dart. + + +=============================================================================== +dart-analyze *ale-dart-analyze* + +Installation +------------------------------------------------------------------------------- + +Installing Dart should probably ensure that `dart` is in your `$PATH`. + +In case it is not, try to set the executable option to its absolute path. : > + " Set the executable path for dart to the absolute path to it. + let g:ale_dart_format_executable = '/usr/lib/dart/bin/dart' + > + +Install Dart via whatever means. `dart analyze` will be included in the SDK. + +Options +------------------------------------------------------------------------------- + +g:ale_dart_analyze_executable *g:ale_dart_analyze_executable* + *b:ale_dart_analyze_executable* + Type: |String| + Default: `'dart'` + + This variable can be set to specify an absolute path to the + format executable (or to specify an alternate executable). + + +=============================================================================== +dart-format *ale-dart-format* + +Installation +------------------------------------------------------------------------------- + +Installing Dart should probably ensure that `dart` is in your `$PATH`. + +In case it is not, try to set the executable option to its absolute path. : > + " Set the executable path for dart to the absolute path to it. + let g:ale_dart_format_executable = '/usr/lib/dart/bin/dart' + > + +Options +------------------------------------------------------------------------------- + +g:ale_dart_format_executable *g:ale_dart_format_executable* + *b:ale_dart_format_executable* + Type: |String| + Default: `'dart'` + + This variable can be set to specify an absolute path to the + format executable (or to specify an alternate executable). + + +g:ale_dart_format_options *g:ale_dart_format_options* + *b:ale_dart_format_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the dart format fixer. + + + =============================================================================== dartanalyzer *ale-dart-dartanalyzer* diff --git a/vim-config/plugins/ale/doc/ale-desktop.txt b/vim-config/plugins/ale/doc/ale-desktop.txt new file mode 100644 index 00000000..62269e9c --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-desktop.txt @@ -0,0 +1,21 @@ +=============================================================================== +ALE desktop Integration *ale-desktop-options* + + +=============================================================================== +desktop-file-validate *ale-desktop-desktop-file-validate* + +ALE supports checking .desktop files with `desktop-file-validate.` + + +g:ale_desktop_desktop_file_validate_options + *g:ale_desktop_desktop_file_validate_options* + *b:ale_desktop_desktop_file_validate_options* + Type: |String| + Default: `''` + + This variable can be changed to set options for `desktop-file-validate`, + such as `'--warn-kde'`. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-development.txt b/vim-config/plugins/ale/doc/ale-development.txt old mode 100755 new mode 100644 index 408b176f..3d0dd524 --- a/vim-config/plugins/ale/doc/ale-development.txt +++ b/vim-config/plugins/ale/doc/ale-development.txt @@ -12,6 +12,8 @@ CONTENTS *ale-development-contents* 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| + 4.3. Running Tests in a Windows VM....|ale-development-windows-tests| =============================================================================== 1. Introduction *ale-development-introduction* @@ -146,14 +148,16 @@ Apply the following rules when writing Bash scripts. =============================================================================== 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. +ALE is tested with a suite of tests executed via GitHub Actions 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.0204 on Linux via Travis CI. -3. NeoVim 0.2.0 on Linux via Travis CI. -4. NeoVim 0.3.0 on Linux via Travis CI. -5. Vim 8 (stable builds) on Windows via AppVeyor. +1. Vim 8.0.0027 on Linux via GitHub Actions. +2. Vim 8.2.2401 on Linux via GitHub Actions. +3. NeoVim 0.2.0 on Linux via GitHub Actions. +4. NeoVim 0.4.4 on Linux via GitHub Actions. +5. NeoVim 0.5.0 on Linux via GitHub Actions. +6. 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 @@ -169,27 +173,36 @@ 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. +Once you get used to dealing with Vim and NeoVim compatibility issues, you +probably want to use `./run-tests --fast -q` for running tests with only the +fastest available Vim version, and with success messages from tests +suppressed. + 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 linter definition -> Write tests in `test/linter` * 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 +If you need to add any supporting files for tests, such as empty files present +to test searching upwards through paths for configuration files, they can be +added to the `test/test-files` directory. + 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. > - +When you add new linters or fixers, make sure to add them into the tables in +supported-tools.md and |ale-supported-languages-and-tools.txt|. If you forget to +keep them both in sync, you should see an error like the following in the +builds run for GitHub Actions. +> ======================================== - diff README.md and doc/ale.txt tables + diff supported-tools.md and doc/ale-supported-languages-and-tools.txt tables ======================================== Differences follow: @@ -266,8 +279,8 @@ be written like so. > \ '1:Something went wrong', \ ] < -Tests for what ALE runs should go in the `test/command_callback` directory, -and should be written like so. > +Tests for what ALE runs should go in the `test/linter` directory, and should +be written like so. > Before: " Load the linter and set up a series of commands, reset linter variables, @@ -288,10 +301,10 @@ and should be written like so. > AssertLinter 'some-command', ale#Escape('some-command') . ' --foo' Execute(Check chained commands): - " WithChainResults can be called with 1 or more list for passing output + " 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. - WithChainResults ['v2.1.2'] + 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', [ @@ -302,7 +315,8 @@ and should be written like so. > The full list of commands that will be temporarily defined for linter tests given the above setup are as follows. -`WithChainResults [...]` - Define output for command chain functions. +`GivenCommandOutput [...]` - Define output for ale#command#Run. +`AssertLinterCwd cwd` - Check the `cwd` for the linter. `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. @@ -311,5 +325,124 @@ given the above setup are as follows. `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. +`AssertFixerCwd cwd` - Check the `cwd` for the fixer. +`AssertFixer results` - Check the fixer results +`AssertFixerNotExecuted` - Check that fixers will not be executed. + + +=============================================================================== +4.3 Running Tests in a Windows VM *ale-development-windows-tests* + +Tests are run for ALE in a build of Vim 8 for Windows via AppVeyor. These +tests can frequently break due to minor differences in paths and how escaping +is done for commands on Windows. If you are a Linux or Mac user, running these +tests locally can be difficult. Here is a process that will make that easier. + +First, you want to install a Windows image with VirtualBox. Install VirtualBox +and grab a VirtualBox image for Windows such as from here: +https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ + +NOTE: If you need to enter a password for the virtual machine at any point, +the password is "Passw0rd!" without the double quotes. + +NOTE: If your trial period for Windows runs out, run the commands like the +wallpaper tells you to. + +Your virtual machine will need to have PowerShell installed. Before you go any +further, confirm that PowerShell is installed in your Windows virtual machine. + +Consult the VirtualBox documentation on how to install "Guest Additions." +You probably want to install "Guest Additions" for most things to work +properly. + +After you've loaded your virtual machine image, go into "Settings" for your +virtual machine, and "Shared Folders." Add a shared folder with the name +"ale", and set the "Folder Path" to the path to your ALE repository, for +example: "/home/w0rp/ale" + +Find out which drive letter "ale" has been mounted as in Windows. We'll use +"E:" as the drive letter, for example. Open the command prompt as an +administrator by typing in `cmd` in the start menu, right clicking on the +command prompt application, and clicking "Run as administrator." Click "Yes" +when prompted to ask if you're sure you want to run the command prompt. You +should type in the following command to mount the "ale" directory for testing, +where "E:" is replaced with your drive letter. > + + mklink /D C:\testplugin E: +< +Close the administrator Command Prompt, and try running the command +`type C:\testplugin\LICENSE` in a new Command Prompt which you are NOT running +as administrator. You should see the license for ALE in your terminal. After +you have confirmed that you have mounted ALE on your machine, search in the +Start Menu for "power shell," run PowerShell as an administrator, and issue +the following commands to install the correct Vim and Vader versions for +running tests. > + + Add-Type -A System.IO.Compression.FileSystem + + Invoke-WebRequest ftp://ftp.vim.org/pub/vim/pc/vim80-586w32.zip -OutFile C:\vim.zip + [IO.Compression.ZipFile]::ExtractToDirectory('C:\vim.zip', 'C:\vim') + rm C:\vim.zip + + Invoke-WebRequest ftp://ftp.vim.org/pub/vim/pc/vim80-586rt.zip -OutFile C:\rt.zip + [IO.Compression.ZipFile]::ExtractToDirectory('C:\rt.zip', 'C:\vim') + rm C:\rt.zip + + Invoke-WebRequest https://github.com/junegunn/vader.vim/archive/c6243dd81c98350df4dec608fa972df98fa2a3af.zip -OutFile C:\vader.zip + [IO.Compression.ZipFile]::ExtractToDirectory('C:\vader.zip', 'C:\') + mv C:\vader.vim-c6243dd81c98350df4dec608fa972df98fa2a3af C:\vader + rm C:\vader.zip +< +After you have finished installing everything, you can run all of the tests +in Windows by opening a Command Prompt NOT as an administrator by navigating +to the directory where you've mounted the ALE code, which must be named +`C:\testplugin`, and by running the `run-tests.bat` batch file. > + + cd C:\testplugin + run-tests +< +It will probably take several minutes for all of the tests to run. Be patient. +You can run a specific test by passing the filename as an argument to the +batch file, for example: `run-tests test/test_c_flag_parsing.vader` . This will +give you results much more quickly. + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-dhall.txt b/vim-config/plugins/ale/doc/ale-dhall.txt new file mode 100644 index 00000000..9b997b9e --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-dhall.txt @@ -0,0 +1,52 @@ +=============================================================================== +ALE Dhall Integration *ale-dhall-options* + +g:ale_dhall_executable *g:ale_dhall_executable* + *b:ale_dhall_executable* + Type: |String| + Default: `'dhall'` + +g:ale_dhall_options *g:ale_dhall_options* + *b:ale_dhall_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the 'dhall` executable. + This is shared with `dhall-freeze` and `dhall-lint`. +> + let g:ale_dhall_options = '--ascii' +< + +=============================================================================== +dhall-format *ale-dhall-format* + +Dhall + (https://dhall-lang.org/) + + +=============================================================================== +dhall-freeze *ale-dhall-freeze* + +Dhall + (https://dhall-lang.org/) + +g:ale_dhall_freeze_options *g:ale_dhall_freeze_options* + *b:ale_dhall_freeze_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the 'dhall freeze` + executable. +> + let g:ale_dhall_freeze_options = '--all' +< + +=============================================================================== +dhall-lint *ale-dhall-lint* + +Dhall + (https://dhall-lang.org/) + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-dockerfile.txt b/vim-config/plugins/ale/doc/ale-dockerfile.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-elixir.txt b/vim-config/plugins/ale/doc/ale-elixir.txt old mode 100755 new mode 100644 index 45c6de1d..a4e5c2c6 --- a/vim-config/plugins/ale/doc/ale-elixir.txt +++ b/vim-config/plugins/ale/doc/ale-elixir.txt @@ -6,7 +6,7 @@ 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. +The `mix` linter is disabled by default, as it can be too expensive to run. See `:help g:ale_linters` @@ -72,6 +72,25 @@ g:ale_elixir_elixir_ls_config *g:ale_elixir_elixir_ls_config* \ } < 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. + +g:ale_elixir_credo_config_file g:ale_elixir_credo_config_file + + Type: String + Default: '' + + Tells credo to use a custom configuration file. =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-elm.txt b/vim-config/plugins/ale/doc/ale-elm.txt old mode 100755 new mode 100644 index de7d8939..b1510241 --- a/vim-config/plugins/ale/doc/ale-elm.txt +++ b/vim-config/plugins/ale/doc/ale-elm.txt @@ -28,6 +28,56 @@ g:ale_elm_format_options *g:ale_elm_format_options* This variable can be set to pass additional options to elm-format. +=============================================================================== +elm-ls *ale-elm-elm-ls* + +g:ale_elm_ls_executable *g:ale_elm_ls_executable* + *b:ale_elm_ls_executable* + Type: |String| + Default: `'elm-language-server'` + + See |ale-integrations-local-executables| + + +g:ale_elm_ls_use_global *g:ale_elm_ls_use_global* + *b:ale_elm_ls_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 1)` + + See |ale-integrations-local-executables| + + +g:ale_elm_ls_elm_path *g:ale_elm_ls_elm_path* + *b:ale_elm_ls_elm_path* + Type: |String| + Default: `''` + + See |ale-integrations-local-executables| + + +g:ale_elm_ls_elm_format_path *g:ale_elm_ls_elm_format_path* + *b:ale_elm_ls_elm_format_path* + Type: |String| + Default: `''` + + See |ale-integrations-local-executables| + + +g:ale_elm_ls_elm_test_path *g:ale_elm_ls_elm_test_path* + *b:ale_elm_ls_elm_test_path* + Type: |String| + Default: `''` + + See |ale-integrations-local-executables| + + +g:ale_elm_ls_elm_analyse_trigger *g:ale_elm_ls_elm_analyse_trigger* + *b:ale_elm_ls_elm_analyse_trigger* + Type: |String| + Default: `'change'` + + One of 'change', 'save' or 'never' + =============================================================================== elm-make *ale-elm-elm-make* diff --git a/vim-config/plugins/ale/doc/ale-erlang.txt b/vim-config/plugins/ale/doc/ale-erlang.txt old mode 100755 new mode 100644 index ad3c1e5a..ede179d1 --- a/vim-config/plugins/ale/doc/ale-erlang.txt +++ b/vim-config/plugins/ale/doc/ale-erlang.txt @@ -3,8 +3,65 @@ 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_options *g:ale_erlang_dialyzer_options* + *b:ale_erlang_dialyzer_options* + Type: |String| + Default: `'-Wunmatched_returns -Werror_handling -Wrace_conditions -Wunderspec'` + + This variable can be changed to specify the options to pass to 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. + + +------------------------------------------------------------------------------- +elvis *ale-erlang-elvis* + +g:ale_erlang_elvis_executable *g:ale_erlang_elvis_executable* + *b:ale_erlang_elvis_executable* + Type: |String| + Default: `'elvis'` + + This variable can be changed to specify the elvis executable. + + +------------------------------------------------------------------------------- erlc *ale-erlang-erlc* +g:ale_erlang_erlc_executable *g:ale_erlang_erlc_executable* + *b:ale_erlang_erlc_executable* + Type: |String| + Default: `'erlc'` + + This variable can be changed to specify the erlc executable. + + g:ale_erlang_erlc_options *g:ale_erlang_erlc_options* *b:ale_erlang_erlc_options* Type: |String| @@ -14,6 +71,26 @@ g:ale_erlang_erlc_options *g:ale_erlang_erlc_options* or `-pa`. +------------------------------------------------------------------------------- +erlfmt *ale-erlang-erlfmt* + +g:ale_erlang_erlfmt_executable *g:ale_erlang_erlfmt_executable* + *b:ale_erlang_erlfmt_executable* + Type: |String| + Default: `'erlfmt'` + + This variable can be changed to specify the erlfmt executable. + + +g:ale_erlang_erlfmt_options *g:ale_erlang_erlfmt_options* + *b:ale_erlang_erlfmt_options* + Type: |String| + Default: `''` + + This variable controls additional parameters passed to `erlfmt`, such as + `--insert-pragma` or `--print-width`. + + ------------------------------------------------------------------------------- syntaxerl *ale-erlang-syntaxerl* diff --git a/vim-config/plugins/ale/doc/ale-eruby.txt b/vim-config/plugins/ale/doc/ale-eruby.txt old mode 100755 new mode 100644 index d75d3868..48a34895 --- a/vim-config/plugins/ale/doc/ale-eruby.txt +++ b/vim-config/plugins/ale/doc/ale-eruby.txt @@ -4,6 +4,7 @@ ALE Eruby Integration *ale-eruby-options* There are four linters for `eruby` files: - `erb` +- `erblint` - `erubis` - `erubi` - `ruumba` @@ -13,6 +14,26 @@ 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|. +=============================================================================== +erblint *ale-eruby-erblint* + +g:ale_eruby_erblint_executable *g:ale_eruby_erblint_executable* + *b:ale_eruby_erblint_executable* + Type: |String| + Default: `'erblint'` + + Override the invoked erblint binary. This is useful for running erblint + from binstubs or a bundle. + + +g:ale_eruby_erblint_options *g:ale_ruby_erblint_options* + *b:ale_ruby_erblint_options* + Type: |String| + Default: `''` + + This variable can be change to modify flags given to erblint. + + =============================================================================== ruumba *ale-eruby-ruumba* diff --git a/vim-config/plugins/ale/doc/ale-fish.txt b/vim-config/plugins/ale/doc/ale-fish.txt old mode 100755 new mode 100644 index 8450b38a..7dbbc10c --- a/vim-config/plugins/ale/doc/ale-fish.txt +++ b/vim-config/plugins/ale/doc/ale-fish.txt @@ -10,5 +10,22 @@ 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. +=============================================================================== +fish_indent *ale-fish-fish_indent* + +g:ale_fish_fish_indent_executable *g:ale_fish_fish_indent_executable* + *b:ale_fish_fish_indent_executable* + Type: |String| + Default: `'fish_indent'` + + This variable can be changed to use a different executable for fish_indent. + +g:ale_fish_fish_indent_options *g:ale_fish_fish_indent_options* + *b:ale_fish_fish_indent_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to fish_indent. + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-fortran.txt b/vim-config/plugins/ale/doc/ale-fortran.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-fountain.txt b/vim-config/plugins/ale/doc/ale-fountain.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-fuse.txt b/vim-config/plugins/ale/doc/ale-fuse.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-gitcommit.txt b/vim-config/plugins/ale/doc/ale-gitcommit.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-glsl.txt b/vim-config/plugins/ale/doc/ale-glsl.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-go.txt b/vim-config/plugins/ale/doc/ale-go.txt old mode 100755 new mode 100644 index 3fbc6fb9..2f1e4c1c --- a/vim-config/plugins/ale/doc/ale-go.txt +++ b/vim-config/plugins/ale/doc/ale-go.txt @@ -20,8 +20,8 @@ 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* +g:ale_go_go_executable *g:ale_go_go_executable* + *b:ale_go_go_executable* Type: |String| Default: `'go'` @@ -30,6 +30,33 @@ g:ale_go_go_executable *g:ale_go_go_options* the `gomod` fixer. +g:ale_go_go111module *g:ale_go_go111module* + *b:ale_go_go111module* + Type: |String| + Default: `''` + + Override the value of the `$GO111MODULE` environment variable for + golang tools. + + + +=============================================================================== +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* @@ -53,6 +80,77 @@ g:ale_go_gofmt_options *g:ale_go_gofmt_options* 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. + +=============================================================================== +golines *ale-go-golines* + +g:ale_go_golines_executable *g:ale_go_lines_executable* + *b:ale_go_lines_executable* + Type: |String| + Default: `'golines'` + + Location of the golines binary file + +g:ale_go_golines_options *g:ale_go_golines_options* + *b:ale_go_golines_options* + Type: |String| + Default: '' + + Additional options passed to the golines command. By default golines has + --max-length=100 (lines above 100 characters will be wrapped) + =============================================================================== golint *ale-go-golint* @@ -72,17 +170,6 @@ g:ale_go_golint_options *g:ale_go_golint_options* This variable can be set to pass additional options to the golint linter. -=============================================================================== -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. - - =============================================================================== gometalinter *ale-go-gometalinter* @@ -122,72 +209,126 @@ g:ale_go_gometalinter_lint_package *g:ale_go_gometalinter_lint_package* =============================================================================== -staticcheck *ale-go-staticcheck* +gopls *ale-go-gopls* -g:ale_go_staticcheck_options *g:ale_go_staticcheck_options* - *b:ale_go_staticcheck_options* +gopls is the official Go language server, and is enabled for use with ALE by +default. + +To install the latest stable version of `gopls` to your `$GOPATH`, try the +following command: > + + GO111MODULE=on go get golang.org/x/tools/gopls@latest +< +If `$GOPATH` is readable by ALE, it should probably work without you having to +do anything else. See the `gopls` README file for more information: + +https://github.com/golang/tools/blob/master/gopls/README.md + + +g:ale_go_gopls_executable *g:ale_go_gopls_executable* + *b:ale_go_gopls_executable* + Type: |String| + Default: `'gopls'` + + See |ale-integrations-local-executables| + + ALE will search for `gopls` in locally installed directories first by + default, and fall back on a globally installed `gopls` if it can't be found + otherwise. + + +g:ale_go_gopls_options *g:ale_go_gopls_options* + *b:ale_go_gopls_options* Type: |String| Default: `''` - This variable can be set to pass additional options to the staticcheck - linter. + Command-line options passed to the gopls executable. See `gopls -h`. -g:ale_go_staticcheck_lint_package *g:ale_go_staticcheck_lint_package* - *b:ale_go_staticcheck_lint_package* - Type: |Number| - Default: `0` +g:ale_go_gopls_init_options *g:ale_go_gopls_init_options* + *b:ale_go_gopls_init_options* + Type: |Dictionary| + Default: `{}` - When set to `1`, the whole Go package will be checked instead of only the - current file. + LSP initialization options passed to gopls. This can be used to configure + the behaviour of gopls. + Example: > + let g:ale_go_gopls_init_options = {'ui.diagnostic.analyses': { + \ 'composites': v:false, + \ 'unusedparams': v:true, + \ 'unusedresult': v:true, + \ }} +< -=============================================================================== -golangserver *ale-go-golangserver* + For a full list of supported analyzers, see: + https://github.com/golang/tools/blob/master/gopls/doc/analyzers.md -g:ale_go_langserver_executable *g:ale_go_langserver_executable* - *b:ale_go_langserver_executable* + +g:ale_go_gopls_use_global *g:ale_go_gopls_use_global* + *b:ale_go_gopls_use_global* Type: |String| - Default: `'go-langserver'` + Default: `get(g:, 'ale_use_global_executables', 0)` - Location of the go-langserver binary file. + See |ale-integrations-local-executables| -g:ale_go_langserver_options *g:ale_go_langserver_options* - *b:ale_go_langserver_options* + +=============================================================================== +govet *ale-go-govet* + +g:ale_go_govet_options *g:ale_go_govet_options* + *b:ale_go_govet_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. + This variable can be set to pass additional options to the go vet linter. =============================================================================== -golangci-lint *ale-go-golangci-lint* +revive *ale-go-revive* -`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_revive_executable *g:ale_go_revive_executable* + *b:ale_go_revive_executable* + Type: |String| + Default: `'revive'` -g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable* - *b:ale_go_golangci_lint_executable* + This variable can be set to change the revive executable path. + + +g:ale_go_revive_options *g:ale_go_revive_options* + *b:ale_go_revive_options* Type: |String| - Default: `'golangci-lint'` + Default: `''` - The executable that will be run for golangci-lint. + This variable can be set to pass additional options to the revive -g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options* - *b:ale_go_golangci_lint_options* +=============================================================================== +staticcheck *ale-go-staticcheck* + +g:ale_go_staticcheck_executable *g:ale_go_staticcheck_executable* + *b:ale_go_staticcheck_executable* Type: |String| - Default: `'--enable-all'` + Default: `'staticcheck'` - This variable can be changed to alter the command-line arguments to the - golangci-lint invocation. + See |ale-integrations-local-executables| + ALE will search for `staticcheck` in locally installed directories first by + default, and fall back on a globally installed `staticcheck` if it can't be + found otherwise. -g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package* - *b:ale_go_golangci_lint_package* + +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` @@ -195,20 +336,12 @@ g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package* current file. -=============================================================================== -bingo *ale-go-bingo* - -g:ale_go_bingo_executable *g:ale_go_bingo_executable* - *b:ale_go_bingo_executable* +g:ale_go_staticcheck_use_global *g:ale_go_staticcheck_use_global* + *b:ale_go_staticcheck_use_global* Type: |String| - Default: `'go-bingo'` + Default: `get(g:, 'ale_use_global_executables', 0)` - Location of the go-bingo binary file. - -g:ale_go_bingo_options *g:ale_go_bingo_options* - *b:ale_go_bingo_options* - Type: |String| - Default: `''` + See |ale-integrations-local-executables| =============================================================================== diff --git a/vim-config/plugins/ale/doc/ale-graphql.txt b/vim-config/plugins/ale/doc/ale-graphql.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-hack.txt b/vim-config/plugins/ale/doc/ale-hack.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-handlebars.txt b/vim-config/plugins/ale/doc/ale-handlebars.txt old mode 100755 new mode 100644 index 061c5d3c..4a5a3870 --- a/vim-config/plugins/ale/doc/ale-handlebars.txt +++ b/vim-config/plugins/ale/doc/ale-handlebars.txt @@ -2,12 +2,20 @@ ALE Handlebars Integration *ale-handlebars-options* +=============================================================================== +prettier *ale-handlebars-prettier* + +See |ale-javascript-prettier| for information about the available options. +Uses glimmer parser by default. + + =============================================================================== ember-template-lint *ale-handlebars-embertemplatelint* g:ale_handlebars_embertemplatelint_executable *g:ale_handlebars_embertemplatelint_executable* - Type: |String| *b:ale_handlebars_embertemplatelint_executable* + *b:ale_handlebars_embertemplatelint_executable* + Type: |String| Default: `'ember-template-lint'` See |ale-integrations-local-executables| @@ -15,7 +23,8 @@ g:ale_handlebars_embertemplatelint_executable g:ale_handlebars_embertemplatelint_use_global *g:ale_handlebars_embertemplatelint_use_global* - Type: |Number| *b:ale_handlebars_embertemplatelint_use_global* + *b:ale_handlebars_embertemplatelint_use_global* + Type: |Number| Default: `get(g:, 'ale_use_global_executables', 0)` See |ale-integrations-local-executables| diff --git a/vim-config/plugins/ale/doc/ale-haskell.txt b/vim-config/plugins/ale/doc/ale-haskell.txt old mode 100755 new mode 100644 index a4db683b..09894340 --- a/vim-config/plugins/ale/doc/ale-haskell.txt +++ b/vim-config/plugins/ale/doc/ale-haskell.txt @@ -12,6 +12,18 @@ g:ale_haskell_brittany_executable *g:ale_haskell_brittany_executable* 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* @@ -22,6 +34,7 @@ g:ale_haskell_ghc_options *g:ale_haskell_ghc_options* This variable can be changed to modify flags given to ghc. + =============================================================================== ghc-mod *ale-haskell-ghc-mod* @@ -32,6 +45,7 @@ g:ale_haskell_ghc_mod_executable *g:ale_haskell_ghc_mod_executable* This variable can be changed to use a different executable for ghc-mod. + =============================================================================== cabal-ghc *ale-haskell-cabal-ghc* @@ -43,6 +57,7 @@ g:ale_haskell_cabal_ghc_options *g:ale_haskell_cabal_ghc_options* This variable can be changed to modify flags given to ghc through cabal exec. + =============================================================================== hdevtools *ale-haskell-hdevtools* @@ -77,6 +92,18 @@ g:ale_haskell_hfmt_executable *g:ale_haskell_hfmt_executable* This variable can be changed to use a different executable for hfmt. + +=============================================================================== +hindent *ale-haskell-hindent* + +g:ale_haskell_hindent_executable *g:ale_haskell_hindent_executable* + *b:ale_haskell_hindent_executable* + Type: |String| + Default: `'hindent'` + + This variable can be changed to use a different executable for hindent. + + =============================================================================== hlint *ale-haskell-hlint* @@ -96,6 +123,19 @@ g:ale_haskell_hlint_options g:ale_haskell_hlint_options This variable can be used to pass extra options to the underlying hlint executable. + +=============================================================================== +hls *ale-haskell-hls* + +g:ale_haskell_hls_executable *g:ale_haskell_hls_executable* + *b:ale_haskell_his_executable* + Type: |String| + Default: `'haskell-language-server-wrapper'` + + This variable can be changed to use a different executable for the haskell + language server. + + =============================================================================== stack-build *ale-haskell-stack-build* @@ -107,6 +147,19 @@ g:ale_haskell_stack_build_options *g:ale_haskell_stack_build_options* 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* @@ -118,6 +171,7 @@ g:ale_haskell_stylish_haskell_executable This variable can be changed to use a different executable for stylish-haskell. + =============================================================================== hie *ale-haskell-hie* @@ -129,5 +183,26 @@ g:ale_haskell_hie_executable *g:ale_haskell_hie_executable* This variable can be changed to use a different executable for the haskell ide engine. i.e. `'hie-wrapper'` + +=============================================================================== +ormolu *ale-haskell-ormolu* + +g:ale_haskell_ormolu_executable *g:ale_haskell_ormolu_executable* + *b:ale_haskell_ormolu_executable* + Type: |String| + Default: `'ormolu'` + + This variable can be changed to use a different executable for ormolu. + + +g:ale_haskell_ormolu_options *g:ale_haskell_ormolu_options* + *b:ale_haskell_ormolu_options* + Type: String + Default: '' + + This variable can be used to pass extra options to the underlying ormolu + executable. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-hcl.txt b/vim-config/plugins/ale/doc/ale-hcl.txt old mode 100755 new mode 100644 index 8060ac44..59b0a9da --- a/vim-config/plugins/ale/doc/ale-hcl.txt +++ b/vim-config/plugins/ale/doc/ale-hcl.txt @@ -5,7 +5,7 @@ ALE HCL Integration *ale-hcl-options* =============================================================================== terraform-fmt *ale-hcl-terraform-fmt* -See |ale-terraform-fmt| for information about the available options. +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/vim-config/plugins/ale/doc/ale-html.txt b/vim-config/plugins/ale/doc/ale-html.txt old mode 100755 new mode 100644 index 1d30929f..2c048148 --- a/vim-config/plugins/ale/doc/ale-html.txt +++ b/vim-config/plugins/ale/doc/ale-html.txt @@ -2,6 +2,52 @@ ALE HTML Integration *ale-html-options* +=============================================================================== +angular *ale-html-angular* + +ALE supports language server features for Angular. You can install it via `npm`: > + + $ npm install --save-dev @angular/language-server +< +Angular 11 and up are supported. + + +g:ale_html_angular_executable *g:ale_html_angular_executable* + *b:ale_html_angular_executable* + Type: |String| + Default: `'ngserver'` + + See |ale-integrations-local-executables| + + +g:ale_html_angular_use_global *g:ale_html_angular_use_global* + *b:ale_html_angular_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +fecs *ale-html-fecs* + +`fecs` options for HTML are the same as the options for JavaScript, and both +of them read `./.fecsrc` as the default configuration file. + +See: |ale-javascript-fecs|. + + +=============================================================================== +html-beautify *ale-html-beautify* + +g:ale_html_beautify_options *g:ale_html_beautify_options* + *b:ale_html_beautify_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to html-beautify. + + =============================================================================== htmlhint *ale-html-htmlhint* @@ -29,6 +75,40 @@ g:ale_html_htmlhint_use_global *g:ale_html_htmlhint_use_global* 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| + + =============================================================================== tidy *ale-html-tidy* @@ -79,39 +159,6 @@ g:ale_html_tidy_use_global *g:html_tidy_use_global* 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* diff --git a/vim-config/plugins/ale/doc/ale-idris.txt b/vim-config/plugins/ale/doc/ale-idris.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-ink.txt b/vim-config/plugins/ale/doc/ale-ink.txt new file mode 100644 index 00000000..9412a09f --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-ink.txt @@ -0,0 +1,40 @@ +=============================================================================== +ALE Ink Integration *ale-ink-options* + + +=============================================================================== +ink-language-server *ale-ink-language-server* + +Ink Language Server + (https://github.com/ephraim/ink-language-server) + +g:ale_ink_ls_executable g:ale_ink_ls_executable + b:ale_ink_ls_executable + Type: |String| + Default: `'ink-language-server'` + + Ink language server executable. + +g:ale_ink_ls_initialization_options + g:ale_ink_ls_initialization_options + b:ale_ink_ls_initialization_options + Type: |Dictionary| + Default: `{}` + + Dictionary containing configuration settings that will be passed to the + language server at startup. For certain platforms and certain story + structures, the defaults will suffice. However, many projects will need to + change these settings - see the ink-language-server website for more + information. + + An example of setting non-default options: + { + \ 'ink': { + \ 'mainStoryPath': 'init.ink', + \ 'inklecateExecutablePath': '/usr/local/bin/inklecate', + \ 'runThroughMono': v:false + \ } + \} + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-inko.txt b/vim-config/plugins/ale/doc/ale-inko.txt new file mode 100644 index 00000000..5ca14af6 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-inko.txt @@ -0,0 +1,22 @@ +=============================================================================== +ALE Inko Integration *ale-inko-options* + *ale-integration-inko* + +=============================================================================== +Integration Information + + Currently, the only supported linter for Inko is the Inko compiler itself. + +=============================================================================== +inko *ale-inko-inko* + +g:ale_inko_inko_executable *g:ale_inko_inko_executable* + *b:ale_inko_inko_executable* + Type: |String| + Default: `'inko'` + + This variable can be modified to change the executable path for `inko`. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-ispc.txt b/vim-config/plugins/ale/doc/ale-ispc.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-java.txt b/vim-config/plugins/ale/doc/ale-java.txt old mode 100755 new mode 100644 index 8e40aea0..6bd04ef9 --- a/vim-config/plugins/ale/doc/ale-java.txt +++ b/vim-config/plugins/ale/doc/ale-java.txt @@ -5,21 +5,48 @@ 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: '-c /google_checks.xml' + 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| + Type: |String| or |List| Default: `''` This variable can be set to change the global classpath for Java. @@ -40,6 +67,30 @@ g:ale_java_javac_options *g:ale_java_javac_options* This variable can be set to pass additional options to javac. +g:ale_java_javac_sourcepath *g:ale_java_javac_sourcepath* + *b:ale_java_javac_sourcepath* + Type: |String| or |List| + Default: `''` + +This variable can set multiple source code paths, the source code path is a +relative path (relative to the project root directory). + +Example: + +String type: +Note that the unix system separator is a colon(`:`) window system +is a semicolon(`;`). +> + let g:ale_java_javac_sourcepath = 'build/gen/source/xx/main:build/gen/source' +< +List type: +> + let g:ale_java_javac_sourcepath = [ + \ 'build/generated/source/querydsl/main', + \ 'target/generated-sources/source/querydsl/main' + \ ] +< + =============================================================================== google-java-format *ale-java-google-java-format* @@ -79,30 +130,141 @@ g:ale_java_pmd_options *g:ale_java_pmd_options* 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/vscode-javac. Simply -download the source code and then build the plugin using maven: +language server from https://github.com/georgewfraser/java-language-server. + +Before building the language server you need to install pre-requisites: npm, +maven, and protobuf. You also need to have Java 13 and JAVA_HOME properly +set. + +After downloading the source code and installing all pre-requisites you can +build the language server with the included build.sh script: - mvn package + scripts/build.sh -This generates a out/fat-jar.jar file that contains the language server. To -let ALE use this language server you need to set the g:ale_java_javalsp_jar -variable to the absolute path of this jar file. +This will create launch scripts for Linux, Mac, and Windows in the dist folder +within the repo: + + - lang_server_linux.sh + - lang_server_mac.sh + - lang_server_windows.sh + +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 for your platform. g:ale_java_javalsp_executable *g:ale_java_javalsp_executable* *b:ale_java_javalsp_executable* Type: |String| + Default: `''` + +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/lang_server_linux.sh +< + +g:ale_java_javalsp_config *g:ale_java_javalsp_config* + *b:ale_java_javalsp_config* + Type: |Dictionary| + Default: `{}` + +The javalsp linter automatically detects external depenencies for Maven and +Gradle projects. In case the javalsp fails to detect some of them, you can +specify them setting a dictionary to |g:ale_java_javalsp_config| variable. +> + let g:ale_java_javalsp_config = + \ { + \ 'java': { + \ 'externalDependencies': [ + \ 'junit:junit:jar:4.12:test', " Maven format + \ 'junit:junit:4.1' " Gradle format + \ ], + \ 'classPath': [ + \ 'lib/some-dependency.jar', + \ '/android-sdk/platforms/android-28.jar' + \ ] + \ } + \ } + +The Java language server will look for the dependencies you specify in +`externalDependencies` array in your Maven and Gradle caches ~/.m2 and +~/.gradle. + +=============================================================================== +eclipselsp *ale-java-eclipselsp* + +To enable Eclipse JDT 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 11. 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 changed to use a different executable for java. + This variable can be set to change the executable path used for java. -g:ale_java_javalsp_jar *g:ale_java_javalsp_jar* - *b:ale_java_javalsp_jar* +g:ale_java_eclipselsp_config_path *g:ale_java_eclipse_config_path* + *b:ale_java_eclipse_config_path* Type: |String| - Default: `'fat-jar.jar'` + 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. - Path to the location of the vscode-javac language server plugin. +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. + +g:ale_java_eclipselsp_javaagent *g:ale_java_eclipselsp_javaagent* + *b:ale_java_eclipselsp_javaagent* + + Type: |String| + Default: `''` + + A variable to add java agent for annotation processing such as Lombok. + If you have multiple java agent files, use space to separate them. For example: +> + let g:ale_java_eclipselsp_javaagent='/eclipse/lombok.jar /eclipse/jacoco.jar' +< =============================================================================== uncrustify *ale-java-uncrustify* diff --git a/vim-config/plugins/ale/doc/ale-javascript.txt b/vim-config/plugins/ale/doc/ale-javascript.txt old mode 100755 new mode 100644 index 53a70fd7..acd886c9 --- a/vim-config/plugins/ale/doc/ale-javascript.txt +++ b/vim-config/plugins/ale/doc/ale-javascript.txt @@ -23,6 +23,11 @@ To this: > /path/foo/bar/.eslintrc.js # extends: ["/path/foo/.base-eslintrc.js"] < +=============================================================================== +deno *ale-javascript-deno* + +Check the docs over at |ale-typescript-deno|. + =============================================================================== eslint *ale-javascript-eslint* @@ -73,6 +78,33 @@ g:ale_javascript_eslint_suppress_missing_config 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* @@ -111,7 +143,7 @@ g:ale_javascript_flow_use_respect_pragma 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`. + `0` to disable that behavior, so all files can be checked by `flow`. =============================================================================== diff --git a/vim-config/plugins/ale/doc/ale-json.txt b/vim-config/plugins/ale/doc/ale-json.txt old mode 100755 new mode 100644 index 6a0a9fae..ad0a05b1 --- a/vim-config/plugins/ale/doc/ale-json.txt +++ b/vim-config/plugins/ale/doc/ale-json.txt @@ -2,6 +2,15 @@ ALE JSON Integration *ale-json-options* +=============================================================================== +eslint *ale-json-eslint* + +The `eslint` linter for JSON uses the JavaScript options for `eslint`; see: +|ale-javascript-eslint|. + +You will need a JSON ESLint plugin installed for this to work. + + =============================================================================== fixjson *ale-json-fixjson* @@ -52,7 +61,21 @@ g:ale_json_fixjson_use_global *g:ale_json_fixjson_use_global* =============================================================================== jsonlint *ale-json-jsonlint* -There are no options available. +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| =============================================================================== @@ -87,5 +110,37 @@ prettier *ale-json-prettier* See |ale-javascript-prettier| for information about the available options. +=============================================================================== +spectral *ale-json-spectral* + +Website: https://github.com/stoplightio/spectral + +Installation +------------------------------------------------------------------------------- + +Install spectral either globally or locally: > + + npm install @stoplight/spectral -g # global + npm install @stoplight/spectral # local +< + +Options +------------------------------------------------------------------------------- + +g:ale_json_spectral_executable *g:ale_json_spectral_executable* + *b:ale_json_spectral_executable* + Type: |String| + Default: `'spectral'` + + This variable can be set to change the path to spectral. + +g:ale_json_spectral_use_global *g:ale_json_spectral_use_global* + *b:ale_json_spectral_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/vim-config/plugins/ale/doc/ale-json5.txt b/vim-config/plugins/ale/doc/ale-json5.txt new file mode 100644 index 00000000..bafa60d1 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-json5.txt @@ -0,0 +1,15 @@ +=============================================================================== +ALE JSON5 Integration *ale-json5-options* + + +=============================================================================== +eslint *ale-json5-eslint* + +The `eslint` linter for JSON uses the JavaScript options for `eslint`; see: +|ale-javascript-eslint|. + +You will need a JSON5 ESLint plugin installed for this to work. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-jsonc.txt b/vim-config/plugins/ale/doc/ale-jsonc.txt new file mode 100644 index 00000000..92247cd4 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-jsonc.txt @@ -0,0 +1,15 @@ +=============================================================================== +ALE JSONC Integration *ale-jsonc-options* + + +=============================================================================== +eslint *ale-jsonc-eslint* + +The `eslint` linter for JSON uses the JavaScript options for `eslint`; see: +|ale-javascript-eslint|. + +You will need a JSONC ESLint plugin installed for this to work. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-jsonnet.txt b/vim-config/plugins/ale/doc/ale-jsonnet.txt new file mode 100644 index 00000000..f99d415f --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-jsonnet.txt @@ -0,0 +1,43 @@ +=============================================================================== +ALE Jsonnet Integration *ale-jsonnet-options* + + +=============================================================================== +jsonnetfmt *ale-jsonnet-jsonnetfmt* + +g:ale_jsonnet_jsonnetfmt_executable *g:ale_jsonnet_jsonnetfmt_executable* + *b:ale_jsonnet_jsonnetfmt_executable* + Type: |String| + Default: `'jsonnetfmt'` + + This option can be changed to change the path for `jsonnetfmt`. + + +g:ale_jsonnet_jsonnetfmt_options *g:ale_jsonnet_jsonnetfmt_options* + *b:ale_jsonnet_jsonnetfmt_options* + Type: |String| + Default: `''` + + This option can be changed to pass extra options to `jsonnetfmt`. + + +=============================================================================== +jsonnet-lint *ale-jsonnet-jsonnet-lint* + +g:ale_jsonnet_jsonnet_lint_executable *g:ale_jsonnet_jsonnet_lint_executable* + *b:ale_jsonnet_jsonnet_lint_executable* + Type: |String| + Default: `'jsonnet-lint'` + + This option can be changed to change the path for `jsonnet-lint`. + + +g:ale_jsonnet_jsonnet_lint_options *g:ale_jsonnet_jsonnet_lint_options* + *b:ale_jsonnet_jsonnet_lint_options* + Type: |String| + Default: `''` + + This option can be changed to pass extra options to `jsonnet-lint`. + + + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-julia.txt b/vim-config/plugins/ale/doc/ale-julia.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-kotlin.txt b/vim-config/plugins/ale/doc/ale-kotlin.txt old mode 100755 new mode 100644 index 9f9fd16e..4028531f --- a/vim-config/plugins/ale/doc/ale-kotlin.txt +++ b/vim-config/plugins/ale/doc/ale-kotlin.txt @@ -84,9 +84,17 @@ g:ale_kotlin_ktlint_rulesets *g:ale_kotlin_ktlint_rulesets* 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-rulset.jar', + 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* diff --git a/vim-config/plugins/ale/doc/ale-latex.txt b/vim-config/plugins/ale/doc/ale-latex.txt old mode 100755 new mode 100644 index 87fbd4e8..bedbabcd --- a/vim-config/plugins/ale/doc/ale-latex.txt +++ b/vim-config/plugins/ale/doc/ale-latex.txt @@ -8,5 +8,11 @@ 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/vim-config/plugins/ale/doc/ale-less.txt b/vim-config/plugins/ale/doc/ale-less.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-llvm.txt b/vim-config/plugins/ale/doc/ale-llvm.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-lua.txt b/vim-config/plugins/ale/doc/ale-lua.txt old mode 100755 new mode 100644 index f1286f89..ac92b9ac --- a/vim-config/plugins/ale/doc/ale-lua.txt +++ b/vim-config/plugins/ale/doc/ale-lua.txt @@ -1,6 +1,24 @@ =============================================================================== ALE Lua Integration *ale-lua-options* +=============================================================================== +lua-format *ale-lua-lua-format* + +g:ale_lua_lua_format_executable *g:ale_lua_lua_format_executable* + *b:ale_lua_lua_format_executable* + Type: |String| + Default: `'lua-format'` + + This variable can be changed to change the path to lua-format. + +g:ale_lua_lua_format_options *g:ale_lua_lua_format_options* + *b:ale_lua_lua_format_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to lua-format. + + =============================================================================== luac *ale-lua-luac* @@ -30,5 +48,41 @@ g:ale_lua_luacheck_options *g:ale_lua_luacheck_options* This variable can be set to pass additional options to luacheck. +=============================================================================== +luafmt *ale-lua-luafmt* + +g:ale_lua_luafmt_executable *g:ale_lua_luafmt_executable* + *b:ale_lua_luafmt_executable* + Type: |String| + Default: `'luafmt'` + + This variable can be set to use a different executable for luafmt. + +g:ale_lua_luafmt_options *g:ale_lua_luafmt_options* + *b:ale_lua_luafmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the luafmt fixer. + + +=============================================================================== +stylua *ale-lua-stylua* + +g:ale_lua_stylua_executable *g:ale_lua_stylua_executable* + *b:ale_lua_stylua_executable* + Type: |String| + Default: `'stylua'` + + This variable can be set to use a different executable for stylua. + +g:ale_lua_stylua_options *g:ale_lua_stylua_options* + *b:ale_lua_stylua_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the stylua fixer. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-markdown.txt b/vim-config/plugins/ale/doc/ale-markdown.txt old mode 100755 new mode 100644 index 4e27eb91..feb37fc9 --- a/vim-config/plugins/ale/doc/ale-markdown.txt +++ b/vim-config/plugins/ale/doc/ale-markdown.txt @@ -2,6 +2,17 @@ ALE Markdown Integration *ale-markdown-options* +=============================================================================== +markdownlint *ale-markdown-markdownlint* + +g:ale_markdown_markdownlint_options *g:ale_markdown_markdownlint_options* + *b:ale_markdown_markdownlint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to markdownlint. + + =============================================================================== mdl *ale-markdown-mdl* @@ -22,6 +33,25 @@ g:ale_markdown_mdl_options *g:ale_markdown_mdl_options* This variable can be set to pass additional options to mdl. +=============================================================================== +pandoc *ale-markdown-pandoc* + +g:ale_markdown_pandoc_executable *g:ale_markdown_pandoc_executable* + *b:ale_markdown_pandoc_executable* + Type: |String| + Default: `'pandoc'` + + This variable can be set to specify where to find the pandoc executable + + +g:ale_markdown_pandoc_options *g:ale_markdown_pandoc_options* + *b:ale_markdown_pandoc_options* + Type: |String| + Default: `'-f gfm -t gfm -s -'` + + This variable can be set to change the default options passed to pandoc + + =============================================================================== prettier *ale-markdown-prettier* diff --git a/vim-config/plugins/ale/doc/ale-mercury.txt b/vim-config/plugins/ale/doc/ale-mercury.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-nasm.txt b/vim-config/plugins/ale/doc/ale-nasm.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-nim.txt b/vim-config/plugins/ale/doc/ale-nim.txt new file mode 100644 index 00000000..8985aeb8 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-nim.txt @@ -0,0 +1,45 @@ +=============================================================================== +ALE Nim Integration *ale-nim-options* + + +=============================================================================== +nimcheck *ale-nim-nimcheck* + + ALE does not provide additional configuration options for `nimcheck` at this + point. + + +=============================================================================== +nimlsp *ale-nim-nimlsp* + +g:nim_nimlsp_nim_sources *g:nim_nimlsp_nim_sources* + + Type: |String| + Default: `''` + + Sets the path to Nim source repository as the first argument to `nimlsp` + command. + + +=============================================================================== +nimpretty *ale-nim-nimpretty* + + +g:ale_nim_nimpretty_executable *g:ale_nim_nimpretty_executable* + *b:ale_nim_nimpretty_executable* + Type: |String| + Default: `'nimpretty'` + + This variable can be changed to use a different executable for nimpretty. + + +g:ale_nim_nimpretty_options *g:ale_nim_nimpretty_options* + *b:ale_nim_nimpretty_options* + Type: |String| + Default: `'--maxLineLen:80'` + + This variable can be changed to modify flags given to nimpretty. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-nix.txt b/vim-config/plugins/ale/doc/ale-nix.txt new file mode 100644 index 00000000..c38b93db --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-nix.txt @@ -0,0 +1,42 @@ +=============================================================================== +ALE Nix Integration *ale-nix-options* + + +=============================================================================== +nixfmt *ale-nix-nixfmt* + +g:ale_nix_nixfmt_executable *g:ale_nix_nixfmt_executable* + *b:ale_nix_nixfmt_executable* + Type: String + Default: 'nixfmt' + + This variable sets the executable used for nixfmt. + +g:ale_nix_nixfmt_options *g:ale_nix_nixfmt_options* + *b:ale_nix_nixfmt_options* + Type: String + Default: '' + + This variable can be set to pass additional options to the nixfmt fixer. + + +=============================================================================== +nixpkgs-fmt *ale-nix-nixpkgs-fmt* + +g:ale_nix_nixpkgsfmt_executable *g:ale_nix_nixpkgsfmt_executable* + *b:ale_nix_nixpkgsfmt_executable* + Type: |String| + Default: `'nixpkgs-fmt'` + + This variable sets executable used for nixpkgs-fmt. + +g:ale_nix_nixpkgsfmt_options *g:ale_nix_nixpkgsfmt_options* + *b:ale_nix_nixpkgsfmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the nixpkgs-fmt fixer. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-nroff.txt b/vim-config/plugins/ale/doc/ale-nroff.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-objc.txt b/vim-config/plugins/ale/doc/ale-objc.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-objcpp.txt b/vim-config/plugins/ale/doc/ale-objcpp.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-ocaml.txt b/vim-config/plugins/ale/doc/ale-ocaml.txt old mode 100755 new mode 100644 index adf17716..afbc2386 --- a/vim-config/plugins/ale/doc/ale-ocaml.txt +++ b/vim-config/plugins/ale/doc/ale-ocaml.txt @@ -10,6 +10,21 @@ merlin *ale-ocaml-merlin* detailed instructions (https://github.com/the-lambda-church/merlin/wiki/vim-from-scratch). +=============================================================================== +ocamllsp *ale-ocaml-ocamllsp* + + The `ocaml-lsp-server` is the official OCaml implementation of the Language + Server Protocol. See the installation instructions: + https://github.com/ocaml/ocaml-lsp#installation + +g:ale_ocaml_ocamllsp_use_opam *g:ale_ocaml_ocamllsp_use_opam* + *b:ale_ocaml_ocamllsp_use_opam* + Type: |Number| + Default: `get(g:, 'ale_ocaml_ocamllsp_use_opam', 1)` + + This variable can be set to change whether or not opam is used to execute + the language server. + =============================================================================== ols *ale-ocaml-ols* @@ -50,5 +65,33 @@ g:ale_ocaml_ocamlformat_options *g:ale_ocaml_ocamlformat_options* 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/vim-config/plugins/ale/doc/ale-openapi.txt b/vim-config/plugins/ale/doc/ale-openapi.txt new file mode 100644 index 00000000..1fc41add --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-openapi.txt @@ -0,0 +1,74 @@ +=============================================================================== +ALE OpenApi Integration *ale-openapi-options* + +=============================================================================== +ibm_validator *ale-openapi-ibm-validator* + +Website: https://github.com/IBM/openapi-validator + + +Installation +------------------------------------------------------------------------------- + +Install ibm-openapi-validator either globally or locally: > + + npm install ibm-openapi-validator -g # global + npm install ibm-openapi-validator # local +< +Configuration +------------------------------------------------------------------------------- + +OpenAPI files can be written in YAML or JSON so in order for ALE plugins to +work with these files we must set the buffer |filetype| to either |openapi.yaml| +or |openapi.json| respectively. This causes ALE to lint the file with linters +configured for openapi and yaml files or openapi and json files respectively. + +For example setting filetype to |openapi.yaml| on a buffer and the following +|g:ale_linters| configuration will enable linting of openapi files using both +|ibm_validator| and |yamlint|: + +> + let g:ale_linters = { + \ 'yaml': ['yamllint'], + \ 'openapi': ['ibm_validator'] + \} +< + +The following plugin will detect openapi files automatically and set the +filetype to |openapi.yaml| or |openapi.json|: + + https://github.com/hsanson/vim-openapi + +Options +------------------------------------------------------------------------------- + +g:ale_openapi_ibm_validator_executable *g:ale_openapi_ibm_validator_executable* + *b:ale_openapi_ibm_validator_executable* + Type: |String| + Default: `'lint-openapi'` + + This variable can be set to change the path to lint-openapi. + + +g:ale_openapi_ibm_validator_options *g:ale_openapi_ibm_validator_options* + *b:ale_openapi_ibm_validator_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to lint-openapi. + + +=============================================================================== +prettier *ale-openapi-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +yamllint *ale-openapi-yamllint* + +See |ale-yaml-yamllint| for information about the available options. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-pascal.txt b/vim-config/plugins/ale/doc/ale-pascal.txt new file mode 100644 index 00000000..03d9a004 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-pascal.txt @@ -0,0 +1,24 @@ +=============================================================================== +ALE Pascal Integration *ale-pascal-options* + +=============================================================================== +ptop *ale-pascal-ptop* + +g:ale_pascal_ptop_executable *g:ale_pascal_ptop_executable* + *b:ale_pascal_ptop_executable* + Type: |String| + Default: `'ptop'` + + This variable can be changed to specify the ptop executable. + + +g:ale_pascal_ptop_options *g:ale_pascal_ptop_options* + *b:ale_pascal_ptop_options* + Type: |String| + Default: `''` + +This variable can be set to pass additional options to the ptop fixer. + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-pawn.txt b/vim-config/plugins/ale/doc/ale-pawn.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-perl.txt b/vim-config/plugins/ale/doc/ale-perl.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-perl6.txt b/vim-config/plugins/ale/doc/ale-perl6.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-php.txt b/vim-config/plugins/ale/doc/ale-php.txt old mode 100755 new mode 100644 index 83bc0fd5..4ee016fb --- a/vim-config/plugins/ale/doc/ale-php.txt +++ b/vim-config/plugins/ale/doc/ale-php.txt @@ -85,6 +85,14 @@ g:ale_php_phpcbf_use_global *g:ale_php_phpcbf_use_global* See |ale-integrations-local-executables| +g:ale_php_phpcbf_options *g:ale_php_phpcbf_options* + *b:ale_php_phpcbf_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to php-cbf + + =============================================================================== phpcs *ale-php-phpcs* @@ -154,11 +162,13 @@ g:ale_php_phpstan_executable *g:ale_php_phpstan_executable* g:ale_php_phpstan_level *g:ale_php_phpstan_level* *b:ale_php_phpstan_level* - Type: |Number| - Default: `4` + Type: |String| + Default: `''` - This variable controls the rule levels. 0 is the loosest and 4 is the - strictest. + This variable controls the rule levels. 0 is the loosest and 7 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, `'7'` will + be used instead. g:ale_php_phpstan_configuration *g:ale_php_phpstan_configuration* @@ -169,6 +179,14 @@ g:ale_php_phpstan_configuration *g:ale_php_phpstan_configuration* 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* @@ -179,39 +197,124 @@ g:ale_php_psalm_executable *g:ale_php_psalm_executable* 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* +g:ale_php_psalm_options *g:ale_php_psalm_options* + *b:ale_php_psalm_options* Type: |String| - Default: `'php-cs-fixer'` + Default: `''` - This variable sets executable used for php-cs-fixer. + This variable can be set to pass additional options to psalm. -g:ale_php_cs_fixer_use_global *g:ale_php_cs_fixer_use_global* - *b:ale_php_cs_fixer_use_global* + +g:ale_php_psalm_use_global *g:ale_php_psalm_use_global* + *b:ale_php_psalm_use_global* Type: |Boolean| Default: `get(g:, 'ale_use_global_executables', 0)` - This variable force globally installed fixer. + See |ale-integrations-local-executables| -g:ale_php_cs_fixer_options *g:ale_php_cs_fixer_options* - *b:ale_php_cs_fixer_options* + +=============================================================================== +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_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. + +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)` + + See |ale-integrations-local-executables| + + =============================================================================== -php *ale-php-php* +php *ale-php-php* -g:ale_php_php_executable *g:ale_php_php_executable* - *b:ale_php_php_executable* +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. + +=============================================================================== +tlint *ale-php-tlint* + +g:ale_php_tlint_executable *g:ale_php_tlint_executable* + *b:ale_php_tlint_executable* + Type: |String| + Default: `'tlint'` + + See |ale-integrations-local-executables| + + +g:ale_php_tlint_use_global *g:ale_php_tlint_use_global* + *b:ale_php_tlint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_php_tlint_options *g:ale_php_tlint_options* + *b:ale_php_tlint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to tlint + + +=============================================================================== +intelephense *ale-php-intelephense* + +g:ale_php_intelephense_executable *g:ale_php_intelephense_executable* + *b:ale_php_intelephense_executable* + Type: |String| + Default: `'intelephense'` + + The variable can be set to configure the executable that will be used for + running the intelephense language server. `node_modules` directory + executable will be preferred instead of this setting if + |g:ale_php_intelephense_use_global| is `0`. + + See: |ale-integrations-local-executables| + + +g:ale_php_intelephense_use_global *g:ale_php_intelephense_use_global* + *b:ale_php_intelephense_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_intelephense_executable|. + + See: |ale-integrations-local-executables| + + +g:ale_php_intelephense_config *g:ale_php_intelephense_config* + *b:ale_php_intelephense_config* + Type: |Dictionary| + Default: `{}` + + The initialization options config specified by Intelephense. Refer to the + installation docs provided by intelephense (github.com/bmewburn/intelephense + -docs). + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-po.txt b/vim-config/plugins/ale/doc/ale-po.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-pod.txt b/vim-config/plugins/ale/doc/ale-pod.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-pony.txt b/vim-config/plugins/ale/doc/ale-pony.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-powershell.txt b/vim-config/plugins/ale/doc/ale-powershell.txt new file mode 100644 index 00000000..485c9bd0 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-powershell.txt @@ -0,0 +1,70 @@ +=============================================================================== +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. + +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/vim-config/plugins/ale/doc/ale-prolog.txt b/vim-config/plugins/ale/doc/ale-prolog.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-proto.txt b/vim-config/plugins/ale/doc/ale-proto.txt old mode 100755 new mode 100644 index 734e23d5..8ab56a14 --- a/vim-config/plugins/ale/doc/ale-proto.txt +++ b/vim-config/plugins/ale/doc/ale-proto.txt @@ -5,14 +5,15 @@ 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']} + let g:ale_linters = {'proto': ['protoc-gen-lint', 'protolint']} + +To enable `.proto` file fixing, update |g:ale_fixers| as appropriate: +> + " Enable linter for .proto files + let b:ale_fixers = {'proto': ['protolint']} < =============================================================================== protoc-gen-lint *ale-proto-protoc-gen-lint* @@ -29,5 +30,31 @@ g:ale_proto_protoc_gen_lint_options *g:ale_proto_protoc_gen_lint_options* directory of the linted file is always passed as an include path with '-I' before any user-supplied options. +=============================================================================== +protolint *ale-proto-protolint* + + The linter is a pluggable tool that doesn't depend on the `protoc` binary. + This supports both linting and fixing. + Make sure the binary is available in the system path, or set + ale_proto_protolint_executable. + Note that the binary with v0.22.0 or above is supported. + +g:ale_proto_protolint_executable *g:ale_proto_protolint_executable* + + Type: |String| + Default: 'protolint' + + This variable can be changed to modify the executable used for protolint. + +g:ale_proto_protolint_config *g:ale_proto_protolint_config* + + Type: |String| + Default: `''` + + A path to a protolint configuration file. + + 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. + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-pug.txt b/vim-config/plugins/ale/doc/ale-pug.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-puppet.txt b/vim-config/plugins/ale/doc/ale-puppet.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-purescript.txt b/vim-config/plugins/ale/doc/ale-purescript.txt new file mode 100644 index 00000000..91bef558 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-purescript.txt @@ -0,0 +1,69 @@ +=============================================================================== +ALE PureScript Integration *ale-purescript-options* + + +=============================================================================== +purescript-language-server *ale-purescript-language-server* + +PureScript Language Server + (https://github.com/nwolverson/purescript-language-server) + +g:ale_purescript_ls_executable g:ale_purescript_ls_executable + b:ale_purescript_ls_executable + Type: |String| + Default: `'purescript-language-server'` + + PureScript language server executable. + +g:ale_purescript_ls_config g:ale_purescript_ls_config + b:ale_purescript_ls_config + Type: |Dictionary| + Default: `{}` + + Dictionary containing configuration settings that will be passed to the + language server. For example, with a spago project: + { + \ 'purescript': { + \ 'addSpagoSources': v:true, + \ 'addNpmPath': v:true, + \ 'buildCommand': 'spago --quiet build --purs-args --json-errors' + \ } + \} +=============================================================================== +purs-tidy *ale-purescript-tidy* + +g:ale_purescript_tidy_executable *g:ale_purescript_tidy_executable* + *b:ale_purescript_tidy_executable* + Type: |String| + Default: `'purs-tidy'` + + This variable can be changed to use a different executable for purs-tidy. + +g:ale_purescript_tidy_use_global *g:ale_purescript_tidy_use_global* + *b:ale_purescript_tidy_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + +g:ale_purescript_tidy_options *g:ale_purescript_tidy_options* + *b:ale_purescript_tidy_options* + Type: String + Default: `''` + + This variable can be set to pass in additional option to the 'purs-tidy' + executable. +> + let g:ale_purescript_options = '--indent 3' +< +=============================================================================== +purty *ale-purescript-purty* + +g:ale_purescript_purty_executable *g:ale_purescript_purty_executable* + *b:ale_purescript_purty_executable* + Type: |String| + Default: `'purty'` + + This variable can be changed to use a different executable for purty. +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-pyrex.txt b/vim-config/plugins/ale/doc/ale-pyrex.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-python.txt b/vim-config/plugins/ale/doc/ale-python.txt old mode 100755 new mode 100644 index 3d355bc6..10cc2897 --- a/vim-config/plugins/ale/doc/ale-python.txt +++ b/vim-config/plugins/ale/doc/ale-python.txt @@ -10,6 +10,14 @@ g:ale_python_auto_pipenv *g:ale_python_auto_pipenv* 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_auto_poetry *g:ale_python_auto_poetry* + *b:ale_python_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + =============================================================================== ALE Python Project Root Behavior *ale-python-root* @@ -27,17 +35,78 @@ ALE will look for configuration files with the following filenames. > setup.cfg pytest.ini tox.ini + .pyre_configuration.local mypy.ini pycodestyle.cfg - flake8.cfg + .flake8 .flake8rc + pylama.ini + pylintrc + .pylintrc Pipfile Pipfile.lock + poetry.lock + pyproject.toml + .tool-versions < The first directory containing any of the files named above will be used. +=============================================================================== +autoflake *ale-python-autoflake* + +g:ale_python_autoflake_executable *g:ale_python_autoflake_executable* + *b:ale_python_autoflake_executable* + Type: |String| + Default: `'autoflake'` + + See |ale-integrations-local-executables| + + +g:ale_python_autoflake_options *g:ale_python_autoflake_options* + *b:ale_python_autoflake_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to autoflake. + + +g:ale_python_autoflake_use_global *g:ale_python_autoflake_use_global* + *b:ale_python_autoflake_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +autoimport *ale-python-autoimport* + +g:ale_python_autoimport_executable *g:ale_python_autoimport_executable* + *b:ale_python_autoimport_executable* + Type: |String| + Default: `'autoimport'` + + See |ale-integrations-local-executables| + + +g:ale_python_autoimport_options *g:ale_python_autoimport_options* + *b:ale_python_autoimport_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to autoimport. + + +g:ale_python_autoimport_use_global *g:ale_python_autoimport_use_global* + *b:ale_python_autoimport_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== autopep8 *ale-python-autopep8* @@ -65,6 +134,66 @@ g:ale_python_autopep8_use_global *g:ale_python_autopep8_use_global* 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'`. + Set this to `'poetry'` to invoke `'poetry` `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. + + +g:ale_python_bandit_auto_poetry *g:ale_python_bandit_auto_poetry* + *b:ale_python_bandit_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + =============================================================================== black *ale-python-black* @@ -92,36 +221,56 @@ g:ale_python_black_use_global *g:ale_python_black_use_global* See |ale-integrations-local-executables| -g:ale_python_black_auto_pipenv *g:ale_python_black_auto_pipenv* - *b:ale_python_black_auto_pipenv* +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_auto_poetry *g:ale_python_black_auto_poetry* + *b:ale_python_black_auto_poetry* + Type: |Number| + Default: `0` -=============================================================================== -flake8 *ale-python-flake8* + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. -g:ale_python_flake8_change_directory *g:ale_python_flake8_change_directory* - *b:ale_python_flake8_change_directory* +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 `flake8` is in before checking it. This helps `flake8` find + 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: |String| + Default: `project` + + If set to `project`, ALE will switch to the project root before checking file. + If set to `file`, ALE will switch to directory the Python file being + checked with `flake8` is in before checking it. + You can turn it off with `off` option 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'`. + this to `'pipenv'` to invoke `'pipenv` `run` `flake8'`. Set this to + `'poetry'` to invoke `'poetry` `run` `flake8'`. g:ale_python_flake8_options *g:ale_python_flake8_options* @@ -163,6 +312,78 @@ g:ale_python_flake8_auto_pipenv *g:ale_python_flake8_auto_pipenv* if true. This is overridden by a manually-set executable. +g:ale_python_flake8_auto_poetry *g:ale_python_flake8_auto_poetry* + *b:ale_python_flake8_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + +=============================================================================== +flakehell *ale-python-flakehell* + +g:ale_python_flakehell_change_directory*g:ale_python_flakehell_change_directory* + *b:ale_python_flakehell_change_directory* + Type: |String| + Default: `project` + + If set to `project`, ALE will switch to the project root before checking file. + If set to `file`, ALE will switch to directory the Python file being + checked with `flakehell` is in before checking it. + You can turn it off with `off` option if you want to control the directory + Python is executed from yourself. + + +g:ale_python_flakehell_executable *g:ale_python_flakehell_executable* + *b:ale_python_flakehell_executable* + Type: |String| + Default: `'flakehell'` + + This variable can be changed to modify the executable used for flakehell. Set + this to `'pipenv'` to invoke `'pipenv` `run` `flakehell'`. Set this to + `'poetry'` to invoke `'poetry` `run` `flakehell'`. Set this to `'python'` to + invoke `'python` `-m` `flakehell'`. + + +g:ale_python_flakehell_options *g:ale_python_flakehell_options* + *b:ale_python_flakehell_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the flakehell + lint invocation. + + +g:ale_python_flakehell_use_global *g:ale_python_flakehell_use_global* + *b:ale_python_flakehell_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable controls whether or not ALE will search for flakehell in a + virtualenv directory first. If this variable is set to `1`, then ALE will + always use |g:ale_python_flakehell_executable| for the executable path. + + Both variables can be set with `b:` buffer variables instead. + + +g:ale_python_flakehell_auto_pipenv *g:ale_python_flakehell_auto_pipenv* + *b:ale_python_flakehell_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_flakehell_auto_poetry *g:ale_python_flakehell_auto_poetry* + *b:ale_python_flakehell_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + =============================================================================== isort *ale-python-isort* @@ -190,6 +411,24 @@ g:ale_python_isort_use_global *g:ale_python_isort_use_global* See |ale-integrations-local-executables| +g:ale_python_isort_auto_pipenv *g:ale_python_isort_auto_pipenv* + *b:ale_python_isort_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_isort_auto_poetry *g:ale_python_isort_auto_poetry* + *b:ale_python_isort_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + =============================================================================== mypy *ale-python-mypy* @@ -200,6 +439,24 @@ to check for errors while you type. `mypy` will be run from a detected project root, per |ale-python-root|. +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. + + +g:ale_python_mypy_auto_poetry *g:ale_python_mypy_auto_poetry* + *b:ale_python_mypy_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + g:ale_python_mypy_executable *g:ale_python_mypy_executable* *b:ale_python_mypy_executable* Type: |String| @@ -208,6 +465,8 @@ g:ale_python_mypy_executable *g:ale_python_mypy_executable* See |ale-integrations-local-executables| Set this to `'pipenv'` to invoke `'pipenv` `run` `mypy'`. + Set this to `'poetry'` to invoke `'poetry` `run` `mypy'`. + g:ale_python_mypy_ignore_invalid_syntax *g:ale_python_mypy_ignore_invalid_syntax* @@ -229,6 +488,14 @@ g:ale_python_mypy_options *g:ale_python_mypy_options* invocation. +g:ale_python_mypy_show_notes *g:ale_python_mypy_show_notes* + *b:ale_python_mypy_show_notes* + Type: |Number| + Default: `1` + + If enabled, notes on lines will be displayed as 'I' (info) messages. + + g:ale_python_mypy_use_global *g:ale_python_mypy_use_global* *b:ale_python_mypy_use_global* Type: |Number| @@ -237,14 +504,6 @@ g:ale_python_mypy_use_global *g:ale_python_mypy_use_global* 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* @@ -257,6 +516,7 @@ g:ale_python_prospector_executable *g:ale_python_prospector_executable* See |ale-integrations-local-executables| Set this to `'pipenv'` to invoke `'pipenv` `run` `prospector'`. + Set this to `'poetry'` to invoke `'poetry` `run` `prospector'`. g:ale_python_prospector_options *g:ale_python_prospector_options* @@ -297,6 +557,15 @@ g:ale_python_prospector_auto_pipenv *g:ale_python_prospector_auto_pipenv* if true. This is overridden by a manually-set executable. +g:ale_python_prospector_auto_poetry *g:ale_python_prospector_auto_poetry* + *b:ale_python_prospector_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + =============================================================================== pycodestyle *ale-python-pycodestyle* @@ -309,6 +578,7 @@ g:ale_python_pycodestyle_executable *g:ale_python_pycodestyle_executable* See |ale-integrations-local-executables| Set this to `'pipenv'` to invoke `'pipenv` `run` `pycodestyle'`. + Set this to `'poetry'` to invoke `'poetry` `run` `pycodestyle'`. g:ale_python_pycodestyle_options *g:ale_python_pycodestyle_options* @@ -337,6 +607,15 @@ g:ale_python_pycodestyle_auto_pipenv *g:ale_python_pycodestyle_auto_pipenv* if true. This is overridden by a manually-set executable. +g:ale_python_pycodestyle_auto_poetry *g:ale_python_pycodestyle_auto_poetry* + *b:ale_python_pycodestyle_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + =============================================================================== pydocstyle *ale-python-pydocstyle* @@ -349,6 +628,7 @@ g:ale_python_pydocstyle_executable *g:ale_python_pydocstyle_executable* See |ale-integrations-local-executables| Set this to `'pipenv'` to invoke `'pipenv` `run` `pydocstyle'`. + Set this to `'poetry'` to invoke `'poetry` `run` `pydocstyle'`. g:ale_python_pydocstyle_options *g:ale_python_pydocstyle_options* @@ -377,6 +657,15 @@ g:ale_python_pydocstyle_auto_pipenv *g:ale_python_pydocstyle_auto_pipenv* if true. This is overridden by a manually-set executable. +g:ale_python_pydocstyle_auto_poetry *g:ale_python_pydocstyle_auto_poetry* + *b:ale_python_pydocstyle_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + =============================================================================== pyflakes *ale-python-pyflakes* @@ -389,6 +678,7 @@ g:ale_python_pyflakes_executable *g:ale_python_pyflakes_executable* See |ale-integrations-local-executables| Set this to `'pipenv'` to invoke `'pipenv` `run` `pyflakes'`. + Set this to `'poetry'` to invoke `'poetry` `run` `pyflakes'`. g:ale_python_pyflakes_auto_pipenv *g:ale_python_pyflakes_auto_pipenv* @@ -400,6 +690,79 @@ g:ale_python_pyflakes_auto_pipenv *g:ale_python_pyflakes_auto_pipenv* if true. This is overridden by a manually-set executable. +g:ale_python_pyflakes_auto_poetry *g:ale_python_pyflakes_auto_poetry* + *b:ale_python_pyflakes_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + 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'`. Set this to + `'poetry'` to invoke `'poetry` `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. + + +g:ale_python_pylama_auto_poetry *g:ale_python_pylama_auto_poetry* + *b:ale_python_pylama_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + =============================================================================== pylint *ale-python-pylint* @@ -408,10 +771,12 @@ g:ale_python_pylint_change_directory *g:ale_python_pylint_change_directory* Type: |Number| Default: `1` - If set to `1`, ALE will switch to the directory the Python file being - checked with `pylint` is in before checking it. This helps `pylint` find - configuration files more easily. This option can be turned off if you want - to control the directory Python is executed from yourself. + 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* @@ -422,6 +787,7 @@ g:ale_python_pylint_executable *g:ale_python_pylint_executable* See |ale-integrations-local-executables| Set this to `'pipenv'` to invoke `'pipenv` `run` `pylint'`. + Set this to `'poetry'` to invoke `'poetry` `run` `pylint'`. g:ale_python_pylint_options *g:ale_python_pylint_options* @@ -461,32 +827,51 @@ g:ale_python_pylint_auto_pipenv *g:ale_python_pylint_auto_pipenv* if true. This is overridden by a manually-set executable. +g:ale_python_pylint_auto_poetry *g:ale_python_pylint_auto_poetry* + *b:ale_python_pylint_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + 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* +pylsp *ale-python-pylsp* -`pyls` will be run from a detected project root, per |ale-python-root|. +`pylsp` 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* +g:ale_python_pylsp_executable *g:ale_python_pylsp_executable* + *b:ale_python_pylsp_executable* Type: |String| - Default: `'pyls'` + Default: `'pylsp'` See |ale-integrations-local-executables| - Set this to `'pipenv'` to invoke `'pipenv` `run` `pyls'`. + Set this to `'pipenv'` to invoke `'pipenv` `run` `pylsp'`. + Set this to `'poetry'` to invoke `'poetry` `run` `pyls'`. -g:ale_python_pyls_use_global *g:ale_python_pyls_use_global* - *b:ale_python_pyls_use_global* +g:ale_python_pylsp_use_global *g:ale_python_pylsp_use_global* + *b:ale_python_pylsp_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* +g:ale_python_pylsp_auto_pipenv *g:ale_python_pylsp_auto_pipenv* + *b:ale_python_pylsp_auto_pipenv* Type: |Number| Default: `0` @@ -494,15 +879,24 @@ g:ale_python_pyls_auto_pipenv *g:ale_python_pyls_auto_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* +g:ale_python_pylsp_auto_poetry *g:ale_python_pylsp_auto_poetry* + *b:ale_python_pylsp_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + +g:ale_python_pylsp_config *g:ale_python_pylsp_config* + *b:ale_python_pylsp_config* Type: |Dictionary| Default: `{}` - Dictionary with configuration settings for pyls. For example, to disable + Dictionary with configuration settings for pylsp. For example, to disable the pycodestyle linter: > { - \ 'pyls': { + \ 'pylsp': { \ 'plugins': { \ 'pycodestyle': { \ 'enabled': v:false @@ -512,6 +906,25 @@ g:ale_python_pyls_config *g:ale_python_pyls_config* \ } < +g:ale_python_pylsp_options *g:ale_python_pylsp_options* + *b:ale_python_pylsp_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the pylsp + invocation. Note that this is not the same thing as ale_python_pylsp_config, + which allows configuration of how pylsp functions; this is intended to + provide flexibility in how the pylsp command is invoked. + + For example, if you had installed `pylsp` but your `pylsp` executable was not + on your `PATH` for some reason, an alternative way to run the pylsp server + would be: + let g:ale_python_pylsp_executable = 'python3' + let g:ale_python_pylsp_options = '-m pylsp' + + An example stragety for installing `pylsp`: + `python3 -m pip install --user pylsp` + =============================================================================== pyre *ale-python-pyre* @@ -526,6 +939,7 @@ g:ale_python_pyre_executable *g:ale_python_pyre_executable* See |ale-integrations-local-executables| Set this to `'pipenv'` to invoke `'pipenv` `run` `pyre'`. + Set this to `'poetry'` to invoke `'poetry` `run` `pyre'`. g:ale_python_pyre_use_global *g:ale_python_pyre_use_global* @@ -545,6 +959,104 @@ g:ale_python_pyre_auto_pipenv *g:ale_python_pyre_auto_pipenv* if true. This is overridden by a manually-set executable. +g:ale_python_pyre_auto_poetry *g:ale_python_pyre_auto_poetry* + *b:ale_python_pyre_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +pyright *ale-python-pyright* + +The `pyright` linter requires a recent version of `pyright` which includes +the `pyright-langserver` executable. You can install `pyright` on your system +through `npm` with `sudo npm install -g pyright` or similar. + +Refer to their README for installation instructions: +https://github.com/Microsoft/pyright + +`pyright` needs to know the path to your Python executable and probably a +virtualenv to run. ALE will try to detect these automatically. +See |g:ale_python_pyright_config|. + + +g:ale_python_pyright_executable *g:ale_python_pyright_executable* + *b:ale_python_pyright_executable* + Type: |String| + Default: `'pyright-langserver'` + + The executable for running `pyright`, which is typically installed globally. + + +g:ale_python_pyright_config *g:ale_python_pyright_config* + *b:ale_python_pyright_config* + Type: |Dictionary| + Default: `{}` + + Settings for configuring the `pyright` language server. + + See pyright's documentation for a full list of options: + https://github.com/microsoft/pyright/blob/master/docs/settings.md + + ALE will automatically try to set defaults for `venvPath` and `pythonPath` + so your project can automatically be checked with the right libraries. + You can override these settings with whatever you want in your ftplugin + file like so: > + + let b:ale_python_pyright_config = { + \ 'python': { + \ 'pythonPath': '/bin/python', + \ 'venvPath': '/other/dir', + \ }, + \} +< + If `venvPath` is set, but `pythonPath` is not, + ALE will use `venvPath . '/bin/python'` or similar as `pythonPath`. + + A commonly used setting for `pyright` is disabling language services + apart from type checking and "hover" (|ale-hover|), you can set this + setting like so, or use whatever other settings you want: > + + let b:ale_python_pyright_config = { + \ 'pyright': { + \ 'disableLanguageServices': v:true, + \ }, + \} +< + +=============================================================================== +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* @@ -567,6 +1079,15 @@ g:ale_python_vulture_executable *g:ale_python_vulture_executable* 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| diff --git a/vim-config/plugins/ale/doc/ale-qml.txt b/vim-config/plugins/ale/doc/ale-qml.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-r.txt b/vim-config/plugins/ale/doc/ale-r.txt old mode 100755 new mode 100644 index f85f48fd..3fabf702 --- a/vim-config/plugins/ale/doc/ale-r.txt +++ b/vim-config/plugins/ale/doc/ale-r.txt @@ -2,6 +2,29 @@ ALE R Integration *ale-r-options* +=============================================================================== +languageserver *ale-r-languageserver* + +g:ale_r_languageserver_cmd *g:ale_r_languageserver_cmd* + *b:ale_r_languageserver_cmd* + Type: |String| + Default: `'languageserver::run()'` + + This option can be configured to change the execution command for + languageserver. + + See the languageserver documentation for more options. + + +g:ale_r_languageserver_config *g:ale_r_languageserver_config* + *b:ale_r_languageserver_config* + Type: |Dictionary| + Default: `{}` + + This option can be configured to change settings for languageserver. See the + languageserver documentation for more information. + + =============================================================================== lintr *ale-r-lintr* @@ -22,8 +45,24 @@ g:ale_r_lintr_lint_package *g:ale_r_lintr_lint_package* 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 + 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/vim-config/plugins/ale/doc/ale-reasonml.txt b/vim-config/plugins/ale/doc/ale-reasonml.txt old mode 100755 new mode 100644 index 426d4c46..b8729a55 --- a/vim-config/plugins/ale/doc/ale-reasonml.txt +++ b/vim-config/plugins/ale/doc/ale-reasonml.txt @@ -5,18 +5,19 @@ 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). +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 +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* @@ -25,6 +26,7 @@ g:ale_reason_ols_executable *g:ale_reason_ols_executable* 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| @@ -33,6 +35,24 @@ g:ale_reason_ols_use_global *g:ale_reason_ols_use_global* 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* @@ -43,6 +63,7 @@ g:ale_reasonml_refmt_executable *g:ale_reasonml_refmt_executable* 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| @@ -50,5 +71,6 @@ g:ale_reasonml_refmt_options *g:ale_reasonml_refmt_options* 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/vim-config/plugins/ale/doc/ale-restructuredtext.txt b/vim-config/plugins/ale/doc/ale-restructuredtext.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-robot.txt b/vim-config/plugins/ale/doc/ale-robot.txt new file mode 100644 index 00000000..405ae277 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-robot.txt @@ -0,0 +1,16 @@ +=============================================================================== +ALE Robot Integration *ale-robot-options* + + +=============================================================================== +rflint *ale-robot-rflint* + +g:ale_robot_rflint_executable *g:ale_robot_rflint_executable* + *b:ale_robot_rflint_executable* + Type: |String| + Default: `'rflint'` + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/vim-config/plugins/ale/doc/ale-ruby.txt b/vim-config/plugins/ale/doc/ale-ruby.txt old mode 100755 new mode 100644 index bf971e7c..69c643a9 --- a/vim-config/plugins/ale/doc/ale-ruby.txt +++ b/vim-config/plugins/ale/doc/ale-ruby.txt @@ -21,6 +21,31 @@ g:ale_ruby_brakeman_options *g:ale_ruby_brakeman_options* The contents of this variable will be passed through to brakeman. +=============================================================================== +debride *ale-ruby-debride* + +g:ale_ruby_debride_executable *g:ale_ruby_debride_executable* + *b:ale_ruby_debride_executable* + Type: String + Default: `'debride'` + + Override the invoked debride binary. Set this to `'bundle'` to invoke + `'bundle` `exec` debride'. + + +g:ale_ruby_debride_options *g:ale_ruby_debride_options* + *b:ale_ruby_debride_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to debride. + + +=============================================================================== +prettier *ale-ruby-prettier* + +See |ale-javascript-prettier| for information about the available options. + =============================================================================== rails_best_practices *ale-ruby-rails_best_practices* @@ -91,7 +116,15 @@ g:ale_ruby_rubocop_options *g:ale_ruby_rubocop_options* Type: |String| Default: `''` - This variable can be change to modify flags given to rubocop. + This variable can be changed to modify flags given to rubocop. + + +g:ale_ruby_rubocop_auto_correct_all *g:ale_ruby_rubocop_auto_correct_all* + *b:ale_ruby_rubocop_auto_correct_all* + Type: Number + Default: `0` + + This variable can be changed to make rubocop to correct all offenses (unsafe). =============================================================================== @@ -129,11 +162,41 @@ g:ale_ruby_solargraph_executable *g:ale_ruby_solargraph_executable* from binstubs or a bundle. +=============================================================================== +sorbet *ale-ruby-sorbet* + +g:ale_ruby_sorbet_executable *g:ale_ruby_sorbet_executable* + *b:ale_ruby_sorbet_executable* + Type: String + Default: `'srb'` + + Override the invoked sorbet binary. Set this to `'bundle'` to invoke + `'bundle` `exec` srb'. + + +g:ale_ruby_sorbet_options *g:ale_ruby_sorbet_options* + *b:ale_ruby_sorbet_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to sorbet. + + +g:ale_ruby_sorbet_enable_watchman *g:ale_ruby_sorbet_enable_watchman* + *b:ale_ruby_sorbet_enable_watchman* + Type: |Number| + Default: `0` + + Whether or not to use watchman to let the LSP server to know about changes + to files from outside of vim. Defaults to disable watchman because it + requires watchman to be installed separately from sorbet. + + =============================================================================== standardrb *ale-ruby-standardrb* -g:ale_ruby_standardrb_executable *g:ale_ruby_standardrb_executable* - *b:ale_ruby_standardrb_executable* +g:ale_ruby_standardrb_executable *g:ale_ruby_standardrb_executable* + *b:ale_ruby_standardrb_executable* Type: String Default: `'standardrb'` @@ -146,7 +209,7 @@ g:ale_ruby_standardrb_options *g:ale_ruby_standardrb_options* Type: |String| Default: `''` - This variable can be change to modify flags given to standardrb. + This variable can be changed to modify flags given to standardrb. =============================================================================== diff --git a/vim-config/plugins/ale/doc/ale-rust.txt b/vim-config/plugins/ale/doc/ale-rust.txt old mode 100755 new mode 100644 index 7510dfbd..3aa63673 --- a/vim-config/plugins/ale/doc/ale-rust.txt +++ b/vim-config/plugins/ale/doc/ale-rust.txt @@ -9,7 +9,7 @@ Integration Information 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: + Note that there are several possible linters and fixers 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 @@ -22,20 +22,45 @@ Integration Information 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 + requires Rust files to be contained in Cargo projects. + 4. analyzer -- If you have rust-analyzer installed, you might prefer using + this linter over cargo and rls. rust-analyzer also implements the + Language Server Protocol for incremental compilation of Rust code, and is + the next iteration of rls. rust-analyzer, like rls, requires Rust files + to be contained in Cargo projects. + 5. 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: > + Only cargo and rls are 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']} + let g:ale_linters = {'rust': ['rustc', 'rls']} < Also note that rustc 1.12. or later is needed. +=============================================================================== +analyzer *ale-rust-analyzer* + +g:ale_rust_analyzer_executable *g:ale_rust_analyzer_executable* + *b:ale_rust_analyzer_executable* + Type: |String| + Default: `'rust-analyzer'` + + This variable can be modified to change the executable path for + `rust-analyzer`. + + +g:ale_rust_analyzer_config *g:ale_rust_analyzer_config* + *b:ale_rust_analyzer_config* + Type: |Dictionary| + Default: `{}` + + Dictionary with configuration settings for rust-analyzer. + + =============================================================================== cargo *ale-rust-cargo* @@ -150,6 +175,18 @@ g:ale_rust_cargo_clippy_options only `cargo clippy` supports (e.g. `--deny`). +g:ale_rust_cargo_target_dir + *g:ale_rust_cargo_target_dir* + *b:ale_rust_cargo_target_dir* + + Type: |String| + Default: `''` + + Use a custom target directory when running the commands for ALE. This can + help to avoid "waiting for file lock on build directory" messages when + running `cargo` commands manually while ALE is performing its checks. + + =============================================================================== rls *ale-rust-rls* @@ -164,14 +201,32 @@ g:ale_rust_rls_executable *g:ale_rust_rls_executable* g:ale_rust_rls_toolchain *g:ale_rust_rls_toolchain* *b:ale_rust_rls_toolchain* Type: |String| - Default: `'nightly'` + Default: `''` This option can be set to change the toolchain used for `rls`. Possible - values include `'nightly'`, `'beta'`, and `'stable'`. + 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* @@ -198,23 +253,25 @@ g:ale_rust_ignore_error_codes *g:ale_rust_ignore_error_codes* > 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: > + When set to 1, instructs the Rust error reporting 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 + 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 + 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* diff --git a/vim-config/plugins/ale/doc/ale-salt.tmt b/vim-config/plugins/ale/doc/ale-salt.tmt new file mode 100644 index 00000000..ac500d37 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-salt.tmt @@ -0,0 +1,43 @@ +=============================================================================== +ALE SALT Integration *ale-salt-options* + +=============================================================================== +salt-lint *ale-salt-salt-lint* + +Website: https://github.com/warpnet/salt-lint + + +Installation +------------------------------------------------------------------------------- + +Install salt-lint in your a virtualenv directory, locally, or globally: > + + pip install salt-lint # After activating virtualenv + pip install --user salt-lint # Install to ~/.local/bin + sudo pip install salt-lint # Install globally + +See |g:ale_virtualenv_dir_names| for configuring how ALE searches for +virtualenv directories. + + +Options +------------------------------------------------------------------------------- + +g:ale_salt_salt-lint_executable *g:ale_salt_salt_lint_executable* + *b:ale_salt_salt_lint_executable* + Type: |String| + Default: `'salt-lint'` + + This variable can be set to change the path to salt-lint. + + +g:ale_salt_salt-lint_options *g:ale_salt_salt-lint_options* + *b:ale_salt_salt-lint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to salt-lint. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-sass.txt b/vim-config/plugins/ale/doc/ale-sass.txt old mode 100755 new mode 100644 index 735f44b2..22d7c472 --- a/vim-config/plugins/ale/doc/ale-sass.txt +++ b/vim-config/plugins/ale/doc/ale-sass.txt @@ -1,5 +1,5 @@ =============================================================================== -ALE SASS Integration *ale-sass-options* +ALE Sass Integration *ale-sass-options* =============================================================================== diff --git a/vim-config/plugins/ale/doc/ale-scala.txt b/vim-config/plugins/ale/doc/ale-scala.txt old mode 100755 new mode 100644 index ff43cd6c..c9638baf --- a/vim-config/plugins/ale/doc/ale-scala.txt +++ b/vim-config/plugins/ale/doc/ale-scala.txt @@ -2,6 +2,32 @@ ALE Scala Integration *ale-scala-options* +=============================================================================== +metals *ale-scala-metals* + +`metals` requires either an SBT project, a Mill project, or a running Bloop +server. + + +g:ale_scala_metals_executable *g:ale_scala_metals_executable* + *b:ale_scala_metals_executable* + Type: |String| + Default: `'metals-vim'` + + Override the invoked `metals` binary. + + +g:ale_scala_metals_project_root *g:ale_scala_metals_project_root* + *b:ale_scala_metals_project_root* + Type: |String| + Default: `''` + + By default the project root is found by searching upwards for `build.sbt`, + `build.sc`, `.bloop` or `.metals`. + If the project root is elsewhere, you can override the project root + directory. + + =============================================================================== sbtserver *ale-scala-sbtserver* diff --git a/vim-config/plugins/ale/doc/ale-scss.txt b/vim-config/plugins/ale/doc/ale-scss.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-sh.txt b/vim-config/plugins/ale/doc/ale-sh.txt old mode 100755 new mode 100644 index 7557e522..c06f737a --- a/vim-config/plugins/ale/doc/ale-sh.txt +++ b/vim-config/plugins/ale/doc/ale-sh.txt @@ -2,6 +2,29 @@ ALE Shell Integration *ale-sh-options* +=============================================================================== +bashate *ale-sh-bashate* + +g:ale_sh_bashate_executable *g:ale_sh_bashate_executable* + *b:ale_sh_bashate_executable* + Type: |String| + Default: `'bashate'` + + This variable sets executable used for bashate. + + +g:ale_sh_bashate_options *g:ale_sh_bashate_options* + *b:ale_sh_bashate_options* + Type: |String| + Default: `''` + + With this variable we are able to pass extra arguments for bashate. For + example to ignore the indentation rule: + +> + let g:ale_sh_bashate_options = '-i E003' +< + =============================================================================== sh-language-server *ale-sh-language-server* @@ -61,6 +84,30 @@ g:ale_sh_shellcheck_options *g:ale_sh_shellcheck_options* 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| diff --git a/vim-config/plugins/ale/doc/ale-sml.txt b/vim-config/plugins/ale/doc/ale-sml.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-solidity.txt b/vim-config/plugins/ale/doc/ale-solidity.txt old mode 100755 new mode 100644 index 4b74a27a..c4d2f02f --- a/vim-config/plugins/ale/doc/ale-solidity.txt +++ b/vim-config/plugins/ale/doc/ale-solidity.txt @@ -2,6 +2,24 @@ ALE Solidity Integration *ale-solidity-options* +=============================================================================== +solc *ale-solidity-solc* + +g:ale_solidity_solc_executable *g:ale_solidity_solc_executable* + *b:ale_solidity_solc_executable* + Type: |String| + Default: `'solc'` + + Override the invoked solc binary. For truffle/hardhat binaries. + +g:ale_solidity_solc_options *g:ale_solidity_solc_options* + *b:ale_solidity_solc_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to solc. + + =============================================================================== solhint *ale-solidity-solhint* @@ -21,4 +39,3 @@ solium *ale-solidity-solium* =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: - diff --git a/vim-config/plugins/ale/doc/ale-spec.txt b/vim-config/plugins/ale/doc/ale-spec.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-sql.txt b/vim-config/plugins/ale/doc/ale-sql.txt old mode 100755 new mode 100644 index 75d4b0cf..398e24d3 --- a/vim-config/plugins/ale/doc/ale-sql.txt +++ b/vim-config/plugins/ale/doc/ale-sql.txt @@ -2,6 +2,24 @@ 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* @@ -21,5 +39,23 @@ g:ale_sql_sqlfmt_options *g:ale_sql_sqlfmt_options* At this time only the -u flag is available to format with upper-case. +=============================================================================== +sqlformat *ale-sql-sqlformat* + +g:ale_sql_sqlformat_executable *g:ale_sql_sqlformat_executable* + *b:ale_sql_sqlformat_executable* + Type: |String| + Default: `'sqlformat'` + + This variable sets executable used for sqlformat. + +g:ale_sql_sqlformat_options *g:ale_sql_sqlformat_options* + *b:ale_sql_sqlformat_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the sqlformat fixer. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-stylus.txt b/vim-config/plugins/ale/doc/ale-stylus.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-sugarss.txt b/vim-config/plugins/ale/doc/ale-sugarss.txt new file mode 100644 index 00000000..8e991e54 --- /dev/null +++ b/vim-config/plugins/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/vim-config/plugins/ale/doc/ale-supported-languages-and-tools.txt b/vim-config/plugins/ale/doc/ale-supported-languages-and-tools.txt new file mode 100644 index 00000000..36ef83ea --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-supported-languages-and-tools.txt @@ -0,0 +1,610 @@ +*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 + * `ada_language_server` + * `gcc` + * `gnatpp` +* Ansible + * `ansible-lint`!! +* API Blueprint + * `drafter` +* APKBUILD + * `apkbuild-lint` + * `secfixes-check` +* AsciiDoc + * `alex`!! + * `languagetool`!! + * `proselint` + * `redpen` + * `textlint` + * `vale` + * `write-good` +* ASM + * `gcc` +* Awk + * `gawk` +* Bash + * `bashate` + * `language-server` + * `shell` (-n flag) + * `shellcheck` + * `shfmt` +* Bats + * `shellcheck` +* Bazel + * `buildifier` +* BibTeX + * `bibclean` +* Bourne Shell + * `shell` (-n flag) + * `shellcheck` + * `shfmt` +* C + * `astyle` + * `ccls` + * `clang` (`cc`) + * `clang-format` + * `clangd` + * `clangtidy`!! + * `cppcheck` + * `cpplint`!! + * `cquery` + * `flawfinder` + * `gcc` (`cc`) + * `uncrustify` +* C# + * `csc`!! + * `dotnet-format` + * `mcs` + * `mcsc`!! + * `uncrustify` +* C++ (filetype cpp) + * `astyle` + * `ccls` + * `clang` (`cc`) + * `clang-format` + * `clangcheck`!! + * `clangd` + * `clangtidy`!! + * `clazy`!! + * `cppcheck` + * `cpplint`!! + * `cquery` + * `flawfinder` + * `gcc` (`cc`) + * `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 + * `clangd` + * `nvcc`!! +* Cypher + * `cypher-lint` +* Cython (pyrex filetype) + * `cython` +* D + * `dfmt` + * `dls` + * `dmd` + * `uncrustify` +* Dafny + * `dafny`!! +* Dart + * `analysis_server` + * `dart-analyze`!! + * `dart-format`!! + * `dartanalyzer`!! + * `dartfmt`!! + * `language_server` +* desktop + * `desktop-file-validate` +* Dhall + * `dhall-format` + * `dhall-freeze` + * `dhall-lint` +* Dockerfile + * `dockerfile_lint` + * `hadolint` +* Elixir + * `credo` + * `dialyxir` + * `dogma`!! + * `elixir-ls` + * `mix`!! +* Elm + * `elm-format` + * `elm-ls` + * `elm-make` +* Erb + * `erb` + * `erblint` + * `erubi` + * `erubis` + * `ruumba` +* Erlang + * `SyntaxErl` + * `dialyzer`!! + * `elvis`!! + * `erlc` + * `erlfmt` +* Fish + * `fish` (-n flag) + * `fish_indent` +* Fortran + * `gcc` + * `language_server` +* Fountain + * `proselint` +* FusionScript + * `fusion-lint` +* Git Commit Messages + * `gitlint` +* GLSL + * `glslang` + * `glslls` +* Go + * `bingo` + * `go build`!! + * `go mod`!! + * `go vet`!! + * `gofmt` + * `goimports` + * `golangci-lint`!! + * `golangserver` + * `golines` + * `golint` + * `gometalinter`!! + * `gopls` + * `gosimple`!! + * `gotype`!! + * `revive`!! + * `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` + * `hindent` + * `hlint` + * `hls` + * `ormolu` + * `stack-build`!! + * `stack-ghc` + * `stylish-haskell` +* HCL + * `terraform-fmt` +* HTML + * `alex`!! + * `angular` + * `fecs` + * `html-beautify` + * `htmlhint` + * `prettier` + * `proselint` + * `tidy` + * `write-good` +* Idris + * `idris` +* Ink + * `ink-language-server` +* Inko + * `inko` !! +* ISPC + * `ispc`!! +* Java + * `PMD` + * `checkstyle`!! + * `eclipselsp` + * `google-java-format` + * `javac` + * `javalsp` + * `uncrustify` +* JavaScript + * `deno` + * `eslint` + * `fecs` + * `flow` + * `jscs` + * `jshint` + * `prettier` + * `prettier-eslint` + * `prettier-standard` + * `standard` + * `tsserver` + * `xo` +* JSON + * `eslint` + * `fixjson` + * `jq` + * `jsonlint` + * `prettier` + * `spectral` +* JSON5 + * `eslint` +* JSONC + * `eslint` +* Jsonnet + * `jsonnet-lint` + * `jsonnetfmt` +* 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 + * `lua-format` + * `luac` + * `luacheck` + * `luafmt` + * `stylua` +* Mail + * `alex`!! + * `languagetool`!! + * `proselint` + * `vale` +* Make + * `checkmake` +* Markdown + * `alex`!! + * `languagetool`!! + * `markdownlint`!! + * `mdl` + * `pandoc` + * `prettier` + * `proselint` + * `redpen` + * `remark-lint` + * `textlint` + * `vale` + * `write-good` +* MATLAB + * `mlint` +* Mercury + * `mmc`!! +* NASM + * `nasm`!! +* Nim + * `nim check`!! + * `nimlsp` + * `nimpretty` +* nix + * `nix-instantiate` + * `nixfmt` + * `nixpkgs-fmt` + * `rnix-lsp` +* nroff + * `alex`!! + * `proselint` + * `write-good` +* Objective-C + * `ccls` + * `clang` + * `clangd` + * `uncrustify` +* Objective-C++ + * `clang` + * `clangd` + * `uncrustify` +* OCaml + * `merlin` (see |ale-ocaml-merlin|) + * `ocamlformat` + * `ocamllsp` + * `ocp-indent` + * `ols` +* OpenApi + * `ibm_validator` + * `prettier` + * `yamllint` +* Pascal + * `ptop` +* Pawn + * `uncrustify` +* Perl + * `perl -c` + * `perl-critic` + * `perltidy` +* Perl6 + * `perl6 -c` +* PHP + * `intelephense` + * `langserver` + * `phan` + * `php -l` + * `php-cs-fixer` + * `phpcbf` + * `phpcs` + * `phpmd` + * `phpstan` + * `psalm`!! + * `tlint` +* PO + * `alex`!! + * `msgfmt` + * `proselint` + * `write-good` +* Pod + * `alex`!! + * `proselint` + * `write-good` +* Pony + * `ponyc` +* PowerShell + * `powershell` + * `psscriptanalyzer` +* Prolog + * `swipl` +* proto + * `protoc-gen-lint`!! + * `protolint`!! +* Pug + * `pug-lint` +* Puppet + * `languageserver` + * `puppet` + * `puppet-lint` +* PureScript + * `purescript-language-server` + * `purs-tidy` + * `purty` +* Python + * `autoflake`!! + * `autoimport` + * `autopep8` + * `bandit` + * `black` + * `flake8` + * `flakehell` + * `isort` + * `mypy` + * `prospector`!! + * `pycodestyle` + * `pydocstyle` + * `pyflakes` + * `pylama`!! + * `pylint`!! + * `pylsp` + * `pyre` + * `pyright` + * `reorder-python-imports` + * `vulture`!! + * `yapf` +* QML + * `qmlfmt` + * `qmllint` +* R + * `languageserver` + * `lintr` + * `styler` +* Racket + * `racket-langserver` + * `raco` +* Re:VIEW + * `redpen` +* ReasonML + * `merlin` + * `ols` + * `reason-language-server` + * `refmt` +* reStructuredText + * `alex`!! + * `proselint` + * `redpen` + * `rstcheck` + * `textlint` + * `vale` + * `write-good` +* Robot + * `rflint` +* RPM spec + * `rpmlint` +* Ruby + * `brakeman`!! + * `debride` + * `prettier` + * `rails_best_practices`!! + * `reek` + * `rubocop` + * `ruby` + * `rufo` + * `solargraph` + * `sorbet` + * `standardrb` +* Rust + * `cargo`!! + * `rls` + * `rust-analyzer` + * `rustc` (see |ale-integration-rust|) + * `rustfmt` +* Salt + * `salt-lint` +* Sass + * `sass-lint` + * `stylelint` +* Scala + * `fsc` + * `metals` + * `sbtserver` + * `scalac` + * `scalafmt` + * `scalastyle` +* SCSS + * `prettier` + * `sass-lint` + * `scss-lint` + * `stylelint` +* Slim + * `slim-lint` +* SML + * `smlnj` +* Solidity + * `solc` + * `solhint` + * `solium` +* SQL + * `pgformatter` + * `sql-lint` + * `sqlfmt` + * `sqlformat` + * `sqlint` +* Stylus + * `stylelint` +* SugarSS + * `stylelint` +* Svelte + * `prettier` + * `svelteserver` +* Swift + * Apple `swift-format` + * `sourcekit-lsp` + * `swiftformat` + * `swiftlint` +* systemd + * `systemd-analyze`!! +* Tcl + * `nagelfar`!! +* Terraform + * `terraform` + * `terraform-fmt-fixer` + * `terraform-ls` + * `terraform-lsp` + * `tflint` +* Texinfo + * `alex`!! + * `proselint` + * `write-good` +* Text^ + * `alex`!! + * `languagetool`!! + * `proselint` + * `redpen` + * `textlint` + * `vale` + * `write-good` +* Thrift + * `thrift` + * `thriftcheck` +* TypeScript + * `deno` + * `eslint` + * `fecs` + * `prettier` + * `standard` + * `tslint` + * `tsserver` + * `typecheck` +* V + * `v`!! + * `vfmt` +* VALA + * `uncrustify` + * `vala_lint`!! +* Verilog + * `hdl-checker` + * `iverilog` + * `verilator` + * `vlog` + * `xvlog` + * `yosys`!! +* VHDL + * `ghdl` + * `vcom` + * `xvhdl` +* Vim + * `vimls` + * `vint` +* Vim help^ + * `alex`!! + * `proselint` + * `write-good` +* Vue + * `prettier` + * `vls` +* XHTML + * `alex`!! + * `proselint` + * `write-good` +* XML + * `xmllint` +* YAML + * `circleci`!! + * `prettier` + * `spectral` + * `swaglint` + * `yamlfix` + * `yamllint` +* YANG + * `yang-lsp` +* Zeek + * `zeek`!! +* Zig + * `zls` + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-svelte.txt b/vim-config/plugins/ale/doc/ale-svelte.txt new file mode 100644 index 00000000..92f109f7 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-svelte.txt @@ -0,0 +1,31 @@ +=============================================================================== +ALE Svelte Integration *ale-svelte-options* + + +=============================================================================== +prettier *ale-svelte-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +svelteserver *ale-svelte-svelteserver* + +g:ale_svelte_svelteserver_executable *g:ale_svelte_svelteserver_executable* + *b:ale_svelte_svelteserver_executable* + Type: |String| + Default: `'svelteserver'` + + See |ale-integrations-local-executables| + + +g:ale_svelte_svelteserver_use_global *g:ale_svelte_svelteserver_use_global* + *b:ale_svelte_svelteserver_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/vim-config/plugins/ale/doc/ale-swift.txt b/vim-config/plugins/ale/doc/ale-swift.txt new file mode 100644 index 00000000..6d53ca7c --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-swift.txt @@ -0,0 +1,60 @@ +=============================================================================== +ALE Swift Integration *ale-swift-options* + + +=============================================================================== +apple-swift-format *ale-swift-apple-swift-format* + +There are 3 options to enable linting and fixing with Apple's swift-format: + +1. Install the local executable in your path, as described here: + https://github.com/apple/swift-format +2. Install the executable via your OS package manager, for instance via + Homebrew with `brew install swift-format` +3. Your Swift project has a dependency on the swift-format package, so it can + be run with `swift run swift-format lint ...` In this case, you need to set + a variable, see |g:ale_swift_appleswiftformat_use_swiftpm|. + +Additionally, ALE tries to locate and use the nearest existing `.swift-format` +configuration file. + + +g:ale_swift_appleswiftformat_executable *g:ale_swift_appleswiftformat_executable* + *b:ale_swift_appleswiftformat_executable* + Type: |String| + Default: `'swift-format'` + + This variable can be modified to change the executable path for + `swift-format`. + + +g:ale_swift_appleswiftformat_use_swiftpm *g:ale_swift_appleswiftformat_use_swiftpm* + *b:ale_swift_appleswiftformat_use_swiftpm* + Type: |Number| + Default: `0` + + When set to `1`, this option will cause ALE to use + `swift run swift-format lint ...` instead of the global executable. Use this + option if your Swift project has a dependency on the swift-format package. + + See |ale-integrations-local-executables| + + +=============================================================================== +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/vim-config/plugins/ale/doc/ale-systemd.txt b/vim-config/plugins/ale/doc/ale-systemd.txt new file mode 100644 index 00000000..13c7037f --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-systemd.txt @@ -0,0 +1,14 @@ +=============================================================================== +ALE systemd Integration *ale-systemd-options* + + +=============================================================================== +systemd-analyze *ale-systemd-analyze* + +ALE supports checking user systemd units with `systemd-analyze --user verify` +Checks will only work with user unit files in their proper location. There +aren't any options, and checks can only run after saving the file. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-tcl.txt b/vim-config/plugins/ale/doc/ale-tcl.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-terraform.txt b/vim-config/plugins/ale/doc/ale-terraform.txt old mode 100755 new mode 100644 index 49a55028..175bdf5c --- a/vim-config/plugins/ale/doc/ale-terraform.txt +++ b/vim-config/plugins/ale/doc/ale-terraform.txt @@ -3,7 +3,7 @@ ALE Terraform Integration *ale-terraform-options* =============================================================================== -fmt *ale-terraform-fmt* +terraform-fmt-fixer *ale-terraform-fmt-fixer* g:ale_terraform_fmt_executable *g:ale_terraform_fmt_executable* *b:ale_terraform_fmt_executable* @@ -20,6 +20,59 @@ g:ale_terraform_fmt_options *g:ale_terraform_fmt_options* 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. + + +=============================================================================== +terraform-ls *ale-terraform-terraform-ls* + +Official terraform language server. More stable than *terraform-lsp* but +currently has less features. + +g:ale_terraform_ls_executable *g:ale_terraform_ls_executable* + *b:ale_terraform_ls_executable* + Type: |String| + Default: `'terraform-ls'` + + This variable can be changed to use a different executable for terraform-ls. + + +g:ale_terraform_ls_options *g:ale_terraform_ls_options* + *b:ale_terraform_ls_options* + Type: |String| + Default: `''` + + This variable can be changed to pass custom CLI flags to terraform-ls. + + +=============================================================================== +terraform-lsp *ale-terraform-terraform-lsp* + +g:ale_terraform_langserver_executable *g:ale_terraform_langserver_executable* + *b:ale_terraform_langserver_executable* + Type: |String| + Default: `'terraform-lsp'` + + This variable can be changed to use a different executable for terraform-lsp. + + +g:ale_terraform_langserver_options *g:ale_terraform_langserver_options* + *b:ale_terraform_langserver_options* + Type: |String| + Default: `''` + + This variable can be changed to pass custom CLI flags to terraform-lsp. + + =============================================================================== tflint *ale-terraform-tflint* diff --git a/vim-config/plugins/ale/doc/ale-tex.txt b/vim-config/plugins/ale/doc/ale-tex.txt old mode 100755 new mode 100644 index 24aa3112..ceb9fa81 --- a/vim-config/plugins/ale/doc/ale-tex.txt +++ b/vim-config/plugins/ale/doc/ale-tex.txt @@ -32,5 +32,46 @@ g:ale_lacheck_executable *g:ale_lacheck_executable* 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/vim-config/plugins/ale/doc/ale-texinfo.txt b/vim-config/plugins/ale/doc/ale-texinfo.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-text.txt b/vim-config/plugins/ale/doc/ale-text.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-thrift.txt b/vim-config/plugins/ale/doc/ale-thrift.txt old mode 100755 new mode 100644 index bb2ec058..810127b4 --- a/vim-config/plugins/ale/doc/ale-thrift.txt +++ b/vim-config/plugins/ale/doc/ale-thrift.txt @@ -42,5 +42,24 @@ g:ale_thrift_thrift_options *g:ale_thrift_thrift_options* This variable can be changed to customize the additional command-line arguments that are passed to the thrift compiler. +=============================================================================== +thriftcheck *ale-thrift-thriftcheck* + +g:ale_thrift_thriftcheck_executable *g:ale_thrift_thriftcheck_executable* + *b:ale_thrift_thriftcheck_executable* + Type: |String| + Default: `'thriftcheck'` + + See |ale-integrations-local-executables| + + +g:ale_thrift_thriftcheck_options *g:ale_thrift_thriftcheck_options* + *b:ale_thrift_thriftcheck_options* + Type: |String| + Default: `''` + + This variable can be changed to customize the additional command-line + arguments that are passed to thriftcheck. + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-typescript.txt b/vim-config/plugins/ale/doc/ale-typescript.txt old mode 100755 new mode 100644 index 7dc59820..8984e183 --- a/vim-config/plugins/ale/doc/ale-typescript.txt +++ b/vim-config/plugins/ale/doc/ale-typescript.txt @@ -2,6 +2,45 @@ ALE TypeScript Integration *ale-typescript-options* +=============================================================================== +deno *ale-typescript-deno* + +Starting from version 1.6.0, Deno comes with its own language server. Earlier +versions are not supported. + +g:ale_deno_executable *g:ale_deno_executable* + *b:ale_deno_executable* + Type: |String| + Default: `'deno'` + + +g:ale_deno_lsp_project_root *g:ale_deno_lsp_project_root* + *b:ale_deno_lsp_project_root* + Type: |String| + Default: `''` + + If this variable is left unset, ALE will try to find the project root by + executing the following steps in the given order: + + 1. Find an ancestor directory containing a tsconfig.json. + 2. Find an ancestory directory containing a .git folder. + 3. Use the directory of the current buffer (if the buffer was opened from + a file). + +g:ale_deno_unstable *g:ale_deno_unstable* + *b:ale_deno_unstable* + Type: |Number| + Default: `0` + + Enable or disable unstable Deno features and APIs. + +g:ale_deno_importMap *g:ale_deno_importMap* + *b:ale_deno_importMap* + Type: |String| + Default: `'import_map.json'` + + Specify the import map filename to load url maps in a deno project. + =============================================================================== eslint *ale-typescript-eslint* @@ -16,6 +55,33 @@ prettier *ale-typescript-prettier* See |ale-javascript-prettier| for information about the available options. +=============================================================================== +standard *ale-typescript-standard* + +g:ale_typescript_standard_executable *g:ale_typescript_standard_executable* + *b:ale_typescript_standard_executable* + Type: |String| + Default: `'standard'` + + See |ale-integrations-local-executables| + + +g:ale_typescript_standard_options *g:ale_typescript_standard_options* + *b:ale_typescript_standard_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to standard. + + +g:ale_typescript_standard_use_global *g:ale_typescript_standard_use_global* + *b:ale_typescript_standard_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== tslint *ale-typescript-tslint* @@ -111,5 +177,32 @@ g:ale_typescript_tsserver_use_global *g:ale_typescript_tsserver_use_global* tsserver in node_modules. +=============================================================================== +xo *ale-typescript-xo* + +g:ale_typescript_xo_executable *g:ale_typescript_xo_executable* + *b:ale_typescript_xo_executable* + Type: |String| + Default: `'xo'` + + See |ale-integrations-local-executables| + + +g:ale_typescript_xo_options *g:ale_typescript_xo_options* + *b:ale_typescript_xo_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to xo. + + +g:ale_typescript_xo_use_global *g:ale_typescript_xo_use_global* + *b:ale_typescript_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/vim-config/plugins/ale/doc/ale-v.txt b/vim-config/plugins/ale/doc/ale-v.txt new file mode 100644 index 00000000..8c641447 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-v.txt @@ -0,0 +1,45 @@ +=============================================================================== +ALE V Integration *ale-v-options* + + +=============================================================================== +Integration Information + +`v` is V's build tool. `vfmt` (called as `v fmt` from the same +executable that does the builds) is the autoformatter/fixer. + +g:ale_v_v_executable *g:ale_v_v_executable* + *b:ale_v_v_executable* + + Type: |String| + Default: `'v'` + + The executable that will be run for the `v` linter and the `vfmt` fixer. + + +=============================================================================== +v *ale-v-v* + +g:ale_v_v_options *g:ale_v_v_options* + *b:ale_v_v_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the v linter. + They are injected directly after "v .". + + +=============================================================================== +vfmt *ale-v-vfmt* + +g:ale_v_vfmt_options *g:ale_v_vfmt_options* + *b:ale_v_vfmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the vfmt fixer. + They are injected directly after "v fmt". + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-vala.txt b/vim-config/plugins/ale/doc/ale-vala.txt old mode 100755 new mode 100644 index ca24bcf4..d48f68bb --- a/vim-config/plugins/ale/doc/ale-vala.txt +++ b/vim-config/plugins/ale/doc/ale-vala.txt @@ -8,5 +8,26 @@ uncrustify *ale-vala-uncrustify* See |ale-c-uncrustify| for information about the available options. +=============================================================================== +Vala-Lint *ale-vala-vala-lint* + +g:vala_vala_lint_executable *g:vala_vala_lint_executable* + *b:vala_vala_lint_executable* + Type: |String| + Default: `'io.elementary.vala-lint'` + + This variable can be set to specify a Vala-Lint executable file. + + +g:vala_vala_lint_config_filename *g:vala_vala_lint_config_filename* + *b:vala_vala_lint_config_filename* + Type: |String| + Default: `'vala-lint.conf'` + + This variable can be set to specify a Vala-Lint config filename. When a file + with the specified name was not found or this variable was set to empty, + Vala-Lint will be executed without specifying a config filename. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-verilog.txt b/vim-config/plugins/ale/doc/ale-verilog.txt old mode 100755 new mode 100644 index 2b8ce5e2..11e988bb --- a/vim-config/plugins/ale/doc/ale-verilog.txt +++ b/vim-config/plugins/ale/doc/ale-verilog.txt @@ -3,7 +3,10 @@ ALE Verilog/SystemVerilog Integration *ale-verilog-options* =============================================================================== -ALE can use two different linters for Verilog HDL: +ALE can use six different linters for Verilog HDL: + + HDL Checker + Using `hdl_checker --lsp` iverilog: Using `iverilog -t null -Wall` @@ -11,6 +14,15 @@ ALE can use two different linters for Verilog HDL: verilator Using `verilator --lint-only -Wall` + ModelSim/Questa + Using `vlog -quiet -lint` + + Vivado + Using `xvlog` + + Yosys + Using `ysoys -Q -T -p 'read_verilog'` + By default, both 'verilog' and 'systemverilog' filetypes are checked. You can limit 'systemverilog' files to be checked using only 'verilator' by @@ -20,6 +32,33 @@ defining 'g:ale_linters' variable: \ let g:ale_linters = {'systemverilog' : ['verilator'],} < +=============================================================================== +General notes + +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. + +HDL Checker is an alternative for some of the issues described above. It wraps +around ghdl, Vivado and ModelSim/Questa and, when using the latter, it can +handle mixed language (VHDL, Verilog, SystemVerilog) designs. + +=============================================================================== +hdl-checker *ale-verilog-hdl-checker* + +See |ale-vhdl-hdl-checker| + + =============================================================================== iverilog *ale-verilog-iverilog* @@ -39,5 +78,65 @@ g:ale_verilog_verilator_options *g:ale_verilog_verilator_options* 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'. + + +=============================================================================== +yosys *ale-verilog-yosys* + +g:ale_verilog_yosys_executable *g:ale_verilog_yosys_executable* + *b:ale_verilog_yosys_executable* + Type: |String| + Default: `'yosys'` + + This variable can be changed to the path to the 'yosys' executable. + + +g:ale_verilog_yosys_options *g:ale_verilog_yosys_options* + *b:ale_verilog_yosys_options* + Type: |String| + Default: `'-Q -T -p ''read_verilog %s'''` + + This variable can be changed to modify the flags/options passed to 'yosys'. + By default, Yosys is an interative program. To obtain linting functionality, + the `'read_verilog'` command is used. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale-vhdl.txt b/vim-config/plugins/ale/doc/ale-vhdl.txt new file mode 100644 index 00000000..c2870240 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-vhdl.txt @@ -0,0 +1,157 @@ +=============================================================================== +ALE VHDL Integration *ale-vhdl-options* + + +=============================================================================== +ALE can use four different linters for VHDL: + + ghdl: + Using `ghdl --std=08` + + ModelSim/Questa + Using `vcom -2008 -quiet -lint` + + Vivado + Using `xvhdl --2008` + + HDL Checker + Using `hdl_checker --lsp` + +=============================================================================== +General notes + +ghdl, ModelSim/Questa and Vivado 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. + +HDL Checker is an alternative for some of the issues described above. It wraps +around ghdl, Vivado and ModelSim/Questa and, when using the latter, it can +handle mixed language (VHDL, Verilog, SystemVerilog) designs. + +=============================================================================== +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'. + + +=============================================================================== +hdl-checker *ale-vhdl-hdl-checker* + +HDL Checker is a wrapper for VHDL/Verilg/SystemVerilog tools that aims to +reduce the boilerplate code needed to set things up. It can automatically +infer libraries for VHDL sources, determine the compilation order and provide +some static checks. + +You can install it using pip: +> + $ pip install hdl-checker + +`hdl-checker` will be run from a detected project root, determined by the +following methods, in order: + +1. Find the first directory containing a configuration file (see + |g:ale_hdl_checker_config_file|) +2. If no configuration file can be found, find the first directory containing + a folder named `'.git' +3. If no such folder is found, use the directory of the current buffer + + +g:ale_hdl_checker_executable + *g:ale_hdl_checker_executable* + *b:ale_hdl_checker_executable* + Type: |String| + Default: `'hdl_checker'` + + This variable can be changed to the path to the 'hdl_checker' executable. + + +g:ale_hdl_checker_options *g:ale_hdl_checker_options* + *b:ale_hdl_checker_options* + Type: |String| + Default: `''` + + This variable can be changed to modify the flags/options passed to the + 'hdl_checker' server startup command. + + +g:ale_hdl_checker_config_file *g:ale_hdl_checker_config_file* + *b:ale_hdl_checker_config_file* + Type: |String| + Default: `'.hdl_checker.config'` (Unix), + `'_hdl_checker.config'` (Windows) + + This variable can be changed to modify the config file HDL Checker will try + to look for. It will also affect how the project's root directory is + determined (see |ale-vhdl-hdl-checker|). + + More info on the configuration file format can be found at: + https://github.com/suoto/hdl_checker/wiki/Setting-up-a-project + + +=============================================================================== +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/vim-config/plugins/ale/doc/ale-vim-help.txt b/vim-config/plugins/ale/doc/ale-vim-help.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-vim.txt b/vim-config/plugins/ale/doc/ale-vim.txt old mode 100755 new mode 100644 index 772bad23..f85b43eb --- a/vim-config/plugins/ale/doc/ale-vim.txt +++ b/vim-config/plugins/ale/doc/ale-vim.txt @@ -2,6 +2,61 @@ ALE Vim Integration *ale-vim-options* +=============================================================================== +vimls *ale-vim-vimls* + + The `vim-language-server` is the engine that powers VimL editor support + using the Language Server Protocol. See the installation instructions: + https://github.com/iamcco/vim-language-server#install + +g:ale_vim_vimls_executable *g:ale_vim_vimls_executable* + *b:ale_vim_vimls_executable* + Type: |String| + Default: `'vim-language-server'` + + This option can be set to change the executable path for vimls. + + +g:ale_vim_vimls_config *g:ale_vim_vimls_config* + *b:ale_vim_vimls_config* + Type: |Dictionary| + Default: `{}` + + Dictionary containing configuration settings that will be passed to the + language server. For example: > + { + \ 'vim': { + \ 'iskeyword': '@,48-57,_,192-255,-#', + \ 'vimruntime': '', + \ 'runtimepath': '', + \ 'diagnostic': { + \ 'enable': v:true + \ }, + \ 'indexes': { + \ 'runtimepath': v:true, + \ 'gap': 100, + \ 'count': 3, + \ 'projectRootPatterns' : ['.git', 'autoload', 'plugin'] + \ }, + \ 'suggest': { + \ 'fromVimruntime': v:true, + \ 'fromRuntimepath': v:false + \ }, + \ } + \} +< + Consult the vim-language-server documentation for more information about + settings. + + +g:ale_vim_vimls_use_global *g:ale_vim_vimls_use_global* + *b:ale_vim_vimls_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== vint *ale-vim-vint* diff --git a/vim-config/plugins/ale/doc/ale-vue.txt b/vim-config/plugins/ale/doc/ale-vue.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-xhtml.txt b/vim-config/plugins/ale/doc/ale-xhtml.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-xml.txt b/vim-config/plugins/ale/doc/ale-xml.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-yaml.txt b/vim-config/plugins/ale/doc/ale-yaml.txt old mode 100755 new mode 100644 index c9a12ea1..65e0d069 --- a/vim-config/plugins/ale/doc/ale-yaml.txt +++ b/vim-config/plugins/ale/doc/ale-yaml.txt @@ -1,6 +1,28 @@ =============================================================================== ALE YAML Integration *ale-yaml-options* + +=============================================================================== +circleci *ale-yaml-circleci* + +Website: https://circleci.com/docs/2.0/local-cli + + +Installation +------------------------------------------------------------------------------- + +Follow the instructions on the website, and make sure to test that you can +validate configuration files with: > + + circleci config validate - < .circleci/config.yml +< + +As long as the validator runs correctly, you should be able to see errors when +you save the configuration file. The validator doesn't run as you type because +it sends network requests, and running too often would overload the circleci +servers. + + =============================================================================== prettier *ale-yaml-prettier* @@ -15,7 +37,40 @@ Install prettier either globally or locally: > npm install prettier -g # global npm install prettier # local < - + +=============================================================================== +spectral *ale-yaml-spectral* + +Website: https://github.com/stoplightio/spectral + + +Installation +------------------------------------------------------------------------------- + +Install spectral either globally or locally: > + + npm install @stoplight/spectral -g # global + npm install @stoplight/spectral # local +< + +Options +------------------------------------------------------------------------------- + +g:ale_yaml_spectral_executable *g:ale_yaml_spectral_executable* + *b:ale_yaml_spectral_executable* + Type: |String| + Default: `'spectral'` + + This variable can be set to change the path to spectral. + +g:ale_yaml_spectral_use_global *g:ale_yaml_spectral_use_global* + *b:ale_yaml_spectral_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== swaglint *ale-yaml-swaglint* @@ -50,6 +105,45 @@ g:ale_yaml_swaglint_use_global *g:ale_yaml_swaglint_use_global* See |ale-integrations-local-executables| +=============================================================================== +yamlfix *ale-yaml-yamlfix* + +Website: https://lyz-code.github.io/yamlfix + + +Installation +------------------------------------------------------------------------------- + +Install yamlfix: > + + pip install yamlfix +< + +Options +------------------------------------------------------------------------------- +g:ale_yaml_yamlfix_executable *g:ale_yaml_yamlfix_executable* + *b:ale_yaml_yamlfix_executable* + Type: |String| + Default: `'yamlfix'` + + See |ale-integrations-local-executables| + + +g:ale_yaml_yamlfix_options *g:ale_yaml_yamlfix_options* + *b:ale_yaml_yamlfix_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to yamlfix. + +g:ale_yaml_yamlfix_use_global *g:ale_yaml_yamlfix_use_global* + *b:ale_yaml_yamlfix_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== yamllint *ale-yaml-yamllint* diff --git a/vim-config/plugins/ale/doc/ale-yang.txt b/vim-config/plugins/ale/doc/ale-yang.txt old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/doc/ale-zeek.txt b/vim-config/plugins/ale/doc/ale-zeek.txt new file mode 100644 index 00000000..910bc060 --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-zeek.txt @@ -0,0 +1,23 @@ +=============================================================================== +ALE Zeek Integration *ale-zeek-options* + *ale-integration-zeek* + +=============================================================================== +Integration Information + + Currently, the only supported linter for Zeek is zeek. + +=============================================================================== +zeek *ale-zeek-zeek* + +g:ale_zeek_zeek_executable *g:ale_zeek_zeek_executable* + *b:ale_zeek_zeek_executable* + Type: |String| + Default: `'zeek'` + + This variable can be modified to change the executable path for `zeek`. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/vim-config/plugins/ale/doc/ale-zig.txt b/vim-config/plugins/ale/doc/ale-zig.txt new file mode 100644 index 00000000..70a53bbb --- /dev/null +++ b/vim-config/plugins/ale/doc/ale-zig.txt @@ -0,0 +1,33 @@ +=============================================================================== +ALE Zig Integration *ale-zig-options* + *ale-integration-zig* + +=============================================================================== +Integration Information + + Currently, the only supported linter for zig is zls. + +=============================================================================== +zls *ale-zig-zls* + +g:ale_zig_zls_executable *g:ale_zig_zls_executable* + *b:ale_zig_zls_executable* + Type: |String| + Default: `'zls'` + + This variable can be modified to change the executable path for `zls`. + + +g:ale_zig_zls_config *g:ale_zig_zls_config* + *b:ale_zig_zls_config* + Type: |Dictionary| + Default: `{}` + + WARNING: As of writing, zls does not support receiving configuration + from the client. This variable is a PLACEHOLDER until it does. + + Dictionary with configuration settings for zls. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/vim-config/plugins/ale/doc/ale.txt b/vim-config/plugins/ale/doc/ale.txt old mode 100755 new mode 100644 index ac71ab83..6cc81784 --- a/vim-config/plugins/ale/doc/ale.txt +++ b/vim-config/plugins/ale/doc/ale.txt @@ -1,4 +1,4 @@ -*ale.txt* For Vim version 8.0. +*ale.txt* Plugin to lint and fix files asynchronously *ale* ALE - Asynchronous Lint Engine @@ -9,7 +9,9 @@ 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| + 3.1 Linting On Other Machines.........|ale-lint-other-machines| + 3.2 Adding Language Servers...........|ale-lint-language-servers| + 3.3 Other Sources.....................|ale-lint-other-sources| 4. Fixing Problems......................|ale-fix| 5. Language Server Protocol Support.....|ale-lsp| 5.1 Completion........................|ale-completion| @@ -18,352 +20,14 @@ CONTENTS *ale-contents* 5.4 Find References...................|ale-find-references| 5.5 Hovering..........................|ale-hover| 5.6 Symbol Search.....................|ale-symbol-search| + 5.7 Refactoring: Rename, Actions......|ale-refactor| 6. Global Options.......................|ale-options| 6.1 Highlights........................|ale-highlights| - 6.2 Options for write-good Linter.....|ale-write-good-options| - 7. Integration Documentation............|ale-integrations| - 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| - foodcritic..........................|ale-chef-foodcritic| - clojure...............................|ale-clojure-options| - joker...............................|ale-clojure-joker| - cloudformation........................|ale-cloudformation-options| - cfn-python-lint.....................|ale-cloudformation-cfn-python-lint| - cmake.................................|ale-cmake-options| - cmakelint...........................|ale-cmake-cmakelint| - 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| - prettier............................|ale-css-prettier| - stylelint...........................|ale-css-stylelint| - cuda..................................|ale-cuda-options| - nvcc................................|ale-cuda-nvcc| - 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| - elm...................................|ale-elm-options| - elm-format..........................|ale-elm-elm-format| - elm-make............................|ale-elm-elm-make| - erlang................................|ale-erlang-options| - 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| - gobuild.............................|ale-go-gobuild| - gofmt...............................|ale-go-gofmt| - golint..............................|ale-go-golint| - govet...............................|ale-go-govet| - gometalinter........................|ale-go-gometalinter| - staticcheck.........................|ale-go-staticcheck| - golangserver........................|ale-go-golangserver| - golangci-lint.......................|ale-go-golangci-lint| - bingo...............................|ale-go-bingo| - 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| - 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| - stylish-haskell.....................|ale-haskell-stylish-haskell| - hie.................................|ale-haskell-hie| - hcl...................................|ale-hcl-options| - terraform-fmt.......................|ale-hcl-terraform-fmt| - html..................................|ale-html-options| - 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| - uncrustify..........................|ale-java-uncrustify| - javascript............................|ale-javascript-options| - eslint..............................|ale-javascript-eslint| - 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| - 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| - 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| - 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| - 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| - pylint..............................|ale-python-pylint| - pyls................................|ale-python-pyls| - pyre................................|ale-python-pyre| - vulture.............................|ale-python-vulture| - yapf................................|ale-python-yapf| - qml...................................|ale-qml-options| - qmlfmt..............................|ale-qml-qmlfmt| - r.....................................|ale-r-options| - lintr...............................|ale-r-lintr| - reasonml..............................|ale-reasonml-options| - merlin..............................|ale-reasonml-merlin| - ols.................................|ale-reasonml-ols| - 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| - sqlfmt..............................|ale-sql-sqlfmt| - stylus................................|ale-stylus-options| - stylelint...........................|ale-stylus-stylelint| - tcl...................................|ale-tcl-options| - nagelfar............................|ale-tcl-nagelfar| - terraform.............................|ale-terraform-options| - fmt.................................|ale-terraform-fmt| - tflint..............................|ale-terraform-tflint| - tex...................................|ale-tex-options| - chktex..............................|ale-tex-chktex| - lacheck.............................|ale-tex-lacheck| - 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| - 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| + 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| @@ -399,125 +63,8 @@ developer documentation. See |ale-development| =============================================================================== 2. Supported Languages & Tools *ale-support* -The following languages and tools are supported. - -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` -* ASM: `gcc` -* Ansible: `ansible-lint` -* API Blueprint: `drafter` -* AsciiDoc: `alex`!!, `proselint`, `redpen`, `write-good`, `vale`, `textlint` -* Awk: `gawk` -* Bash: `language-server`, `shell` (-n flag), `shellcheck`, `shfmt` -* BibTeX: `bibclean` -* Bourne Shell: `shell` (-n flag), `shellcheck`, `shfmt` -* C: `cppcheck`, `cpplint`!!, `clang`, `clangd`, `clangtidy`!!, `clang-format`, `cquery`, `flawfinder`, `gcc`, `uncrustify`, `ccls` -* C++ (filetype cpp): `clang`, `clangd`, `clangcheck`!!, `clangtidy`!!, `clang-format`, `clazy`!!, `cppcheck`, `cpplint`!!, `cquery`, `flawfinder`, `gcc`, `uncrustify`, `ccls` -* CUDA: `nvcc`!! -* C#: `mcs`, `mcsc`!!, `uncrustify` -* Chef: `foodcritic` -* Clojure: `joker` -* CloudFormation: `cfn-python-lint` -* CMake: `cmakelint` -* CoffeeScript: `coffee`, `coffeelint` -* Crystal: `crystal`!! -* CSS: `csslint`, `prettier`, `stylelint` -* Cucumber: `cucumber` -* Cython (pyrex filetype): `cython` -* D: `dls`, `dmd`, `uncrustify` -* Dafny: `dafny`!! -* Dart: `dartanalyzer`!!, `language_server`, dartfmt!! -* Dockerfile: `dockerfile_lint`, `hadolint` -* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!!, `elixir-ls` -* Elm: `elm-format, 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: `gofmt`, `goimports`, `go mod`!!, `go vet`!!, `golint`, `gotype`!!, `gometalinter`!!, `go build`!!, `gosimple`!!, `staticcheck`!!, `golangserver`, `golangci-lint`!!, `bingo` -* GraphQL: `eslint`, `gqlint`, `prettier` -* Hack: `hack`, `hackfmt`, `hhast` -* Haml: `haml-lint` -* Handlebars: `ember-template-lint` -* Haskell: `brittany`, `ghc`, `cabal-ghc`, `stylish-haskell`, `stack-ghc`, `stack-build`!!, `ghc-mod`, `hlint`, `hdevtools`, `hfmt`, `hie` -* HCL: `terraform-fmt` -* HTML: `alex`!!, `HTMLHint`, `proselint`, `tidy`, `prettier`, `write-good` -* Idris: `idris` -* ISPC: `ispc`!! -* Java: `checkstyle`, `javac`, `google-java-format`, `PMD`, `javalsp`, `uncrustify` -* JavaScript: `eslint`, `flow`, `jscs`, `jshint`, `prettier`, `prettier-eslint`, `prettier-standard`, `standard`, `xo` -* JSON: `fixjson`, `jsonlint`, `jq`, `prettier` -* Julia: `languageserver` -* Kotlin: `kotlinc`!!, `ktlint`!!, `languageserver` -* LaTeX (tex): `alex`!!, `chktex`, `lacheck`, `proselint`, `redpen`, `vale`, `write-good` -* Less: `lessc`, `prettier`, `stylelint` -* LLVM: `llc` -* Lua: `luac`, `luacheck` -* Mail: `alex`!!, `proselint`, `vale` -* Make: `checkmake` -* Markdown: `alex`!!, `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: `clang`, `clangd`, `uncrustify`, `ccls` -* Objective-C++: `clang`, `clangd`, `uncrustify` -* OCaml: `merlin` (see |ale-ocaml-merlin|), `ols`, `ocamlformat` -* Pawn: `uncrustify` -* Perl: `perl -c`, `perl-critic`, `perltidy` -* Perl6: `perl6 -c` -* PHP: `langserver`, `phan`, `php -l`, `phpcs`, `phpmd`, `phpstan`, `phpcbf`, `php-cs-fixer`, `psalm`!! -* PO: `alex`!!, `msgfmt`, `proselint`, `write-good` -* Pod: `alex`!!, `proselint`, `write-good` -* Pony: `ponyc` -* Prolog: `swipl` -* proto: `protoc-gen-lint` -* Pug: `pug-lint` -* Puppet: `languageserver`, `puppet`, `puppet-lint` -* Python: `autopep8`, `black`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pydocstyle`, `pyls`, `pyre`, `pylint`!!, `vulture`!!, `yapf` -* QML: `qmlfmt`, `qmllint` -* R: `lintr` -* Racket: `raco` -* ReasonML: `merlin`, `ols`, `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` -* SCSS: `prettier`, `sass-lint`, `scss-lint`, `stylelint` -* Scala: `fsc`, `sbtserver`, `scalac`, `scalafmt`, `scalastyle` -* Slim: `slim-lint` -* SML: `smlnj` -* Solidity: `solhint`, `solium` -* Stylus: `stylelint` -* SQL: `sqlint`, `sqlfmt` -* Swift: `swiftlint`, `swiftformat` -* Tcl: `nagelfar`!! -* Terraform: `fmt`, `tflint` -* Texinfo: `alex`!!, `proselint`, `write-good` -* Text^: `alex`!!, `proselint`, `redpen`, `textlint`, `vale`, `write-good` -* Thrift: `thrift` -* TypeScript: `eslint`, `prettier`, `tslint`, `tsserver`, `typecheck` -* VALA: `uncrustify` -* Verilog: `iverilog`, `verilator` -* 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` +ALE supports a wide variety of languages and tools. See |ale-supported-list| +for the full list. =============================================================================== 3. Linting *ale-lint* @@ -540,7 +87,7 @@ 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. (off by default) - |g:ale_lint_on_insert_leave| +* 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| @@ -582,7 +129,7 @@ their relevant options. * 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 +ways of tweaking the behavior 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:|), @@ -598,10 +145,112 @@ 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| +You can stop ALE any currently running linters with the |ALELintStop| command. +Any existing problems will be kept. ------------------------------------------------------------------------------- -3.1 Other Sources *ale-lint-other-sources* +3.1 Linting On Other Machines *ale-lint-other-machines* + +ALE offers support for running linters or fixers on files you are editing +locally on other machines, so long as the other machine has access to the file +you are editing. This could be a linter or fixer run inside of a Docker image, +running in a virtual machine, running on a remote server, etc. + +In order to run tools on other machines, you will need to configure your tools +to run via scripts that execute commands on those machines, such as by setting +the ALE `_executable` options for those tools to a path for a script to run, +or by using |g:ale_command_wrapper| to specify a script to wrap all commands +that are run by ALE, before they are executed. For tools that ALE runs where +ALE looks for locally installed executables first, you may need to set the +`_use_global` options for those tools to `1`, or you can set +|g:ale_use_global_executables| to `1` before ALE is loaded to only use global +executables for all tools. + +In order for ALE to properly lint or fix files which are running on another +file system, you must provide ALE with |List|s of strings for mapping paths to +and from your local file system and the remote file system, such as the file +system of your Docker container. See |g:ale_filename_mappings| for all of the +different ways these filename mappings can be configured. + +For example, you might configure `pylint` to run via Docker by creating a +script like so. > + + #!/usr/bin/env bash + + exec docker run -i --rm -v "$(pwd):/data" cytopia/pylint "$@" +< + +You will run to run Docker commands with `-i` in order to read from stdin. + +With the above script in mind, you might configure ALE to lint your Python +project with `pylint` by providing the path to the script to execute, and +mappings which describe how to between the two file systems in your +`python.vim` |ftplugin| file, like so: > + + if expand('%:p') =~# '^/home/w0rp/git/test-pylint/' + let b:ale_linters = ['pylint'] + let b:ale_python_pylint_use_global = 1 + " This is the path to the script above. + let b:ale_python_pylint_executable = '/home/w0rp/git/test-pylint/pylint.sh' + " /data matches the path in Docker. + let b:ale_filename_mappings = { + \ 'pylint': [ + \ ['/home/w0rp/git/test-pylint', '/data'], + \ ], + \} + endif +< + +You might consider using a Vim plugin for loading Vim configuration files +specific to each project, if you have a lot of projects to manage. + + +------------------------------------------------------------------------------- +3.2 Adding Language Servers *ale-lint-language-servers* + +ALE comes with many default configurations for language servers, so they can +be detected and run automatically. ALE can connect to other language servers +by defining a new linter for a filetype. New linters can be defined in |vimrc|, +in plugin files, or `ale_linters` directories in |runtimepath|. + +See |ale-linter-loading-behavior| for more information on loading linters. + +A minimal configuration for a language server linter might look so. > + + call ale#linter#Define('filetype_here', { + \ 'name': 'any_name_you_want', + \ 'lsp': 'stdio', + \ 'executable': '/path/to/executable', + \ 'command': '%e run', + \ 'project_root': '/path/to/root_of_project', + \}) +< +For language servers that use a TCP or named pipe socket connection, you +should define the address to connect to instead. > + + call ale#linter#Define('filetype_here', { + \ 'name': 'any_name_you_want', + \ 'lsp': 'socket', + \ 'address': 'servername:1234', + \ 'project_root': '/path/to/root_of_project', + \}) +< + Most of the options for a language server can be replaced with a |Funcref| + for a function accepting a buffer number for dynamically computing values + such as the executable path, the project path, the server address, etc, + most of which can also be determined based on executing some other + asynchronous task. See |ale#command#Run()| for computing linter options + based on asynchronous results. + + See |ale#linter#Define()| for a detailed explanation of all of the options + for configuring linters. + + +------------------------------------------------------------------------------- +3.3 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 @@ -658,7 +307,7 @@ A plugin might integrate its own checks with ALE like so: > function! WorkDone(buffer, results) abort " Send results to ALE after they have been collected. - call ale#other_source#ShowResults(buffer, 'some-name', a:results) + call ale#other_source#ShowResults(a:buffer, 'some-name', a:results) endfunction < @@ -680,14 +329,10 @@ The values for `g:ale_fixers` can be a list of |String|, |Funcref|, or for a function set in the ALE fixer registry. Each function for fixing errors must accept either one argument `(buffer)` or -three arguments `(buffer, done, lines)`, representing the buffer being fixed, -a function to call with results, 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 `v:true` -for indicating that results will be provided asynchronously via the `done` -callback. - -NOTE: The `done` function has not been implemented yet. +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 @@ -697,12 +342,20 @@ the buffers being checked. When a |Dictionary| is returned for an |ALEFix| callback, the following keys are supported for running the commands. + `cwd` An optional |String| for setting the working directory + for the command. + + If not set, or `v:null`, the `cwd` of the last command + that spawn this one will be used. + `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. + See |ale-command-format-strings| for formatting options. + `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 @@ -717,26 +370,6 @@ are supported for running the commands. A |List| of |String|s must be returned. - `chain_with` An optional key for defining a callback to call next. - - The callback must accept two or three arguments, - `(buffer, output)` or `(buffer, output, input)` . - Functions receiving a variable number of arguments will - only receive the first two values. The `output` argument - will contain the lines of output from the command run. - The `input` argument is the List of lines for the - buffer, after applying any previous fixers. - - The callback must return the same values returned for - any fixer function. This allows fixer functions to be - chained recursively. - - When the command string returned for a fixer is an empty - string, the next command in the chain will still be run. - This allows commands to be skipped, like version checks - that are cached. An empty List will be passed to the - next callback in the chain for the `output`. - `read_buffer` An optional key for disabling reading the buffer. When set to `0`, ALE will not pipe the buffer's data @@ -744,10 +377,7 @@ are supported for running the commands. the buffer is not read when `read_temporary_file` is `1`. - This option defaults to `0` when `chain_with` is defined - as anything other than `v:null`, and defaults to `1` - otherwise. This is so earlier commands in a chain - do not receive the buffer's data by default. + This option defaults to `1`. *ale-fix-configuration* @@ -792,6 +422,13 @@ 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|. + +Fixers can be run on another machines, just like linters, such as fixers run +from a Docker container, running in a virtual machine, running a remote +server, etc. See |ale-lint-other-machines|. + =============================================================================== 5. Language Server Protocol Support *ale-lsp* @@ -801,81 +438,197 @@ 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. -ALE supports the following LSP/tsserver features: - -1. Diagnostics/linting - Enabled via selecting linters as usual. -2. Completion -3. Go to definition - +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 limited support for automatic completion of code while you type. +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. -Suggestions will be made while you type after completion is enabled. -Completion 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|. ALE will only suggest so many -possible matches for completion. The maximum number of items can be controlled -with |g:ale_completion_max_suggestions|. + *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-asyncomplete-integration* + +ALE additionally integrates with asyncomplete.vim for offering automatic +completion data. ALE's asyncomplete source requires registration and should +use the defaults provided by the |asyncomplete#sources#ale#get_source_options| function > + + " Use ALE's function for asyncomplete defaults + au User asyncomplete_setup call asyncomplete#register_source(asyncomplete#sources#ale#get_source_options({ + \ 'priority': 10, " Provide your own overrides here + \ })) +> +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 automatic completion will not work when 'paste' is active. Only set +'paste' when you are copy and pasting text into your buffers. + +ALE automatic completion will interfere with default insert completion with +`CTRL-N` and so on (|compl-vim|). You can write your own keybinds and a +function in your |vimrc| file to force insert completion instead, like so: > + + function! SmartInsertCompletion() abort + " Use the default CTRL-N in completion menus + if pumvisible() + return "\" + endif + + " Exit and re-enter insert mode, and use insert completion + return "\a\" + endfunction + + inoremap =SmartInsertCompletion() +< +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-completion-fallback* + +You can write your own completion function and fallback on other methods of +completion by checking if there are no results that ALE can determine. For +example, for Python code, you could fall back on the `python3complete` +function. > + + function! TestCompletionFunc(findstart, base) abort + let l:result = ale#completion#OmniFunc(a:findstart, a:base) + + " Check if ALE couldn't find anything. + if (a:findstart && l:result is -3) + \|| (!a:findstart && empty(l:result)) + " Defer to another omnifunc if ALE couldn't find anything. + return python3complete#Complete(a:findstart, a:base) + endif + + return l:result + endfunction + + set omnifunc=TestCompletionFunc +< +See |complete-functions| for documentation on how to write completion +functions. + +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`. +even when |g:ale_completion_enabled| is set to `0`. For manually requesting +completion information with Deoplete, consult Deoplete's documentation. + +ALE by can support automatic imports from external modules. This behavior can +be enabled by setting the |g:ale_completion_autoimport| variable to `1`. + +You can manually request imports for symbols at the cursor with the +|ALEImport| command. The word at the cursor must be an exact match for some +potential completion result which includes additional text to insert into the +current buffer, which ALE will assume is code for an import line. This command +can be useful when your code already contains something you need to import. + +You can execute other commands whenever ALE inserts some completion text with +the |ALECompletePost| event. - *ale-completion-completopt-bug* +When working with TypeScript files, ALE can remove warnings from your +completions by setting the |g:ale_completion_tsserver_remove_warnings| +variable to 1. -ALE implements completion as you type by temporarily adjusting |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. > + *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 < +Or alternatively, if you want to show documentation in popups: > + set completeopt=menu,menuone,popup,noselect,noinsert +< + *ale-symbols* + +ALE provides a set of basic completion symbols. If you want to replace those +symbols with others, you can set the variable |g:ale_completion_symbols| with +a mapping of the type of completion to the symbol or other string that you +would like to use. An example here shows the available options for symbols > + + let g:ale_completion_symbols = { + \ 'text': '', + \ 'method': '', + \ 'function': '', + \ 'constructor': '', + \ 'field': '', + \ 'variable': '', + \ 'class': '', + \ 'interface': '', + \ 'module': '', + \ 'property': '', + \ 'unit': 'unit', + \ 'value': 'val', + \ 'enum': '', + \ 'keyword': 'keyword', + \ 'snippet': '', + \ 'color': 'color', + \ 'file': '', + \ 'reference': 'ref', + \ 'folder': '', + \ 'enum member': '', + \ 'constant': '', + \ 'struct': '', + \ 'event': 'event', + \ 'operator': '', + \ 'type_parameter': 'type param', + \ '': 'v' + \ } +< ------------------------------------------------------------------------------- 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: +information returned by LSP servers. The |ALEGoToDefinition| command will jump +to the definition of symbols under the cursor. See the documentation for the +command for configuring how the location will be displayed. -|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. - +on the information returned by LSP servers. The |ALEGoToTypeDefinition| +command will jump to the definition of symbols under the cursor. See the +documentation for the command for configuring how the location will be +displayed. ------------------------------------------------------------------------------- 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. - +ALE supports finding references for symbols though any enabled LSP linters +with the |ALEFindReferences| command. See the documentation for the command +for a full list of options. ------------------------------------------------------------------------------- 5.5 Hovering *ale-hover* @@ -885,12 +638,23 @@ at the cursor taken from LSP linters. The following commands are supported: |ALEHover| - Print information about the symbol at the cursor. +Truncated information will be displayed when the cursor rests on a symbol by +default, as long as there are no problems on the same line. You can disable +this behavior by setting |g:ale_hover_cursor| to `0`. + 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. +Hover information can be displayed in the preview window instead by setting +|g:ale_hover_to_preview| to `1`. + +When using Neovim or Vim with |popupwin|, if |g:ale_hover_to_floating_preview| +or |g:ale_floating_preview| is set to 1, the hover information will show in a +floating window. And |g:ale_floating_window_border| for the border setting. + 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 @@ -911,12 +675,38 @@ Documentation for symbols at the cursor can be retrieved using the ------------------------------------------------------------------------------- 5.6 Symbol Search *ale-symbol-search* -ALE supports searching for workspace symbols via LSP linters. The following -commands are supported: +ALE supports searching for workspace symbols via LSP linters with the +|ALESymbolSearch| command. See the documentation for the command +for a full list of options. + +------------------------------------------------------------------------------- +5.7 Refactoring: Rename, Actions *ale-refactor* + +ALE supports renaming symbols in code such as variables or class names with +the |ALERename| command. + +|ALECodeAction| will execute actions on the cursor or applied to a visual +range selection, such as automatically fixing errors. -|ALESymbolSearch| - Search for symbols in the workspace. +Actions will appear in the right click mouse menu by default for GUI versions +of Vim, unless disabled by setting |g:ale_popup_menu_enabled| to `0`. +Make sure to set your Vim to move the cursor position whenever you right +click, and enable the mouse menu: > + set mouse=a + set mousemodel=popup_setpos +< +You may wish to remove some other menu items you don't want to see: > + + silent! aunmenu PopUp.Select\ Word + silent! aunmenu PopUp.Select\ Sentence + silent! aunmenu PopUp.Select\ Paragraph + silent! aunmenu PopUp.Select\ Line + silent! aunmenu PopUp.Select\ Block + silent! aunmenu PopUp.Select\ Blockwise + silent! aunmenu PopUp.Select\ All +< =============================================================================== 6. Global Options *ale-options* @@ -1022,6 +812,7 @@ g:ale_completion_delay *g:ale_completion_delay* g:ale_completion_enabled *g:ale_completion_enabled* + *b:ale_completion_enabled* Type: |Number| Default: `0` @@ -1031,9 +822,40 @@ g:ale_completion_enabled *g:ale_completion_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. + + ALE automatic completion will not work when 'paste' is active. Only set + 'paste' when you are copy and pasting text into your buffers. + + 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_tsserver_remove_warnings* +g:ale_completion_tsserver_remove_warnings + + Type: Number + Default: `0` + + When this option is set to `0`, ALE will return all completion items, + including those that are a warning. Warnings can be excluded from completed + items by setting it to `1`. + + +g:ale_completion_autoimport *g:ale_completion_autoimport* + + Type: Number + Default: `0` + + When this option is set to `0`, ALE will not try to automatically import + completion results from external modules. It can be enabled by setting it + to `1`. + + g:ale_completion_excluded_words *g:ale_completion_excluded_words* *b:ale_completion_excluded_words* Type: |List| @@ -1052,6 +874,47 @@ g:ale_completion_excluded_words *g:ale_completion_excluded_words* let b:ale_completion_excluded_words = ['it', 'describe'] < +g:ale_completion_symbols *g:ale_completion_symbols* + + Type: |Dictionary| + + + A mapping from completion types to symbols for completions. See + |ale-symbols| for more information. + + By default, this mapping only uses built in Vim completion kinds, but it can + be updated to use any unicode character for the completion kind. For + example: > + let g:ale_completion_symbols = { + \ 'text': '', + \ 'method': '', + \ 'function': '', + \ 'constructor': '', + \ 'field': '', + \ 'variable': '', + \ 'class': '', + \ 'interface': '', + \ 'module': '', + \ 'property': '', + \ 'unit': 'v', + \ 'value': 'v', + \ 'enum': 't', + \ 'keyword': 'v', + \ 'snippet': 'v', + \ 'color': 'v', + \ 'file': 'v', + \ 'reference': 'v', + \ 'folder': 'v', + \ 'enum_member': 'm', + \ 'constant': 'm', + \ 'struct': 't', + \ 'event': 'v', + \ 'operator': 'f', + \ 'type_parameter': 'p', + \ '': 'v' + \ }) +< + g:ale_completion_max_suggestions *g:ale_completion_max_suggestions* Type: |Number| @@ -1090,6 +953,37 @@ g:ale_cursor_detail *g:ale_cursor_detail* loaded for messages to be displayed. See |ale-lint-settings-on-startup|. +g:ale_default_navigation *g:ale_default_navigation* + *b:ale_default_navigation* + + Type: |String| + Default: `'buffer'` + + The default method for navigating away from the current buffer to another + buffer, such as for |ALEFindReferences|, or |ALEGoToDefinition|. + + +g:ale_detail_to_floating_preview *g:ale_detail_to_floating_preview* + *b:ale_detail_to_floating_preview* + Type: |Number| + Default: `0` + + When this option is set to `1`, Neovim or Vim with |popupwin| will use a + floating window for ALEDetail output. + + +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| @@ -1130,7 +1024,7 @@ g:ale_echo_msg_error_str *g:ale_echo_msg_error_str* g:ale_echo_msg_format *g:ale_echo_msg_format* -b:ale_echo_msg_format *b:ale_echo_msg_format* + *b:ale_echo_msg_format* Type: |String| Default: `'%code: %%s'` @@ -1141,7 +1035,7 @@ b:ale_echo_msg_format *b:ale_echo_msg_format* `%s` - replaced with the text for the problem `%...code...% `- replaced with the error code `%linter%` - replaced with the name of the linter - `%severity%` - replaced withe severity of the problem + `%severity%` - replaced with the severity of the problem The strings for `%severity%` can be configured with the following options. @@ -1158,7 +1052,7 @@ b:ale_echo_msg_format *b:ale_echo_msg_format* |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 differnt languages. (Say in ftplugin + so different formats can be used for different languages. (Say in ftplugin files.) @@ -1170,6 +1064,15 @@ g:ale_echo_msg_info_str *g:ale_echo_msg_info_str* The string used for `%severity%` for info. See |g:ale_echo_msg_format| +g:ale_echo_msg_log_str *g:ale_echo_msg_log_str* + + Type: |String| + Default: `'Log'` + + The string used for `%severity%` for log, used only for handling LSP show + message requests. See |g:ale_lsp_show_message_format| + + g:ale_echo_msg_warning_str *g:ale_echo_msg_warning_str* Type: |String| @@ -1199,6 +1102,21 @@ g:ale_enabled *g:ale_enabled* See |g:ale_pattern_options| for more information on that option. +g:ale_exclude_highlights *g:ale_exclude_highlights* + *b:ale_exclude_highlights* + + Type: |List| + Default: `[]` + + A list of regular expressions for matching against highlight messages to + remove. For example: > + + " Do not highlight messages matching strings like these. + let b:ale_exclude_highlights = ['line too long', 'foo.*bar'] +< + See also: |g:ale_set_highlights| + + g:ale_fixers *g:ale_fixers* *b:ale_fixers* @@ -1222,7 +1140,7 @@ g:ale_fixers *g:ale_fixers* < g:ale_fix_on_save *g:ale_fix_on_save* -b:ale_fix_on_save *b:ale_fix_on_save* + *b:ale_fix_on_save* Type: |Number| Default: `0` @@ -1239,6 +1157,67 @@ b:ale_fix_on_save *b:ale_fix_on_save* 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* + + 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_floating_preview *g:ale_floating_preview* + + Type: |Number| + Default: `0` + + When set to `1`, Neovim or Vim with |popupwin| will use a floating window + for ale's preview window. + This is equivalent to setting |g:ale_hover_to_floating_preview| and + |g:ale_detail_to_floating_preview| to `1`. + + +g:ale_floating_window_border *g:ale_floating_window_border* + + Type: |List| + Default: `['|', '-', '+', '+', '+', '+']` + + When set to `[]`, window borders are disabled. The elements in the list set + the horizontal, top, top-left, top-right, bottom-right and bottom-left + border characters, respectively. + + If the terminal supports Unicode, you might try setting the value to + ` ['│', '─', '╭', '╮', '╯', '╰']`, to make it look nicer. + g:ale_history_enabled *g:ale_history_enabled* @@ -1270,6 +1249,43 @@ g:ale_history_log_output *g:ale_history_log_output* if you want to save on some memory usage. +g:ale_hover_cursor *g:ale_hover_cursor* + + Type: |Number| + Default: `1` + + If set to `1`, ALE will show truncated information in the echo line about + the symbol at the cursor automatically when the |CursorHold| event is fired. + The delay before requesting hover information is based on 'updatetime', as + with all |CursorHold| events. + + If there's a problem on the line where the cursor is resting, ALE will not + show any hover information. + + See |ale-hover| for more information on hover information. + + 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_hover_to_preview *g:ale_hover_to_preview* + *b:ale_hover_to_preview* + Type: |Number| + Default: `0` + + If set to `1`, hover messages will be displayed in the preview window, + instead of in balloons or the message line. + + +g:ale_hover_to_floating_preview *g:ale_hover_to_floating_preview* + *b:ale_hover_to_floating_preview* + Type: |Number| + Default: `0` + + If set to `1`, Neovim or Vim with |popupwin| will use floating windows for + hover messages. + + g:ale_keep_list_window_open *g:ale_keep_list_window_open* *b:ale_keep_list_window_open* Type: |Number| @@ -1297,7 +1313,7 @@ g:ale_list_window_size *g:ale_list_window_size* g:ale_lint_delay *g:ale_lint_delay* - + *b:ale_lint_delay* Type: |Number| Default: `200` @@ -1305,6 +1321,9 @@ g:ale_lint_delay *g:ale_lint_delay* 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`. + A buffer-local option, `b:ale_lint_delay`, can be set to change the delay + for different buffers, such as in |ftplugin| files. + g:ale_lint_on_enter *g:ale_lint_on_enter* @@ -1352,7 +1371,7 @@ g:ale_lint_on_save *g:ale_lint_on_save* g:ale_lint_on_text_changed *g:ale_lint_on_text_changed* Type: |String| - Default: `'always'` + Default: `'normal'` This option controls how ALE will check your files as you make changes. The following values can be used. @@ -1377,9 +1396,10 @@ g:ale_lint_on_text_changed *g:ale_lint_on_text_changed* g:ale_lint_on_insert_leave *g:ale_lint_on_insert_leave* + *b:ale_lint_on_insert_leave* Type: |Number| - Default: `0` + Default: `1` When set to `1` in your vimrc file, this option will cause ALE to run linters when you leave insert mode. @@ -1391,6 +1411,10 @@ g:ale_lint_on_insert_leave *g:ale_lint_on_insert_leave* " 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|. @@ -1410,11 +1434,19 @@ g:ale_linter_aliases *g:ale_linter_aliases* { \ 'Dockerfile': 'dockerfile', \ 'csh': 'sh', + \ 'javascriptreact': ['javascript', 'jsx'], \ 'plaintex': 'tex', + \ 'ps1': 'powershell', + \ 'rmarkdown': 'r', + \ 'rmd': 'r', + \ 'svelte': ['svelte', 'javascript'], \ 'systemverilog': 'verilog', + \ 'typescriptreact': ['typescript', 'tsx'], \ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], \ 'vimwiki': 'markdown', \ 'vue': ['vue', 'javascript'], + \ 'xsd': ['xsd', 'xml'], + \ 'xslt': ['xslt', 'xml'], \ 'zsh': 'sh', \} < @@ -1450,6 +1482,90 @@ g:ale_linter_aliases *g:ale_linter_aliases* < No linters will be loaded when the buffer's filetype is empty. + +g:ale_filename_mappings *g:ale_filename_mappings* + *b:ale_filename_mappings* + + Type: |Dictionary| or |List| + Default: `{}` + + Either a |Dictionary| mapping a linter or fixer name, as displayed in + |:ALEInfo|, to a |List| of two-item |List|s for filename mappings, or just a + |List| of two-item |List|s. When given some paths to files, the value of + this setting will be used to convert filenames on a local file system to + filenames on some remote file system, such as paths in a Docker image, + virtual machine, or network drive. + + For example: > + + let g:ale_filename_mappings = { + \ 'pylint': [ + \ ['/home/john/proj', '/data'], + \ ], + \} +< + With the above configuration, a filename such as `/home/john/proj/foo.py` + will be provided to the linter/fixer as `/data/foo.py`, and paths parsed + from linter results such as `/data/foo.py` will be converted back to + `/home/john/proj/foo.py`. + + You can use `*` as to apply a |List| of filename mappings to all other + linters or fixers not otherwise matched. > + + " Use one List of paths for pylint. + " Use another List of paths for everything else. + let g:ale_filename_mappings = { + \ 'pylint': [ + \ ['/home/john/proj', '/data'], + \ ], + \ '*': [ + \ ['/home/john/proj', '/other-data'], + \ ], + \} +< + If you just want every single linter or fixer to use the same filename + mapping, you can just use a |List|. > + + " Same as above, but for ALL linters and fixers. + let g:ale_filename_mappings = [ + \ ['/home/john/proj', '/data'], + \] +< + You can provide many such filename paths for multiple projects. Paths are + matched by checking if the start of a file path matches the given strings, + in a case-sensitive manner. Earlier entries in the |List| will be tried + before later entries when mapping to a given file system. + + Buffer-local options can be set to the same values to override the global + options, such as in |ftplugin| files. + + NOTE: Only fixers registered with a short name can support filename mapping + by their fixer names. See |ale-fix|. Filename mappings set for all tools by + using only a |List| for the setting will also be applied to fixers not in + the registry. + + NOTE: In order for this filename mapping to work correctly, linters and + fixers must exclusively determine paths to files to lint or fix via ALE + command formatting as per |ale-command-format-strings|, and paths parsed + from linter files must be provided in `filename` keys if a linter returns + results for more than one file at a time, as per |ale-loclist-format|. If + you discover a linter or fixer which does not behave properly, please report + it as an issue. + + If you are running a linter or fixer through Docker or another remote file + system, you may have to mount your temporary directory, which you can + discover with the following command: > + + :echo fnamemodify(tempname(), ':h:h') +< + You should provide a mapping from this temporary directory to whatever you + mount this directory to in Docker, or whatever remote file system you are + working with. + + You can inspect the filename mappings ALE will use with the + |ale#GetFilenameMappings()| function. + + g:ale_linters *g:ale_linters* *b:ale_linters* Type: |Dictionary| @@ -1462,19 +1578,23 @@ g:ale_linters *g:ale_linters* following values: > { + \ 'apkbuild': ['apkbuild_lint', 'secfixes_check'], \ 'csh': ['shell'], - \ 'elixir': ['credo', 'dialyxir', 'dogma', 'elixir-ls'], - \ 'go': ['gofmt', 'golint', 'go vet'], + \ 'elixir': ['credo', 'dialyxir', 'dogma'], + \ 'go': ['gofmt', 'golint', 'gopls', 'govet'], \ 'hack': ['hack'], \ 'help': [], + \ 'inko': ['inko'], \ 'perl': ['perlcritic'], \ 'perl6': [], - \ 'python': ['flake8', 'mypy', 'pylint'], - \ 'rust': ['cargo'], + \ 'python': ['flake8', 'mypy', 'pylint', 'pyright'], + \ 'rust': ['cargo', 'rls'], \ 'spec': [], + \ 'svelte': ['eslint', 'svelteserver'], \ 'text': [], \ 'vue': ['eslint', 'vls'], \ 'zsh': ['shell'], + \ 'v': ['v'], \} < This option can be used to enable only a particular set of linters for a @@ -1562,7 +1682,7 @@ g:ale_list_vertical *g:ale_list_vertical* g:ale_loclist_msg_format *g:ale_loclist_msg_format* -b:ale_loclist_msg_format *b:ale_loclist_msg_format* + *b:ale_loclist_msg_format* Type: |String| Default: `g:ale_echo_msg_format` @@ -1573,6 +1693,55 @@ b:ale_loclist_msg_format *b:ale_loclist_msg_format* The strings for configuring `%severity%` are also used for this option. +g:ale_lsp_show_message_format *g:ale_lsp_show_message_format* + + Type: |String| + Default: `'%severity%:%linter%: %s'` + + This variable defines the format that messages received from an LSP will + have when echoed. The following sequences of characters will be replaced. + + `%s` - replaced with the message text + `%linter%` - replaced with the name of the linter + `%severity%` - replaced with the severity of the message + + The strings for `%severity%` levels "error", "info" and "warning" are shared + with |g:ale_echo_msg_format|. Severity "log" is unique to + |g:ale_lsp_show_message_format| and it can be configured via + + |g:ale_echo_msg_log_str| - Defaults to `'Log'` + + Please note that |g:ale_lsp_show_message_format| *can not* be configured + separately for each buffer like |g:ale_echo_msg_format| can. + + +g:ale_lsp_show_message_severity *g:ale_lsp_show_message_severity* + + Type: |String| + Default: `'error'` + + This variable defines the minimum severity level an LSP message needs to be + displayed. Messages below this level are discarded; please note that + messages with `Log` severity level are always discarded. + + Possible values follow the LSP spec `MessageType` definition: + + `'error'` - Displays only errors. + `'warning'` - Displays errors and warnings. + `'information'` - Displays errors, warnings and infos + `'log'` - Same as `'information'` + `'disabled'` - Doesn't display any information at all. + + +g:ale_lsp_suggestions *g:ale_lsp_suggestions* + + Type: |Number| + Default: `0` + + If set to `1`, show hints/suggestions from LSP servers or tsserver, in + addition to warnings and errors. + + g:ale_max_buffer_history_size *g:ale_max_buffer_history_size* Type: |Number| @@ -1681,10 +1850,65 @@ g:ale_pattern_options_enabled *g:ale_pattern_options_enabled* will not set buffer variables per |g:ale_pattern_options|. +g:ale_popup_menu_enabled *g:ale_popup_menu_enabled* + + Type: |Number| + Default: `has('gui_running')` + + When this option is set to `1`, ALE will show code actions and rename + capabilities in the right click mouse menu when there's a LSP server or + tsserver available. See |ale-refactor|. + + This feature is only supported in GUI versions of Vim. + + 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_rename_tsserver_find_in_comments *g:ale_rename_tsserver_find_in_comments* + + Type: |Number| + Default: `0` + + If enabled, this option will tell tsserver to find and replace text in + comments when calling |ALERename|. It can be enabled by settings the value + to `1`. + + +g:ale_rename_tsserver_find_in_strings *g:ale_rename_tsserver_find_in_strings* + + + Type: |Number| + Default: `0` + + If enabled, this option will tell tsserver to find and replace text in + strings when calling |ALERename|. It can be enabled by settings the value to + `1`. + + +g:ale_root *g:ale_root* + *b:ale_root* + + Type: |Dictionary| or |String| + Default: {} + + This option is used to determine the project root for a 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, and the linter is an + LSP linter, it will not run. + + g:ale_set_balloons *g:ale_set_balloons* *b:ale_set_balloons* - Type: |Number| + Type: |Number| or |String| Default: `has('balloon_eval') && has('gui_running')` When this option is set to `1`, balloon messages will be displayed for @@ -1695,6 +1919,13 @@ g:ale_set_balloons *g:ale_set_balloons* supporting "Hover" information, per |ale-hover|, then brief information about the symbol under the cursor will be displayed in a balloon. + This option can be set to `'hover'` to only enable balloons for hover + message, so diagnostics are never shown in balloons. You may wish to + configure use this setting only in GUI Vim like so: > + + let g:ale_set_balloons = has('gui_running') ? 'hover' : 0 +< + 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 @@ -1749,6 +1980,8 @@ g:ale_set_highlights *g:ale_set_highlights* match highlights, whereas the line highlights when signs are enabled will run to the edge of the screen. + Highlights can be excluded with the |g:ale_exclude_highlights| option. + g:ale_set_loclist *g:ale_set_loclist* @@ -1801,6 +2034,18 @@ g:ale_set_signs *g:ale_set_signs* |ALEWarningLine| - All items with `'type': 'W'` |ALEInfoLine| - All items with `'type': 'I'` + With Neovim 0.3.2 or higher, ALE can use the `numhl` option to highlight the + 'number' column. It uses the following highlight groups. + + |ALEErrorSignLineNr| - Items with `'type': 'E'` + |ALEWarningSignLineNr| - Items with `'type': 'W'` + |ALEInfoSignLineNr| - Items with `'type': 'I'` + |ALEStyleErrorSignLineNr| - Items with `'type': 'E'` and `'sub_type': 'style'` + |ALEStyleWarningSignLineNr| - Items with `'type': 'W'` and `'sub_type': 'style'` + + To enable line number highlighting |g:ale_sign_highlight_linenrs| must be + set to `1` before ALE is loaded. + The markers for the highlights can be customized with the following options: |g:ale_sign_error| @@ -1815,6 +2060,16 @@ g:ale_set_signs *g:ale_set_signs* To limit the number of signs ALE will set, see |g:ale_max_signs|. +g:ale_sign_priority *g:ale_sign_priority* + + Type: |Number| + Default: `30` + + From Neovim 0.4.0 and Vim 8.1, ALE can set sign priority to all signs. The + larger this value is, the higher priority ALE signs have over other plugin + signs. See |sign-priority| for further details on how priority works. + + g:ale_shell *g:ale_shell* Type: |String| @@ -1907,7 +2162,25 @@ g:ale_sign_warning *g:ale_sign_warning* The sign for warnings in the sign gutter. -g:ale_type_map *g:ale_type_map* +g:ale_sign_highlight_linenrs *g:ale_sign_highlight_linenrs* + + Type: |Number| + Default: `0` + + When set to `1`, this option enables highlighting problems on the 'number' + column in Vim versions that support `numhl` highlights. This option must be + configured before ALE is loaded. + + +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: `{}` @@ -1973,7 +2246,8 @@ g:ale_virtualtext_cursor *g:ale_virtualtext_cursor* g:ale_virtualtext_delay *g:ale_virtualtext_delay* -b:ale_virtualtext_delay *b:ale_virtualtext_delay* + *b:ale_virtualtext_delay* + Type: |Number| Default: `10` @@ -1992,7 +2266,7 @@ g:ale_virtualtext_prefix *g:ale_virtualtext_prefix* 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* + *b:ale_virtualenv_dir_names* Type: |List| Default: `['.env', '.venv', 'env', 've-py3', 've', 'virtualenv', 'venv']` @@ -2006,7 +2280,7 @@ b:ale_virtualenv_dir_names *b:ale_virtualenv_dir_names* 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* + *b:ale_warn_about_trailing_blank_lines* Type: |Number| Default: `1` @@ -2018,7 +2292,7 @@ b:ale_warn_about_trailing_blank_lines *b:ale_warn_about_trailing_blank_lines* g:ale_warn_about_trailing_whitespace *g:ale_warn_about_trailing_whitespace* -b:ale_warn_about_trailing_whitespace *b:ale_warn_about_trailing_whitespace* + *b:ale_warn_about_trailing_whitespace* Type: |Number| Default: `1` @@ -2077,6 +2351,15 @@ ALEErrorSign *ALEErrorSign* The highlight for error signs. See |g:ale_set_signs|. +ALEErrorSignLineNr *ALEErrorSignLineNr* + + Default: `highlight link ALEErrorSignLineNr CursorLineNr` + + The highlight for error signs. See |g:ale_set_signs|. + + NOTE: This highlight is only available on Neovim 0.3.2 or higher. + + ALEInfo *ALEInfo.* *ALEInfo-highlight* Default: `highlight link ALEInfo ALEWarning` @@ -2101,6 +2384,15 @@ ALEInfoLine *ALEInfoLine* See |g:ale_set_signs| and |g:ale_set_highlights|. +ALEInfoSignLineNr *ALEInfoSignLineNr* + + Default: `highlight link ALEInfoSignLineNr CursorLineNr` + + The highlight for error signs. See |g:ale_set_signs|. + + NOTE: This highlight is only available on Neovim 0.3.2 or higher. + + ALEStyleError *ALEStyleError* Default: `highlight link ALEStyleError ALEError` @@ -2115,6 +2407,15 @@ ALEStyleErrorSign *ALEStyleErrorSign* The highlight for style error signs. See |g:ale_set_signs|. +ALEStyleErrorSignLineNr *ALEStyleErrorSignLineNr* + + Default: `highlight link ALEStyleErrorSignLineNr CursorLineNr` + + The highlight for error signs. See |g:ale_set_signs|. + + NOTE: This highlight is only available on Neovim 0.3.2 or higher. + + ALEStyleWarning *ALEStyleWarning* Default: `highlight link ALEStyleWarning ALEError` @@ -2129,6 +2430,15 @@ ALEStyleWarningSign *ALEStyleWarningSign* The highlight for style warning signs. See |g:ale_set_signs|. +ALEStyleWarningSignLineNr *ALEStyleWarningSignLineNr* + + Default: `highlight link ALEStyleWarningSignLineNr CursorLineNr` + + The highlight for error signs. See |g:ale_set_signs|. + + NOTE: This highlight is only available on Neovim 0.3.2 or higher. + + ALEVirtualTextError *ALEVirtualTextError* Default: `highlight link ALEVirtualTextError ALEError` @@ -2188,44 +2498,22 @@ ALEWarningSign *ALEWarningSign* The highlight for warning signs. See |g:ale_set_signs|. -------------------------------------------------------------------------------- -6.2. Options for write-good *ale-write-good-options* +ALEWarningSignLineNr *ALEWarningSignLineNr* -The options for the write-good linter are global because it does not make -sense to have them specified on a per-language basis. + Default: `highlight link ALEWarningSignLineNr CursorLineNr` -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)` + The highlight for error signs. See |g:ale_set_signs|. - See |ale-integrations-local-executables| + NOTE: This highlight is only available on Neovim 0.3.2 or higher. =============================================================================== -7. Integration Documentation *ale-integrations* +7. Linter/Fixer Options *ale-integration-options* -Linter and fixer options are documented in individual help files. See the -table of contents at |ale-contents|. +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 +buffer. For example, `b:ale_python_flake8_executable` will override any values set for `g:ale_python_flake8_executable`. *ale-integrations-local-executables* @@ -2246,7 +2534,6 @@ If you prefer to use global executables for those tools, set the relevant 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. @@ -2254,6 +2541,585 @@ 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. + + +g:ale_languagetool_options *g:ale_languagetool_options* + *b:ale_languagetool_options* + Type: |String| + Default: `'--autoDetect'` + + This variable can be set to pass additional options to 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| + gnatpp................................|ale-ada-gnatpp| + ada-language-server...................|ale-ada-language-server| + ansible.................................|ale-ansible-options| + ansible-lint..........................|ale-ansible-ansible-lint| + apkbuild................................|ale-apkbuild-options| + apkbuild-lint.........................|ale-apkbuild-apkbuild-lint| + secfixes-check........................|ale-apkbuild-secfixes-check| + 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| + bats....................................|ale-bats-options| + shellcheck............................|ale-bats-shellcheck| + bazel...................................|ale-bazel-options| + buildifier............................|ale-bazel-buildifier| + bib.....................................|ale-bib-options| + bibclean..............................|ale-bib-bibclean| + c.......................................|ale-c-options| + astyle................................|ale-c-astyle| + cc....................................|ale-c-cc| + ccls..................................|ale-c-ccls| + 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| + uncrustify............................|ale-c-uncrustify| + 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| + astyle................................|ale-cpp-astyle| + cc....................................|ale-cpp-cc| + ccls..................................|ale-cpp-ccls| + clangcheck............................|ale-cpp-clangcheck| + clangd................................|ale-cpp-clangd| + 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| + uncrustify............................|ale-cpp-uncrustify| + c#......................................|ale-cs-options| + csc...................................|ale-cs-csc| + dotnet-format.........................|ale-cs-dotnet-format| + 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| + clangd................................|ale-cuda-clangd| + clang-format..........................|ale-cuda-clangformat| + d.......................................|ale-d-options| + dfmt..................................|ale-d-dfmt| + dls...................................|ale-d-dls| + uncrustify............................|ale-d-uncrustify| + dafny...................................|ale-dafny-options| + dafny.................................|ale-dafny-dafny| + dart....................................|ale-dart-options| + analysis_server.......................|ale-dart-analysis_server| + dart-analyze..........................|ale-dart-analyze| + dart-format...........................|ale-dart-format| + dartanalyzer..........................|ale-dart-dartanalyzer| + dartfmt...............................|ale-dart-dartfmt| + desktop.................................|ale-desktop-options| + desktop-file-validate.................|ale-desktop-desktop-file-validate| + dhall...................................|ale-dhall-options| + dhall-format..........................|ale-dhall-format| + dhall-freeze..........................|ale-dhall-freeze| + dhall-lint............................|ale-dhall-lint| + 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-ls................................|ale-elm-elm-ls| + elm-make..............................|ale-elm-elm-make| + erlang..................................|ale-erlang-options| + dialyzer..............................|ale-erlang-dialyzer| + elvis.................................|ale-erlang-elvis| + erlc..................................|ale-erlang-erlc| + erlfmt................................|ale-erlang-erlfmt| + syntaxerl.............................|ale-erlang-syntaxerl| + eruby...................................|ale-eruby-options| + erblint...............................|ale-eruby-erblint| + ruumba................................|ale-eruby-ruumba| + fish....................................|ale-fish-options| + fish_indent...........................|ale-fish-fish_indent| + 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| + golines...............................|ale-go-golines| + golint................................|ale-go-golint| + gometalinter..........................|ale-go-gometalinter| + gopls.................................|ale-go-gopls| + govet.................................|ale-go-govet| + revive................................|ale-go-revive| + 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| + prettier..............................|ale-handlebars-prettier| + 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| + hindent...............................|ale-haskell-hindent| + hlint.................................|ale-haskell-hlint| + hls...................................|ale-haskell-hls| + stack-build...........................|ale-haskell-stack-build| + stack-ghc.............................|ale-haskell-stack-ghc| + stylish-haskell.......................|ale-haskell-stylish-haskell| + hie...................................|ale-haskell-hie| + ormolu................................|ale-haskell-ormolu| + hcl.....................................|ale-hcl-options| + terraform-fmt.........................|ale-hcl-terraform-fmt| + html....................................|ale-html-options| + angular...............................|ale-html-angular| + fecs..................................|ale-html-fecs| + html-beautify.........................|ale-html-beautify| + htmlhint..............................|ale-html-htmlhint| + prettier..............................|ale-html-prettier| + stylelint.............................|ale-html-stylelint| + tidy..................................|ale-html-tidy| + write-good............................|ale-html-write-good| + idris...................................|ale-idris-options| + idris.................................|ale-idris-idris| + ink.....................................|ale-ink-options| + ink-language-server...................|ale-ink-language-server| + inko....................................|ale-inko-options| + inko..................................|ale-inko-inko| + 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| + deno..................................|ale-javascript-deno| + 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| + eslint................................|ale-json-eslint| + fixjson...............................|ale-json-fixjson| + jsonlint..............................|ale-json-jsonlint| + jq....................................|ale-json-jq| + prettier..............................|ale-json-prettier| + spectral..............................|ale-json-spectral| + jsonc...................................|ale-jsonc-options| + eslint................................|ale-jsonc-eslint| + jsonnet.................................|ale-jsonnet-options| + jsonnetfmt............................|ale-jsonnet-jsonnetfmt| + jsonnet-lint..........................|ale-jsonnet-jsonnet-lint| + json5...................................|ale-json5-options| + eslint................................|ale-json5-eslint| + 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| + lua-format............................|ale-lua-lua-format| + luac..................................|ale-lua-luac| + luacheck..............................|ale-lua-luacheck| + luafmt................................|ale-lua-luafmt| + stylua................................|ale-lua-stylua| + markdown................................|ale-markdown-options| + markdownlint..........................|ale-markdown-markdownlint| + mdl...................................|ale-markdown-mdl| + pandoc................................|ale-markdown-pandoc| + 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| + nim.....................................|ale-nim-options| + nimcheck..............................|ale-nim-nimcheck| + nimlsp................................|ale-nim-nimlsp| + nimpretty.............................|ale-nim-nimpretty| + nix.....................................|ale-nix-options| + nixfmt................................|ale-nix-nixfmt| + nixpkgs-fmt...........................|ale-nix-nixpkgs-fmt| + 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| + ocamllsp..............................|ale-ocaml-ocamllsp| + ols...................................|ale-ocaml-ols| + ocamlformat...........................|ale-ocaml-ocamlformat| + ocp-indent............................|ale-ocaml-ocp-indent| + openapi.................................|ale-openapi-options| + ibm_validator.........................|ale-openapi-ibm-validator| + prettier..............................|ale-openapi-prettier| + yamllint..............................|ale-openapi-yamllint| + pascal..................................|ale-pascal-options| + ptop..................................|ale-pascal-ptop| + 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| + tlint.................................|ale-php-tlint| + intelephense..........................|ale-php-intelephense| + 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| + protolint.............................|ale-proto-protolint| + 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| + purescript..............................|ale-purescript-options| + purescript-language-server............|ale-purescript-language-server| + purs-tidy.............................|ale-purescript-tidy| + purty.................................|ale-purescript-purty| + pyrex (cython)..........................|ale-pyrex-options| + cython................................|ale-pyrex-cython| + python..................................|ale-python-options| + autoflake.............................|ale-python-autoflake| + autoimport............................|ale-python-autoimport| + autopep8..............................|ale-python-autopep8| + bandit................................|ale-python-bandit| + black.................................|ale-python-black| + flake8................................|ale-python-flake8| + flakehell.............................|ale-python-flakehell| + 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| + pylsp.................................|ale-python-pylsp| + pyre..................................|ale-python-pyre| + pyright...............................|ale-python-pyright| + 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| + languageserver........................|ale-r-languageserver| + 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| + robot...................................|ale-robot-options| + rflint................................|ale-robot-rflint| + ruby....................................|ale-ruby-options| + brakeman..............................|ale-ruby-brakeman| + debride...............................|ale-ruby-debride| + prettier..............................|ale-ruby-prettier| + 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| + sorbet................................|ale-ruby-sorbet| + standardrb............................|ale-ruby-standardrb| + rust....................................|ale-rust-options| + analyzer..............................|ale-rust-analyzer| + cargo.................................|ale-rust-cargo| + rls...................................|ale-rust-rls| + rustc.................................|ale-rust-rustc| + rustfmt...............................|ale-rust-rustfmt| + salt....................................|ale-salt-options| + salt-lint.............................|ale-salt-salt-lint| + sass....................................|ale-sass-options| + sasslint..............................|ale-sass-sasslint| + stylelint.............................|ale-sass-stylelint| + scala...................................|ale-scala-options| + metals................................|ale-scala-metals| + 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| + bashate...............................|ale-sh-bashate| + 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| + solc..................................|ale-solidity-solc| + 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| + sqlformat.............................|ale-sql-sqlformat| + stylus..................................|ale-stylus-options| + stylelint.............................|ale-stylus-stylelint| + sugarss.................................|ale-sugarss-options| + stylelint.............................|ale-sugarss-stylelint| + svelte..................................|ale-svelte-options| + prettier..............................|ale-svelte-prettier| + svelteserver..........................|ale-svelte-svelteserver| + swift...................................|ale-swift-options| + apple-swift-format....................|ale-swift-apple-swift-format| + sourcekitlsp..........................|ale-swift-sourcekitlsp| + systemd.................................|ale-systemd-options| + systemd-analyze.......................|ale-systemd-analyze| + tcl.....................................|ale-tcl-options| + nagelfar..............................|ale-tcl-nagelfar| + terraform...............................|ale-terraform-options| + terraform-fmt-fixer...................|ale-terraform-fmt-fixer| + terraform.............................|ale-terraform-terraform| + terraform-ls..........................|ale-terraform-terraform-ls| + terraform-lsp.........................|ale-terraform-terraform-lsp| + 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| + thriftcheck...........................|ale-thrift-thriftcheck| + typescript..............................|ale-typescript-options| + deno..................................|ale-typescript-deno| + eslint................................|ale-typescript-eslint| + prettier..............................|ale-typescript-prettier| + standard..............................|ale-typescript-standard| + tslint................................|ale-typescript-tslint| + tsserver..............................|ale-typescript-tsserver| + xo....................................|ale-typescript-xo| + v.......................................|ale-v-options| + v.....................................|ale-v-v| + vfmt..................................|ale-v-vfmt| + vala....................................|ale-vala-options| + uncrustify............................|ale-vala-uncrustify| + verilog/systemverilog...................|ale-verilog-options| + hdl-checker...........................|ale-verilog-hdl-checker| + iverilog..............................|ale-verilog-iverilog| + verilator.............................|ale-verilog-verilator| + vlog..................................|ale-verilog-vlog| + xvlog.................................|ale-verilog-xvlog| + yosys.................................|ale-verilog-yosys| + vhdl....................................|ale-vhdl-options| + ghdl..................................|ale-vhdl-ghdl| + hdl-checker...........................|ale-vhdl-hdl-checker| + vcom..................................|ale-vhdl-vcom| + xvhdl.................................|ale-vhdl-xvhdl| + vim help................................|ale-vim-help-options| + write-good............................|ale-vim-help-write-good| + vim.....................................|ale-vim-options| + vimls.................................|ale-vim-vimls| + vint..................................|ale-vim-vint| + 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| + circleci..............................|ale-yaml-circleci| + prettier..............................|ale-yaml-prettier| + spectral..............................|ale-yaml-spectral| + swaglint..............................|ale-yaml-swaglint| + yamlfix...............................|ale-yaml-yamlfix| + yamllint..............................|ale-yaml-yamllint| + yang....................................|ale-yang-options| + yang-lsp..............................|ale-yang-lsp| + zeek....................................|ale-zeek-options| + zeek..................................|ale-zeek-zeek| + zig.....................................|ale-zig-options| + zls...................................|ale-zig-zls| + + =============================================================================== 8. Commands/Keybinds *ale-commands* @@ -2262,7 +3128,7 @@ ALEComplete *ALEComplete* Manually trigger LSP autocomplete and show the menu. Works only when called from insert mode. > - inoremap :AleComplete + inoremap :ALEComplete < A plug mapping `(ale_complete)` is defined for this command. > @@ -2289,15 +3155,38 @@ ALEFindReferences *ALEFindReferences* 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. + The locations opened in different ways using the following variations. + + `:ALEFindReferences -tab` - Open the location in a new tab. + `:ALEFindReferences -split` - Open the location in a horizontal split. + `:ALEFindReferences -vsplit` - Open the location in a vertical split. + + The default method used for navigating to a new location can be changed + by modifying |g:ale_default_navigation|. + + You can add `-relative` to the command to view results with relatives paths, + instead of absolute paths. + + The selection can be opened again with the |ALERepeatSelection| command. + 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. + You can define additional plug mapping with any additional options you want + like so: > + + nnoremap (my_mapping) :ALEFindReferences -relative +< ALEFix *ALEFix* Fix problems with the current buffer. See |ale-fix| for more information. + If the command is run with a bang (`:ALEFix!`), all warnings will be + suppressed, including warnings about no fixers being defined, and warnings + about not being able to apply fixes to a file because it has been changed. + A plug mapping `(ale_fix)` is defined for this command. @@ -2308,92 +3197,123 @@ ALEFixSuggest *ALEFixSuggest* See |ale-fix| for more information. -ALEGoToDefinition *ALEGoToDefinition* +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. + The locations opened in different ways using the following variations. + + `:ALEGoToDefinition -tab` - Open the location in a new tab. + `:ALEGoToDefinition -split` - Open the location in a horizontal split. + `:ALEGoToDefinition -vsplit` - Open the location in a vertical split. + + The default method used for navigating to a new location can be changed + by modifying |g:ale_default_navigation|. + 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. + You should consider using the 'hidden' option in combination with this + command. Otherwise, Vim will refuse to leave the buffer you're jumping from + unless you have saved your edits. + The following Plug mappings are defined for this command, which correspond + to the following commands. -ALEGoToDefinitionInTab *ALEGoToDefinitionInTab* + `(ale_go_to_definition)` - `:ALEGoToDefinition` + `(ale_go_to_definition_in_tab)` - `:ALEGoToDefinition -tab` + `(ale_go_to_definition_in_split)` - `:ALEGoToDefinition -split` + `(ale_go_to_definition_in_vsplit)` - `:ALEGoToDefinition -vsplit` - 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. +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. -ALEGoToDefinitionInSplit *ALEGoToDefinitionInSplit* + The locations opened in different ways using the following variations. - The same as |ALEGoToDefinition|, but opens results in a new split. + `:ALEGoToTypeDefinition -tab` - Open the location in a new tab. + `:ALEGoToTypeDefinition -split` - Open the location in a horizontal split. + `:ALEGoToTypeDefinition -vsplit` - Open the location in a vertical split. - A plug mapping `(ale_go_to_definition_in_split)` is defined for this - command. + The default method used for navigating to a new location can be changed + by modifying |g:ale_default_navigation|. + 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|. -ALEGoToDefinitionInVSplit *ALEGoToDefinitionInVSplit* + The following Plug mappings are defined for this command, which correspond + to the following commands. - The same as |ALEGoToDefinition|, but opens results in a new vertical split. + `(ale_go_to_type_definition)` - `:ALEGoToTypeDefinition` + `(ale_go_to_type_definition_in_tab)` - `:ALEGoToTypeDefinition -tab` + `(ale_go_to_type_definition_in_split)` - `:ALEGoToTypeDefinition -split` + `(ale_go_to_type_definition_in_vsplit)` - `:ALEGoToTypeDefinition -vsplit` - A plug mapping `(ale_go_to_definition_in_vsplit)` is defined for this - command. +ALEHover *ALEHover* -ALEGoToTypeDefinition *ALEGoToTypeDefinition* + 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. - This works similar to |ALEGoToDefinition| but instead jumps to the - definition of a type of a symbol undert the cursor. ALE will jump to a - definition if an LSP server provides a location to jump to. Otherwise, ALE - will do nothing. + 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. - 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_hover)` is defined for this command. - A plug mapping `(ale_go_to_type_definition)` is defined for this - command. +ALEImport *ALEImport* -ALEGoToTypeDefinitionInTab *ALEGoToTypeDefinitionInTab* + Try to import a symbol using `tsserver` or a Language Server. - The same as |ALEGoToTypeDefinition|, but opens results in a new tab. + ALE will look for completions for the word at the cursor which contain + additional text edits that possible insert lines to import the symbol. The + first match with additional text edits will be used, and may add other code + to the current buffer other than import lines. - A plug mapping `(ale_go_to_type_definition_in_tab)` is defined for - this command. + If linting is enabled, and |g:ale_lint_on_text_changed| is set to ever check + buffers when text is changed, the buffer will be checked again after changes + are made. + A Plug mapping `(ale_import)` is defined for this command. This + mapping should only be bound for normal mode. -ALEGoToTypeDefinitionInSplit *ALEGoToTypeDefinitionInSplit* - The same as |ALEGoToTypeDefinition|, but opens results in a new split. +ALEOrganizeImports *ALEOrganizeImports* - A plug mapping `(ale_go_to_type_definition_in_split)` is defined for - this command. + Organize imports using tsserver. Currently not implemented for LSPs. -ALEGoToTypeDefinitionInVSplit *ALEGoToTypeDefinitionInVSplit* +ALERename *ALERename* - The same as |ALEGoToTypeDefinition|, but opens results in a new vertical - split. + Rename a symbol using `tsserver` or a Language Server. - A plug mapping `(ale_go_to_type_definition_in_vsplit)` is defined for - this command. + The symbol where the cursor is resting will be the symbol renamed, and a + prompt will open to request a new name. -ALEHover *ALEHover* +ALECodeAction *ALECodeAction* - 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. + Apply a code action via LSP servers or `tsserver`. - 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. + If there is an error present on a line that can be fixed, ALE will + automatically fix a line, unless there are multiple possible code fixes to + apply. - A plug mapping `(ale_hover)` is defined for this command. + This command can be run in visual mode apply actions, such as applicable + refactors. A menu will be shown to select code action to apply. + + +ALERepeatSelection *ALERepeatSelection* + + Repeat the last selection displayed in the preview window. ALESymbolSearch `` *ALESymbolSearch* @@ -2403,18 +3323,28 @@ ALESymbolSearch `` *ALESymbolSearch* The arguments provided to this command will be used as a search query for finding symbols in the workspace, such as functions, types, etc. + You can add `-relative` to the command to view results with relatives paths, + instead of absolute paths. + *: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. + This command will also run linters where `lint_file` is evaluates to `1`, + meaning linters which check the file instead of the Vim buffer. A plug mapping `(ale_lint)` is defined for this command. +ALELintStop *ALELintStop* + + Stop any currently running jobs for checking the current buffer. + + Any problems from previous linter results will continue to be shown. + + ALEPrevious *ALEPrevious* ALEPreviousWrap *ALEPreviousWrap* ALENext *ALENext* @@ -2431,14 +3361,36 @@ ALELast *ALELast* `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 + behavior : + `-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 < @@ -2570,6 +3522,23 @@ ale#Env(variable_name, value) *ale#Env()* 'set VAR="some value" && command' # On Windows +ale#GetFilenameMappings(buffer, name) *ale#GetFilenameMappings()* + + Given a `buffer` and the `name` of either a linter for fixer, return a + |List| of two-item |List|s that describe mapping to and from the local and + foreign file systems for running a particular linter or fixer. + + See |g:ale_filename_mappings| for details on filename mapping. + + +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 @@ -2584,9 +3553,9 @@ ale#Queue(delay, [linting_flag, buffer_number]) *ale#Queue()* 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 `linting_flag` argument can be given. If `linting_flag` is + `'lint_file'`, then linters where the `lint_file` option evaluates to `1` + will be run. Otherwise, those linters will not be run. An optional `buffer_number` argument can be given for specifying the buffer to check. The active buffer (`bufnr('')`) will be checked by default. @@ -2598,26 +3567,123 @@ ale#Queue(delay, [linting_flag, buffer_number]) *ale#Queue()* is broken, or when developing ALE itself. -ale#engine#CreateDirectory(buffer) *ale#engine#CreateDirectory()* +ale#command#CreateDirectory(buffer) *ale#command#CreateDirectory()* Create a new temporary directory with a unique name, and manage that - directory with |ale#engine#ManageDirectory()|, so it will be removed as soon + 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#engine#CreateFile(buffer) *ale#engine#CreateFile()* +ale#command#CreateFile(buffer) *ale#command#CreateFile()* Create a new temporary file with a unique name, and manage that file with - |ale#engine#ManageFile()|, so it will be removed as soon as possible. + |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#engine#EscapeCommandPart(command_part) *ale#engine#EscapeCommandPart()* +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. + + `cwd` - An optional |String| for setting the working directory + for the command, just as per |ale#linter#Define|. + + If not set, or `v:null`, the `cwd` of the last command + that spawned this one will be used. + + `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. + + `filename_mappings` - A |List| of two-item |List|s describing filename + mappings to apply for formatted filenames in the + command string, as per |g:ale_filename_mappings|. + + If the call to this function is being used for a + linter or fixer, the mappings should be provided with + this option, and can be retrieved easily with + |ale#GetFilenameMappings()|. + + The default is `[]`. + + + +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 @@ -2626,27 +3692,22 @@ ale#engine#EscapeCommandPart(command_part) *ale#engine#EscapeCommandPart()* specially. -ale#engine#GetLoclist(buffer) *ale#engine#GetLoclist()* +ale#command#ManageDirectory(buffer, directory) *ale#command#ManageDirectory()* - 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. + 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. - This function can be used for status lines, tab names, etc. + It is advised to use |ale#command#ManageFile()| instead for deleting single + files. -ale#engine#ManageFile(buffer, filename) *ale#engine#ManageFile()* +ale#command#ManageFile(buffer, filename) *ale#command#ManageFile()* - Given a buffer number for a buffer currently running some linting tasks - and a filename, register a filename with ALE for automatic deletion after - linting is complete, or when Vim exits. + 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. @@ -2657,18 +3718,30 @@ ale#engine#ManageFile(buffer, filename) *ale#engine#ManageFile()* 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 separetly with the |ale#engine#ManageDirectory| function. + manages directories separately with the |ale#command#ManageDirectory| function. -ale#engine#ManageDirectory(buffer, directory) *ale#engine#ManageDirectory()* +ale#completion#OmniFunc(findstart, base) *ale#completion#OmniFunc()* - Like |ale#engine#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. + A completion function to use with 'omnifunc'. - It is advised to use |ale#engine#ManageFile()| instead for deleting single - files. + 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]) @@ -2687,6 +3760,21 @@ ale#fix#registry#Add(name, func, filetypes, desc, [aliases]) ALE will search for fixers in the registry first by `name`, then by their `aliases`. + For example to register a custom fixer for `luafmt`: > + + function! FormatLua(buffer) abort + return { + \ 'command': 'luafmt --stdin' + \} + endfunction + + execute ale#fix#registry#Add('luafmt', 'FormatLua', ['lua'], 'luafmt for lua') + + " You can now use it in g:ale_fixers + let g:ale_fixers = { + \ 'lua': ['luafmt'] + } +< ale#linter#Define(filetype, linter) *ale#linter#Define()* @@ -2760,7 +3848,7 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* and have been checked at least once. Temporary files in directories used for Vim - temporary files with `tempname()` will be asssumed + 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. @@ -2783,73 +3871,52 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* Human-readable |String| error code. `executable` A |String| naming the executable itself which - will be run. This value will be used to check if the - program requested is installed or not. + 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. - Either this or the `executable_callback` argument - must be provided. + The result can be computed with |ale#command#Run()|. - `executable_callback ` A |String| or |Funcref| for a callback function - accepting a buffer number. A |String| should be - returned for the executable to check. This can be - used in place of `executable` when more complicated - processing is needed. + The command string can be formatted with format + markers. See |ale-command-format-strings|. - `command` A |String| for an executable to run asynchronously. This command will be fed the lines from the buffer to check, and will produce the lines of output given to the `callback`. - `command_callback` A |String| or |Funcref| for a callback function - accepting a buffer number. A |String| should be - returned for a command to run. This can be used in - place of `command` when more complicated processing - is needed. - - If an empty string is returned from the callback, - no jobs for linting will be run for that linter. - This can be used for skipping a linter call, - say if no configuration file was found. - - *ale-command-chain* - `command_chain` A |List| of |Dictionary| items defining a series - of commands to be run. At least one |Dictionary| - should be provided. Each Dictionary must contain the - key `callback`, defining a |String| or |Funcref| for - a function returning a |String| for a command to run. - - The callback functions for each command after the - first command in in the chain should accept two - arguments `(buffer, output)`, a buffer number and a - |List| of lines of output from the previous command - in the chain. - - The first callback function in a chain accepts only - a `(buffer)` argument, as there are no previous - commands to run which return `output`. - - If an empty string is returned for a command in a - chain, that command in the chain will be skipped, - and the next function in the chain will be called - immediately instead. If the last command in a chain - returns an empty string, then no linting will be - performed. - - Commands in the chain will all use the - `output_stream` value provided in the root - |Dictionary|. Each command in the chain can also - provide an `output_stream` key to override this value. - See the `output_stream` description for more - information. - - Commands in the chain all behave as if `read_buffer` - is set to `0` by default, except for the last command - in the chain, which uses the value set for - `read_buffer` in the root |Dictionary|. Each command - in the chain can also provide a `read_buffer` key - to override these values. - See the `read_buffer` description for more - information. + `cwd` An optional |String| for setting the working + directory for the command, or a |Funcref| for a + function to call for computing the command, accepting + a buffer number. The working directory can be + specified as a format string for determining the path + dynamically. See |ale-command-format-strings|. + + To set the working directory to the directory + containing the file you're checking, you should + probably use `'%s:h'` as the option value. + + If this option is absent or the string is empty, the + `command` will be run with no determined working + directory in particular. + + The directory specified with this option will be used + as the default working directory for all commands run + in a chain with |ale#command#Run()|, unless otherwise + specified. `output_stream` A |String| for the output stream the lines of output should be read from for the command which is run. The @@ -2866,24 +3933,30 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* if a command manually reads from a temporary file instead, etc. + This option behaves as if it was set to `0` when the + `lint_file` option evaluates to `1`. + *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. + `lint_file` A |Number| (`0` or `1`), or a |Funcref| for a function + accepting a buffer number for computing either `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. + + The result can be computed with |ale#command#Run()|. + + Linters where the eventual value of this option + evaluates to `1` 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 where this option + evaluates to `1` will also be run when the |ALELint| + command is run. + + When this option is evaluates to `1`, ALE will behave + as if `read_buffer` was set to `0`. *ale-lsp-linters* `lsp` A |String| for defining LSP (Language Server Protocol) @@ -2896,21 +3969,20 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* 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` or `executable_callback` must be set, - and `command` or `command_callback` must be set. + `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_callback` must be set - with a callback returning an address to connect to. + or named pipe socket connection. `address` must be set. + ALE will not start a server automatically. - When this argument is not empty - `project_root_callback` must be defined. + When this argument is not empty `project_root` must + be defined. - `language` or `language_callback` can be defined to - describe the language for a file. The filetype will - be used as the language by default. + `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. @@ -2918,45 +3990,44 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* An optional `completion_filter` callback may be defined for filtering completion results. - An optional `initialization_options` or - `initialization_options_callback` may be defined to - pass initialization options to the LSP. + `initialization_options` may be defined to pass + initialization options to the LSP. - An optional `lsp_config` or `lsp_config_callback` may - be defined to pass configuration settings to the LSP. + `lsp_config` may be defined to pass configuration + settings to the LSP. - `address_callback` A |String| or |Funcref| for a callback function - accepting a buffer number. A |String| should be - returned with an address to connect to. + `address` A |String| representing an address to connect to, + or a |Funcref| accepting a buffer number and + returning the |String|. If the value contains a + colon, it is interpreted as referring to a TCP + socket; otherwise it is interpreted as the path of a + named pipe. + + 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_callback` A |String| or |Funcref| for a callback function - accepting a buffer number. A |String| should be - returned representing the path to the project for the - file being checked with the language server. If an - empty string is returned, the file will not be + `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. This string will be sent to the LSP to - tell it what type of language is being checked. - - If this or `language_callback` isn't set, the - language will default to the value of the filetype - given to |ale#linter#Define|. - - `language_callback` A |String| or |Funcref| for a callback function - accepting a buffer number. A |String| should be - returned representing the name of the language being - checked. + 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. - This option can be used instead of `language` if a - linter can check multiple languages. + 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. @@ -2974,38 +4045,24 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* setting can make it easier to guess the linter name by offering a few alternatives. - `initialization_options` A |Dictionary| of initialization options for LSPs. + `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. - `initialization_options_callback` - A |String| or |Funcref| for a callback function - accepting a buffer number. A |Dictionary| should be - returned for initialization options to pass the LSP. - This can be used in place of `initialization_options` - when more complicated processing is needed. + `lsp_config` A |Dictionary| for configuring a language server, + or a |Funcref| for a callback function accepting + a buffer number and returning the |Dictionary|. - `lsp_config` A |Dictionary| of configuration settings for LSPs. This will be fed (as JSON) to the LSP in the workspace/didChangeConfiguration command. - `lsp_config_callback` A |String| or |Funcref| for a callback function - accepting a buffer number. A |Dictionary| should be - returned for configuration settings to pass the LSP. - This can be used in place of `lsp_config` when more - complicated processing is needed. - - Only one of `command`, `command_callback`, or `command_chain` should be - specified. `command_callback` is generally recommended when a command string - needs to be generated dynamically, or any global options are used. - `command_chain` is recommended where any system calls need to be made to - retrieve some kind of information before running the final command. - If temporary files or directories are created for commands run with - `command_callback` or `command_chain`, then these tempoary files or - directories can be managed by ALE, for automatic deletion. - See |ale#engine#ManageFile()| and |ale#engine#ManageDirectory| for more - information. + `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* @@ -3022,17 +4079,17 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* 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#engine#ManageDirectory|. This option can be used for some linters which + will be automatically deleted, following the behavior 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` or `executable_callback`. This provides a convenient way - to define a command string which needs to include a dynamic executable name, - but which is otherwise static. + 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', @@ -3041,13 +4098,22 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* command, so literal character sequences `%s` and `%t` can be escaped by using `%%s` and `%%t` instead, etc. + Some |filename-modifiers| can be applied to `%s` and `%t`. Only `:h`, `:t`, + `:r`, and `:e` may be applied, other modifiers will be ignored. Filename + modifiers can be applied to the format markers by placing them after them. + + For example: > + 'command': '%s:h %s:e %s:h:t', +< + Given a path `/foo/baz/bar.txt`, the above command string will generate + something akin to `'/foo/baz' 'txt' 'baz'` + 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#engine#EscapeCommandPart()| function can + 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: > @@ -3095,6 +4161,33 @@ ale#linter#PreventLoading(filetype) *ale#linter#PreventLoading()* |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; + `method` - 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()* @@ -3129,6 +4222,21 @@ ale#statusline#Count(buffer) *ale#statusline#Count()* `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 @@ -3149,6 +4257,23 @@ g:ale_want_results_buffer *g:ale_want_results_buffer* figure out which buffer other sources should lint. +ALECompletePost *ALECompletePost-autocmd* + *ALECompletePost* + + This |User| autocmd is triggered after ALE inserts an item on + |CompleteDone|. This event can be used to run commands after a buffer + is changed by ALE as the result of completion. For example, |ALEFix| can + be configured to run automatically when completion is done: > + + augroup FixAfterComplete + autocmd! + " Run ALEFix when completion items are added. + autocmd User ALECompletePost ALEFix! + " If ALE starts fixing a file, stop linters running for now. + autocmd User ALEFixPre ALELintStop + augroup END +< + ALELintPre *ALELintPre-autocmd* *ALELintPre* ALELintPost *ALELintPost-autocmd* @@ -3191,6 +4316,13 @@ ALEJobStarted *ALEJobStarted-autocmd* |ale#engine#IsCheckingBuffer()| over |ALELintPre-autocmd|, which is actually triggered before any linters are executed. +ALELSPStarted *ALELSPStarted-autocmd* + *ALELSPStarted* + + This |User| autocommand is trigged immediately after an LSP connection is + successfully initialized. This provides a way to perform any additional + initialization work, such as setting up buffer-level mappings. + ALEWantResults *ALEWantResults-autocmd* *ALEWantResults* @@ -3218,7 +4350,7 @@ 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 +page for issues and more at https://github.com/dense-analysis/ale If you wish to contact the author of this plugin directly, please feel free to send an email to devw0rp@gmail.com. diff --git a/vim-config/plugins/ale/doc/tags b/vim-config/plugins/ale/doc/tags old mode 100755 new mode 100644 index a1b59c5a..3cf2bcb4 --- a/vim-config/plugins/ale/doc/tags +++ b/vim-config/plugins/ale/doc/tags @@ -1,7 +1,10 @@ :ALEDetail ale.txt /*:ALEDetail* :ALEInfo ale.txt /*:ALEInfo* :ALELint ale.txt /*:ALELint* +ALECodeAction ale.txt /*ALECodeAction* ALEComplete ale.txt /*ALEComplete* +ALECompletePost ale.txt /*ALECompletePost* +ALECompletePost-autocmd ale.txt /*ALECompletePost-autocmd* ALEDetail ale.txt /*ALEDetail* ALEDisable ale.txt /*ALEDisable* ALEDisableBuffer ale.txt /*ALEDisableBuffer* @@ -11,6 +14,7 @@ ALEEnableBuffer ale.txt /*ALEEnableBuffer* ALEError ale.txt /*ALEError* ALEErrorLine ale.txt /*ALEErrorLine* ALEErrorSign ale.txt /*ALEErrorSign* +ALEErrorSignLineNr ale.txt /*ALEErrorSignLineNr* ALEFindReferences ale.txt /*ALEFindReferences* ALEFirst ale.txt /*ALEFirst* ALEFix ale.txt /*ALEFix* @@ -20,39 +24,43 @@ ALEFixPre ale.txt /*ALEFixPre* ALEFixPre-autocmd ale.txt /*ALEFixPre-autocmd* ALEFixSuggest ale.txt /*ALEFixSuggest* ALEGoToDefinition ale.txt /*ALEGoToDefinition* -ALEGoToDefinitionInSplit ale.txt /*ALEGoToDefinitionInSplit* -ALEGoToDefinitionInTab ale.txt /*ALEGoToDefinitionInTab* -ALEGoToDefinitionInVSplit ale.txt /*ALEGoToDefinitionInVSplit* ALEGoToTypeDefinition ale.txt /*ALEGoToTypeDefinition* -ALEGoToTypeDefinitionInSplit ale.txt /*ALEGoToTypeDefinitionInSplit* -ALEGoToTypeDefinitionInTab ale.txt /*ALEGoToTypeDefinitionInTab* -ALEGoToTypeDefinitionInVSplit ale.txt /*ALEGoToTypeDefinitionInVSplit* ALEHover ale.txt /*ALEHover* +ALEImport ale.txt /*ALEImport* ALEInfo ale.txt /*ALEInfo* ALEInfo-highlight ale.txt /*ALEInfo-highlight* ALEInfo. ale.txt /*ALEInfo.* ALEInfoLine ale.txt /*ALEInfoLine* ALEInfoSign ale.txt /*ALEInfoSign* +ALEInfoSignLineNr ale.txt /*ALEInfoSignLineNr* ALEInfoToClipboard ale.txt /*ALEInfoToClipboard* ALEJobStarted ale.txt /*ALEJobStarted* ALEJobStarted-autocmd ale.txt /*ALEJobStarted-autocmd* +ALELSPStarted ale.txt /*ALELSPStarted* +ALELSPStarted-autocmd ale.txt /*ALELSPStarted-autocmd* ALELast ale.txt /*ALELast* ALELint ale.txt /*ALELint* ALELintPost ale.txt /*ALELintPost* ALELintPost-autocmd ale.txt /*ALELintPost-autocmd* ALELintPre ale.txt /*ALELintPre* ALELintPre-autocmd ale.txt /*ALELintPre-autocmd* +ALELintStop ale.txt /*ALELintStop* ALENext ale.txt /*ALENext* ALENextWrap ale.txt /*ALENextWrap* +ALEOrganizeImports ale.txt /*ALEOrganizeImports* ALEPrevious ale.txt /*ALEPrevious* ALEPreviousWrap ale.txt /*ALEPreviousWrap* +ALERename ale.txt /*ALERename* +ALERepeatSelection ale.txt /*ALERepeatSelection* ALEReset ale.txt /*ALEReset* ALEResetBuffer ale.txt /*ALEResetBuffer* ALEStopAllLSPs ale.txt /*ALEStopAllLSPs* ALEStyleError ale.txt /*ALEStyleError* ALEStyleErrorSign ale.txt /*ALEStyleErrorSign* +ALEStyleErrorSignLineNr ale.txt /*ALEStyleErrorSignLineNr* ALEStyleWarning ale.txt /*ALEStyleWarning* ALEStyleWarningSign ale.txt /*ALEStyleWarningSign* +ALEStyleWarningSignLineNr ale.txt /*ALEStyleWarningSignLineNr* ALESymbolSearch ale.txt /*ALESymbolSearch* ALEToggle ale.txt /*ALEToggle* ALEToggleBuffer ale.txt /*ALEToggleBuffer* @@ -66,38 +74,58 @@ ALEWantResults-autocmd ale.txt /*ALEWantResults-autocmd* ALEWarning ale.txt /*ALEWarning* ALEWarningLine ale.txt /*ALEWarningLine* ALEWarningSign ale.txt /*ALEWarningSign* +ALEWarningSignLineNr ale.txt /*ALEWarningSignLineNr* ale ale.txt /*ale* ale#Env() ale.txt /*ale#Env()* +ale#GetFilenameMappings() ale.txt /*ale#GetFilenameMappings()* +ale#Has() ale.txt /*ale#Has()* ale#Pad() ale.txt /*ale#Pad()* ale#Queue() ale.txt /*ale#Queue()* -ale#engine#CreateDirectory() ale.txt /*ale#engine#CreateDirectory()* -ale#engine#CreateFile() ale.txt /*ale#engine#CreateFile()* -ale#engine#EscapeCommandPart() ale.txt /*ale#engine#EscapeCommandPart()* +ale#command#CreateDirectory() ale.txt /*ale#command#CreateDirectory()* +ale#command#CreateFile() ale.txt /*ale#command#CreateFile()* +ale#command#EscapeCommandPart() ale.txt /*ale#command#EscapeCommandPart()* +ale#command#ManageDirectory() ale.txt /*ale#command#ManageDirectory()* +ale#command#ManageFile() ale.txt /*ale#command#ManageFile()* +ale#command#Run() ale.txt /*ale#command#Run()* +ale#completion#OmniFunc() ale.txt /*ale#completion#OmniFunc()* ale#engine#GetLoclist() ale.txt /*ale#engine#GetLoclist()* ale#engine#IsCheckingBuffer() ale.txt /*ale#engine#IsCheckingBuffer()* -ale#engine#ManageDirectory() ale.txt /*ale#engine#ManageDirectory()* -ale#engine#ManageFile() ale.txt /*ale#engine#ManageFile()* ale#fix#registry#Add() ale.txt /*ale#fix#registry#Add()* ale#linter#Define() ale.txt /*ale#linter#Define()* ale#linter#Get() ale.txt /*ale#linter#Get()* ale#linter#PreventLoading() ale.txt /*ale#linter#PreventLoading()* +ale#lsp_linter#SendRequest() ale.txt /*ale#lsp_linter#SendRequest()* ale#other_source#ShowResults() ale.txt /*ale#other_source#ShowResults()* ale#other_source#StartChecking() ale.txt /*ale#other_source#StartChecking()* ale#statusline#Count() ale.txt /*ale#statusline#Count()* +ale#statusline#FirstProblem() ale.txt /*ale#statusline#FirstProblem()* ale-ada-gcc ale-ada.txt /*ale-ada-gcc* +ale-ada-gnatpp ale-ada.txt /*ale-ada-gnatpp* +ale-ada-language-server ale-ada.txt /*ale-ada-language-server* ale-ada-options ale-ada.txt /*ale-ada-options* +ale-alex-options ale.txt /*ale-alex-options* ale-ansible-ansible-lint ale-ansible.txt /*ale-ansible-ansible-lint* ale-ansible-options ale-ansible.txt /*ale-ansible-options* ale-api ale.txt /*ale-api* +ale-apkbuild-apkbuild-lint ale-apkbuild.txt /*ale-apkbuild-apkbuild-lint* +ale-apkbuild-options ale-apkbuild.txt /*ale-apkbuild-options* +ale-apkbuild-secfixes-check ale-apkbuild.txt /*ale-apkbuild-secfixes-check* ale-asciidoc-options ale-asciidoc.txt /*ale-asciidoc-options* ale-asciidoc-textlint ale-asciidoc.txt /*ale-asciidoc-textlint* ale-asciidoc-write-good ale-asciidoc.txt /*ale-asciidoc-write-good* ale-asm-gcc ale-asm.txt /*ale-asm-gcc* ale-asm-options ale-asm.txt /*ale-asm-options* +ale-asyncomplete-integration ale.txt /*ale-asyncomplete-integration* ale-awk-gawk ale-awk.txt /*ale-awk-gawk* ale-awk-options ale-awk.txt /*ale-awk-options* +ale-bats-options ale-bats.txt /*ale-bats-options* +ale-bats-shellcheck ale-bats.txt /*ale-bats-shellcheck* +ale-bazel-buildifier ale-bazel.txt /*ale-bazel-buildifier* +ale-bazel-options ale-bazel.txt /*ale-bazel-options* ale-bib-bibclean ale-bib.txt /*ale-bib-bibclean* ale-bib-options ale-bib.txt /*ale-bib-options* +ale-c-astyle ale-c.txt /*ale-c-astyle* +ale-c-cc ale-c.txt /*ale-c-cc* ale-c-ccls ale-c.txt /*ale-c-ccls* ale-c-clang ale-c.txt /*ale-c-clang* ale-c-clangd ale-c.txt /*ale-c-clangd* @@ -109,23 +137,28 @@ ale-c-flawfinder ale-c.txt /*ale-c-flawfinder* ale-c-gcc ale-c.txt /*ale-c-gcc* ale-c-options ale-c.txt /*ale-c-options* ale-c-uncrustify ale-c.txt /*ale-c-uncrustify* +ale-chef-cookstyle ale-chef.txt /*ale-chef-cookstyle* ale-chef-foodcritic ale-chef.txt /*ale-chef-foodcritic* ale-chef-options ale-chef.txt /*ale-chef-options* +ale-clojure-clj-kondo ale-clojure.txt /*ale-clojure-clj-kondo* ale-clojure-joker ale-clojure.txt /*ale-clojure-joker* ale-clojure-options ale-clojure.txt /*ale-clojure-options* ale-cloudformation-cfn-python-lint ale-cloudformation.txt /*ale-cloudformation-cfn-python-lint* ale-cloudformation-options ale-cloudformation.txt /*ale-cloudformation-options* +ale-cmake-cmakeformat ale-cmake.txt /*ale-cmake-cmakeformat* ale-cmake-cmakelint ale-cmake.txt /*ale-cmake-cmakelint* ale-cmake-options ale-cmake.txt /*ale-cmake-options* ale-coding-standards ale-development.txt /*ale-coding-standards* -ale-command-chain ale.txt /*ale-command-chain* ale-command-format-strings ale.txt /*ale-command-format-strings* ale-commands ale.txt /*ale-commands* ale-completion ale.txt /*ale-completion* -ale-completion-completopt-bug ale.txt /*ale-completion-completopt-bug* +ale-completion-completeopt-bug ale.txt /*ale-completion-completeopt-bug* +ale-completion-fallback ale.txt /*ale-completion-fallback* ale-contact ale.txt /*ale-contact* ale-contents ale.txt /*ale-contents* ale-cool-down ale.txt /*ale-cool-down* +ale-cpp-astyle ale-cpp.txt /*ale-cpp-astyle* +ale-cpp-cc ale-cpp.txt /*ale-cpp-cc* ale-cpp-ccls ale-cpp.txt /*ale-cpp-ccls* ale-cpp-clang ale-cpp.txt /*ale-cpp-clang* ale-cpp-clangcheck ale-cpp.txt /*ale-cpp-clangcheck* @@ -140,48 +173,75 @@ ale-cpp-flawfinder ale-cpp.txt /*ale-cpp-flawfinder* ale-cpp-gcc ale-cpp.txt /*ale-cpp-gcc* ale-cpp-options ale-cpp.txt /*ale-cpp-options* ale-cpp-uncrustify ale-cpp.txt /*ale-cpp-uncrustify* +ale-cs-csc ale-cs.txt /*ale-cs-csc* +ale-cs-dotnet-format ale-cs.txt /*ale-cs-dotnet-format* ale-cs-mcs ale-cs.txt /*ale-cs-mcs* ale-cs-mcsc ale-cs.txt /*ale-cs-mcsc* ale-cs-options ale-cs.txt /*ale-cs-options* ale-cs-uncrustify ale-cs.txt /*ale-cs-uncrustify* +ale-css-fecs ale-css.txt /*ale-css-fecs* ale-css-options ale-css.txt /*ale-css-options* ale-css-prettier ale-css.txt /*ale-css-prettier* ale-css-stylelint ale-css.txt /*ale-css-stylelint* +ale-cuda-clangd ale-cuda.txt /*ale-cuda-clangd* +ale-cuda-clangformat ale-cuda.txt /*ale-cuda-clangformat* ale-cuda-nvcc ale-cuda.txt /*ale-cuda-nvcc* ale-cuda-options ale-cuda.txt /*ale-cuda-options* +ale-d-dfmt ale-d.txt /*ale-d-dfmt* ale-d-dls ale-d.txt /*ale-d-dls* ale-d-options ale-d.txt /*ale-d-options* ale-d-uncrustify ale-d.txt /*ale-d-uncrustify* +ale-dafny-dafny ale-dafny.txt /*ale-dafny-dafny* +ale-dafny-options ale-dafny.txt /*ale-dafny-options* +ale-dart-analysis_server ale-dart.txt /*ale-dart-analysis_server* +ale-dart-analyze ale-dart.txt /*ale-dart-analyze* ale-dart-dartanalyzer ale-dart.txt /*ale-dart-dartanalyzer* ale-dart-dartfmt ale-dart.txt /*ale-dart-dartfmt* +ale-dart-format ale-dart.txt /*ale-dart-format* ale-dart-options ale-dart.txt /*ale-dart-options* +ale-deoplete-integration ale.txt /*ale-deoplete-integration* ale-design-goals ale-development.txt /*ale-design-goals* +ale-desktop-desktop-file-validate ale-desktop.txt /*ale-desktop-desktop-file-validate* +ale-desktop-options ale-desktop.txt /*ale-desktop-options* ale-dev ale-development.txt /*ale-dev* ale-dev-tests ale-development.txt /*ale-dev-tests* ale-development ale-development.txt /*ale-development* ale-development-contents ale-development.txt /*ale-development-contents* +ale-development-fixer-tests ale-development.txt /*ale-development-fixer-tests* ale-development-introduction ale-development.txt /*ale-development-introduction* ale-development-linter-tests ale-development.txt /*ale-development-linter-tests* ale-development-tests ale-development.txt /*ale-development-tests* +ale-development-windows-tests ale-development.txt /*ale-development-windows-tests* ale-development.txt ale-development.txt /*ale-development.txt* +ale-dhall-format ale-dhall.txt /*ale-dhall-format* +ale-dhall-freeze ale-dhall.txt /*ale-dhall-freeze* +ale-dhall-lint ale-dhall.txt /*ale-dhall-lint* +ale-dhall-options ale-dhall.txt /*ale-dhall-options* ale-dockerfile-dockerfile_lint ale-dockerfile.txt /*ale-dockerfile-dockerfile_lint* ale-dockerfile-hadolint ale-dockerfile.txt /*ale-dockerfile-hadolint* ale-dockerfile-options ale-dockerfile.txt /*ale-dockerfile-options* +ale-elixir-credo ale-elixir.txt /*ale-elixir-credo* ale-elixir-dialyxir ale-elixir.txt /*ale-elixir-dialyxir* ale-elixir-elixir-ls ale-elixir.txt /*ale-elixir-elixir-ls* ale-elixir-mix ale-elixir.txt /*ale-elixir-mix* ale-elixir-mix-format ale-elixir.txt /*ale-elixir-mix-format* ale-elixir-options ale-elixir.txt /*ale-elixir-options* ale-elm-elm-format ale-elm.txt /*ale-elm-elm-format* +ale-elm-elm-ls ale-elm.txt /*ale-elm-elm-ls* ale-elm-elm-make ale-elm.txt /*ale-elm-elm-make* ale-elm-options ale-elm.txt /*ale-elm-options* +ale-erlang-dialyzer ale-erlang.txt /*ale-erlang-dialyzer* +ale-erlang-elvis ale-erlang.txt /*ale-erlang-elvis* ale-erlang-erlc ale-erlang.txt /*ale-erlang-erlc* +ale-erlang-erlfmt ale-erlang.txt /*ale-erlang-erlfmt* ale-erlang-options ale-erlang.txt /*ale-erlang-options* ale-erlang-syntaxerl ale-erlang.txt /*ale-erlang-syntaxerl* +ale-eruby-erblint ale-eruby.txt /*ale-eruby-erblint* ale-eruby-options ale-eruby.txt /*ale-eruby-options* ale-eruby-ruumba ale-eruby.txt /*ale-eruby-ruumba* ale-eslint-nested-configuration-files ale-javascript.txt /*ale-eslint-nested-configuration-files* ale-find-references ale.txt /*ale-find-references* +ale-fish-fish_indent ale-fish.txt /*ale-fish-fish_indent* ale-fish-options ale-fish.txt /*ale-fish-options* ale-fix ale.txt /*ale-fix* ale-fix-configuration ale.txt /*ale-fix-configuration* @@ -201,10 +261,13 @@ ale-go-gobuild ale-go.txt /*ale-go-gobuild* ale-go-gofmt ale-go.txt /*ale-go-gofmt* ale-go-golangci-lint ale-go.txt /*ale-go-golangci-lint* ale-go-golangserver ale-go.txt /*ale-go-golangserver* +ale-go-golines ale-go.txt /*ale-go-golines* ale-go-golint ale-go.txt /*ale-go-golint* ale-go-gometalinter ale-go.txt /*ale-go-gometalinter* +ale-go-gopls ale-go.txt /*ale-go-gopls* ale-go-govet ale-go.txt /*ale-go-govet* ale-go-options ale-go.txt /*ale-go-options* +ale-go-revive ale-go.txt /*ale-go-revive* ale-go-staticcheck ale-go.txt /*ale-go-staticcheck* ale-go-to-definition ale.txt /*ale-go-to-definition* ale-go-to-type-definition ale.txt /*ale-go-to-type-definition* @@ -218,21 +281,30 @@ ale-hack-hhast ale-hack.txt /*ale-hack-hhast* ale-hack-options ale-hack.txt /*ale-hack-options* ale-handlebars-embertemplatelint ale-handlebars.txt /*ale-handlebars-embertemplatelint* ale-handlebars-options ale-handlebars.txt /*ale-handlebars-options* +ale-handlebars-prettier ale-handlebars.txt /*ale-handlebars-prettier* ale-haskell-brittany ale-haskell.txt /*ale-haskell-brittany* ale-haskell-cabal-ghc ale-haskell.txt /*ale-haskell-cabal-ghc* +ale-haskell-floskell ale-haskell.txt /*ale-haskell-floskell* ale-haskell-ghc ale-haskell.txt /*ale-haskell-ghc* ale-haskell-ghc-mod ale-haskell.txt /*ale-haskell-ghc-mod* ale-haskell-hdevtools ale-haskell.txt /*ale-haskell-hdevtools* ale-haskell-hfmt ale-haskell.txt /*ale-haskell-hfmt* ale-haskell-hie ale-haskell.txt /*ale-haskell-hie* +ale-haskell-hindent ale-haskell.txt /*ale-haskell-hindent* ale-haskell-hlint ale-haskell.txt /*ale-haskell-hlint* +ale-haskell-hls ale-haskell.txt /*ale-haskell-hls* ale-haskell-options ale-haskell.txt /*ale-haskell-options* +ale-haskell-ormolu ale-haskell.txt /*ale-haskell-ormolu* ale-haskell-stack-build ale-haskell.txt /*ale-haskell-stack-build* +ale-haskell-stack-ghc ale-haskell.txt /*ale-haskell-stack-ghc* ale-haskell-stylish-haskell ale-haskell.txt /*ale-haskell-stylish-haskell* ale-hcl-options ale-hcl.txt /*ale-hcl-options* ale-hcl-terraform-fmt ale-hcl.txt /*ale-hcl-terraform-fmt* ale-highlights ale.txt /*ale-highlights* ale-hover ale.txt /*ale-hover* +ale-html-angular ale-html.txt /*ale-html-angular* +ale-html-beautify ale-html.txt /*ale-html-beautify* +ale-html-fecs ale-html.txt /*ale-html-fecs* ale-html-htmlhint ale-html.txt /*ale-html-htmlhint* ale-html-options ale-html.txt /*ale-html-options* ale-html-prettier ale-html.txt /*ale-html-prettier* @@ -241,24 +313,34 @@ ale-html-tidy ale-html.txt /*ale-html-tidy* ale-html-write-good ale-html.txt /*ale-html-write-good* ale-idris-idris ale-idris.txt /*ale-idris-idris* ale-idris-options ale-idris.txt /*ale-idris-options* +ale-ink-language-server ale-ink.txt /*ale-ink-language-server* +ale-ink-options ale-ink.txt /*ale-ink-options* +ale-inko-inko ale-inko.txt /*ale-inko-inko* +ale-inko-options ale-inko.txt /*ale-inko-options* ale-integration-glsl ale-glsl.txt /*ale-integration-glsl* ale-integration-hack ale-hack.txt /*ale-integration-hack* +ale-integration-inko ale-inko.txt /*ale-integration-inko* ale-integration-kotlin ale-kotlin.txt /*ale-integration-kotlin* +ale-integration-options ale.txt /*ale-integration-options* ale-integration-rust ale-rust.txt /*ale-integration-rust* ale-integration-spec ale-spec.txt /*ale-integration-spec* -ale-integrations ale.txt /*ale-integrations* +ale-integration-zeek ale-zeek.txt /*ale-integration-zeek* +ale-integration-zig ale-zig.txt /*ale-integration-zig* ale-integrations-local-executables ale.txt /*ale-integrations-local-executables* ale-introduction ale.txt /*ale-introduction* ale-ispc-ispc ale-ispc.txt /*ale-ispc-ispc* ale-ispc-options ale-ispc.txt /*ale-ispc-options* ale-java-checkstyle ale-java.txt /*ale-java-checkstyle* +ale-java-eclipselsp ale-java.txt /*ale-java-eclipselsp* ale-java-google-java-format ale-java.txt /*ale-java-google-java-format* ale-java-javac ale-java.txt /*ale-java-javac* ale-java-javalsp ale-java.txt /*ale-java-javalsp* ale-java-options ale-java.txt /*ale-java-options* ale-java-pmd ale-java.txt /*ale-java-pmd* ale-java-uncrustify ale-java.txt /*ale-java-uncrustify* +ale-javascript-deno ale-javascript.txt /*ale-javascript-deno* ale-javascript-eslint ale-javascript.txt /*ale-javascript-eslint* +ale-javascript-fecs ale-javascript.txt /*ale-javascript-fecs* ale-javascript-flow ale-javascript.txt /*ale-javascript-flow* ale-javascript-importjs ale-javascript.txt /*ale-javascript-importjs* ale-javascript-jscs ale-javascript.txt /*ale-javascript-jscs* @@ -269,18 +351,29 @@ ale-javascript-prettier-eslint ale-javascript.txt /*ale-javascript-prettier-esli ale-javascript-prettier-standard ale-javascript.txt /*ale-javascript-prettier-standard* ale-javascript-standard ale-javascript.txt /*ale-javascript-standard* ale-javascript-xo ale-javascript.txt /*ale-javascript-xo* +ale-json-eslint ale-json.txt /*ale-json-eslint* ale-json-fixjson ale-json.txt /*ale-json-fixjson* ale-json-jq ale-json.txt /*ale-json-jq* ale-json-jsonlint ale-json.txt /*ale-json-jsonlint* ale-json-options ale-json.txt /*ale-json-options* ale-json-prettier ale-json.txt /*ale-json-prettier* +ale-json-spectral ale-json.txt /*ale-json-spectral* +ale-json5-eslint ale-json5.txt /*ale-json5-eslint* +ale-json5-options ale-json5.txt /*ale-json5-options* +ale-jsonc-eslint ale-jsonc.txt /*ale-jsonc-eslint* +ale-jsonc-options ale-jsonc.txt /*ale-jsonc-options* +ale-jsonnet-jsonnet-lint ale-jsonnet.txt /*ale-jsonnet-jsonnet-lint* +ale-jsonnet-jsonnetfmt ale-jsonnet.txt /*ale-jsonnet-jsonnetfmt* +ale-jsonnet-options ale-jsonnet.txt /*ale-jsonnet-options* ale-julia-languageserver ale-julia.txt /*ale-julia-languageserver* ale-julia-options ale-julia.txt /*ale-julia-options* ale-kotlin-kotlinc ale-kotlin.txt /*ale-kotlin-kotlinc* ale-kotlin-ktlint ale-kotlin.txt /*ale-kotlin-ktlint* ale-kotlin-languageserver ale-kotlin.txt /*ale-kotlin-languageserver* ale-kotlin-options ale-kotlin.txt /*ale-kotlin-options* +ale-languagetool-options ale.txt /*ale-languagetool-options* ale-latex-options ale-latex.txt /*ale-latex-options* +ale-latex-textlint ale-latex.txt /*ale-latex-textlint* ale-latex-write-good ale-latex.txt /*ale-latex-write-good* ale-less-lessc ale-less.txt /*ale-less-lessc* ale-less-options ale-less.txt /*ale-less-options* @@ -289,21 +382,27 @@ ale-less-stylelint ale-less.txt /*ale-less-stylelint* ale-lint ale.txt /*ale-lint* ale-lint-file ale.txt /*ale-lint-file* ale-lint-file-linters ale.txt /*ale-lint-file-linters* +ale-lint-language-servers ale.txt /*ale-lint-language-servers* +ale-lint-other-machines ale.txt /*ale-lint-other-machines* ale-lint-other-sources ale.txt /*ale-lint-other-sources* ale-lint-settings-on-startup ale.txt /*ale-lint-settings-on-startup* ale-linter-loading-behavior ale.txt /*ale-linter-loading-behavior* -ale-linter-loading-behaviour ale.txt /*ale-linter-loading-behaviour* ale-linting-interrupts-mapping ale.txt /*ale-linting-interrupts-mapping* ale-llvm-llc ale-llvm.txt /*ale-llvm-llc* ale-llvm-options ale-llvm.txt /*ale-llvm-options* ale-loclist-format ale.txt /*ale-loclist-format* ale-lsp ale.txt /*ale-lsp* ale-lsp-linters ale.txt /*ale-lsp-linters* +ale-lua-lua-format ale-lua.txt /*ale-lua-lua-format* ale-lua-luac ale-lua.txt /*ale-lua-luac* ale-lua-luacheck ale-lua.txt /*ale-lua-luacheck* +ale-lua-luafmt ale-lua.txt /*ale-lua-luafmt* ale-lua-options ale-lua.txt /*ale-lua-options* +ale-lua-stylua ale-lua.txt /*ale-lua-stylua* +ale-markdown-markdownlint ale-markdown.txt /*ale-markdown-markdownlint* ale-markdown-mdl ale-markdown.txt /*ale-markdown-mdl* ale-markdown-options ale-markdown.txt /*ale-markdown-options* +ale-markdown-pandoc ale-markdown.txt /*ale-markdown-pandoc* ale-markdown-prettier ale-markdown.txt /*ale-markdown-prettier* ale-markdown-remark-lint ale-markdown.txt /*ale-markdown-remark-lint* ale-markdown-textlint ale-markdown.txt /*ale-markdown-textlint* @@ -313,6 +412,13 @@ ale-mercury-options ale-mercury.txt /*ale-mercury-options* ale-nasm-nasm ale-nasm.txt /*ale-nasm-nasm* ale-nasm-options ale-nasm.txt /*ale-nasm-options* ale-navigation-commands ale.txt /*ale-navigation-commands* +ale-nim-nimcheck ale-nim.txt /*ale-nim-nimcheck* +ale-nim-nimlsp ale-nim.txt /*ale-nim-nimlsp* +ale-nim-nimpretty ale-nim.txt /*ale-nim-nimpretty* +ale-nim-options ale-nim.txt /*ale-nim-options* +ale-nix-nixfmt ale-nix.txt /*ale-nix-nixfmt* +ale-nix-nixpkgs-fmt ale-nix.txt /*ale-nix-nixpkgs-fmt* +ale-nix-options ale-nix.txt /*ale-nix-options* ale-nroff-options ale-nroff.txt /*ale-nroff-options* ale-nroff-write-good ale-nroff.txt /*ale-nroff-write-good* ale-objc-ccls ale-objc.txt /*ale-objc-ccls* @@ -326,9 +432,18 @@ ale-objcpp-options ale-objcpp.txt /*ale-objcpp-options* ale-objcpp-uncrustify ale-objcpp.txt /*ale-objcpp-uncrustify* ale-ocaml-merlin ale-ocaml.txt /*ale-ocaml-merlin* ale-ocaml-ocamlformat ale-ocaml.txt /*ale-ocaml-ocamlformat* +ale-ocaml-ocamllsp ale-ocaml.txt /*ale-ocaml-ocamllsp* +ale-ocaml-ocp-indent ale-ocaml.txt /*ale-ocaml-ocp-indent* ale-ocaml-ols ale-ocaml.txt /*ale-ocaml-ols* ale-ocaml-options ale-ocaml.txt /*ale-ocaml-options* +ale-openapi-ibm-validator ale-openapi.txt /*ale-openapi-ibm-validator* +ale-openapi-options ale-openapi.txt /*ale-openapi-options* +ale-openapi-prettier ale-openapi.txt /*ale-openapi-prettier* +ale-openapi-yamllint ale-openapi.txt /*ale-openapi-yamllint* ale-options ale.txt /*ale-options* +ale-other-integration-options ale.txt /*ale-other-integration-options* +ale-pascal-options ale-pascal.txt /*ale-pascal-options* +ale-pascal-ptop ale-pascal.txt /*ale-pascal-ptop* ale-pawn-options ale-pawn.txt /*ale-pawn-options* ale-pawn-uncrustify ale-pawn.txt /*ale-pawn-uncrustify* ale-perl-options ale-perl.txt /*ale-perl-options* @@ -337,6 +452,7 @@ ale-perl-perlcritic ale-perl.txt /*ale-perl-perlcritic* ale-perl-perltidy ale-perl.txt /*ale-perl-perltidy* ale-perl6-options ale-perl6.txt /*ale-perl6-options* ale-perl6-perl6 ale-perl6.txt /*ale-perl6-perl6* +ale-php-intelephense ale-php.txt /*ale-php-intelephense* ale-php-langserver ale-php.txt /*ale-php-langserver* ale-php-options ale-php.txt /*ale-php-options* ale-php-phan ale-php.txt /*ale-php-phan* @@ -347,27 +463,40 @@ ale-php-phpcs ale-php.txt /*ale-php-phpcs* ale-php-phpmd ale-php.txt /*ale-php-phpmd* ale-php-phpstan ale-php.txt /*ale-php-phpstan* ale-php-psalm ale-php.txt /*ale-php-psalm* +ale-php-tlint ale-php.txt /*ale-php-tlint* ale-po-options ale-po.txt /*ale-po-options* ale-po-write-good ale-po.txt /*ale-po-write-good* ale-pod-options ale-pod.txt /*ale-pod-options* ale-pod-write-good ale-pod.txt /*ale-pod-write-good* ale-pony-options ale-pony.txt /*ale-pony-options* ale-pony-ponyc ale-pony.txt /*ale-pony-ponyc* +ale-powershell-options ale-powershell.txt /*ale-powershell-options* +ale-powershell-powershell ale-powershell.txt /*ale-powershell-powershell* +ale-powershell-psscriptanalyzer ale-powershell.txt /*ale-powershell-psscriptanalyzer* ale-prolog-options ale-prolog.txt /*ale-prolog-options* ale-prolog-swipl ale-prolog.txt /*ale-prolog-swipl* ale-proto-options ale-proto.txt /*ale-proto-options* ale-proto-protoc-gen-lint ale-proto.txt /*ale-proto-protoc-gen-lint* +ale-proto-protolint ale-proto.txt /*ale-proto-protolint* ale-pug-options ale-pug.txt /*ale-pug-options* ale-pug-puglint ale-pug.txt /*ale-pug-puglint* ale-puppet-languageserver ale-puppet.txt /*ale-puppet-languageserver* ale-puppet-options ale-puppet.txt /*ale-puppet-options* ale-puppet-puppet ale-puppet.txt /*ale-puppet-puppet* ale-puppet-puppetlint ale-puppet.txt /*ale-puppet-puppetlint* +ale-purescript-language-server ale-purescript.txt /*ale-purescript-language-server* +ale-purescript-options ale-purescript.txt /*ale-purescript-options* +ale-purescript-purty ale-purescript.txt /*ale-purescript-purty* +ale-purescript-tidy ale-purescript.txt /*ale-purescript-tidy* ale-pyrex-cython ale-pyrex.txt /*ale-pyrex-cython* ale-pyrex-options ale-pyrex.txt /*ale-pyrex-options* +ale-python-autoflake ale-python.txt /*ale-python-autoflake* +ale-python-autoimport ale-python.txt /*ale-python-autoimport* ale-python-autopep8 ale-python.txt /*ale-python-autopep8* +ale-python-bandit ale-python.txt /*ale-python-bandit* ale-python-black ale-python.txt /*ale-python-black* ale-python-flake8 ale-python.txt /*ale-python-flake8* +ale-python-flakehell ale-python.txt /*ale-python-flakehell* ale-python-isort ale-python.txt /*ale-python-isort* ale-python-mypy ale-python.txt /*ale-python-mypy* ale-python-options ale-python.txt /*ale-python-options* @@ -375,32 +504,45 @@ ale-python-prospector ale-python.txt /*ale-python-prospector* ale-python-pycodestyle ale-python.txt /*ale-python-pycodestyle* ale-python-pydocstyle ale-python.txt /*ale-python-pydocstyle* ale-python-pyflakes ale-python.txt /*ale-python-pyflakes* +ale-python-pylama ale-python.txt /*ale-python-pylama* ale-python-pylint ale-python.txt /*ale-python-pylint* -ale-python-pyls ale-python.txt /*ale-python-pyls* +ale-python-pylsp ale-python.txt /*ale-python-pylsp* ale-python-pyre ale-python.txt /*ale-python-pyre* +ale-python-pyright ale-python.txt /*ale-python-pyright* +ale-python-reorder_python_imports ale-python.txt /*ale-python-reorder_python_imports* ale-python-root ale-python.txt /*ale-python-root* ale-python-vulture ale-python.txt /*ale-python-vulture* ale-python-yapf ale-python.txt /*ale-python-yapf* ale-qml-options ale-qml.txt /*ale-qml-options* ale-qml-qmlfmt ale-qml.txt /*ale-qml-qmlfmt* +ale-r-languageserver ale-r.txt /*ale-r-languageserver* ale-r-lintr ale-r.txt /*ale-r-lintr* ale-r-options ale-r.txt /*ale-r-options* +ale-r-styler ale-r.txt /*ale-r-styler* +ale-reasonml-language-server ale-reasonml.txt /*ale-reasonml-language-server* ale-reasonml-merlin ale-reasonml.txt /*ale-reasonml-merlin* ale-reasonml-ols ale-reasonml.txt /*ale-reasonml-ols* ale-reasonml-options ale-reasonml.txt /*ale-reasonml-options* ale-reasonml-refmt ale-reasonml.txt /*ale-reasonml-refmt* +ale-refactor ale.txt /*ale-refactor* ale-restructuredtext-options ale-restructuredtext.txt /*ale-restructuredtext-options* ale-restructuredtext-textlint ale-restructuredtext.txt /*ale-restructuredtext-textlint* ale-restructuredtext-write-good ale-restructuredtext.txt /*ale-restructuredtext-write-good* +ale-robot-options ale-robot.txt /*ale-robot-options* +ale-robot-rflint ale-robot.txt /*ale-robot-rflint* ale-ruby-brakeman ale-ruby.txt /*ale-ruby-brakeman* +ale-ruby-debride ale-ruby.txt /*ale-ruby-debride* ale-ruby-options ale-ruby.txt /*ale-ruby-options* +ale-ruby-prettier ale-ruby.txt /*ale-ruby-prettier* ale-ruby-rails_best_practices ale-ruby.txt /*ale-ruby-rails_best_practices* ale-ruby-reek ale-ruby.txt /*ale-ruby-reek* ale-ruby-rubocop ale-ruby.txt /*ale-ruby-rubocop* ale-ruby-ruby ale-ruby.txt /*ale-ruby-ruby* ale-ruby-rufo ale-ruby.txt /*ale-ruby-rufo* ale-ruby-solargraph ale-ruby.txt /*ale-ruby-solargraph* +ale-ruby-sorbet ale-ruby.txt /*ale-ruby-sorbet* ale-ruby-standardrb ale-ruby.txt /*ale-ruby-standardrb* +ale-rust-analyzer ale-rust.txt /*ale-rust-analyzer* ale-rust-cargo ale-rust.txt /*ale-rust-cargo* ale-rust-options ale-rust.txt /*ale-rust-options* ale-rust-rls ale-rust.txt /*ale-rust-rls* @@ -409,6 +551,7 @@ ale-rust-rustfmt ale-rust.txt /*ale-rust-rustfmt* ale-sass-options ale-sass.txt /*ale-sass-options* ale-sass-sasslint ale-sass.txt /*ale-sass-sasslint* ale-sass-stylelint ale-sass.txt /*ale-sass-stylelint* +ale-scala-metals ale-scala.txt /*ale-scala-metals* ale-scala-options ale-scala.txt /*ale-scala-options* ale-scala-sbtserver ale-scala.txt /*ale-scala-sbtserver* ale-scala-scalafmt ale-scala.txt /*ale-scala-scalafmt* @@ -417,6 +560,7 @@ ale-scss-options ale-scss.txt /*ale-scss-options* ale-scss-prettier ale-scss.txt /*ale-scss-prettier* ale-scss-sasslint ale-scss.txt /*ale-scss-sasslint* ale-scss-stylelint ale-scss.txt /*ale-scss-stylelint* +ale-sh-bashate ale-sh.txt /*ale-sh-bashate* ale-sh-language-server ale-sh.txt /*ale-sh-language-server* ale-sh-options ale-sh.txt /*ale-sh-options* ale-sh-shell ale-sh.txt /*ale-sh-shell* @@ -426,26 +570,47 @@ ale-sml-options ale-sml.txt /*ale-sml-options* ale-sml-smlnj ale-sml.txt /*ale-sml-smlnj* ale-sml-smlnj-cm ale-sml.txt /*ale-sml-smlnj-cm* ale-solidity-options ale-solidity.txt /*ale-solidity-options* +ale-solidity-solc ale-solidity.txt /*ale-solidity-solc* ale-solidity-solhint ale-solidity.txt /*ale-solidity-solhint* ale-solidity-solium ale-solidity.txt /*ale-solidity-solium* ale-spec-options ale-spec.txt /*ale-spec-options* ale-spec-rpmlint ale-spec.txt /*ale-spec-rpmlint* ale-special-thanks ale.txt /*ale-special-thanks* ale-sql-options ale-sql.txt /*ale-sql-options* +ale-sql-pgformatter ale-sql.txt /*ale-sql-pgformatter* ale-sql-sqlfmt ale-sql.txt /*ale-sql-sqlfmt* +ale-sql-sqlformat ale-sql.txt /*ale-sql-sqlformat* ale-stylus-options ale-stylus.txt /*ale-stylus-options* ale-stylus-stylelint ale-stylus.txt /*ale-stylus-stylelint* +ale-sugarss-options ale-sugarss.txt /*ale-sugarss-options* +ale-sugarss-stylelint ale-sugarss.txt /*ale-sugarss-stylelint* ale-support ale.txt /*ale-support* +ale-supported-languages-and-tools.txt ale-supported-languages-and-tools.txt /*ale-supported-languages-and-tools.txt* +ale-supported-list ale-supported-languages-and-tools.txt /*ale-supported-list* +ale-svelte-options ale-svelte.txt /*ale-svelte-options* +ale-svelte-prettier ale-svelte.txt /*ale-svelte-prettier* +ale-svelte-svelteserver ale-svelte.txt /*ale-svelte-svelteserver* +ale-swift-apple-swift-format ale-swift.txt /*ale-swift-apple-swift-format* +ale-swift-options ale-swift.txt /*ale-swift-options* +ale-swift-sourcekitlsp ale-swift.txt /*ale-swift-sourcekitlsp* ale-symbol-search ale.txt /*ale-symbol-search* +ale-symbols ale.txt /*ale-symbols* +ale-systemd-analyze ale-systemd.txt /*ale-systemd-analyze* +ale-systemd-options ale-systemd.txt /*ale-systemd-options* ale-tcl-nagelfar ale-tcl.txt /*ale-tcl-nagelfar* ale-tcl-options ale-tcl.txt /*ale-tcl-options* -ale-terraform-fmt ale-terraform.txt /*ale-terraform-fmt* +ale-terraform-fmt-fixer ale-terraform.txt /*ale-terraform-fmt-fixer* ale-terraform-options ale-terraform.txt /*ale-terraform-options* +ale-terraform-terraform ale-terraform.txt /*ale-terraform-terraform* +ale-terraform-terraform-ls ale-terraform.txt /*ale-terraform-terraform-ls* +ale-terraform-terraform-lsp ale-terraform.txt /*ale-terraform-terraform-lsp* ale-terraform-tflint ale-terraform.txt /*ale-terraform-tflint* ale-tests ale-development.txt /*ale-tests* ale-tex-chktex ale-tex.txt /*ale-tex-chktex* ale-tex-lacheck ale-tex.txt /*ale-tex-lacheck* +ale-tex-latexindent ale-tex.txt /*ale-tex-latexindent* ale-tex-options ale-tex.txt /*ale-tex-options* +ale-tex-texlab ale-tex.txt /*ale-tex-texlab* ale-texinfo-options ale-texinfo.txt /*ale-texinfo-options* ale-texinfo-write-good ale-texinfo.txt /*ale-texinfo-write-good* ale-text-options ale-text.txt /*ale-text-options* @@ -453,19 +618,37 @@ ale-text-textlint ale-text.txt /*ale-text-textlint* ale-text-write-good ale-text.txt /*ale-text-write-good* ale-thrift-options ale-thrift.txt /*ale-thrift-options* ale-thrift-thrift ale-thrift.txt /*ale-thrift-thrift* +ale-thrift-thriftcheck ale-thrift.txt /*ale-thrift-thriftcheck* +ale-typescript-deno ale-typescript.txt /*ale-typescript-deno* ale-typescript-eslint ale-typescript.txt /*ale-typescript-eslint* ale-typescript-options ale-typescript.txt /*ale-typescript-options* ale-typescript-prettier ale-typescript.txt /*ale-typescript-prettier* +ale-typescript-standard ale-typescript.txt /*ale-typescript-standard* ale-typescript-tslint ale-typescript.txt /*ale-typescript-tslint* ale-typescript-tsserver ale-typescript.txt /*ale-typescript-tsserver* +ale-typescript-xo ale-typescript.txt /*ale-typescript-xo* +ale-v-options ale-v.txt /*ale-v-options* +ale-v-v ale-v.txt /*ale-v-v* +ale-v-vfmt ale-v.txt /*ale-v-vfmt* ale-vala-options ale-vala.txt /*ale-vala-options* ale-vala-uncrustify ale-vala.txt /*ale-vala-uncrustify* +ale-vala-vala-lint ale-vala.txt /*ale-vala-vala-lint* +ale-verilog-hdl-checker ale-verilog.txt /*ale-verilog-hdl-checker* ale-verilog-iverilog ale-verilog.txt /*ale-verilog-iverilog* ale-verilog-options ale-verilog.txt /*ale-verilog-options* ale-verilog-verilator ale-verilog.txt /*ale-verilog-verilator* +ale-verilog-vlog ale-verilog.txt /*ale-verilog-vlog* +ale-verilog-xvlog ale-verilog.txt /*ale-verilog-xvlog* +ale-verilog-yosys ale-verilog.txt /*ale-verilog-yosys* +ale-vhdl-ghdl ale-vhdl.txt /*ale-vhdl-ghdl* +ale-vhdl-hdl-checker ale-vhdl.txt /*ale-vhdl-hdl-checker* +ale-vhdl-options ale-vhdl.txt /*ale-vhdl-options* +ale-vhdl-vcom ale-vhdl.txt /*ale-vhdl-vcom* +ale-vhdl-xvhdl ale-vhdl.txt /*ale-vhdl-xvhdl* ale-vim-help-options ale-vim-help.txt /*ale-vim-help-options* ale-vim-help-write-good ale-vim-help.txt /*ale-vim-help-write-good* ale-vim-options ale-vim.txt /*ale-vim-options* +ale-vim-vimls ale-vim.txt /*ale-vim-vimls* ale-vim-vint ale-vim.txt /*ale-vim-vint* ale-vue-options ale-vue.txt /*ale-vue-options* ale-vue-prettier ale-vue.txt /*ale-vue-prettier* @@ -475,34 +658,59 @@ ale-xhtml-options ale-xhtml.txt /*ale-xhtml-options* ale-xhtml-write-good ale-xhtml.txt /*ale-xhtml-write-good* ale-xml-options ale-xml.txt /*ale-xml-options* ale-xml-xmllint ale-xml.txt /*ale-xml-xmllint* +ale-yaml-circleci ale-yaml.txt /*ale-yaml-circleci* ale-yaml-options ale-yaml.txt /*ale-yaml-options* ale-yaml-prettier ale-yaml.txt /*ale-yaml-prettier* +ale-yaml-spectral ale-yaml.txt /*ale-yaml-spectral* ale-yaml-swaglint ale-yaml.txt /*ale-yaml-swaglint* +ale-yaml-yamlfix ale-yaml.txt /*ale-yaml-yamlfix* ale-yaml-yamllint ale-yaml.txt /*ale-yaml-yamllint* ale-yang-lsp ale-yang.txt /*ale-yang-lsp* ale-yang-options ale-yang.txt /*ale-yang-options* +ale-zeek-options ale-zeek.txt /*ale-zeek-options* +ale-zeek-zeek ale-zeek.txt /*ale-zeek-zeek* +ale-zig-options ale-zig.txt /*ale-zig-options* +ale-zig-zls ale-zig.txt /*ale-zig-zls* ale.txt ale.txt /*ale.txt* b:ale-c-flawfinder ale-c.txt /*b:ale-c-flawfinder* b:ale-cpp-flawfinder ale-cpp.txt /*b:ale-cpp-flawfinder* +b:ale_ada_adals_encoding ale-ada.txt /*b:ale_ada_adals_encoding* +b:ale_ada_adals_executable ale-ada.txt /*b:ale_ada_adals_executable* +b:ale_ada_adals_project ale-ada.txt /*b:ale_ada_adals_project* b:ale_ada_gcc_executable ale-ada.txt /*b:ale_ada_gcc_executable* b:ale_ada_gcc_options ale-ada.txt /*b:ale_ada_gcc_options* +b:ale_ada_gnatpp_options ale-ada.txt /*b:ale_ada_gnatpp_options* +b:ale_alex_executable ale.txt /*b:ale_alex_executable* +b:ale_alex_use_global ale.txt /*b:ale_alex_use_global* b:ale_ansible_ansible_lint_executable ale-ansible.txt /*b:ale_ansible_ansible_lint_executable* +b:ale_apkbuild_apkbuild_lint_executable ale-apkbuild.txt /*b:ale_apkbuild_apkbuild_lint_executable* +b:ale_apkbuild_secfixes_check_executable ale-apkbuild.txt /*b:ale_apkbuild_secfixes_check_executable* b:ale_asm_gcc_executable ale-asm.txt /*b:ale_asm_gcc_executable* b:ale_asm_gcc_options ale-asm.txt /*b:ale_asm_gcc_options* b:ale_awk_gawk_executable ale-awk.txt /*b:ale_awk_gawk_executable* b:ale_awk_gawk_options ale-awk.txt /*b:ale_awk_gawk_options* +b:ale_bazel_buildifier_executable ale-bazel.txt /*b:ale_bazel_buildifier_executable* +b:ale_bazel_buildifier_options ale-bazel.txt /*b:ale_bazel_buildifier_options* +b:ale_bazel_buildifier_use_global ale-bazel.txt /*b:ale_bazel_buildifier_use_global* +b:ale_c_always_make ale-c.txt /*b:ale_c_always_make* +b:ale_c_astyle_executable ale-c.txt /*b:ale_c_astyle_executable* +b:ale_c_astyle_project_options ale-c.txt /*b:ale_c_astyle_project_options* b:ale_c_build_dir ale-c.txt /*b:ale_c_build_dir* b:ale_c_build_dir_names ale-c.txt /*b:ale_c_build_dir_names* +b:ale_c_cc_executable ale-c.txt /*b:ale_c_cc_executable* +b:ale_c_cc_options ale-c.txt /*b:ale_c_cc_options* b:ale_c_ccls_executable ale-c.txt /*b:ale_c_ccls_executable* b:ale_c_ccls_init_options ale-c.txt /*b:ale_c_ccls_init_options* -b:ale_c_clang_executable ale-c.txt /*b:ale_c_clang_executable* -b:ale_c_clang_options ale-c.txt /*b:ale_c_clang_options* b:ale_c_clangd_executable ale-c.txt /*b:ale_c_clangd_executable* b:ale_c_clangd_options ale-c.txt /*b:ale_c_clangd_options* b:ale_c_clangformat_executable ale-c.txt /*b:ale_c_clangformat_executable* b:ale_c_clangformat_options ale-c.txt /*b:ale_c_clangformat_options* +b:ale_c_clangformat_style_option ale-c.txt /*b:ale_c_clangformat_style_option* +b:ale_c_clangformat_use_local_file ale-c.txt /*b:ale_c_clangformat_use_local_file* b:ale_c_clangtidy_checks ale-c.txt /*b:ale_c_clangtidy_checks* b:ale_c_clangtidy_executable ale-c.txt /*b:ale_c_clangtidy_executable* +b:ale_c_clangtidy_extra_options ale-c.txt /*b:ale_c_clangtidy_extra_options* +b:ale_c_clangtidy_fix_errors ale-c.txt /*b:ale_c_clangtidy_fix_errors* b:ale_c_clangtidy_options ale-c.txt /*b:ale_c_clangtidy_options* b:ale_c_cppcheck_executable ale-c.txt /*b:ale_c_cppcheck_executable* b:ale_c_cppcheck_options ale-c.txt /*b:ale_c_cppcheck_options* @@ -511,28 +719,36 @@ b:ale_c_cquery_executable ale-c.txt /*b:ale_c_cquery_executable* b:ale_c_flawfinder_error_severity ale-c.txt /*b:ale_c_flawfinder_error_severity* b:ale_c_flawfinder_executable ale-c.txt /*b:ale_c_flawfinder_executable* b:ale_c_flawfinder_minlevel ale-c.txt /*b:ale_c_flawfinder_minlevel* -b:ale_c_gcc_executable ale-c.txt /*b:ale_c_gcc_executable* -b:ale_c_gcc_options ale-c.txt /*b:ale_c_gcc_options* b:ale_c_parse_compile_commands ale-c.txt /*b:ale_c_parse_compile_commands* b:ale_c_parse_makefile ale-c.txt /*b:ale_c_parse_makefile* b:ale_c_uncrustify_executable ale-c.txt /*b:ale_c_uncrustify_executable* b:ale_c_uncrustify_options ale-c.txt /*b:ale_c_uncrustify_options* +b:ale_chef_cookstyle_executable ale-chef.txt /*b:ale_chef_cookstyle_executable* +b:ale_chef_cookstyle_options ale-chef.txt /*b:ale_chef_cookstyle_options* b:ale_chef_foodcritic_executable ale-chef.txt /*b:ale_chef_foodcritic_executable* b:ale_chef_foodcritic_options ale-chef.txt /*b:ale_chef_foodcritic_options* +b:ale_clojure_clj_kondo_options ale-clojure.txt /*b:ale_clojure_clj_kondo_options* +b:ale_cmake_cmakeformat_executable ale-cmake.txt /*b:ale_cmake_cmakeformat_executable* +b:ale_cmake_cmakeformat_options ale-cmake.txt /*b:ale_cmake_cmakeformat_options* b:ale_cmake_cmakelint_executable ale-cmake.txt /*b:ale_cmake_cmakelint_executable* b:ale_cmake_cmakelint_options ale-cmake.txt /*b:ale_cmake_cmakelint_options* b:ale_command_wrapper ale.txt /*b:ale_command_wrapper* +b:ale_completion_enabled ale.txt /*b:ale_completion_enabled* b:ale_completion_excluded_words ale.txt /*b:ale_completion_excluded_words* +b:ale_cpp_astyle_executable ale-cpp.txt /*b:ale_cpp_astyle_executable* +b:ale_cpp_astyle_project_options ale-cpp.txt /*b:ale_cpp_astyle_project_options* +b:ale_cpp_cc_executable ale-cpp.txt /*b:ale_cpp_cc_executable* +b:ale_cpp_cc_options ale-cpp.txt /*b:ale_cpp_cc_options* b:ale_cpp_ccls_executable ale-cpp.txt /*b:ale_cpp_ccls_executable* b:ale_cpp_ccls_init_options ale-cpp.txt /*b:ale_cpp_ccls_init_options* -b:ale_cpp_clang_executable ale-cpp.txt /*b:ale_cpp_clang_executable* -b:ale_cpp_clang_options ale-cpp.txt /*b:ale_cpp_clang_options* b:ale_cpp_clangcheck_executable ale-cpp.txt /*b:ale_cpp_clangcheck_executable* b:ale_cpp_clangcheck_options ale-cpp.txt /*b:ale_cpp_clangcheck_options* b:ale_cpp_clangd_executable ale-cpp.txt /*b:ale_cpp_clangd_executable* b:ale_cpp_clangd_options ale-cpp.txt /*b:ale_cpp_clangd_options* b:ale_cpp_clangtidy_checks ale-cpp.txt /*b:ale_cpp_clangtidy_checks* b:ale_cpp_clangtidy_executable ale-cpp.txt /*b:ale_cpp_clangtidy_executable* +b:ale_cpp_clangtidy_extra_options ale-cpp.txt /*b:ale_cpp_clangtidy_extra_options* +b:ale_cpp_clangtidy_fix_errors ale-cpp.txt /*b:ale_cpp_clangtidy_fix_errors* b:ale_cpp_clangtidy_options ale-cpp.txt /*b:ale_cpp_clangtidy_options* b:ale_cpp_clazy_checks ale-cpp.txt /*b:ale_cpp_clazy_checks* b:ale_cpp_clazy_executable ale-cpp.txt /*b:ale_cpp_clazy_executable* @@ -545,8 +761,12 @@ b:ale_cpp_cquery_cache_directory ale-cpp.txt /*b:ale_cpp_cquery_cache_directory* b:ale_cpp_cquery_executable ale-cpp.txt /*b:ale_cpp_cquery_executable* b:ale_cpp_flawfinder_executable ale-cpp.txt /*b:ale_cpp_flawfinder_executable* b:ale_cpp_flawfinder_minlevel ale-cpp.txt /*b:ale_cpp_flawfinder_minlevel* -b:ale_cpp_gcc_executable ale-cpp.txt /*b:ale_cpp_gcc_executable* -b:ale_cpp_gcc_options ale-cpp.txt /*b:ale_cpp_gcc_options* +b:ale_cs_csc_assemblies ale-cs.txt /*b:ale_cs_csc_assemblies* +b:ale_cs_csc_assembly_path ale-cs.txt /*b:ale_cs_csc_assembly_path* +b:ale_cs_csc_options ale-cs.txt /*b:ale_cs_csc_options* +b:ale_cs_csc_source ale-cs.txt /*b:ale_cs_csc_source* +b:ale_cs_dotnet_format_executable ale-cs.txt /*b:ale_cs_dotnet_format_executable* +b:ale_cs_dotnet_format_options ale-cs.txt /*b:ale_cs_dotnet_format_options* b:ale_cs_mcs_options ale-cs.txt /*b:ale_cs_mcs_options* b:ale_cs_mcsc_assemblies ale-cs.txt /*b:ale_cs_mcsc_assemblies* b:ale_cs_mcsc_assembly_path ale-cs.txt /*b:ale_cs_mcsc_assembly_path* @@ -555,12 +775,31 @@ b:ale_cs_mcsc_source ale-cs.txt /*b:ale_cs_mcsc_source* b:ale_css_stylelint_executable ale-css.txt /*b:ale_css_stylelint_executable* b:ale_css_stylelint_options ale-css.txt /*b:ale_css_stylelint_options* b:ale_css_stylelint_use_global ale-css.txt /*b:ale_css_stylelint_use_global* +b:ale_cuda_clangd_executable ale-cuda.txt /*b:ale_cuda_clangd_executable* +b:ale_cuda_clangd_options ale-cuda.txt /*b:ale_cuda_clangd_options* b:ale_cuda_nvcc_executable ale-cuda.txt /*b:ale_cuda_nvcc_executable* b:ale_cuda_nvcc_options ale-cuda.txt /*b:ale_cuda_nvcc_options* +b:ale_d_dfmt_options ale-d.txt /*b:ale_d_dfmt_options* b:ale_d_dls_executable ale-d.txt /*b:ale_d_dls_executable* +b:ale_dafny_dafny_timelimit ale-dafny.txt /*b:ale_dafny_dafny_timelimit* +b:ale_dart_analysis_server_executable ale-dart.txt /*b:ale_dart_analysis_server_executable* +b:ale_dart_analyze_executable ale-dart.txt /*b:ale_dart_analyze_executable* b:ale_dart_dartanalyzer_executable ale-dart.txt /*b:ale_dart_dartanalyzer_executable* b:ale_dart_dartfmt_executable ale-dart.txt /*b:ale_dart_dartfmt_executable* b:ale_dart_dartfmt_options ale-dart.txt /*b:ale_dart_dartfmt_options* +b:ale_dart_format_executable ale-dart.txt /*b:ale_dart_format_executable* +b:ale_dart_format_options ale-dart.txt /*b:ale_dart_format_options* +b:ale_default_navigation ale.txt /*b:ale_default_navigation* +b:ale_deno_executable ale-typescript.txt /*b:ale_deno_executable* +b:ale_deno_importMap ale-typescript.txt /*b:ale_deno_importMap* +b:ale_deno_lsp_project_root ale-typescript.txt /*b:ale_deno_lsp_project_root* +b:ale_deno_unstable ale-typescript.txt /*b:ale_deno_unstable* +b:ale_desktop_desktop_file_validate_options ale-desktop.txt /*b:ale_desktop_desktop_file_validate_options* +b:ale_detail_to_floating_preview ale.txt /*b:ale_detail_to_floating_preview* +b:ale_dhall_executable ale-dhall.txt /*b:ale_dhall_executable* +b:ale_dhall_freeze_options ale-dhall.txt /*b:ale_dhall_freeze_options* +b:ale_dhall_options ale-dhall.txt /*b:ale_dhall_options* +b:ale_disable_lsp ale.txt /*b:ale_disable_lsp* b:ale_dockerfile_dockerfile_lint_executable ale-dockerfile.txt /*b:ale_dockerfile_dockerfile_lint_executable* b:ale_dockerfile_dockerfile_lint_options ale-dockerfile.txt /*b:ale_dockerfile_dockerfile_lint_options* b:ale_dockerfile_hadolint_image ale-dockerfile.txt /*b:ale_dockerfile_hadolint_image* @@ -574,13 +813,33 @@ b:ale_elixir_mix_options ale-elixir.txt /*b:ale_elixir_mix_options* b:ale_elm_format_executable ale-elm.txt /*b:ale_elm_format_executable* b:ale_elm_format_options ale-elm.txt /*b:ale_elm_format_options* b:ale_elm_format_use_global ale-elm.txt /*b:ale_elm_format_use_global* +b:ale_elm_ls_elm_analyse_trigger ale-elm.txt /*b:ale_elm_ls_elm_analyse_trigger* +b:ale_elm_ls_elm_format_path ale-elm.txt /*b:ale_elm_ls_elm_format_path* +b:ale_elm_ls_elm_path ale-elm.txt /*b:ale_elm_ls_elm_path* +b:ale_elm_ls_elm_test_path ale-elm.txt /*b:ale_elm_ls_elm_test_path* +b:ale_elm_ls_executable ale-elm.txt /*b:ale_elm_ls_executable* +b:ale_elm_ls_use_global ale-elm.txt /*b:ale_elm_ls_use_global* b:ale_elm_make_executable ale-elm.txt /*b:ale_elm_make_executable* b:ale_elm_make_use_global ale-elm.txt /*b:ale_elm_make_use_global* b:ale_enabled ale.txt /*b:ale_enabled* +b:ale_erlang_dialyzer_executable ale-erlang.txt /*b:ale_erlang_dialyzer_executable* +b:ale_erlang_dialyzer_options ale-erlang.txt /*b:ale_erlang_dialyzer_options* +b:ale_erlang_dialyzer_plt_file ale-erlang.txt /*b:ale_erlang_dialyzer_plt_file* +b:ale_erlang_dialyzer_rebar3_profile ale-erlang.txt /*b:ale_erlang_dialyzer_rebar3_profile* +b:ale_erlang_elvis_executable ale-erlang.txt /*b:ale_erlang_elvis_executable* +b:ale_erlang_erlc_executable ale-erlang.txt /*b:ale_erlang_erlc_executable* b:ale_erlang_erlc_options ale-erlang.txt /*b:ale_erlang_erlc_options* +b:ale_erlang_erlfmt_executable ale-erlang.txt /*b:ale_erlang_erlfmt_executable* +b:ale_erlang_erlfmt_options ale-erlang.txt /*b:ale_erlang_erlfmt_options* b:ale_erlang_syntaxerl_executable ale-erlang.txt /*b:ale_erlang_syntaxerl_executable* +b:ale_eruby_erblint_executable ale-eruby.txt /*b:ale_eruby_erblint_executable* b:ale_eruby_ruumba_executable ale-eruby.txt /*b:ale_eruby_ruumba_executable* +b:ale_exclude_highlights ale.txt /*b:ale_exclude_highlights* +b:ale_filename_mappings ale.txt /*b:ale_filename_mappings* +b:ale_fish_fish_indent_executable ale-fish.txt /*b:ale_fish_fish_indent_executable* +b:ale_fish_fish_indent_options ale-fish.txt /*b:ale_fish_fish_indent_options* b:ale_fix_on_save ale.txt /*b:ale_fix_on_save* +b:ale_fix_on_save_ignore ale.txt /*b:ale_fix_on_save_ignore* b:ale_fixers ale.txt /*b:ale_fixers* b:ale_fortran_gcc_executable ale-fortran.txt /*b:ale_fortran_gcc_executable* b:ale_fortran_gcc_options ale-fortran.txt /*b:ale_fortran_gcc_options* @@ -598,22 +857,33 @@ b:ale_glsl_glslls_executable ale-glsl.txt /*b:ale_glsl_glslls_executable* b:ale_glsl_glslls_logfile ale-glsl.txt /*b:ale_glsl_glslls_logfile* b:ale_go_bingo_executable ale-go.txt /*b:ale_go_bingo_executable* b:ale_go_bingo_options ale-go.txt /*b:ale_go_bingo_options* -b:ale_go_go_options ale-go.txt /*b:ale_go_go_options* +b:ale_go_go111module ale-go.txt /*b:ale_go_go111module* +b:ale_go_go_executable ale-go.txt /*b:ale_go_go_executable* b:ale_go_gobuild_options ale-go.txt /*b:ale_go_gobuild_options* b:ale_go_gofmt_options ale-go.txt /*b:ale_go_gofmt_options* b:ale_go_golangci_lint_executable ale-go.txt /*b:ale_go_golangci_lint_executable* b:ale_go_golangci_lint_options ale-go.txt /*b:ale_go_golangci_lint_options* b:ale_go_golangci_lint_package ale-go.txt /*b:ale_go_golangci_lint_package* +b:ale_go_golines_options ale-go.txt /*b:ale_go_golines_options* b:ale_go_golint_executable ale-go.txt /*b:ale_go_golint_executable* b:ale_go_golint_options ale-go.txt /*b:ale_go_golint_options* b:ale_go_gometalinter_executable ale-go.txt /*b:ale_go_gometalinter_executable* b:ale_go_gometalinter_lint_package ale-go.txt /*b:ale_go_gometalinter_lint_package* b:ale_go_gometalinter_options ale-go.txt /*b:ale_go_gometalinter_options* +b:ale_go_gopls_executable ale-go.txt /*b:ale_go_gopls_executable* +b:ale_go_gopls_init_options ale-go.txt /*b:ale_go_gopls_init_options* +b:ale_go_gopls_options ale-go.txt /*b:ale_go_gopls_options* +b:ale_go_gopls_use_global ale-go.txt /*b:ale_go_gopls_use_global* b:ale_go_govet_options ale-go.txt /*b:ale_go_govet_options* b:ale_go_langserver_executable ale-go.txt /*b:ale_go_langserver_executable* b:ale_go_langserver_options ale-go.txt /*b:ale_go_langserver_options* +b:ale_go_lines_executable ale-go.txt /*b:ale_go_lines_executable* +b:ale_go_revive_executable ale-go.txt /*b:ale_go_revive_executable* +b:ale_go_revive_options ale-go.txt /*b:ale_go_revive_options* +b:ale_go_staticcheck_executable ale-go.txt /*b:ale_go_staticcheck_executable* b:ale_go_staticcheck_lint_package ale-go.txt /*b:ale_go_staticcheck_lint_package* b:ale_go_staticcheck_options ale-go.txt /*b:ale_go_staticcheck_options* +b:ale_go_staticcheck_use_global ale-go.txt /*b:ale_go_staticcheck_use_global* b:ale_hack_hack_executable ale-hack.txt /*b:ale_hack_hack_executable* b:ale_hack_hackfmt_options ale-hack.txt /*b:ale_hack_hackfmt_options* b:ale_hack_hhast_executable ale-hack.txt /*b:ale_hack_hhast_executable* @@ -621,15 +891,29 @@ b:ale_handlebars_embertemplatelint_executable ale-handlebars.txt /*b:ale_handleb b:ale_handlebars_embertemplatelint_use_global ale-handlebars.txt /*b:ale_handlebars_embertemplatelint_use_global* b:ale_haskell_brittany_executable ale-haskell.txt /*b:ale_haskell_brittany_executable* b:ale_haskell_cabal_ghc_options ale-haskell.txt /*b:ale_haskell_cabal_ghc_options* +b:ale_haskell_floskell_executable ale-haskell.txt /*b:ale_haskell_floskell_executable* b:ale_haskell_ghc_mod_executable ale-haskell.txt /*b:ale_haskell_ghc_mod_executable* b:ale_haskell_ghc_options ale-haskell.txt /*b:ale_haskell_ghc_options* b:ale_haskell_hdevtools_executable ale-haskell.txt /*b:ale_haskell_hdevtools_executable* b:ale_haskell_hdevtools_options ale-haskell.txt /*b:ale_haskell_hdevtools_options* b:ale_haskell_hfmt_executable ale-haskell.txt /*b:ale_haskell_hfmt_executable* b:ale_haskell_hie_executable ale-haskell.txt /*b:ale_haskell_hie_executable* +b:ale_haskell_hindent_executable ale-haskell.txt /*b:ale_haskell_hindent_executable* +b:ale_haskell_his_executable ale-haskell.txt /*b:ale_haskell_his_executable* b:ale_haskell_hlint_executable ale-haskell.txt /*b:ale_haskell_hlint_executable* +b:ale_haskell_ormolu_executable ale-haskell.txt /*b:ale_haskell_ormolu_executable* +b:ale_haskell_ormolu_options ale-haskell.txt /*b:ale_haskell_ormolu_options* b:ale_haskell_stack_build_options ale-haskell.txt /*b:ale_haskell_stack_build_options* +b:ale_haskell_stack_ghc_options ale-haskell.txt /*b:ale_haskell_stack_ghc_options* b:ale_haskell_stylish_haskell_executable ale-haskell.txt /*b:ale_haskell_stylish_haskell_executable* +b:ale_hdl_checker_config_file ale-vhdl.txt /*b:ale_hdl_checker_config_file* +b:ale_hdl_checker_executable ale-vhdl.txt /*b:ale_hdl_checker_executable* +b:ale_hdl_checker_options ale-vhdl.txt /*b:ale_hdl_checker_options* +b:ale_hover_to_floating_preview ale.txt /*b:ale_hover_to_floating_preview* +b:ale_hover_to_preview ale.txt /*b:ale_hover_to_preview* +b:ale_html_angular_executable ale-html.txt /*b:ale_html_angular_executable* +b:ale_html_angular_use_global ale-html.txt /*b:ale_html_angular_use_global* +b:ale_html_beautify_options ale-html.txt /*b:ale_html_beautify_options* b:ale_html_htmlhint_executable ale-html.txt /*b:ale_html_htmlhint_executable* b:ale_html_htmlhint_options ale-html.txt /*b:ale_html_htmlhint_options* b:ale_html_htmlhint_use_global ale-html.txt /*b:ale_html_htmlhint_use_global* @@ -640,22 +924,33 @@ b:ale_html_tidy_executable ale-html.txt /*b:ale_html_tidy_executable* b:ale_html_tidy_options ale-html.txt /*b:ale_html_tidy_options* b:ale_idris_idris_executable ale-idris.txt /*b:ale_idris_idris_executable* b:ale_idris_idris_options ale-idris.txt /*b:ale_idris_idris_options* +b:ale_inko_inko_executable ale-inko.txt /*b:ale_inko_inko_executable* b:ale_ispc_ispc_executable ale-ispc.txt /*b:ale_ispc_ispc_executable* b:ale_ispc_ispc_options ale-ispc.txt /*b:ale_ispc_ispc_options* +b:ale_java_checkstyle_config ale-java.txt /*b:ale_java_checkstyle_config* +b:ale_java_checkstyle_executable ale-java.txt /*b:ale_java_checkstyle_executable* b:ale_java_checkstyle_options ale-java.txt /*b:ale_java_checkstyle_options* +b:ale_java_eclipse_config_path ale-java.txt /*b:ale_java_eclipse_config_path* +b:ale_java_eclipse_executable ale-java.txt /*b:ale_java_eclipse_executable* +b:ale_java_eclipselsp_javaagent ale-java.txt /*b:ale_java_eclipselsp_javaagent* +b:ale_java_eclipselsp_path ale-java.txt /*b:ale_java_eclipselsp_path* +b:ale_java_eclipselsp_workspace_path ale-java.txt /*b:ale_java_eclipselsp_workspace_path* b:ale_java_google_java_format_executable ale-java.txt /*b:ale_java_google_java_format_executable* b:ale_java_google_java_format_options ale-java.txt /*b:ale_java_google_java_format_options* b:ale_java_javac_classpath ale-java.txt /*b:ale_java_javac_classpath* b:ale_java_javac_executable ale-java.txt /*b:ale_java_javac_executable* b:ale_java_javac_options ale-java.txt /*b:ale_java_javac_options* +b:ale_java_javac_sourcepath ale-java.txt /*b:ale_java_javac_sourcepath* +b:ale_java_javalsp_config ale-java.txt /*b:ale_java_javalsp_config* b:ale_java_javalsp_executable ale-java.txt /*b:ale_java_javalsp_executable* -b:ale_java_javalsp_jar ale-java.txt /*b:ale_java_javalsp_jar* b:ale_java_pmd_options ale-java.txt /*b:ale_java_pmd_options* b:ale_javascript_eslint_executable ale-javascript.txt /*b:ale_javascript_eslint_executable* b:ale_javascript_eslint_options ale-javascript.txt /*b:ale_javascript_eslint_options* b:ale_javascript_eslint_suppress_eslintignore ale-javascript.txt /*b:ale_javascript_eslint_suppress_eslintignore* b:ale_javascript_eslint_suppress_missing_config ale-javascript.txt /*b:ale_javascript_eslint_suppress_missing_config* b:ale_javascript_eslint_use_global ale-javascript.txt /*b:ale_javascript_eslint_use_global* +b:ale_javascript_fecs_executable ale-javascript.txt /*b:ale_javascript_fecs_executable* +b:ale_javascript_fecs_use_global ale-javascript.txt /*b:ale_javascript_fecs_use_global* b:ale_javascript_flow_executable ale-javascript.txt /*b:ale_javascript_flow_executable* b:ale_javascript_flow_use_global ale-javascript.txt /*b:ale_javascript_flow_use_global* b:ale_javascript_flow_use_home_config ale-javascript.txt /*b:ale_javascript_flow_use_home_config* @@ -686,15 +981,27 @@ b:ale_json_fixjson_use_global ale-json.txt /*b:ale_json_fixjson_use_global* b:ale_json_jq_executable ale-json.txt /*b:ale_json_jq_executable* b:ale_json_jq_filters ale-json.txt /*b:ale_json_jq_filters* b:ale_json_jq_options ale-json.txt /*b:ale_json_jq_options* +b:ale_json_jsonlint_executable ale-json.txt /*b:ale_json_jsonlint_executable* +b:ale_json_jsonlint_use_global ale-json.txt /*b:ale_json_jsonlint_use_global* +b:ale_json_spectral_executable ale-json.txt /*b:ale_json_spectral_executable* +b:ale_json_spectral_use_global ale-json.txt /*b:ale_json_spectral_use_global* +b:ale_jsonnet_jsonnet_lint_executable ale-jsonnet.txt /*b:ale_jsonnet_jsonnet_lint_executable* +b:ale_jsonnet_jsonnet_lint_options ale-jsonnet.txt /*b:ale_jsonnet_jsonnet_lint_options* +b:ale_jsonnet_jsonnetfmt_executable ale-jsonnet.txt /*b:ale_jsonnet_jsonnetfmt_executable* +b:ale_jsonnet_jsonnetfmt_options ale-jsonnet.txt /*b:ale_jsonnet_jsonnetfmt_options* b:ale_julia_executable ale-julia.txt /*b:ale_julia_executable* b:ale_keep_list_window_open ale.txt /*b:ale_keep_list_window_open* b:ale_lacheck_executable ale-tex.txt /*b:ale_lacheck_executable* +b:ale_languagetool_executable ale.txt /*b:ale_languagetool_executable* +b:ale_languagetool_options ale.txt /*b:ale_languagetool_options* b:ale_less_lessc_executable ale-less.txt /*b:ale_less_lessc_executable* b:ale_less_lessc_options ale-less.txt /*b:ale_less_lessc_options* b:ale_less_lessc_use_global ale-less.txt /*b:ale_less_lessc_use_global* b:ale_less_stylelint_executable ale-less.txt /*b:ale_less_stylelint_executable* b:ale_less_stylelint_options ale-less.txt /*b:ale_less_stylelint_options* b:ale_less_stylelint_use_global ale-less.txt /*b:ale_less_stylelint_use_global* +b:ale_lint_delay ale.txt /*b:ale_lint_delay* +b:ale_lint_on_insert_leave ale.txt /*b:ale_lint_on_insert_leave* b:ale_linted ale.txt /*b:ale_linted* b:ale_linter_aliases ale.txt /*b:ale_linter_aliases* b:ale_linters ale.txt /*b:ale_linters* @@ -703,11 +1010,20 @@ b:ale_list_vertical ale.txt /*b:ale_list_vertical* b:ale_list_window_size ale.txt /*b:ale_list_window_size* b:ale_llvm_llc_executable ale-llvm.txt /*b:ale_llvm_llc_executable* b:ale_loclist_msg_format ale.txt /*b:ale_loclist_msg_format* +b:ale_lua_lua_format_executable ale-lua.txt /*b:ale_lua_lua_format_executable* +b:ale_lua_lua_format_options ale-lua.txt /*b:ale_lua_lua_format_options* b:ale_lua_luac_executable ale-lua.txt /*b:ale_lua_luac_executable* b:ale_lua_luacheck_executable ale-lua.txt /*b:ale_lua_luacheck_executable* b:ale_lua_luacheck_options ale-lua.txt /*b:ale_lua_luacheck_options* +b:ale_lua_luafmt_executable ale-lua.txt /*b:ale_lua_luafmt_executable* +b:ale_lua_luafmt_options ale-lua.txt /*b:ale_lua_luafmt_options* +b:ale_lua_stylua_executable ale-lua.txt /*b:ale_lua_stylua_executable* +b:ale_lua_stylua_options ale-lua.txt /*b:ale_lua_stylua_options* +b:ale_markdown_markdownlint_options ale-markdown.txt /*b:ale_markdown_markdownlint_options* b:ale_markdown_mdl_executable ale-markdown.txt /*b:ale_markdown_mdl_executable* b:ale_markdown_mdl_options ale-markdown.txt /*b:ale_markdown_mdl_options* +b:ale_markdown_pandoc_executable ale-markdown.txt /*b:ale_markdown_pandoc_executable* +b:ale_markdown_pandoc_options ale-markdown.txt /*b:ale_markdown_pandoc_options* b:ale_markdown_remark_lint_executable ale-markdown.txt /*b:ale_markdown_remark_lint_executable* b:ale_markdown_remark_lint_options ale-markdown.txt /*b:ale_markdown_remark_lint_options* b:ale_markdown_remark_lint_use_global ale-markdown.txt /*b:ale_markdown_remark_lint_use_global* @@ -717,6 +1033,12 @@ b:ale_mercury_mmc_executable ale-mercury.txt /*b:ale_mercury_mmc_executable* b:ale_mercury_mmc_options ale-mercury.txt /*b:ale_mercury_mmc_options* b:ale_nasm_nasm_executable ale-nasm.txt /*b:ale_nasm_nasm_executable* b:ale_nasm_nasm_options ale-nasm.txt /*b:ale_nasm_nasm_options* +b:ale_nim_nimpretty_executable ale-nim.txt /*b:ale_nim_nimpretty_executable* +b:ale_nim_nimpretty_options ale-nim.txt /*b:ale_nim_nimpretty_options* +b:ale_nix_nixfmt_executable ale-nix.txt /*b:ale_nix_nixfmt_executable* +b:ale_nix_nixfmt_options ale-nix.txt /*b:ale_nix_nixfmt_options* +b:ale_nix_nixpkgsfmt_executable ale-nix.txt /*b:ale_nix_nixpkgsfmt_executable* +b:ale_nix_nixpkgsfmt_options ale-nix.txt /*b:ale_nix_nixpkgsfmt_options* b:ale_objc_ccls_executable ale-objc.txt /*b:ale_objc_ccls_executable* b:ale_objc_ccls_init_options ale-objc.txt /*b:ale_objc_ccls_init_options* b:ale_objc_clang_options ale-objc.txt /*b:ale_objc_clang_options* @@ -727,9 +1049,17 @@ b:ale_objcpp_clangd_executable ale-objcpp.txt /*b:ale_objcpp_clangd_executable* b:ale_objcpp_clangd_options ale-objcpp.txt /*b:ale_objcpp_clangd_options* b:ale_ocaml_ocamlformat_executable ale-ocaml.txt /*b:ale_ocaml_ocamlformat_executable* b:ale_ocaml_ocamlformat_options ale-ocaml.txt /*b:ale_ocaml_ocamlformat_options* +b:ale_ocaml_ocamllsp_use_opam ale-ocaml.txt /*b:ale_ocaml_ocamllsp_use_opam* +b:ale_ocaml_ocp_indent_config ale-ocaml.txt /*b:ale_ocaml_ocp_indent_config* +b:ale_ocaml_ocp_indent_executable ale-ocaml.txt /*b:ale_ocaml_ocp_indent_executable* +b:ale_ocaml_ocp_indent_options ale-ocaml.txt /*b:ale_ocaml_ocp_indent_options* b:ale_ocaml_ols_executable ale-ocaml.txt /*b:ale_ocaml_ols_executable* b:ale_ocaml_ols_use_global ale-ocaml.txt /*b:ale_ocaml_ols_use_global* b:ale_open_list ale.txt /*b:ale_open_list* +b:ale_openapi_ibm_validator_executable ale-openapi.txt /*b:ale_openapi_ibm_validator_executable* +b:ale_openapi_ibm_validator_options ale-openapi.txt /*b:ale_openapi_ibm_validator_options* +b:ale_pascal_ptop_executable ale-pascal.txt /*b:ale_pascal_ptop_executable* +b:ale_pascal_ptop_options ale-pascal.txt /*b:ale_pascal_ptop_options* b:ale_perl6_perl6_executable ale-perl6.txt /*b:ale_perl6_perl6_executable* b:ale_perl6_perl6_options ale-perl6.txt /*b:ale_perl6_perl6_options* b:ale_perl_perl_executable ale-perl.txt /*b:ale_perl_perl_executable* @@ -741,6 +1071,9 @@ b:ale_perl_perltidy_options ale-perl.txt /*b:ale_perl_perltidy_options* b:ale_php_cs_fixer_executable ale-php.txt /*b:ale_php_cs_fixer_executable* b:ale_php_cs_fixer_options ale-php.txt /*b:ale_php_cs_fixer_options* b:ale_php_cs_fixer_use_global ale-php.txt /*b:ale_php_cs_fixer_use_global* +b:ale_php_intelephense_config ale-php.txt /*b:ale_php_intelephense_config* +b:ale_php_intelephense_executable ale-php.txt /*b:ale_php_intelephense_executable* +b:ale_php_intelephense_use_global ale-php.txt /*b:ale_php_intelephense_use_global* b:ale_php_langserver_executable ale-php.txt /*b:ale_php_langserver_executable* b:ale_php_langserver_use_global ale-php.txt /*b:ale_php_langserver_use_global* b:ale_php_phan_executable ale-php.txt /*b:ale_php_phan_executable* @@ -748,6 +1081,7 @@ b:ale_php_phan_minimum_severity ale-php.txt /*b:ale_php_phan_minimum_severity* b:ale_php_phan_use_client ale-php.txt /*b:ale_php_phan_use_client* b:ale_php_php_executable ale-php.txt /*b:ale_php_php_executable* b:ale_php_phpcbf_executable ale-php.txt /*b:ale_php_phpcbf_executable* +b:ale_php_phpcbf_options ale-php.txt /*b:ale_php_phpcbf_options* b:ale_php_phpcbf_standard ale-php.txt /*b:ale_php_phpcbf_standard* b:ale_php_phpcbf_use_global ale-php.txt /*b:ale_php_phpcbf_use_global* b:ale_php_phpcs_executable ale-php.txt /*b:ale_php_phpcs_executable* @@ -756,12 +1090,22 @@ b:ale_php_phpcs_standard ale-php.txt /*b:ale_php_phpcs_standard* b:ale_php_phpcs_use_global ale-php.txt /*b:ale_php_phpcs_use_global* b:ale_php_phpmd_executable ale-php.txt /*b:ale_php_phpmd_executable* b:ale_php_phpmd_ruleset ale-php.txt /*b:ale_php_phpmd_ruleset* +b:ale_php_phpstan_autoload ale-php.txt /*b:ale_php_phpstan_autoload* b:ale_php_phpstan_configuration ale-php.txt /*b:ale_php_phpstan_configuration* b:ale_php_phpstan_executable ale-php.txt /*b:ale_php_phpstan_executable* b:ale_php_phpstan_level ale-php.txt /*b:ale_php_phpstan_level* b:ale_php_psalm_executable ale-php.txt /*b:ale_php_psalm_executable* +b:ale_php_psalm_options ale-php.txt /*b:ale_php_psalm_options* +b:ale_php_psalm_use_global ale-php.txt /*b:ale_php_psalm_use_global* +b:ale_php_tlint_executable ale-php.txt /*b:ale_php_tlint_executable* +b:ale_php_tlint_options ale-php.txt /*b:ale_php_tlint_options* +b:ale_php_tlint_use_global ale-php.txt /*b:ale_php_tlint_use_global* b:ale_pony_ponyc_executable ale-pony.txt /*b:ale_pony_ponyc_executable* b:ale_pony_ponyc_options ale-pony.txt /*b:ale_pony_ponyc_options* +b:ale_powershell_powershell_executable ale-powershell.txt /*b:ale_powershell_powershell_executable* +b:ale_powershell_psscriptanalyzer_exclusions ale-powershell.txt /*b:ale_powershell_psscriptanalyzer_exclusions* +b:ale_powershell_psscriptanalyzer_executable ale-powershell.txt /*b:ale_powershell_psscriptanalyzer_executable* +b:ale_powershell_psscriptanalyzer_module ale-powershell.txt /*b:ale_powershell_psscriptanalyzer_module* b:ale_prolog_swipl_alarm ale-prolog.txt /*b:ale_prolog_swipl_alarm* b:ale_prolog_swipl_alarm_handler ale-prolog.txt /*b:ale_prolog_swipl_alarm_handler* b:ale_prolog_swipl_executable ale-prolog.txt /*b:ale_prolog_swipl_executable* @@ -775,82 +1119,148 @@ b:ale_puppet_puppet_executable ale-puppet.txt /*b:ale_puppet_puppet_executable* b:ale_puppet_puppet_options ale-puppet.txt /*b:ale_puppet_puppet_options* b:ale_puppet_puppetlint_executable ale-puppet.txt /*b:ale_puppet_puppetlint_executable* b:ale_puppet_puppetlint_options ale-puppet.txt /*b:ale_puppet_puppetlint_options* +b:ale_purescript_purty_executable ale-purescript.txt /*b:ale_purescript_purty_executable* +b:ale_purescript_tidy_executable ale-purescript.txt /*b:ale_purescript_tidy_executable* +b:ale_purescript_tidy_options ale-purescript.txt /*b:ale_purescript_tidy_options* +b:ale_purescript_tidy_use_global ale-purescript.txt /*b:ale_purescript_tidy_use_global* b:ale_pyrex_cython_executable ale-pyrex.txt /*b:ale_pyrex_cython_executable* b:ale_pyrex_cython_options ale-pyrex.txt /*b:ale_pyrex_cython_options* b:ale_python_auto_pipenv ale-python.txt /*b:ale_python_auto_pipenv* +b:ale_python_auto_poetry ale-python.txt /*b:ale_python_auto_poetry* +b:ale_python_autoflake_executable ale-python.txt /*b:ale_python_autoflake_executable* +b:ale_python_autoflake_options ale-python.txt /*b:ale_python_autoflake_options* +b:ale_python_autoflake_use_global ale-python.txt /*b:ale_python_autoflake_use_global* +b:ale_python_autoimport_executable ale-python.txt /*b:ale_python_autoimport_executable* +b:ale_python_autoimport_options ale-python.txt /*b:ale_python_autoimport_options* +b:ale_python_autoimport_use_global ale-python.txt /*b:ale_python_autoimport_use_global* b:ale_python_autopep8_executable ale-python.txt /*b:ale_python_autopep8_executable* b:ale_python_autopep8_options ale-python.txt /*b:ale_python_autopep8_options* b:ale_python_autopep8_use_global ale-python.txt /*b:ale_python_autopep8_use_global* +b:ale_python_bandit_auto_pipenv ale-python.txt /*b:ale_python_bandit_auto_pipenv* +b:ale_python_bandit_auto_poetry ale-python.txt /*b:ale_python_bandit_auto_poetry* +b:ale_python_bandit_executable ale-python.txt /*b:ale_python_bandit_executable* +b:ale_python_bandit_options ale-python.txt /*b:ale_python_bandit_options* +b:ale_python_bandit_use_config ale-python.txt /*b:ale_python_bandit_use_config* +b:ale_python_bandit_use_global ale-python.txt /*b:ale_python_bandit_use_global* b:ale_python_black_auto_pipenv ale-python.txt /*b:ale_python_black_auto_pipenv* +b:ale_python_black_auto_poetry ale-python.txt /*b:ale_python_black_auto_poetry* +b:ale_python_black_change_directory ale-python.txt /*b:ale_python_black_change_directory* b:ale_python_black_executable ale-python.txt /*b:ale_python_black_executable* b:ale_python_black_options ale-python.txt /*b:ale_python_black_options* b:ale_python_black_use_global ale-python.txt /*b:ale_python_black_use_global* b:ale_python_flake8_auto_pipenv ale-python.txt /*b:ale_python_flake8_auto_pipenv* +b:ale_python_flake8_auto_poetry ale-python.txt /*b:ale_python_flake8_auto_poetry* b:ale_python_flake8_change_directory ale-python.txt /*b:ale_python_flake8_change_directory* b:ale_python_flake8_executable ale-python.txt /*b:ale_python_flake8_executable* b:ale_python_flake8_options ale-python.txt /*b:ale_python_flake8_options* b:ale_python_flake8_use_global ale-python.txt /*b:ale_python_flake8_use_global* +b:ale_python_flakehell_auto_pipenv ale-python.txt /*b:ale_python_flakehell_auto_pipenv* +b:ale_python_flakehell_auto_poetry ale-python.txt /*b:ale_python_flakehell_auto_poetry* +b:ale_python_flakehell_change_directory ale-python.txt /*b:ale_python_flakehell_change_directory* +b:ale_python_flakehell_executable ale-python.txt /*b:ale_python_flakehell_executable* +b:ale_python_flakehell_options ale-python.txt /*b:ale_python_flakehell_options* +b:ale_python_flakehell_use_global ale-python.txt /*b:ale_python_flakehell_use_global* +b:ale_python_isort_auto_pipenv ale-python.txt /*b:ale_python_isort_auto_pipenv* +b:ale_python_isort_auto_poetry ale-python.txt /*b:ale_python_isort_auto_poetry* b:ale_python_isort_executable ale-python.txt /*b:ale_python_isort_executable* b:ale_python_isort_options ale-python.txt /*b:ale_python_isort_options* b:ale_python_isort_use_global ale-python.txt /*b:ale_python_isort_use_global* b:ale_python_mypy_auto_pipenv ale-python.txt /*b:ale_python_mypy_auto_pipenv* +b:ale_python_mypy_auto_poetry ale-python.txt /*b:ale_python_mypy_auto_poetry* b:ale_python_mypy_executable ale-python.txt /*b:ale_python_mypy_executable* b:ale_python_mypy_ignore_invalid_syntax ale-python.txt /*b:ale_python_mypy_ignore_invalid_syntax* b:ale_python_mypy_options ale-python.txt /*b:ale_python_mypy_options* +b:ale_python_mypy_show_notes ale-python.txt /*b:ale_python_mypy_show_notes* b:ale_python_mypy_use_global ale-python.txt /*b:ale_python_mypy_use_global* b:ale_python_prospector_auto_pipenv ale-python.txt /*b:ale_python_prospector_auto_pipenv* +b:ale_python_prospector_auto_poetry ale-python.txt /*b:ale_python_prospector_auto_poetry* b:ale_python_prospector_executable ale-python.txt /*b:ale_python_prospector_executable* b:ale_python_prospector_options ale-python.txt /*b:ale_python_prospector_options* b:ale_python_prospector_use_global ale-python.txt /*b:ale_python_prospector_use_global* b:ale_python_pycodestyle_auto_pipenv ale-python.txt /*b:ale_python_pycodestyle_auto_pipenv* +b:ale_python_pycodestyle_auto_poetry ale-python.txt /*b:ale_python_pycodestyle_auto_poetry* b:ale_python_pycodestyle_executable ale-python.txt /*b:ale_python_pycodestyle_executable* b:ale_python_pycodestyle_options ale-python.txt /*b:ale_python_pycodestyle_options* b:ale_python_pycodestyle_use_global ale-python.txt /*b:ale_python_pycodestyle_use_global* b:ale_python_pydocstyle_auto_pipenv ale-python.txt /*b:ale_python_pydocstyle_auto_pipenv* +b:ale_python_pydocstyle_auto_poetry ale-python.txt /*b:ale_python_pydocstyle_auto_poetry* b:ale_python_pydocstyle_executable ale-python.txt /*b:ale_python_pydocstyle_executable* b:ale_python_pydocstyle_options ale-python.txt /*b:ale_python_pydocstyle_options* b:ale_python_pydocstyle_use_global ale-python.txt /*b:ale_python_pydocstyle_use_global* b:ale_python_pyflakes_auto_pipenv ale-python.txt /*b:ale_python_pyflakes_auto_pipenv* +b:ale_python_pyflakes_auto_poetry ale-python.txt /*b:ale_python_pyflakes_auto_poetry* b:ale_python_pyflakes_executable ale-python.txt /*b:ale_python_pyflakes_executable* +b:ale_python_pylama_auto_pipenv ale-python.txt /*b:ale_python_pylama_auto_pipenv* +b:ale_python_pylama_auto_poetry ale-python.txt /*b:ale_python_pylama_auto_poetry* +b:ale_python_pylama_change_directory ale-python.txt /*b:ale_python_pylama_change_directory* +b:ale_python_pylama_executable ale-python.txt /*b:ale_python_pylama_executable* +b:ale_python_pylama_options ale-python.txt /*b:ale_python_pylama_options* +b:ale_python_pylama_use_global ale-python.txt /*b:ale_python_pylama_use_global* b:ale_python_pylint_auto_pipenv ale-python.txt /*b:ale_python_pylint_auto_pipenv* +b:ale_python_pylint_auto_poetry ale-python.txt /*b:ale_python_pylint_auto_poetry* b:ale_python_pylint_change_directory ale-python.txt /*b:ale_python_pylint_change_directory* b:ale_python_pylint_executable ale-python.txt /*b:ale_python_pylint_executable* b:ale_python_pylint_options ale-python.txt /*b:ale_python_pylint_options* b:ale_python_pylint_use_global ale-python.txt /*b:ale_python_pylint_use_global* -b:ale_python_pyls_auto_pipenv ale-python.txt /*b:ale_python_pyls_auto_pipenv* -b:ale_python_pyls_config ale-python.txt /*b:ale_python_pyls_config* -b:ale_python_pyls_executable ale-python.txt /*b:ale_python_pyls_executable* -b:ale_python_pyls_use_global ale-python.txt /*b:ale_python_pyls_use_global* +b:ale_python_pylint_use_msg_id ale-python.txt /*b:ale_python_pylint_use_msg_id* +b:ale_python_pylsp_auto_pipenv ale-python.txt /*b:ale_python_pylsp_auto_pipenv* +b:ale_python_pylsp_auto_poetry ale-python.txt /*b:ale_python_pylsp_auto_poetry* +b:ale_python_pylsp_config ale-python.txt /*b:ale_python_pylsp_config* +b:ale_python_pylsp_executable ale-python.txt /*b:ale_python_pylsp_executable* +b:ale_python_pylsp_options ale-python.txt /*b:ale_python_pylsp_options* +b:ale_python_pylsp_use_global ale-python.txt /*b:ale_python_pylsp_use_global* b:ale_python_pyre_auto_pipenv ale-python.txt /*b:ale_python_pyre_auto_pipenv* +b:ale_python_pyre_auto_poetry ale-python.txt /*b:ale_python_pyre_auto_poetry* b:ale_python_pyre_executable ale-python.txt /*b:ale_python_pyre_executable* b:ale_python_pyre_use_global ale-python.txt /*b:ale_python_pyre_use_global* +b:ale_python_pyright_config ale-python.txt /*b:ale_python_pyright_config* +b:ale_python_pyright_executable ale-python.txt /*b:ale_python_pyright_executable* +b:ale_python_reorder_python_imports_executable ale-python.txt /*b:ale_python_reorder_python_imports_executable* +b:ale_python_reorder_python_imports_options ale-python.txt /*b:ale_python_reorder_python_imports_options* +b:ale_python_reorder_python_imports_use_global ale-python.txt /*b:ale_python_reorder_python_imports_use_global* b:ale_python_vulture_change_directory ale-python.txt /*b:ale_python_vulture_change_directory* b:ale_python_vulture_executable ale-python.txt /*b:ale_python_vulture_executable* +b:ale_python_vulture_options ale-python.txt /*b:ale_python_vulture_options* b:ale_python_vulture_use_global ale-python.txt /*b:ale_python_vulture_use_global* b:ale_python_yapf_executable ale-python.txt /*b:ale_python_yapf_executable* b:ale_python_yapf_use_global ale-python.txt /*b:ale_python_yapf_use_global* b:ale_qml_qmlfmt_executable ale-qml.txt /*b:ale_qml_qmlfmt_executable* +b:ale_r_languageserver_cmd ale-r.txt /*b:ale_r_languageserver_cmd* +b:ale_r_languageserver_config ale-r.txt /*b:ale_r_languageserver_config* b:ale_r_lintr_lint_package ale-r.txt /*b:ale_r_lintr_lint_package* b:ale_r_lintr_options ale-r.txt /*b:ale_r_lintr_options* +b:ale_r_styler_options ale-r.txt /*b:ale_r_styler_options* +b:ale_reason_ls_executable ale-reasonml.txt /*b:ale_reason_ls_executable* b:ale_reason_ols_executable ale-reasonml.txt /*b:ale_reason_ols_executable* b:ale_reason_ols_use_global ale-reasonml.txt /*b:ale_reason_ols_use_global* b:ale_reasonml_refmt_executable ale-reasonml.txt /*b:ale_reasonml_refmt_executable* b:ale_reasonml_refmt_options ale-reasonml.txt /*b:ale_reasonml_refmt_options* +b:ale_robot_rflint_executable ale-robot.txt /*b:ale_robot_rflint_executable* +b:ale_root ale.txt /*b:ale_root* b:ale_ruby_brakeman_executable ale-ruby.txt /*b:ale_ruby_brakeman_executable* b:ale_ruby_brakeman_options ale-ruby.txt /*b:ale_ruby_brakeman_options* +b:ale_ruby_debride_executable ale-ruby.txt /*b:ale_ruby_debride_executable* +b:ale_ruby_debride_options ale-ruby.txt /*b:ale_ruby_debride_options* +b:ale_ruby_erblint_options ale-eruby.txt /*b:ale_ruby_erblint_options* b:ale_ruby_rails_best_practices_executable ale-ruby.txt /*b:ale_ruby_rails_best_practices_executable* b:ale_ruby_rails_best_practices_options ale-ruby.txt /*b:ale_ruby_rails_best_practices_options* b:ale_ruby_reek_executable ale-ruby.txt /*b:ale_ruby_reek_executable* b:ale_ruby_reek_show_context ale-ruby.txt /*b:ale_ruby_reek_show_context* b:ale_ruby_reek_show_wiki_link ale-ruby.txt /*b:ale_ruby_reek_show_wiki_link* +b:ale_ruby_rubocop_auto_correct_all ale-ruby.txt /*b:ale_ruby_rubocop_auto_correct_all* b:ale_ruby_rubocop_executable ale-ruby.txt /*b:ale_ruby_rubocop_executable* b:ale_ruby_rubocop_options ale-ruby.txt /*b:ale_ruby_rubocop_options* b:ale_ruby_ruby_executable ale-ruby.txt /*b:ale_ruby_ruby_executable* b:ale_ruby_rufo_executable ale-ruby.txt /*b:ale_ruby_rufo_executable* b:ale_ruby_ruumba_options ale-eruby.txt /*b:ale_ruby_ruumba_options* b:ale_ruby_solargraph_executable ale-ruby.txt /*b:ale_ruby_solargraph_executable* +b:ale_ruby_sorbet_enable_watchman ale-ruby.txt /*b:ale_ruby_sorbet_enable_watchman* +b:ale_ruby_sorbet_executable ale-ruby.txt /*b:ale_ruby_sorbet_executable* +b:ale_ruby_sorbet_options ale-ruby.txt /*b:ale_ruby_sorbet_options* b:ale_ruby_standardrb_executable ale-ruby.txt /*b:ale_ruby_standardrb_executable* b:ale_ruby_standardrb_options ale-ruby.txt /*b:ale_ruby_standardrb_options* +b:ale_rust_analyzer_config ale-rust.txt /*b:ale_rust_analyzer_config* +b:ale_rust_analyzer_executable ale-rust.txt /*b:ale_rust_analyzer_executable* b:ale_rust_cargo_avoid_whole_workspace ale-rust.txt /*b:ale_rust_cargo_avoid_whole_workspace* b:ale_rust_cargo_check_all_targets ale-rust.txt /*b:ale_rust_cargo_check_all_targets* b:ale_rust_cargo_check_examples ale-rust.txt /*b:ale_rust_cargo_check_examples* @@ -858,16 +1268,20 @@ b:ale_rust_cargo_check_tests ale-rust.txt /*b:ale_rust_cargo_check_tests* b:ale_rust_cargo_clippy_options ale-rust.txt /*b:ale_rust_cargo_clippy_options* b:ale_rust_cargo_default_feature_behavior ale-rust.txt /*b:ale_rust_cargo_default_feature_behavior* b:ale_rust_cargo_include_features ale-rust.txt /*b:ale_rust_cargo_include_features* +b:ale_rust_cargo_target_dir ale-rust.txt /*b:ale_rust_cargo_target_dir* b:ale_rust_cargo_use_check ale-rust.txt /*b:ale_rust_cargo_use_check* b:ale_rust_cargo_use_clippy ale-rust.txt /*b:ale_rust_cargo_use_clippy* b:ale_rust_ignore_error_codes ale-rust.txt /*b:ale_rust_ignore_error_codes* b:ale_rust_ignore_secondary_spans ale-rust.txt /*b:ale_rust_ignore_secondary_spans* +b:ale_rust_rls_config ale-rust.txt /*b:ale_rust_rls_config* b:ale_rust_rls_executable ale-rust.txt /*b:ale_rust_rls_executable* b:ale_rust_rls_toolchain ale-rust.txt /*b:ale_rust_rls_toolchain* b:ale_rust_rustc_options ale-rust.txt /*b:ale_rust_rustc_options* b:ale_rust_rustfmt_options ale-rust.txt /*b:ale_rust_rustfmt_options* b:ale_sass_stylelint_executable ale-sass.txt /*b:ale_sass_stylelint_executable* b:ale_sass_stylelint_use_global ale-sass.txt /*b:ale_sass_stylelint_use_global* +b:ale_scala_metals_executable ale-scala.txt /*b:ale_scala_metals_executable* +b:ale_scala_metals_project_root ale-scala.txt /*b:ale_scala_metals_project_root* b:ale_scala_sbtserver_address ale-scala.txt /*b:ale_scala_sbtserver_address* b:ale_scala_sbtserver_project_root ale-scala.txt /*b:ale_scala_sbtserver_project_root* b:ale_scala_scalafmt_executable ale-scala.txt /*b:ale_scala_scalafmt_executable* @@ -882,29 +1296,56 @@ b:ale_scss_stylelint_options ale-scss.txt /*b:ale_scss_stylelint_options* b:ale_scss_stylelint_use_global ale-scss.txt /*b:ale_scss_stylelint_use_global* b:ale_set_balloons ale.txt /*b:ale_set_balloons* b:ale_set_balloons_legacy_echo ale.txt /*b:ale_set_balloons_legacy_echo* +b:ale_sh_bashate_executable ale-sh.txt /*b:ale_sh_bashate_executable* +b:ale_sh_bashate_options ale-sh.txt /*b:ale_sh_bashate_options* b:ale_sh_language_server_executable ale-sh.txt /*b:ale_sh_language_server_executable* b:ale_sh_language_server_use_global ale-sh.txt /*b:ale_sh_language_server_use_global* b:ale_sh_shell_default_shell ale-sh.txt /*b:ale_sh_shell_default_shell* +b:ale_sh_shellcheck_change_directory ale-sh.txt /*b:ale_sh_shellcheck_change_directory* +b:ale_sh_shellcheck_dialect ale-sh.txt /*b:ale_sh_shellcheck_dialect* b:ale_sh_shellcheck_exclusions ale-sh.txt /*b:ale_sh_shellcheck_exclusions* b:ale_sh_shellcheck_executable ale-sh.txt /*b:ale_sh_shellcheck_executable* b:ale_sh_shellcheck_options ale-sh.txt /*b:ale_sh_shellcheck_options* b:ale_sh_shfmt_options ale-sh.txt /*b:ale_sh_shfmt_options* b:ale_sml_smlnj_cm_file ale-sml.txt /*b:ale_sml_smlnj_cm_file* +b:ale_solidity_solc_executable ale-solidity.txt /*b:ale_solidity_solc_executable* +b:ale_solidity_solc_options ale-solidity.txt /*b:ale_solidity_solc_options* +b:ale_sourcekit_lsp_executable ale-swift.txt /*b:ale_sourcekit_lsp_executable* b:ale_spec_rpmlint_executable ale-spec.txt /*b:ale_spec_rpmlint_executable* b:ale_spec_rpmlint_options ale-spec.txt /*b:ale_spec_rpmlint_options* +b:ale_sql_pgformatter_executable ale-sql.txt /*b:ale_sql_pgformatter_executable* +b:ale_sql_pgformatter_options ale-sql.txt /*b:ale_sql_pgformatter_options* b:ale_sql_sqlfmt_executable ale-sql.txt /*b:ale_sql_sqlfmt_executable* b:ale_sql_sqlfmt_options ale-sql.txt /*b:ale_sql_sqlfmt_options* +b:ale_sql_sqlformat_executable ale-sql.txt /*b:ale_sql_sqlformat_executable* +b:ale_sql_sqlformat_options ale-sql.txt /*b:ale_sql_sqlformat_options* b:ale_stylus_stylelint_executable ale-stylus.txt /*b:ale_stylus_stylelint_executable* b:ale_stylus_stylelint_options ale-stylus.txt /*b:ale_stylus_stylelint_options* b:ale_stylus_stylelint_use_global ale-stylus.txt /*b:ale_stylus_stylelint_use_global* +b:ale_sugarss_stylelint_executable ale-sugarss.txt /*b:ale_sugarss_stylelint_executable* +b:ale_sugarss_stylelint_options ale-sugarss.txt /*b:ale_sugarss_stylelint_options* +b:ale_sugarss_stylelint_use_global ale-sugarss.txt /*b:ale_sugarss_stylelint_use_global* +b:ale_svelte_svelteserver_executable ale-svelte.txt /*b:ale_svelte_svelteserver_executable* +b:ale_svelte_svelteserver_use_global ale-svelte.txt /*b:ale_svelte_svelteserver_use_global* +b:ale_swift_appleswiftformat_executable ale-swift.txt /*b:ale_swift_appleswiftformat_executable* +b:ale_swift_appleswiftformat_use_swiftpm ale-swift.txt /*b:ale_swift_appleswiftformat_use_swiftpm* b:ale_tcl_nagelfar_executable ale-tcl.txt /*b:ale_tcl_nagelfar_executable* b:ale_tcl_nagelfar_options ale-tcl.txt /*b:ale_tcl_nagelfar_options* b:ale_terraform_fmt_executable ale-terraform.txt /*b:ale_terraform_fmt_executable* b:ale_terraform_fmt_options ale-terraform.txt /*b:ale_terraform_fmt_options* +b:ale_terraform_langserver_executable ale-terraform.txt /*b:ale_terraform_langserver_executable* +b:ale_terraform_langserver_options ale-terraform.txt /*b:ale_terraform_langserver_options* +b:ale_terraform_ls_executable ale-terraform.txt /*b:ale_terraform_ls_executable* +b:ale_terraform_ls_options ale-terraform.txt /*b:ale_terraform_ls_options* +b:ale_terraform_terraform_executable ale-terraform.txt /*b:ale_terraform_terraform_executable* b:ale_terraform_tflint_executable ale-terraform.txt /*b:ale_terraform_tflint_executable* b:ale_terraform_tflint_options ale-terraform.txt /*b:ale_terraform_tflint_options* b:ale_tex_chktex_executable ale-tex.txt /*b:ale_tex_chktex_executable* b:ale_tex_chktex_options ale-tex.txt /*b:ale_tex_chktex_options* +b:ale_tex_latexindent_executable ale-tex.txt /*b:ale_tex_latexindent_executable* +b:ale_tex_latexindent_options ale-tex.txt /*b:ale_tex_latexindent_options* +b:ale_tex_texlab_executable ale-tex.txt /*b:ale_tex_texlab_executable* +b:ale_tex_texlab_options ale-tex.txt /*b:ale_tex_texlab_options* b:ale_textlint_executable ale-text.txt /*b:ale_textlint_executable* b:ale_textlint_options ale-text.txt /*b:ale_textlint_options* b:ale_textlint_use_global ale-text.txt /*b:ale_textlint_use_global* @@ -912,7 +1353,12 @@ b:ale_thrift_thrift_executable ale-thrift.txt /*b:ale_thrift_thrift_executable* b:ale_thrift_thrift_generators ale-thrift.txt /*b:ale_thrift_thrift_generators* b:ale_thrift_thrift_includes ale-thrift.txt /*b:ale_thrift_thrift_includes* b:ale_thrift_thrift_options ale-thrift.txt /*b:ale_thrift_thrift_options* +b:ale_thrift_thriftcheck_executable ale-thrift.txt /*b:ale_thrift_thriftcheck_executable* +b:ale_thrift_thriftcheck_options ale-thrift.txt /*b:ale_thrift_thriftcheck_options* b:ale_type_map ale.txt /*b:ale_type_map* +b:ale_typescript_standard_executable ale-typescript.txt /*b:ale_typescript_standard_executable* +b:ale_typescript_standard_options ale-typescript.txt /*b:ale_typescript_standard_options* +b:ale_typescript_standard_use_global ale-typescript.txt /*b:ale_typescript_standard_use_global* b:ale_typescript_tslint_config_path ale-typescript.txt /*b:ale_typescript_tslint_config_path* b:ale_typescript_tslint_executable ale-typescript.txt /*b:ale_typescript_tslint_executable* b:ale_typescript_tslint_ignore_empty_files ale-typescript.txt /*b:ale_typescript_tslint_ignore_empty_files* @@ -921,7 +1367,29 @@ b:ale_typescript_tslint_use_global ale-typescript.txt /*b:ale_typescript_tslint_ b:ale_typescript_tsserver_config_path ale-typescript.txt /*b:ale_typescript_tsserver_config_path* b:ale_typescript_tsserver_executable ale-typescript.txt /*b:ale_typescript_tsserver_executable* b:ale_typescript_tsserver_use_global ale-typescript.txt /*b:ale_typescript_tsserver_use_global* +b:ale_typescript_xo_executable ale-typescript.txt /*b:ale_typescript_xo_executable* +b:ale_typescript_xo_options ale-typescript.txt /*b:ale_typescript_xo_options* +b:ale_typescript_xo_use_global ale-typescript.txt /*b:ale_typescript_xo_use_global* +b:ale_update_tagstack ale.txt /*b:ale_update_tagstack* +b:ale_v_v_executable ale-v.txt /*b:ale_v_v_executable* +b:ale_v_v_options ale-v.txt /*b:ale_v_v_options* +b:ale_v_vfmt_options ale-v.txt /*b:ale_v_vfmt_options* b:ale_verilog_verilator_options ale-verilog.txt /*b:ale_verilog_verilator_options* +b:ale_verilog_vlog_executable ale-verilog.txt /*b:ale_verilog_vlog_executable* +b:ale_verilog_vlog_options ale-verilog.txt /*b:ale_verilog_vlog_options* +b:ale_verilog_xvlog_executable ale-verilog.txt /*b:ale_verilog_xvlog_executable* +b:ale_verilog_xvlog_options ale-verilog.txt /*b:ale_verilog_xvlog_options* +b:ale_verilog_yosys_executable ale-verilog.txt /*b:ale_verilog_yosys_executable* +b:ale_verilog_yosys_options ale-verilog.txt /*b:ale_verilog_yosys_options* +b:ale_vhdl_ghdl_executable ale-vhdl.txt /*b:ale_vhdl_ghdl_executable* +b:ale_vhdl_ghdl_options ale-vhdl.txt /*b:ale_vhdl_ghdl_options* +b:ale_vhdl_vcom_executable ale-vhdl.txt /*b:ale_vhdl_vcom_executable* +b:ale_vhdl_vcom_options ale-vhdl.txt /*b:ale_vhdl_vcom_options* +b:ale_vhdl_xvhdl_executable ale-vhdl.txt /*b:ale_vhdl_xvhdl_executable* +b:ale_vhdl_xvhdl_options ale-vhdl.txt /*b:ale_vhdl_xvhdl_options* +b:ale_vim_vimls_config ale-vim.txt /*b:ale_vim_vimls_config* +b:ale_vim_vimls_executable ale-vim.txt /*b:ale_vim_vimls_executable* +b:ale_vim_vimls_use_global ale-vim.txt /*b:ale_vim_vimls_use_global* b:ale_vim_vint_executable ale-vim.txt /*b:ale_vim_vint_executable* b:ale_vim_vint_show_style_issues ale-vim.txt /*b:ale_vim_vint_show_style_issues* b:ale_virtualenv_dir_names ale.txt /*b:ale_virtualenv_dir_names* @@ -937,35 +1405,63 @@ b:ale_writegood_use_global ale.txt /*b:ale_writegood_use_global* b:ale_xml_xmllint_executable ale-xml.txt /*b:ale_xml_xmllint_executable* b:ale_xml_xmllint_indentsize ale-xml.txt /*b:ale_xml_xmllint_indentsize* b:ale_xml_xmllint_options ale-xml.txt /*b:ale_xml_xmllint_options* +b:ale_yaml_spectral_executable ale-yaml.txt /*b:ale_yaml_spectral_executable* +b:ale_yaml_spectral_use_global ale-yaml.txt /*b:ale_yaml_spectral_use_global* b:ale_yaml_swaglint_executable ale-yaml.txt /*b:ale_yaml_swaglint_executable* b:ale_yaml_swaglint_use_global ale-yaml.txt /*b:ale_yaml_swaglint_use_global* +b:ale_yaml_yamlfix_executable ale-yaml.txt /*b:ale_yaml_yamlfix_executable* +b:ale_yaml_yamlfix_options ale-yaml.txt /*b:ale_yaml_yamlfix_options* +b:ale_yaml_yamlfix_use_global ale-yaml.txt /*b:ale_yaml_yamlfix_use_global* b:ale_yaml_yamllint_executable ale-yaml.txt /*b:ale_yaml_yamllint_executable* b:ale_yaml_yamllint_options ale-yaml.txt /*b:ale_yaml_yamllint_options* b:ale_yang_lsp_executable ale-yang.txt /*b:ale_yang_lsp_executable* +b:ale_zeek_zeek_executable ale-zeek.txt /*b:ale_zeek_zeek_executable* +b:ale_zig_zls_config ale-zig.txt /*b:ale_zig_zls_config* +b:ale_zig_zls_executable ale-zig.txt /*b:ale_zig_zls_executable* +b:vala_vala_lint_config_filename ale-vala.txt /*b:vala_vala_lint_config_filename* +b:vala_vala_lint_executable ale-vala.txt /*b:vala_vala_lint_executable* g:airline#extensions#ale#enabled ale.txt /*g:airline#extensions#ale#enabled* g:ale-c-flawfinder ale-c.txt /*g:ale-c-flawfinder* g:ale-cpp-flawfinder ale-cpp.txt /*g:ale-cpp-flawfinder* +g:ale_ada_adals_encoding ale-ada.txt /*g:ale_ada_adals_encoding* +g:ale_ada_adals_executable ale-ada.txt /*g:ale_ada_adals_executable* +g:ale_ada_adals_project ale-ada.txt /*g:ale_ada_adals_project* g:ale_ada_gcc_executable ale-ada.txt /*g:ale_ada_gcc_executable* g:ale_ada_gcc_options ale-ada.txt /*g:ale_ada_gcc_options* +g:ale_ada_gnatpp_options ale-ada.txt /*g:ale_ada_gnatpp_options* +g:ale_alex_executable ale.txt /*g:ale_alex_executable* +g:ale_alex_use_global ale.txt /*g:ale_alex_use_global* g:ale_ansible_ansible_lint_executable ale-ansible.txt /*g:ale_ansible_ansible_lint_executable* +g:ale_apkbuild_apkbuild_lint_executable ale-apkbuild.txt /*g:ale_apkbuild_apkbuild_lint_executable* +g:ale_apkbuild_secfixes_check_executable ale-apkbuild.txt /*g:ale_apkbuild_secfixes_check_executable* g:ale_asm_gcc_executable ale-asm.txt /*g:ale_asm_gcc_executable* g:ale_asm_gcc_options ale-asm.txt /*g:ale_asm_gcc_options* g:ale_awk_gawk_executable ale-awk.txt /*g:ale_awk_gawk_executable* g:ale_awk_gawk_options ale-awk.txt /*g:ale_awk_gawk_options* +g:ale_bazel_buildifier_executable ale-bazel.txt /*g:ale_bazel_buildifier_executable* +g:ale_bazel_buildifier_options ale-bazel.txt /*g:ale_bazel_buildifier_options* +g:ale_bazel_buildifier_use_global ale-bazel.txt /*g:ale_bazel_buildifier_use_global* g:ale_bib_bibclean_executable ale-bib.txt /*g:ale_bib_bibclean_executable* g:ale_bib_bibclean_options ale-bib.txt /*g:ale_bib_bibclean_options* +g:ale_c_always_make ale-c.txt /*g:ale_c_always_make* +g:ale_c_astyle_executable ale-c.txt /*g:ale_c_astyle_executable* +g:ale_c_astyle_project_options ale-c.txt /*g:ale_c_astyle_project_options* g:ale_c_build_dir ale-c.txt /*g:ale_c_build_dir* g:ale_c_build_dir_names ale-c.txt /*g:ale_c_build_dir_names* +g:ale_c_cc_executable ale-c.txt /*g:ale_c_cc_executable* +g:ale_c_cc_options ale-c.txt /*g:ale_c_cc_options* g:ale_c_ccls_executable ale-c.txt /*g:ale_c_ccls_executable* g:ale_c_ccls_init_options ale-c.txt /*g:ale_c_ccls_init_options* -g:ale_c_clang_executable ale-c.txt /*g:ale_c_clang_executable* -g:ale_c_clang_options ale-c.txt /*g:ale_c_clang_options* g:ale_c_clangd_executable ale-c.txt /*g:ale_c_clangd_executable* g:ale_c_clangd_options ale-c.txt /*g:ale_c_clangd_options* g:ale_c_clangformat_executable ale-c.txt /*g:ale_c_clangformat_executable* g:ale_c_clangformat_options ale-c.txt /*g:ale_c_clangformat_options* +g:ale_c_clangformat_style_option ale-c.txt /*g:ale_c_clangformat_style_option* +g:ale_c_clangformat_use_local_file ale-c.txt /*g:ale_c_clangformat_use_local_file* g:ale_c_clangtidy_checks ale-c.txt /*g:ale_c_clangtidy_checks* g:ale_c_clangtidy_executable ale-c.txt /*g:ale_c_clangtidy_executable* +g:ale_c_clangtidy_extra_options ale-c.txt /*g:ale_c_clangtidy_extra_options* +g:ale_c_clangtidy_fix_errors ale-c.txt /*g:ale_c_clangtidy_fix_errors* g:ale_c_clangtidy_options ale-c.txt /*g:ale_c_clangtidy_options* g:ale_c_cppcheck_executable ale-c.txt /*g:ale_c_cppcheck_executable* g:ale_c_cppcheck_options ale-c.txt /*g:ale_c_cppcheck_options* @@ -974,34 +1470,44 @@ g:ale_c_cquery_executable ale-c.txt /*g:ale_c_cquery_executable* g:ale_c_flawfinder_error_severity ale-c.txt /*g:ale_c_flawfinder_error_severity* g:ale_c_flawfinder_executable ale-c.txt /*g:ale_c_flawfinder_executable* g:ale_c_flawfinder_minlevel ale-c.txt /*g:ale_c_flawfinder_minlevel* -g:ale_c_gcc_executable ale-c.txt /*g:ale_c_gcc_executable* -g:ale_c_gcc_options ale-c.txt /*g:ale_c_gcc_options* g:ale_c_parse_compile_commands ale-c.txt /*g:ale_c_parse_compile_commands* g:ale_c_parse_makefile ale-c.txt /*g:ale_c_parse_makefile* g:ale_c_uncrustify_executable ale-c.txt /*g:ale_c_uncrustify_executable* g:ale_c_uncrustify_options ale-c.txt /*g:ale_c_uncrustify_options* g:ale_cache_executable_check_failures ale.txt /*g:ale_cache_executable_check_failures* g:ale_change_sign_column_color ale.txt /*g:ale_change_sign_column_color* +g:ale_chef_cookstyle_executable ale-chef.txt /*g:ale_chef_cookstyle_executable* +g:ale_chef_cookstyle_options ale-chef.txt /*g:ale_chef_cookstyle_options* g:ale_chef_foodcritic_executable ale-chef.txt /*g:ale_chef_foodcritic_executable* g:ale_chef_foodcritic_options ale-chef.txt /*g:ale_chef_foodcritic_options* +g:ale_clojure_clj_kondo_options ale-clojure.txt /*g:ale_clojure_clj_kondo_options* g:ale_close_preview_on_insert ale.txt /*g:ale_close_preview_on_insert* +g:ale_cmake_cmakeformat_executable ale-cmake.txt /*g:ale_cmake_cmakeformat_executable* +g:ale_cmake_cmakeformat_options ale-cmake.txt /*g:ale_cmake_cmakeformat_options* g:ale_cmake_cmakelint_executable ale-cmake.txt /*g:ale_cmake_cmakelint_executable* g:ale_cmake_cmakelint_options ale-cmake.txt /*g:ale_cmake_cmakelint_options* g:ale_command_wrapper ale.txt /*g:ale_command_wrapper* +g:ale_completion_autoimport ale.txt /*g:ale_completion_autoimport* g:ale_completion_delay ale.txt /*g:ale_completion_delay* g:ale_completion_enabled ale.txt /*g:ale_completion_enabled* g:ale_completion_excluded_words ale.txt /*g:ale_completion_excluded_words* g:ale_completion_max_suggestions ale.txt /*g:ale_completion_max_suggestions* +g:ale_completion_symbols ale.txt /*g:ale_completion_symbols* +g:ale_completion_tsserver_remove_warnings ale.txt /*g:ale_completion_tsserver_remove_warnings* +g:ale_cpp_astyle_executable ale-cpp.txt /*g:ale_cpp_astyle_executable* +g:ale_cpp_astyle_project_options ale-cpp.txt /*g:ale_cpp_astyle_project_options* +g:ale_cpp_cc_executable ale-cpp.txt /*g:ale_cpp_cc_executable* +g:ale_cpp_cc_options ale-cpp.txt /*g:ale_cpp_cc_options* g:ale_cpp_ccls_executable ale-cpp.txt /*g:ale_cpp_ccls_executable* g:ale_cpp_ccls_init_options ale-cpp.txt /*g:ale_cpp_ccls_init_options* -g:ale_cpp_clang_executable ale-cpp.txt /*g:ale_cpp_clang_executable* -g:ale_cpp_clang_options ale-cpp.txt /*g:ale_cpp_clang_options* g:ale_cpp_clangcheck_executable ale-cpp.txt /*g:ale_cpp_clangcheck_executable* g:ale_cpp_clangcheck_options ale-cpp.txt /*g:ale_cpp_clangcheck_options* g:ale_cpp_clangd_executable ale-cpp.txt /*g:ale_cpp_clangd_executable* g:ale_cpp_clangd_options ale-cpp.txt /*g:ale_cpp_clangd_options* g:ale_cpp_clangtidy_checks ale-cpp.txt /*g:ale_cpp_clangtidy_checks* g:ale_cpp_clangtidy_executable ale-cpp.txt /*g:ale_cpp_clangtidy_executable* +g:ale_cpp_clangtidy_extra_options ale-cpp.txt /*g:ale_cpp_clangtidy_extra_options* +g:ale_cpp_clangtidy_fix_errors ale-cpp.txt /*g:ale_cpp_clangtidy_fix_errors* g:ale_cpp_clangtidy_options ale-cpp.txt /*g:ale_cpp_clangtidy_options* g:ale_cpp_clazy_checks ale-cpp.txt /*g:ale_cpp_clazy_checks* g:ale_cpp_clazy_executable ale-cpp.txt /*g:ale_cpp_clazy_executable* @@ -1014,8 +1520,12 @@ g:ale_cpp_cquery_cache_directory ale-cpp.txt /*g:ale_cpp_cquery_cache_directory* g:ale_cpp_cquery_executable ale-cpp.txt /*g:ale_cpp_cquery_executable* g:ale_cpp_flawfinder_executable ale-cpp.txt /*g:ale_cpp_flawfinder_executable* g:ale_cpp_flawfinder_minlevel ale-cpp.txt /*g:ale_cpp_flawfinder_minlevel* -g:ale_cpp_gcc_executable ale-cpp.txt /*g:ale_cpp_gcc_executable* -g:ale_cpp_gcc_options ale-cpp.txt /*g:ale_cpp_gcc_options* +g:ale_cs_csc_assemblies ale-cs.txt /*g:ale_cs_csc_assemblies* +g:ale_cs_csc_assembly_path ale-cs.txt /*g:ale_cs_csc_assembly_path* +g:ale_cs_csc_options ale-cs.txt /*g:ale_cs_csc_options* +g:ale_cs_csc_source ale-cs.txt /*g:ale_cs_csc_source* +g:ale_cs_dotnet_format_executable ale-cs.txt /*g:ale_cs_dotnet_format_executable* +g:ale_cs_dotnet_format_options ale-cs.txt /*g:ale_cs_dotnet_format_options* g:ale_cs_mcs_options ale-cs.txt /*g:ale_cs_mcs_options* g:ale_cs_mcsc_assemblies ale-cs.txt /*g:ale_cs_mcsc_assemblies* g:ale_cs_mcsc_assembly_path ale-cs.txt /*g:ale_cs_mcsc_assembly_path* @@ -1024,13 +1534,32 @@ g:ale_cs_mcsc_source ale-cs.txt /*g:ale_cs_mcsc_source* g:ale_css_stylelint_executable ale-css.txt /*g:ale_css_stylelint_executable* g:ale_css_stylelint_options ale-css.txt /*g:ale_css_stylelint_options* g:ale_css_stylelint_use_global ale-css.txt /*g:ale_css_stylelint_use_global* +g:ale_cuda_clangd_executable ale-cuda.txt /*g:ale_cuda_clangd_executable* +g:ale_cuda_clangd_options ale-cuda.txt /*g:ale_cuda_clangd_options* g:ale_cuda_nvcc_executable ale-cuda.txt /*g:ale_cuda_nvcc_executable* g:ale_cuda_nvcc_options ale-cuda.txt /*g:ale_cuda_nvcc_options* g:ale_cursor_detail ale.txt /*g:ale_cursor_detail* +g:ale_d_dfmt_options ale-d.txt /*g:ale_d_dfmt_options* g:ale_d_dls_executable ale-d.txt /*g:ale_d_dls_executable* +g:ale_dafny_dafny_timelimit ale-dafny.txt /*g:ale_dafny_dafny_timelimit* +g:ale_dart_analysis_server_executable ale-dart.txt /*g:ale_dart_analysis_server_executable* +g:ale_dart_analyze_executable ale-dart.txt /*g:ale_dart_analyze_executable* g:ale_dart_dartanalyzer_executable ale-dart.txt /*g:ale_dart_dartanalyzer_executable* g:ale_dart_dartfmt_executable ale-dart.txt /*g:ale_dart_dartfmt_executable* g:ale_dart_dartfmt_options ale-dart.txt /*g:ale_dart_dartfmt_options* +g:ale_dart_format_executable ale-dart.txt /*g:ale_dart_format_executable* +g:ale_dart_format_options ale-dart.txt /*g:ale_dart_format_options* +g:ale_default_navigation ale.txt /*g:ale_default_navigation* +g:ale_deno_executable ale-typescript.txt /*g:ale_deno_executable* +g:ale_deno_importMap ale-typescript.txt /*g:ale_deno_importMap* +g:ale_deno_lsp_project_root ale-typescript.txt /*g:ale_deno_lsp_project_root* +g:ale_deno_unstable ale-typescript.txt /*g:ale_deno_unstable* +g:ale_desktop_desktop_file_validate_options ale-desktop.txt /*g:ale_desktop_desktop_file_validate_options* +g:ale_detail_to_floating_preview ale.txt /*g:ale_detail_to_floating_preview* +g:ale_dhall_executable ale-dhall.txt /*g:ale_dhall_executable* +g:ale_dhall_freeze_options ale-dhall.txt /*g:ale_dhall_freeze_options* +g:ale_dhall_options ale-dhall.txt /*g:ale_dhall_options* +g:ale_disable_lsp ale.txt /*g:ale_disable_lsp* g:ale_dockerfile_dockerfile_lint_executable ale-dockerfile.txt /*g:ale_dockerfile_dockerfile_lint_executable* g:ale_dockerfile_dockerfile_lint_options ale-dockerfile.txt /*g:ale_dockerfile_dockerfile_lint_options* g:ale_dockerfile_hadolint_image ale-dockerfile.txt /*g:ale_dockerfile_hadolint_image* @@ -1040,7 +1569,9 @@ g:ale_echo_delay ale.txt /*g:ale_echo_delay* g:ale_echo_msg_error_str ale.txt /*g:ale_echo_msg_error_str* g:ale_echo_msg_format ale.txt /*g:ale_echo_msg_format* g:ale_echo_msg_info_str ale.txt /*g:ale_echo_msg_info_str* +g:ale_echo_msg_log_str ale.txt /*g:ale_echo_msg_log_str* g:ale_echo_msg_warning_str ale.txt /*g:ale_echo_msg_warning_str* +g:ale_elixir_credo_strict ale-elixir.txt /*g:ale_elixir_credo_strict* g:ale_elixir_elixir_ls_config ale-elixir.txt /*g:ale_elixir_elixir_ls_config* g:ale_elixir_elixir_ls_release ale-elixir.txt /*g:ale_elixir_elixir_ls_release* g:ale_elixir_mix_format_options ale-elixir.txt /*g:ale_elixir_mix_format_options* @@ -1048,14 +1579,36 @@ g:ale_elixir_mix_options ale-elixir.txt /*g:ale_elixir_mix_options* g:ale_elm_format_executable ale-elm.txt /*g:ale_elm_format_executable* g:ale_elm_format_options ale-elm.txt /*g:ale_elm_format_options* g:ale_elm_format_use_global ale-elm.txt /*g:ale_elm_format_use_global* +g:ale_elm_ls_elm_analyse_trigger ale-elm.txt /*g:ale_elm_ls_elm_analyse_trigger* +g:ale_elm_ls_elm_format_path ale-elm.txt /*g:ale_elm_ls_elm_format_path* +g:ale_elm_ls_elm_path ale-elm.txt /*g:ale_elm_ls_elm_path* +g:ale_elm_ls_elm_test_path ale-elm.txt /*g:ale_elm_ls_elm_test_path* +g:ale_elm_ls_executable ale-elm.txt /*g:ale_elm_ls_executable* +g:ale_elm_ls_use_global ale-elm.txt /*g:ale_elm_ls_use_global* g:ale_elm_make_executable ale-elm.txt /*g:ale_elm_make_executable* g:ale_elm_make_use_global ale-elm.txt /*g:ale_elm_make_use_global* g:ale_enabled ale.txt /*g:ale_enabled* +g:ale_erlang_dialyzer_executable ale-erlang.txt /*g:ale_erlang_dialyzer_executable* +g:ale_erlang_dialyzer_options ale-erlang.txt /*g:ale_erlang_dialyzer_options* +g:ale_erlang_dialyzer_plt_file ale-erlang.txt /*g:ale_erlang_dialyzer_plt_file* +g:ale_erlang_dialyzer_rebar3_profile ale-erlang.txt /*g:ale_erlang_dialyzer_rebar3_profile* +g:ale_erlang_elvis_executable ale-erlang.txt /*g:ale_erlang_elvis_executable* +g:ale_erlang_erlc_executable ale-erlang.txt /*g:ale_erlang_erlc_executable* g:ale_erlang_erlc_options ale-erlang.txt /*g:ale_erlang_erlc_options* +g:ale_erlang_erlfmt_executable ale-erlang.txt /*g:ale_erlang_erlfmt_executable* +g:ale_erlang_erlfmt_options ale-erlang.txt /*g:ale_erlang_erlfmt_options* g:ale_erlang_syntaxerl_executable ale-erlang.txt /*g:ale_erlang_syntaxerl_executable* +g:ale_eruby_erblint_executable ale-eruby.txt /*g:ale_eruby_erblint_executable* g:ale_eruby_ruumba_executable ale-eruby.txt /*g:ale_eruby_ruumba_executable* +g:ale_exclude_highlights ale.txt /*g:ale_exclude_highlights* +g:ale_filename_mappings ale.txt /*g:ale_filename_mappings* +g:ale_fish_fish_indent_executable ale-fish.txt /*g:ale_fish_fish_indent_executable* +g:ale_fish_fish_indent_options ale-fish.txt /*g:ale_fish_fish_indent_options* g:ale_fix_on_save ale.txt /*g:ale_fix_on_save* +g:ale_fix_on_save_ignore ale.txt /*g:ale_fix_on_save_ignore* g:ale_fixers ale.txt /*g:ale_fixers* +g:ale_floating_preview ale.txt /*g:ale_floating_preview* +g:ale_floating_window_border ale.txt /*g:ale_floating_window_border* g:ale_fortran_gcc_executable ale-fortran.txt /*g:ale_fortran_gcc_executable* g:ale_fortran_gcc_options ale-fortran.txt /*g:ale_fortran_gcc_options* g:ale_fortran_gcc_use_free_form ale-fortran.txt /*g:ale_fortran_gcc_use_free_form* @@ -1072,22 +1625,33 @@ g:ale_glsl_glslls_executable ale-glsl.txt /*g:ale_glsl_glslls_executable* g:ale_glsl_glslls_logfile ale-glsl.txt /*g:ale_glsl_glslls_logfile* g:ale_go_bingo_executable ale-go.txt /*g:ale_go_bingo_executable* g:ale_go_bingo_options ale-go.txt /*g:ale_go_bingo_options* -g:ale_go_go_options ale-go.txt /*g:ale_go_go_options* +g:ale_go_go111module ale-go.txt /*g:ale_go_go111module* +g:ale_go_go_executable ale-go.txt /*g:ale_go_go_executable* g:ale_go_gobuild_options ale-go.txt /*g:ale_go_gobuild_options* g:ale_go_gofmt_options ale-go.txt /*g:ale_go_gofmt_options* g:ale_go_golangci_lint_executable ale-go.txt /*g:ale_go_golangci_lint_executable* g:ale_go_golangci_lint_options ale-go.txt /*g:ale_go_golangci_lint_options* g:ale_go_golangci_lint_package ale-go.txt /*g:ale_go_golangci_lint_package* +g:ale_go_golines_options ale-go.txt /*g:ale_go_golines_options* g:ale_go_golint_executable ale-go.txt /*g:ale_go_golint_executable* g:ale_go_golint_options ale-go.txt /*g:ale_go_golint_options* g:ale_go_gometalinter_executable ale-go.txt /*g:ale_go_gometalinter_executable* g:ale_go_gometalinter_lint_package ale-go.txt /*g:ale_go_gometalinter_lint_package* g:ale_go_gometalinter_options ale-go.txt /*g:ale_go_gometalinter_options* +g:ale_go_gopls_executable ale-go.txt /*g:ale_go_gopls_executable* +g:ale_go_gopls_init_options ale-go.txt /*g:ale_go_gopls_init_options* +g:ale_go_gopls_options ale-go.txt /*g:ale_go_gopls_options* +g:ale_go_gopls_use_global ale-go.txt /*g:ale_go_gopls_use_global* g:ale_go_govet_options ale-go.txt /*g:ale_go_govet_options* g:ale_go_langserver_executable ale-go.txt /*g:ale_go_langserver_executable* g:ale_go_langserver_options ale-go.txt /*g:ale_go_langserver_options* +g:ale_go_lines_executable ale-go.txt /*g:ale_go_lines_executable* +g:ale_go_revive_executable ale-go.txt /*g:ale_go_revive_executable* +g:ale_go_revive_options ale-go.txt /*g:ale_go_revive_options* +g:ale_go_staticcheck_executable ale-go.txt /*g:ale_go_staticcheck_executable* g:ale_go_staticcheck_lint_package ale-go.txt /*g:ale_go_staticcheck_lint_package* g:ale_go_staticcheck_options ale-go.txt /*g:ale_go_staticcheck_options* +g:ale_go_staticcheck_use_global ale-go.txt /*g:ale_go_staticcheck_use_global* g:ale_hack_hack_executable ale-hack.txt /*g:ale_hack_hack_executable* g:ale_hack_hackfmt_options ale-hack.txt /*g:ale_hack_hackfmt_options* g:ale_hack_hhast_executable ale-hack.txt /*g:ale_hack_hhast_executable* @@ -1095,17 +1659,32 @@ g:ale_handlebars_embertemplatelint_executable ale-handlebars.txt /*g:ale_handleb g:ale_handlebars_embertemplatelint_use_global ale-handlebars.txt /*g:ale_handlebars_embertemplatelint_use_global* g:ale_haskell_brittany_executable ale-haskell.txt /*g:ale_haskell_brittany_executable* g:ale_haskell_cabal_ghc_options ale-haskell.txt /*g:ale_haskell_cabal_ghc_options* +g:ale_haskell_floskell_executable ale-haskell.txt /*g:ale_haskell_floskell_executable* g:ale_haskell_ghc_mod_executable ale-haskell.txt /*g:ale_haskell_ghc_mod_executable* g:ale_haskell_ghc_options ale-haskell.txt /*g:ale_haskell_ghc_options* g:ale_haskell_hdevtools_executable ale-haskell.txt /*g:ale_haskell_hdevtools_executable* g:ale_haskell_hdevtools_options ale-haskell.txt /*g:ale_haskell_hdevtools_options* g:ale_haskell_hfmt_executable ale-haskell.txt /*g:ale_haskell_hfmt_executable* g:ale_haskell_hie_executable ale-haskell.txt /*g:ale_haskell_hie_executable* +g:ale_haskell_hindent_executable ale-haskell.txt /*g:ale_haskell_hindent_executable* g:ale_haskell_hlint_executable ale-haskell.txt /*g:ale_haskell_hlint_executable* +g:ale_haskell_hls_executable ale-haskell.txt /*g:ale_haskell_hls_executable* +g:ale_haskell_ormolu_executable ale-haskell.txt /*g:ale_haskell_ormolu_executable* +g:ale_haskell_ormolu_options ale-haskell.txt /*g:ale_haskell_ormolu_options* g:ale_haskell_stack_build_options ale-haskell.txt /*g:ale_haskell_stack_build_options* +g:ale_haskell_stack_ghc_options ale-haskell.txt /*g:ale_haskell_stack_ghc_options* g:ale_haskell_stylish_haskell_executable ale-haskell.txt /*g:ale_haskell_stylish_haskell_executable* +g:ale_hdl_checker_config_file ale-vhdl.txt /*g:ale_hdl_checker_config_file* +g:ale_hdl_checker_executable ale-vhdl.txt /*g:ale_hdl_checker_executable* +g:ale_hdl_checker_options ale-vhdl.txt /*g:ale_hdl_checker_options* g:ale_history_enabled ale.txt /*g:ale_history_enabled* g:ale_history_log_output ale.txt /*g:ale_history_log_output* +g:ale_hover_cursor ale.txt /*g:ale_hover_cursor* +g:ale_hover_to_floating_preview ale.txt /*g:ale_hover_to_floating_preview* +g:ale_hover_to_preview ale.txt /*g:ale_hover_to_preview* +g:ale_html_angular_executable ale-html.txt /*g:ale_html_angular_executable* +g:ale_html_angular_use_global ale-html.txt /*g:ale_html_angular_use_global* +g:ale_html_beautify_options ale-html.txt /*g:ale_html_beautify_options* g:ale_html_htmlhint_executable ale-html.txt /*g:ale_html_htmlhint_executable* g:ale_html_htmlhint_options ale-html.txt /*g:ale_html_htmlhint_options* g:ale_html_htmlhint_use_global ale-html.txt /*g:ale_html_htmlhint_use_global* @@ -1116,22 +1695,33 @@ g:ale_html_tidy_executable ale-html.txt /*g:ale_html_tidy_executable* g:ale_html_tidy_options ale-html.txt /*g:ale_html_tidy_options* g:ale_idris_idris_executable ale-idris.txt /*g:ale_idris_idris_executable* g:ale_idris_idris_options ale-idris.txt /*g:ale_idris_idris_options* +g:ale_inko_inko_executable ale-inko.txt /*g:ale_inko_inko_executable* g:ale_ispc_ispc_executable ale-ispc.txt /*g:ale_ispc_ispc_executable* g:ale_ispc_ispc_options ale-ispc.txt /*g:ale_ispc_ispc_options* +g:ale_java_checkstyle_config ale-java.txt /*g:ale_java_checkstyle_config* +g:ale_java_checkstyle_executable ale-java.txt /*g:ale_java_checkstyle_executable* g:ale_java_checkstyle_options ale-java.txt /*g:ale_java_checkstyle_options* +g:ale_java_eclipse_config_path ale-java.txt /*g:ale_java_eclipse_config_path* +g:ale_java_eclipse_executable ale-java.txt /*g:ale_java_eclipse_executable* +g:ale_java_eclipselsp_javaagent ale-java.txt /*g:ale_java_eclipselsp_javaagent* +g:ale_java_eclipselsp_path ale-java.txt /*g:ale_java_eclipselsp_path* +g:ale_java_eclipselsp_workspace_path ale-java.txt /*g:ale_java_eclipselsp_workspace_path* g:ale_java_google_java_format_executable ale-java.txt /*g:ale_java_google_java_format_executable* g:ale_java_google_java_format_options ale-java.txt /*g:ale_java_google_java_format_options* g:ale_java_javac_classpath ale-java.txt /*g:ale_java_javac_classpath* g:ale_java_javac_executable ale-java.txt /*g:ale_java_javac_executable* g:ale_java_javac_options ale-java.txt /*g:ale_java_javac_options* +g:ale_java_javac_sourcepath ale-java.txt /*g:ale_java_javac_sourcepath* +g:ale_java_javalsp_config ale-java.txt /*g:ale_java_javalsp_config* g:ale_java_javalsp_executable ale-java.txt /*g:ale_java_javalsp_executable* -g:ale_java_javalsp_jar ale-java.txt /*g:ale_java_javalsp_jar* g:ale_java_pmd_options ale-java.txt /*g:ale_java_pmd_options* g:ale_javascript_eslint_executable ale-javascript.txt /*g:ale_javascript_eslint_executable* g:ale_javascript_eslint_options ale-javascript.txt /*g:ale_javascript_eslint_options* g:ale_javascript_eslint_suppress_eslintignore ale-javascript.txt /*g:ale_javascript_eslint_suppress_eslintignore* g:ale_javascript_eslint_suppress_missing_config ale-javascript.txt /*g:ale_javascript_eslint_suppress_missing_config* g:ale_javascript_eslint_use_global ale-javascript.txt /*g:ale_javascript_eslint_use_global* +g:ale_javascript_fecs_executable ale-javascript.txt /*g:ale_javascript_fecs_executable* +g:ale_javascript_fecs_use_global ale-javascript.txt /*g:ale_javascript_fecs_use_global* g:ale_javascript_flow_executable ale-javascript.txt /*g:ale_javascript_flow_executable* g:ale_javascript_flow_use_global ale-javascript.txt /*g:ale_javascript_flow_use_global* g:ale_javascript_flow_use_home_config ale-javascript.txt /*g:ale_javascript_flow_use_home_config* @@ -1162,6 +1752,14 @@ g:ale_json_fixjson_use_global ale-json.txt /*g:ale_json_fixjson_use_global* g:ale_json_jq_executable ale-json.txt /*g:ale_json_jq_executable* g:ale_json_jq_filters ale-json.txt /*g:ale_json_jq_filters* g:ale_json_jq_options ale-json.txt /*g:ale_json_jq_options* +g:ale_json_jsonlint_executable ale-json.txt /*g:ale_json_jsonlint_executable* +g:ale_json_jsonlint_use_global ale-json.txt /*g:ale_json_jsonlint_use_global* +g:ale_json_spectral_executable ale-json.txt /*g:ale_json_spectral_executable* +g:ale_json_spectral_use_global ale-json.txt /*g:ale_json_spectral_use_global* +g:ale_jsonnet_jsonnet_lint_executable ale-jsonnet.txt /*g:ale_jsonnet_jsonnet_lint_executable* +g:ale_jsonnet_jsonnet_lint_options ale-jsonnet.txt /*g:ale_jsonnet_jsonnet_lint_options* +g:ale_jsonnet_jsonnetfmt_executable ale-jsonnet.txt /*g:ale_jsonnet_jsonnetfmt_executable* +g:ale_jsonnet_jsonnetfmt_options ale-jsonnet.txt /*g:ale_jsonnet_jsonnetfmt_options* g:ale_julia_executable ale-julia.txt /*g:ale_julia_executable* g:ale_keep_list_window_open ale.txt /*g:ale_keep_list_window_open* g:ale_kotlin_kotlinc_classpath ale-kotlin.txt /*g:ale_kotlin_kotlinc_classpath* @@ -1172,9 +1770,12 @@ g:ale_kotlin_kotlinc_options ale-kotlin.txt /*g:ale_kotlin_kotlinc_options* g:ale_kotlin_kotlinc_sourcepath ale-kotlin.txt /*g:ale_kotlin_kotlinc_sourcepath* g:ale_kotlin_kotlinc_use_module_file ale-kotlin.txt /*g:ale_kotlin_kotlinc_use_module_file* g:ale_kotlin_ktlint_executable ale-kotlin.txt /*g:ale_kotlin_ktlint_executable* +g:ale_kotlin_ktlint_options ale-kotlin.txt /*g:ale_kotlin_ktlint_options* g:ale_kotlin_ktlint_rulesets ale-kotlin.txt /*g:ale_kotlin_ktlint_rulesets* g:ale_kotlin_languageserver_executable ale-kotlin.txt /*g:ale_kotlin_languageserver_executable* g:ale_lacheck_executable ale-tex.txt /*g:ale_lacheck_executable* +g:ale_languagetool_executable ale.txt /*g:ale_languagetool_executable* +g:ale_languagetool_options ale.txt /*g:ale_languagetool_options* g:ale_less_lessc_executable ale-less.txt /*g:ale_less_lessc_executable* g:ale_less_lessc_options ale-less.txt /*g:ale_less_lessc_options* g:ale_less_lessc_use_global ale-less.txt /*g:ale_less_lessc_use_global* @@ -1195,11 +1796,23 @@ g:ale_list_vertical ale.txt /*g:ale_list_vertical* g:ale_list_window_size ale.txt /*g:ale_list_window_size* g:ale_llvm_llc_executable ale-llvm.txt /*g:ale_llvm_llc_executable* g:ale_loclist_msg_format ale.txt /*g:ale_loclist_msg_format* +g:ale_lsp_show_message_format ale.txt /*g:ale_lsp_show_message_format* +g:ale_lsp_show_message_severity ale.txt /*g:ale_lsp_show_message_severity* +g:ale_lsp_suggestions ale.txt /*g:ale_lsp_suggestions* +g:ale_lua_lua_format_executable ale-lua.txt /*g:ale_lua_lua_format_executable* +g:ale_lua_lua_format_options ale-lua.txt /*g:ale_lua_lua_format_options* g:ale_lua_luac_executable ale-lua.txt /*g:ale_lua_luac_executable* g:ale_lua_luacheck_executable ale-lua.txt /*g:ale_lua_luacheck_executable* g:ale_lua_luacheck_options ale-lua.txt /*g:ale_lua_luacheck_options* +g:ale_lua_luafmt_executable ale-lua.txt /*g:ale_lua_luafmt_executable* +g:ale_lua_luafmt_options ale-lua.txt /*g:ale_lua_luafmt_options* +g:ale_lua_stylua_executable ale-lua.txt /*g:ale_lua_stylua_executable* +g:ale_lua_stylua_options ale-lua.txt /*g:ale_lua_stylua_options* +g:ale_markdown_markdownlint_options ale-markdown.txt /*g:ale_markdown_markdownlint_options* g:ale_markdown_mdl_executable ale-markdown.txt /*g:ale_markdown_mdl_executable* g:ale_markdown_mdl_options ale-markdown.txt /*g:ale_markdown_mdl_options* +g:ale_markdown_pandoc_executable ale-markdown.txt /*g:ale_markdown_pandoc_executable* +g:ale_markdown_pandoc_options ale-markdown.txt /*g:ale_markdown_pandoc_options* g:ale_markdown_remark_lint_executable ale-markdown.txt /*g:ale_markdown_remark_lint_executable* g:ale_markdown_remark_lint_options ale-markdown.txt /*g:ale_markdown_remark_lint_options* g:ale_markdown_remark_lint_use_global ale-markdown.txt /*g:ale_markdown_remark_lint_use_global* @@ -1210,6 +1823,12 @@ g:ale_mercury_mmc_executable ale-mercury.txt /*g:ale_mercury_mmc_executable* g:ale_mercury_mmc_options ale-mercury.txt /*g:ale_mercury_mmc_options* g:ale_nasm_nasm_executable ale-nasm.txt /*g:ale_nasm_nasm_executable* g:ale_nasm_nasm_options ale-nasm.txt /*g:ale_nasm_nasm_options* +g:ale_nim_nimpretty_executable ale-nim.txt /*g:ale_nim_nimpretty_executable* +g:ale_nim_nimpretty_options ale-nim.txt /*g:ale_nim_nimpretty_options* +g:ale_nix_nixfmt_executable ale-nix.txt /*g:ale_nix_nixfmt_executable* +g:ale_nix_nixfmt_options ale-nix.txt /*g:ale_nix_nixfmt_options* +g:ale_nix_nixpkgsfmt_executable ale-nix.txt /*g:ale_nix_nixpkgsfmt_executable* +g:ale_nix_nixpkgsfmt_options ale-nix.txt /*g:ale_nix_nixpkgsfmt_options* g:ale_objc_ccls_executable ale-objc.txt /*g:ale_objc_ccls_executable* g:ale_objc_ccls_init_options ale-objc.txt /*g:ale_objc_ccls_init_options* g:ale_objc_clang_options ale-objc.txt /*g:ale_objc_clang_options* @@ -1220,9 +1839,17 @@ g:ale_objcpp_clangd_executable ale-objcpp.txt /*g:ale_objcpp_clangd_executable* g:ale_objcpp_clangd_options ale-objcpp.txt /*g:ale_objcpp_clangd_options* g:ale_ocaml_ocamlformat_executable ale-ocaml.txt /*g:ale_ocaml_ocamlformat_executable* g:ale_ocaml_ocamlformat_options ale-ocaml.txt /*g:ale_ocaml_ocamlformat_options* +g:ale_ocaml_ocamllsp_use_opam ale-ocaml.txt /*g:ale_ocaml_ocamllsp_use_opam* +g:ale_ocaml_ocp_indent_config ale-ocaml.txt /*g:ale_ocaml_ocp_indent_config* +g:ale_ocaml_ocp_indent_executable ale-ocaml.txt /*g:ale_ocaml_ocp_indent_executable* +g:ale_ocaml_ocp_indent_options ale-ocaml.txt /*g:ale_ocaml_ocp_indent_options* g:ale_ocaml_ols_executable ale-ocaml.txt /*g:ale_ocaml_ols_executable* g:ale_ocaml_ols_use_global ale-ocaml.txt /*g:ale_ocaml_ols_use_global* g:ale_open_list ale.txt /*g:ale_open_list* +g:ale_openapi_ibm_validator_executable ale-openapi.txt /*g:ale_openapi_ibm_validator_executable* +g:ale_openapi_ibm_validator_options ale-openapi.txt /*g:ale_openapi_ibm_validator_options* +g:ale_pascal_ptop_executable ale-pascal.txt /*g:ale_pascal_ptop_executable* +g:ale_pascal_ptop_options ale-pascal.txt /*g:ale_pascal_ptop_options* g:ale_pattern_options ale.txt /*g:ale_pattern_options* g:ale_pattern_options_enabled ale.txt /*g:ale_pattern_options_enabled* g:ale_perl6_perl6_executable ale-perl6.txt /*g:ale_perl6_perl6_executable* @@ -1237,6 +1864,9 @@ g:ale_perl_perltidy_options ale-perl.txt /*g:ale_perl_perltidy_options* g:ale_php_cs_fixer_executable ale-php.txt /*g:ale_php_cs_fixer_executable* g:ale_php_cs_fixer_options ale-php.txt /*g:ale_php_cs_fixer_options* g:ale_php_cs_fixer_use_global ale-php.txt /*g:ale_php_cs_fixer_use_global* +g:ale_php_intelephense_config ale-php.txt /*g:ale_php_intelephense_config* +g:ale_php_intelephense_executable ale-php.txt /*g:ale_php_intelephense_executable* +g:ale_php_intelephense_use_global ale-php.txt /*g:ale_php_intelephense_use_global* g:ale_php_langserver_executable ale-php.txt /*g:ale_php_langserver_executable* g:ale_php_langserver_use_global ale-php.txt /*g:ale_php_langserver_use_global* g:ale_php_phan_executable ale-php.txt /*g:ale_php_phan_executable* @@ -1244,6 +1874,7 @@ g:ale_php_phan_minimum_severity ale-php.txt /*g:ale_php_phan_minimum_severity* g:ale_php_phan_use_client ale-php.txt /*g:ale_php_phan_use_client* g:ale_php_php_executable ale-php.txt /*g:ale_php_php_executable* g:ale_php_phpcbf_executable ale-php.txt /*g:ale_php_phpcbf_executable* +g:ale_php_phpcbf_options ale-php.txt /*g:ale_php_phpcbf_options* g:ale_php_phpcbf_standard ale-php.txt /*g:ale_php_phpcbf_standard* g:ale_php_phpcbf_use_global ale-php.txt /*g:ale_php_phpcbf_use_global* g:ale_php_phpcs_executable ale-php.txt /*g:ale_php_phpcs_executable* @@ -1252,18 +1883,31 @@ g:ale_php_phpcs_standard ale-php.txt /*g:ale_php_phpcs_standard* g:ale_php_phpcs_use_global ale-php.txt /*g:ale_php_phpcs_use_global* g:ale_php_phpmd_executable ale-php.txt /*g:ale_php_phpmd_executable* g:ale_php_phpmd_ruleset ale-php.txt /*g:ale_php_phpmd_ruleset* +g:ale_php_phpstan_autoload ale-php.txt /*g:ale_php_phpstan_autoload* g:ale_php_phpstan_configuration ale-php.txt /*g:ale_php_phpstan_configuration* g:ale_php_phpstan_executable ale-php.txt /*g:ale_php_phpstan_executable* g:ale_php_phpstan_level ale-php.txt /*g:ale_php_phpstan_level* g:ale_php_psalm_executable ale-php.txt /*g:ale_php_psalm_executable* +g:ale_php_psalm_options ale-php.txt /*g:ale_php_psalm_options* +g:ale_php_psalm_use_global ale-php.txt /*g:ale_php_psalm_use_global* +g:ale_php_tlint_executable ale-php.txt /*g:ale_php_tlint_executable* +g:ale_php_tlint_options ale-php.txt /*g:ale_php_tlint_options* +g:ale_php_tlint_use_global ale-php.txt /*g:ale_php_tlint_use_global* g:ale_pony_ponyc_executable ale-pony.txt /*g:ale_pony_ponyc_executable* g:ale_pony_ponyc_options ale-pony.txt /*g:ale_pony_ponyc_options* +g:ale_popup_menu_enabled ale.txt /*g:ale_popup_menu_enabled* +g:ale_powershell_powershell_executable ale-powershell.txt /*g:ale_powershell_powershell_executable* +g:ale_powershell_psscriptanalyzer_exclusions ale-powershell.txt /*g:ale_powershell_psscriptanalyzer_exclusions* +g:ale_powershell_psscriptanalyzer_executable ale-powershell.txt /*g:ale_powershell_psscriptanalyzer_executable* +g:ale_powershell_psscriptanalyzer_module ale-powershell.txt /*g:ale_powershell_psscriptanalyzer_module* g:ale_prolog_swipl_alarm ale-prolog.txt /*g:ale_prolog_swipl_alarm* g:ale_prolog_swipl_alarm_handler ale-prolog.txt /*g:ale_prolog_swipl_alarm_handler* g:ale_prolog_swipl_executable ale-prolog.txt /*g:ale_prolog_swipl_executable* g:ale_prolog_swipl_load ale-prolog.txt /*g:ale_prolog_swipl_load* g:ale_prolog_swipl_timeout ale-prolog.txt /*g:ale_prolog_swipl_timeout* g:ale_proto_protoc_gen_lint_options ale-proto.txt /*g:ale_proto_protoc_gen_lint_options* +g:ale_proto_protolint_config ale-proto.txt /*g:ale_proto_protolint_config* +g:ale_proto_protolint_executable ale-proto.txt /*g:ale_proto_protolint_executable* g:ale_pug_puglint_executable ale-pug.txt /*g:ale_pug_puglint_executable* g:ale_pug_puglint_options ale-pug.txt /*g:ale_pug_puglint_options* g:ale_pug_puglint_use_global ale-pug.txt /*g:ale_pug_puglint_use_global* @@ -1272,82 +1916,149 @@ g:ale_puppet_puppet_executable ale-puppet.txt /*g:ale_puppet_puppet_executable* g:ale_puppet_puppet_options ale-puppet.txt /*g:ale_puppet_puppet_options* g:ale_puppet_puppetlint_executable ale-puppet.txt /*g:ale_puppet_puppetlint_executable* g:ale_puppet_puppetlint_options ale-puppet.txt /*g:ale_puppet_puppetlint_options* +g:ale_purescript_purty_executable ale-purescript.txt /*g:ale_purescript_purty_executable* +g:ale_purescript_tidy_executable ale-purescript.txt /*g:ale_purescript_tidy_executable* +g:ale_purescript_tidy_options ale-purescript.txt /*g:ale_purescript_tidy_options* +g:ale_purescript_tidy_use_global ale-purescript.txt /*g:ale_purescript_tidy_use_global* g:ale_pyrex_cython_executable ale-pyrex.txt /*g:ale_pyrex_cython_executable* g:ale_pyrex_cython_options ale-pyrex.txt /*g:ale_pyrex_cython_options* g:ale_python_auto_pipenv ale-python.txt /*g:ale_python_auto_pipenv* +g:ale_python_auto_poetry ale-python.txt /*g:ale_python_auto_poetry* +g:ale_python_autoflake_executable ale-python.txt /*g:ale_python_autoflake_executable* +g:ale_python_autoflake_options ale-python.txt /*g:ale_python_autoflake_options* +g:ale_python_autoflake_use_global ale-python.txt /*g:ale_python_autoflake_use_global* +g:ale_python_autoimport_executable ale-python.txt /*g:ale_python_autoimport_executable* +g:ale_python_autoimport_options ale-python.txt /*g:ale_python_autoimport_options* +g:ale_python_autoimport_use_global ale-python.txt /*g:ale_python_autoimport_use_global* g:ale_python_autopep8_executable ale-python.txt /*g:ale_python_autopep8_executable* g:ale_python_autopep8_options ale-python.txt /*g:ale_python_autopep8_options* g:ale_python_autopep8_use_global ale-python.txt /*g:ale_python_autopep8_use_global* +g:ale_python_bandit_auto_pipenv ale-python.txt /*g:ale_python_bandit_auto_pipenv* +g:ale_python_bandit_auto_poetry ale-python.txt /*g:ale_python_bandit_auto_poetry* +g:ale_python_bandit_executable ale-python.txt /*g:ale_python_bandit_executable* +g:ale_python_bandit_options ale-python.txt /*g:ale_python_bandit_options* +g:ale_python_bandit_use_config ale-python.txt /*g:ale_python_bandit_use_config* +g:ale_python_bandit_use_global ale-python.txt /*g:ale_python_bandit_use_global* g:ale_python_black_auto_pipenv ale-python.txt /*g:ale_python_black_auto_pipenv* +g:ale_python_black_auto_poetry ale-python.txt /*g:ale_python_black_auto_poetry* +g:ale_python_black_change_directory ale-python.txt /*g:ale_python_black_change_directory* g:ale_python_black_executable ale-python.txt /*g:ale_python_black_executable* g:ale_python_black_options ale-python.txt /*g:ale_python_black_options* g:ale_python_black_use_global ale-python.txt /*g:ale_python_black_use_global* g:ale_python_flake8_auto_pipenv ale-python.txt /*g:ale_python_flake8_auto_pipenv* +g:ale_python_flake8_auto_poetry ale-python.txt /*g:ale_python_flake8_auto_poetry* g:ale_python_flake8_change_directory ale-python.txt /*g:ale_python_flake8_change_directory* g:ale_python_flake8_executable ale-python.txt /*g:ale_python_flake8_executable* g:ale_python_flake8_options ale-python.txt /*g:ale_python_flake8_options* g:ale_python_flake8_use_global ale-python.txt /*g:ale_python_flake8_use_global* +g:ale_python_flakehell_auto_pipenv ale-python.txt /*g:ale_python_flakehell_auto_pipenv* +g:ale_python_flakehell_auto_poetry ale-python.txt /*g:ale_python_flakehell_auto_poetry* +g:ale_python_flakehell_executable ale-python.txt /*g:ale_python_flakehell_executable* +g:ale_python_flakehell_options ale-python.txt /*g:ale_python_flakehell_options* +g:ale_python_flakehell_use_global ale-python.txt /*g:ale_python_flakehell_use_global* +g:ale_python_isort_auto_pipenv ale-python.txt /*g:ale_python_isort_auto_pipenv* +g:ale_python_isort_auto_poetry ale-python.txt /*g:ale_python_isort_auto_poetry* g:ale_python_isort_executable ale-python.txt /*g:ale_python_isort_executable* g:ale_python_isort_options ale-python.txt /*g:ale_python_isort_options* g:ale_python_isort_use_global ale-python.txt /*g:ale_python_isort_use_global* g:ale_python_mypy_auto_pipenv ale-python.txt /*g:ale_python_mypy_auto_pipenv* +g:ale_python_mypy_auto_poetry ale-python.txt /*g:ale_python_mypy_auto_poetry* g:ale_python_mypy_executable ale-python.txt /*g:ale_python_mypy_executable* g:ale_python_mypy_ignore_invalid_syntax ale-python.txt /*g:ale_python_mypy_ignore_invalid_syntax* g:ale_python_mypy_options ale-python.txt /*g:ale_python_mypy_options* +g:ale_python_mypy_show_notes ale-python.txt /*g:ale_python_mypy_show_notes* g:ale_python_mypy_use_global ale-python.txt /*g:ale_python_mypy_use_global* g:ale_python_prospector_auto_pipenv ale-python.txt /*g:ale_python_prospector_auto_pipenv* +g:ale_python_prospector_auto_poetry ale-python.txt /*g:ale_python_prospector_auto_poetry* g:ale_python_prospector_executable ale-python.txt /*g:ale_python_prospector_executable* g:ale_python_prospector_options ale-python.txt /*g:ale_python_prospector_options* g:ale_python_prospector_use_global ale-python.txt /*g:ale_python_prospector_use_global* g:ale_python_pycodestyle_auto_pipenv ale-python.txt /*g:ale_python_pycodestyle_auto_pipenv* +g:ale_python_pycodestyle_auto_poetry ale-python.txt /*g:ale_python_pycodestyle_auto_poetry* g:ale_python_pycodestyle_executable ale-python.txt /*g:ale_python_pycodestyle_executable* g:ale_python_pycodestyle_options ale-python.txt /*g:ale_python_pycodestyle_options* g:ale_python_pycodestyle_use_global ale-python.txt /*g:ale_python_pycodestyle_use_global* g:ale_python_pydocstyle_auto_pipenv ale-python.txt /*g:ale_python_pydocstyle_auto_pipenv* +g:ale_python_pydocstyle_auto_poetry ale-python.txt /*g:ale_python_pydocstyle_auto_poetry* g:ale_python_pydocstyle_executable ale-python.txt /*g:ale_python_pydocstyle_executable* g:ale_python_pydocstyle_options ale-python.txt /*g:ale_python_pydocstyle_options* g:ale_python_pydocstyle_use_global ale-python.txt /*g:ale_python_pydocstyle_use_global* g:ale_python_pyflakes_auto_pipenv ale-python.txt /*g:ale_python_pyflakes_auto_pipenv* +g:ale_python_pyflakes_auto_poetry ale-python.txt /*g:ale_python_pyflakes_auto_poetry* g:ale_python_pyflakes_executable ale-python.txt /*g:ale_python_pyflakes_executable* +g:ale_python_pylama_auto_pipenv ale-python.txt /*g:ale_python_pylama_auto_pipenv* +g:ale_python_pylama_auto_poetry ale-python.txt /*g:ale_python_pylama_auto_poetry* +g:ale_python_pylama_change_directory ale-python.txt /*g:ale_python_pylama_change_directory* +g:ale_python_pylama_executable ale-python.txt /*g:ale_python_pylama_executable* +g:ale_python_pylama_options ale-python.txt /*g:ale_python_pylama_options* +g:ale_python_pylama_use_global ale-python.txt /*g:ale_python_pylama_use_global* g:ale_python_pylint_auto_pipenv ale-python.txt /*g:ale_python_pylint_auto_pipenv* +g:ale_python_pylint_auto_poetry ale-python.txt /*g:ale_python_pylint_auto_poetry* g:ale_python_pylint_change_directory ale-python.txt /*g:ale_python_pylint_change_directory* g:ale_python_pylint_executable ale-python.txt /*g:ale_python_pylint_executable* g:ale_python_pylint_options ale-python.txt /*g:ale_python_pylint_options* g:ale_python_pylint_use_global ale-python.txt /*g:ale_python_pylint_use_global* -g:ale_python_pyls_auto_pipenv ale-python.txt /*g:ale_python_pyls_auto_pipenv* -g:ale_python_pyls_config ale-python.txt /*g:ale_python_pyls_config* -g:ale_python_pyls_executable ale-python.txt /*g:ale_python_pyls_executable* -g:ale_python_pyls_use_global ale-python.txt /*g:ale_python_pyls_use_global* +g:ale_python_pylint_use_msg_id ale-python.txt /*g:ale_python_pylint_use_msg_id* +g:ale_python_pylsp_auto_pipenv ale-python.txt /*g:ale_python_pylsp_auto_pipenv* +g:ale_python_pylsp_auto_poetry ale-python.txt /*g:ale_python_pylsp_auto_poetry* +g:ale_python_pylsp_config ale-python.txt /*g:ale_python_pylsp_config* +g:ale_python_pylsp_executable ale-python.txt /*g:ale_python_pylsp_executable* +g:ale_python_pylsp_options ale-python.txt /*g:ale_python_pylsp_options* +g:ale_python_pylsp_use_global ale-python.txt /*g:ale_python_pylsp_use_global* g:ale_python_pyre_auto_pipenv ale-python.txt /*g:ale_python_pyre_auto_pipenv* +g:ale_python_pyre_auto_poetry ale-python.txt /*g:ale_python_pyre_auto_poetry* g:ale_python_pyre_executable ale-python.txt /*g:ale_python_pyre_executable* g:ale_python_pyre_use_global ale-python.txt /*g:ale_python_pyre_use_global* +g:ale_python_pyright_config ale-python.txt /*g:ale_python_pyright_config* +g:ale_python_pyright_executable ale-python.txt /*g:ale_python_pyright_executable* +g:ale_python_reorder_python_imports_executable ale-python.txt /*g:ale_python_reorder_python_imports_executable* +g:ale_python_reorder_python_imports_options ale-python.txt /*g:ale_python_reorder_python_imports_options* +g:ale_python_reorder_python_imports_use_global ale-python.txt /*g:ale_python_reorder_python_imports_use_global* g:ale_python_vulture_change_directory ale-python.txt /*g:ale_python_vulture_change_directory* g:ale_python_vulture_executable ale-python.txt /*g:ale_python_vulture_executable* +g:ale_python_vulture_options ale-python.txt /*g:ale_python_vulture_options* g:ale_python_vulture_use_global ale-python.txt /*g:ale_python_vulture_use_global* g:ale_python_yapf_executable ale-python.txt /*g:ale_python_yapf_executable* g:ale_python_yapf_use_global ale-python.txt /*g:ale_python_yapf_use_global* g:ale_qml_qmlfmt_executable ale-qml.txt /*g:ale_qml_qmlfmt_executable* +g:ale_r_languageserver_cmd ale-r.txt /*g:ale_r_languageserver_cmd* +g:ale_r_languageserver_config ale-r.txt /*g:ale_r_languageserver_config* g:ale_r_lintr_lint_package ale-r.txt /*g:ale_r_lintr_lint_package* g:ale_r_lintr_options ale-r.txt /*g:ale_r_lintr_options* +g:ale_r_styler_options ale-r.txt /*g:ale_r_styler_options* +g:ale_reason_ls_executable ale-reasonml.txt /*g:ale_reason_ls_executable* g:ale_reason_ols_executable ale-reasonml.txt /*g:ale_reason_ols_executable* g:ale_reason_ols_use_global ale-reasonml.txt /*g:ale_reason_ols_use_global* g:ale_reasonml_refmt_executable ale-reasonml.txt /*g:ale_reasonml_refmt_executable* g:ale_reasonml_refmt_options ale-reasonml.txt /*g:ale_reasonml_refmt_options* +g:ale_rename_tsserver_find_in_comments ale.txt /*g:ale_rename_tsserver_find_in_comments* +g:ale_rename_tsserver_find_in_strings ale.txt /*g:ale_rename_tsserver_find_in_strings* +g:ale_robot_rflint_executable ale-robot.txt /*g:ale_robot_rflint_executable* +g:ale_root ale.txt /*g:ale_root* g:ale_ruby_brakeman_executable ale-ruby.txt /*g:ale_ruby_brakeman_executable* g:ale_ruby_brakeman_options ale-ruby.txt /*g:ale_ruby_brakeman_options* +g:ale_ruby_debride_executable ale-ruby.txt /*g:ale_ruby_debride_executable* +g:ale_ruby_debride_options ale-ruby.txt /*g:ale_ruby_debride_options* +g:ale_ruby_erblint_options ale-eruby.txt /*g:ale_ruby_erblint_options* g:ale_ruby_rails_best_practices_executable ale-ruby.txt /*g:ale_ruby_rails_best_practices_executable* g:ale_ruby_rails_best_practices_options ale-ruby.txt /*g:ale_ruby_rails_best_practices_options* g:ale_ruby_reek_executable ale-ruby.txt /*g:ale_ruby_reek_executable* g:ale_ruby_reek_show_context ale-ruby.txt /*g:ale_ruby_reek_show_context* g:ale_ruby_reek_show_wiki_link ale-ruby.txt /*g:ale_ruby_reek_show_wiki_link* +g:ale_ruby_rubocop_auto_correct_all ale-ruby.txt /*g:ale_ruby_rubocop_auto_correct_all* g:ale_ruby_rubocop_executable ale-ruby.txt /*g:ale_ruby_rubocop_executable* g:ale_ruby_rubocop_options ale-ruby.txt /*g:ale_ruby_rubocop_options* g:ale_ruby_ruby_executable ale-ruby.txt /*g:ale_ruby_ruby_executable* g:ale_ruby_rufo_executable ale-ruby.txt /*g:ale_ruby_rufo_executable* g:ale_ruby_ruumba_options ale-eruby.txt /*g:ale_ruby_ruumba_options* g:ale_ruby_solargraph_executable ale-ruby.txt /*g:ale_ruby_solargraph_executable* +g:ale_ruby_sorbet_enable_watchman ale-ruby.txt /*g:ale_ruby_sorbet_enable_watchman* +g:ale_ruby_sorbet_executable ale-ruby.txt /*g:ale_ruby_sorbet_executable* +g:ale_ruby_sorbet_options ale-ruby.txt /*g:ale_ruby_sorbet_options* g:ale_ruby_standardrb_executable ale-ruby.txt /*g:ale_ruby_standardrb_executable* g:ale_ruby_standardrb_options ale-ruby.txt /*g:ale_ruby_standardrb_options* +g:ale_rust_analyzer_config ale-rust.txt /*g:ale_rust_analyzer_config* +g:ale_rust_analyzer_executable ale-rust.txt /*g:ale_rust_analyzer_executable* g:ale_rust_cargo_avoid_whole_workspace ale-rust.txt /*g:ale_rust_cargo_avoid_whole_workspace* g:ale_rust_cargo_check_all_targets ale-rust.txt /*g:ale_rust_cargo_check_all_targets* g:ale_rust_cargo_check_examples ale-rust.txt /*g:ale_rust_cargo_check_examples* @@ -1355,16 +2066,20 @@ g:ale_rust_cargo_check_tests ale-rust.txt /*g:ale_rust_cargo_check_tests* g:ale_rust_cargo_clippy_options ale-rust.txt /*g:ale_rust_cargo_clippy_options* g:ale_rust_cargo_default_feature_behavior ale-rust.txt /*g:ale_rust_cargo_default_feature_behavior* g:ale_rust_cargo_include_features ale-rust.txt /*g:ale_rust_cargo_include_features* +g:ale_rust_cargo_target_dir ale-rust.txt /*g:ale_rust_cargo_target_dir* g:ale_rust_cargo_use_check ale-rust.txt /*g:ale_rust_cargo_use_check* g:ale_rust_cargo_use_clippy ale-rust.txt /*g:ale_rust_cargo_use_clippy* g:ale_rust_ignore_error_codes ale-rust.txt /*g:ale_rust_ignore_error_codes* g:ale_rust_ignore_secondary_spans ale-rust.txt /*g:ale_rust_ignore_secondary_spans* +g:ale_rust_rls_config ale-rust.txt /*g:ale_rust_rls_config* g:ale_rust_rls_executable ale-rust.txt /*g:ale_rust_rls_executable* g:ale_rust_rls_toolchain ale-rust.txt /*g:ale_rust_rls_toolchain* g:ale_rust_rustc_options ale-rust.txt /*g:ale_rust_rustc_options* g:ale_rust_rustfmt_options ale-rust.txt /*g:ale_rust_rustfmt_options* g:ale_sass_stylelint_executable ale-sass.txt /*g:ale_sass_stylelint_executable* g:ale_sass_stylelint_use_global ale-sass.txt /*g:ale_sass_stylelint_use_global* +g:ale_scala_metals_executable ale-scala.txt /*g:ale_scala_metals_executable* +g:ale_scala_metals_project_root ale-scala.txt /*g:ale_scala_metals_project_root* g:ale_scala_sbtserver_address ale-scala.txt /*g:ale_scala_sbtserver_address* g:ale_scala_sbtserver_project_root ale-scala.txt /*g:ale_scala_sbtserver_project_root* g:ale_scala_scalafmt_executable ale-scala.txt /*g:ale_scala_scalafmt_executable* @@ -1383,9 +2098,13 @@ g:ale_set_highlights ale.txt /*g:ale_set_highlights* g:ale_set_loclist ale.txt /*g:ale_set_loclist* g:ale_set_quickfix ale.txt /*g:ale_set_quickfix* g:ale_set_signs ale.txt /*g:ale_set_signs* +g:ale_sh_bashate_executable ale-sh.txt /*g:ale_sh_bashate_executable* +g:ale_sh_bashate_options ale-sh.txt /*g:ale_sh_bashate_options* g:ale_sh_language_server_executable ale-sh.txt /*g:ale_sh_language_server_executable* g:ale_sh_language_server_use_global ale-sh.txt /*g:ale_sh_language_server_use_global* g:ale_sh_shell_default_shell ale-sh.txt /*g:ale_sh_shell_default_shell* +g:ale_sh_shellcheck_change_directory ale-sh.txt /*g:ale_sh_shellcheck_change_directory* +g:ale_sh_shellcheck_dialect ale-sh.txt /*g:ale_sh_shellcheck_dialect* g:ale_sh_shellcheck_exclusions ale-sh.txt /*g:ale_sh_shellcheck_exclusions* g:ale_sh_shellcheck_executable ale-sh.txt /*g:ale_sh_shellcheck_executable* g:ale_sh_shellcheck_options ale-sh.txt /*g:ale_sh_shellcheck_options* @@ -1394,27 +2113,52 @@ g:ale_shell ale.txt /*g:ale_shell* g:ale_shell_arguments ale.txt /*g:ale_shell_arguments* g:ale_sign_column_always ale.txt /*g:ale_sign_column_always* g:ale_sign_error ale.txt /*g:ale_sign_error* +g:ale_sign_highlight_linenrs ale.txt /*g:ale_sign_highlight_linenrs* g:ale_sign_info ale.txt /*g:ale_sign_info* g:ale_sign_offset ale.txt /*g:ale_sign_offset* +g:ale_sign_priority ale.txt /*g:ale_sign_priority* g:ale_sign_style_error ale.txt /*g:ale_sign_style_error* g:ale_sign_style_warning ale.txt /*g:ale_sign_style_warning* g:ale_sign_warning ale.txt /*g:ale_sign_warning* g:ale_sml_smlnj_cm_file ale-sml.txt /*g:ale_sml_smlnj_cm_file* +g:ale_solidity_solc_executable ale-solidity.txt /*g:ale_solidity_solc_executable* +g:ale_solidity_solc_options ale-solidity.txt /*g:ale_solidity_solc_options* +g:ale_sourcekit_lsp_executable ale-swift.txt /*g:ale_sourcekit_lsp_executable* g:ale_spec_rpmlint_executable ale-spec.txt /*g:ale_spec_rpmlint_executable* g:ale_spec_rpmlint_options ale-spec.txt /*g:ale_spec_rpmlint_options* +g:ale_sql_pgformatter_executable ale-sql.txt /*g:ale_sql_pgformatter_executable* +g:ale_sql_pgformatter_options ale-sql.txt /*g:ale_sql_pgformatter_options* g:ale_sql_sqlfmt_executable ale-sql.txt /*g:ale_sql_sqlfmt_executable* g:ale_sql_sqlfmt_options ale-sql.txt /*g:ale_sql_sqlfmt_options* +g:ale_sql_sqlformat_executable ale-sql.txt /*g:ale_sql_sqlformat_executable* +g:ale_sql_sqlformat_options ale-sql.txt /*g:ale_sql_sqlformat_options* g:ale_stylus_stylelint_executable ale-stylus.txt /*g:ale_stylus_stylelint_executable* g:ale_stylus_stylelint_options ale-stylus.txt /*g:ale_stylus_stylelint_options* g:ale_stylus_stylelint_use_global ale-stylus.txt /*g:ale_stylus_stylelint_use_global* +g:ale_sugarss_stylelint_executable ale-sugarss.txt /*g:ale_sugarss_stylelint_executable* +g:ale_sugarss_stylelint_options ale-sugarss.txt /*g:ale_sugarss_stylelint_options* +g:ale_sugarss_stylelint_use_global ale-sugarss.txt /*g:ale_sugarss_stylelint_use_global* +g:ale_svelte_svelteserver_executable ale-svelte.txt /*g:ale_svelte_svelteserver_executable* +g:ale_svelte_svelteserver_use_global ale-svelte.txt /*g:ale_svelte_svelteserver_use_global* +g:ale_swift_appleswiftformat_executable ale-swift.txt /*g:ale_swift_appleswiftformat_executable* +g:ale_swift_appleswiftformat_use_swiftpm ale-swift.txt /*g:ale_swift_appleswiftformat_use_swiftpm* g:ale_tcl_nagelfar_executable ale-tcl.txt /*g:ale_tcl_nagelfar_executable* g:ale_tcl_nagelfar_options ale-tcl.txt /*g:ale_tcl_nagelfar_options* g:ale_terraform_fmt_executable ale-terraform.txt /*g:ale_terraform_fmt_executable* g:ale_terraform_fmt_options ale-terraform.txt /*g:ale_terraform_fmt_options* +g:ale_terraform_langserver_executable ale-terraform.txt /*g:ale_terraform_langserver_executable* +g:ale_terraform_langserver_options ale-terraform.txt /*g:ale_terraform_langserver_options* +g:ale_terraform_ls_executable ale-terraform.txt /*g:ale_terraform_ls_executable* +g:ale_terraform_ls_options ale-terraform.txt /*g:ale_terraform_ls_options* +g:ale_terraform_terraform_executable ale-terraform.txt /*g:ale_terraform_terraform_executable* g:ale_terraform_tflint_executable ale-terraform.txt /*g:ale_terraform_tflint_executable* g:ale_terraform_tflint_options ale-terraform.txt /*g:ale_terraform_tflint_options* g:ale_tex_chktex_executable ale-tex.txt /*g:ale_tex_chktex_executable* g:ale_tex_chktex_options ale-tex.txt /*g:ale_tex_chktex_options* +g:ale_tex_latexindent_executable ale-tex.txt /*g:ale_tex_latexindent_executable* +g:ale_tex_latexindent_options ale-tex.txt /*g:ale_tex_latexindent_options* +g:ale_tex_texlab_executable ale-tex.txt /*g:ale_tex_texlab_executable* +g:ale_tex_texlab_options ale-tex.txt /*g:ale_tex_texlab_options* g:ale_textlint_executable ale-text.txt /*g:ale_textlint_executable* g:ale_textlint_options ale-text.txt /*g:ale_textlint_options* g:ale_textlint_use_global ale-text.txt /*g:ale_textlint_use_global* @@ -1422,7 +2166,12 @@ g:ale_thrift_thrift_executable ale-thrift.txt /*g:ale_thrift_thrift_executable* g:ale_thrift_thrift_generators ale-thrift.txt /*g:ale_thrift_thrift_generators* g:ale_thrift_thrift_includes ale-thrift.txt /*g:ale_thrift_thrift_includes* g:ale_thrift_thrift_options ale-thrift.txt /*g:ale_thrift_thrift_options* +g:ale_thrift_thriftcheck_executable ale-thrift.txt /*g:ale_thrift_thriftcheck_executable* +g:ale_thrift_thriftcheck_options ale-thrift.txt /*g:ale_thrift_thriftcheck_options* g:ale_type_map ale.txt /*g:ale_type_map* +g:ale_typescript_standard_executable ale-typescript.txt /*g:ale_typescript_standard_executable* +g:ale_typescript_standard_options ale-typescript.txt /*g:ale_typescript_standard_options* +g:ale_typescript_standard_use_global ale-typescript.txt /*g:ale_typescript_standard_use_global* g:ale_typescript_tslint_config_path ale-typescript.txt /*g:ale_typescript_tslint_config_path* g:ale_typescript_tslint_executable ale-typescript.txt /*g:ale_typescript_tslint_executable* g:ale_typescript_tslint_ignore_empty_files ale-typescript.txt /*g:ale_typescript_tslint_ignore_empty_files* @@ -1431,8 +2180,30 @@ g:ale_typescript_tslint_use_global ale-typescript.txt /*g:ale_typescript_tslint_ g:ale_typescript_tsserver_config_path ale-typescript.txt /*g:ale_typescript_tsserver_config_path* g:ale_typescript_tsserver_executable ale-typescript.txt /*g:ale_typescript_tsserver_executable* g:ale_typescript_tsserver_use_global ale-typescript.txt /*g:ale_typescript_tsserver_use_global* +g:ale_typescript_xo_executable ale-typescript.txt /*g:ale_typescript_xo_executable* +g:ale_typescript_xo_options ale-typescript.txt /*g:ale_typescript_xo_options* +g:ale_typescript_xo_use_global ale-typescript.txt /*g:ale_typescript_xo_use_global* +g:ale_update_tagstack ale.txt /*g:ale_update_tagstack* g:ale_use_global_executables ale.txt /*g:ale_use_global_executables* +g:ale_v_v_executable ale-v.txt /*g:ale_v_v_executable* +g:ale_v_v_options ale-v.txt /*g:ale_v_v_options* +g:ale_v_vfmt_options ale-v.txt /*g:ale_v_vfmt_options* g:ale_verilog_verilator_options ale-verilog.txt /*g:ale_verilog_verilator_options* +g:ale_verilog_vlog_executable ale-verilog.txt /*g:ale_verilog_vlog_executable* +g:ale_verilog_vlog_options ale-verilog.txt /*g:ale_verilog_vlog_options* +g:ale_verilog_xvlog_executable ale-verilog.txt /*g:ale_verilog_xvlog_executable* +g:ale_verilog_xvlog_options ale-verilog.txt /*g:ale_verilog_xvlog_options* +g:ale_verilog_yosys_executable ale-verilog.txt /*g:ale_verilog_yosys_executable* +g:ale_verilog_yosys_options ale-verilog.txt /*g:ale_verilog_yosys_options* +g:ale_vhdl_ghdl_executable ale-vhdl.txt /*g:ale_vhdl_ghdl_executable* +g:ale_vhdl_ghdl_options ale-vhdl.txt /*g:ale_vhdl_ghdl_options* +g:ale_vhdl_vcom_executable ale-vhdl.txt /*g:ale_vhdl_vcom_executable* +g:ale_vhdl_vcom_options ale-vhdl.txt /*g:ale_vhdl_vcom_options* +g:ale_vhdl_xvhdl_executable ale-vhdl.txt /*g:ale_vhdl_xvhdl_executable* +g:ale_vhdl_xvhdl_options ale-vhdl.txt /*g:ale_vhdl_xvhdl_options* +g:ale_vim_vimls_config ale-vim.txt /*g:ale_vim_vimls_config* +g:ale_vim_vimls_executable ale-vim.txt /*g:ale_vim_vimls_executable* +g:ale_vim_vimls_use_global ale-vim.txt /*g:ale_vim_vimls_use_global* g:ale_vim_vint_executable ale-vim.txt /*g:ale_vim_vint_executable* g:ale_vim_vint_show_style_issues ale-vim.txt /*g:ale_vim_vint_show_style_issues* g:ale_virtualenv_dir_names ale.txt /*g:ale_virtualenv_dir_names* @@ -1451,9 +2222,21 @@ g:ale_writegood_use_global ale.txt /*g:ale_writegood_use_global* g:ale_xml_xmllint_executable ale-xml.txt /*g:ale_xml_xmllint_executable* g:ale_xml_xmllint_indentsize ale-xml.txt /*g:ale_xml_xmllint_indentsize* g:ale_xml_xmllint_options ale-xml.txt /*g:ale_xml_xmllint_options* +g:ale_yaml_spectral_executable ale-yaml.txt /*g:ale_yaml_spectral_executable* +g:ale_yaml_spectral_use_global ale-yaml.txt /*g:ale_yaml_spectral_use_global* g:ale_yaml_swaglint_executable ale-yaml.txt /*g:ale_yaml_swaglint_executable* g:ale_yaml_swaglint_use_global ale-yaml.txt /*g:ale_yaml_swaglint_use_global* +g:ale_yaml_yamlfix_executable ale-yaml.txt /*g:ale_yaml_yamlfix_executable* +g:ale_yaml_yamlfix_options ale-yaml.txt /*g:ale_yaml_yamlfix_options* +g:ale_yaml_yamlfix_use_global ale-yaml.txt /*g:ale_yaml_yamlfix_use_global* g:ale_yaml_yamllint_executable ale-yaml.txt /*g:ale_yaml_yamllint_executable* g:ale_yaml_yamllint_options ale-yaml.txt /*g:ale_yaml_yamllint_options* g:ale_yang_lsp_executable ale-yang.txt /*g:ale_yang_lsp_executable* +g:ale_zeek_zeek_executable ale-zeek.txt /*g:ale_zeek_zeek_executable* +g:ale_zig_zls_config ale-zig.txt /*g:ale_zig_zls_config* +g:ale_zig_zls_executable ale-zig.txt /*g:ale_zig_zls_executable* g:html_tidy_use_global ale-html.txt /*g:html_tidy_use_global* +g:nim_nimlsp_nim_sources ale-nim.txt /*g:nim_nimlsp_nim_sources* +g:vala_vala_lint_config_filename ale-vala.txt /*g:vala_vala_lint_config_filename* +g:vala_vala_lint_executable ale-vala.txt /*g:vala_vala_lint_executable* +terraform-lsp ale-terraform.txt /*terraform-lsp* diff --git a/vim-config/plugins/ale/ftplugin/ale-fix-suggest.vim b/vim-config/plugins/ale/ftplugin/ale-fix-suggest.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/ftplugin/ale-preview-selection.vim b/vim-config/plugins/ale/ftplugin/ale-preview-selection.vim old mode 100755 new mode 100644 index d77b4f98..7ec84068 --- a/vim-config/plugins/ale/ftplugin/ale-preview-selection.vim +++ b/vim-config/plugins/ale/ftplugin/ale-preview-selection.vim @@ -12,5 +12,5 @@ noremap A noremap o noremap O " Keybinds for opening selection items. -noremap :call ale#preview#OpenSelectionInBuffer() +noremap :call ale#preview#OpenSelection() noremap t :call ale#preview#OpenSelectionInTab() diff --git a/vim-config/plugins/ale/ftplugin/ale-preview.vim b/vim-config/plugins/ale/ftplugin/ale-preview.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/plugin/ale.vim b/vim-config/plugins/ale/plugin/ale.vim old mode 100755 new mode 100644 index 7d6a48f0..d19824b1 --- a/vim-config/plugins/ale/plugin/ale.vim +++ b/vim-config/plugins/ale/plugin/ale.vim @@ -71,12 +71,12 @@ let g:ale_linter_aliases = get(g:, 'ale_linter_aliases', {}) 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 'insert' or 'normal' to lint when text is -" changed only in insert or normal mode respectively. -let g:ale_lint_on_text_changed = get(g:, 'ale_lint_on_text_changed', 'always') +" 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', 0) +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) @@ -87,6 +87,9 @@ 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) +" If set to 1, hints and suggestion from LSP servers and tsserver will be shown. +let g:ale_lsp_suggestions = get(g:, 'ale_lsp_suggestions', 0) + " 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) @@ -94,6 +97,13 @@ let g:ale_fix_on_save = get(g:, 'ale_fix_on_save', 0) " should be used instead. let g:ale_enabled = get(g:, 'ale_enabled', 1) +" A Dictionary mapping linter or fixer names to Arrays of two-item Arrays +" mapping filename paths from one system to another. +let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {}) + +" This Dictionary configures the default project roots for various linters. +let g:ale_root = get(g:, 'ale_root', {}) + " 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) @@ -106,6 +116,9 @@ 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 List can be configured to exclude particular highlights. +let g:ale_exclude_highlights = get(g:, 'ale_exclude_highlights', []) + " 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) @@ -115,6 +128,9 @@ 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 enable LSP hover messages at the cursor. +let g:ale_hover_cursor = get(g:, 'ale_hover_cursor', 1) + " 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) @@ -122,6 +138,23 @@ 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')) +" Use preview window for hover messages. +let g:ale_hover_to_preview = get(g:, 'ale_hover_to_preview', 0) + +" Float preview windows in Neovim +let g:ale_floating_preview = get(g:, 'ale_floating_preview', 0) + +" Hovers use floating windows in Neovim +let g:ale_hover_to_floating_preview = get(g:, 'ale_hover_to_floating_preview', 0) + +" Detail uses floating windows in Neovim +let g:ale_detail_to_floating_preview = get(g:, 'ale_detail_to_floating_preview', 0) + +" Border setting for floating preview windows in Neovim +" The element in the list presents - horizontal, top, top-left, top-right, +" bottom-right and bottom-left +let g:ale_floating_window_border = get(g:, 'ale_floating_window_border', ['|', '-', '+', '+', '+', '+']) + " 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 @@ -139,7 +172,19 @@ 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 +" Enable automatic detection of poetry for Python linters. +let g:ale_python_auto_poetry = get(g:, 'ale_python_auto_poetry', 0) + +" This variable can be overridden to set the GO111MODULE environment variable. +let g:ale_go_go111module = get(g:, 'ale_go_go111module', '') + +" Default executable for deno, needed set before plugin start +let g:ale_deno_executable = get(g:, 'ale_deno_executable', 'deno') + +" If 1, enable a popup menu for commands. +let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui_running')) + +if g:ale_set_balloons is 1 || g:ale_set_balloons is# 'hover' call ale#balloon#Enable() endif @@ -147,10 +192,17 @@ if g:ale_completion_enabled call ale#completion#Enable() endif +if g:ale_popup_menu_enabled + call ale#code_action#EnablePopUpMenu() +endif + " Define commands for moving through warnings and errors. -command! -bar ALEPrevious :call ale#loclist_jumping#Jump('before', 0) +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 ALENext :call ale#loclist_jumping#Jump('after', 0) 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) @@ -173,6 +225,8 @@ command! -bar ALEStopAllLSPs :call ale#lsp#reset#StopAllLSPs() " A command for linting manually. command! -bar ALELint :call ale#Queue(0, 'lint_file') +" Stop current jobs when linting. +command! -bar ALELintStop :call ale#engine#Stop(bufnr('')) " Define a command to get information about current filetype. command! -bar ALEInfo :call ale#debugging#Info() @@ -182,24 +236,21 @@ command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboard() 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(''), '', ) +command! -bar -bang -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'}) +command! -bar -nargs=* ALEGoToDefinition :call ale#definition#GoToCommandHandler('', ) " 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'}) +command! -bar -nargs=* ALEGoToTypeDefinition :call ale#definition#GoToCommandHandler('type', ) + +" Repeat a previous selection in the preview window +command! -bar ALERepeatSelection :call ale#preview#RepeatSelection() " Find references for tsserver and LSP -command! -bar ALEFindReferences :call ale#references#Find() +command! -bar -nargs=* ALEFindReferences :call ale#references#Find() " Show summary information for the cursor. command! -bar ALEHover :call ale#hover#ShowAtCursor() @@ -210,13 +261,34 @@ 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#AlwaysGetCompletions(0) +" Complete text with tsserver and LSP +command! -bar ALEComplete :call ale#completion#GetCompletions('ale-manual') + +" Try to find completions for the current symbol that add additional text. +command! -bar ALEImport :call ale#completion#Import() + +" Rename symbols using tsserver and LSP +command! -bar -bang ALERename :call ale#rename#Execute() + +" Apply code actions to a range. +command! -bar -range ALECodeAction :call ale#codefix#Execute() + +" Organize import statements using tsserver +command! -bar ALEOrganizeImports :call ale#organize_imports#Execute() " 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 @@ -231,17 +303,21 @@ 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_definition_in_tab) :ALEGoToDefinition -tab +nnoremap (ale_go_to_definition_in_split) :ALEGoToDefinition -split +nnoremap (ale_go_to_definition_in_vsplit) :ALEGoToDefinition -vsplit 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_go_to_type_definition_in_tab) :ALEGoToTypeDefinition -tab +nnoremap (ale_go_to_type_definition_in_split) :ALEGoToTypeDefinition -split +nnoremap (ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionIn -vsplit nnoremap (ale_find_references) :ALEFindReferences nnoremap (ale_hover) :ALEHover nnoremap (ale_documentation) :ALEDocumentation inoremap (ale_complete) :ALEComplete +nnoremap (ale_import) :ALEImport +nnoremap (ale_rename) :ALERename +nnoremap (ale_code_action) :ALECodeAction +nnoremap (ale_repeat_selection) :ALERepeatSelection " Set up autocmd groups now. call ale#events#Init() @@ -255,6 +331,6 @@ augroup ALECleanupGroup autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand(''))) if exists('##VimSuspend') - autocmd VimSuspend * if exists('*ale#engine#CleanupEveryBuffer') | call ale#engine#CleanupEveryBuffer() | endif + autocmd VimSuspend * if exists('*ale#engine#CleanupEveryBuffer') | call ale#engine#CleanupEveryBuffer() | endif endif augroup END diff --git a/vim-config/plugins/ale/rplugin/python3/deoplete/sources/ale.py b/vim-config/plugins/ale/rplugin/python3/deoplete/sources/ale.py new file mode 100644 index 00000000..82d9bbf2 --- /dev/null +++ b/vim-config/plugins/ale/rplugin/python3/deoplete/sources/ale.py @@ -0,0 +1,61 @@ +""" +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 = 1000 + self.is_bytepos = True + self.min_pattern_length = 1 + self.is_volatile = True + # Do not forget to update s:trigger_character_map in completion.vim in + # updating entries in this map. + self.input_patterns = { + '_': r'\.\w*$', + 'rust': r'(\.|::)\w*$', + 'typescript': r'(\.|\'|")\w*$', + 'cpp': r'(\.|::|->)\w*$', + } + + # Returns an integer for the start position, as with omnifunc. + def get_complete_position(self, context): + return self.vim.call( + 'ale#completion#GetCompletionPositionForDeoplete', context['input'] + ) + + 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 + + event = context.get('event') + + if event == 'Async': + result = self.vim.call('ale#completion#GetCompletionResult') + + return result or [] + + if context.get('is_refresh'): + self.vim.command( + "call ale#completion#GetCompletions('ale-callback', " + + "{'callback': {completions -> deoplete#auto_complete() }})" + ) + + return [] diff --git a/vim-config/plugins/ale/run-tests b/vim-config/plugins/ale/run-tests new file mode 100755 index 00000000..6cfa3fae --- /dev/null +++ b/vim-config/plugins/ale/run-tests @@ -0,0 +1,289 @@ +#!/usr/bin/env bash + +# Author: w0rp +# +# This script runs tests for the ALE project. Run `./run-tests --help` for +# options, or read the output below. +# + +image=denseanalysis/ale + +# Create docker image tag based on Dockerfile contents +if [ -n "$(command -v md5)" ]; then + image_tag=$(md5 -q Dockerfile) +else + image_tag=$(md5sum Dockerfile | cut -d' ' -f1) +fi +git_version=$(git describe --always --tags) + +# Used in all test scripts for running the selected Docker image. +DOCKER_RUN_IMAGE="$image:$image_tag" +export DOCKER_RUN_IMAGE + +tests='test/*.vader test/*/*.vader test/*/*/*.vader test/*/*/*.vader' +# These flags are forwarded to the script for running Vader tests. +verbose_flag='' +quiet_flag='' +run_neovim_02_tests=1 +run_neovim_04_tests=1 +run_neovim_05_tests=1 +run_vim_80_tests=1 +run_vim_82_tests=1 +run_linters=1 + +while [ $# -ne 0 ]; do + case $1 in + -v) + verbose_flag='-v' + shift + ;; + -q) + quiet_flag='-q' + shift + ;; + --build-image) + run_vim_80_tests=0 + run_vim_82_tests=0 + run_neovim_02_tests=0 + run_neovim_04_tests=0 + run_neovim_05_tests=0 + run_linters=0 + shift + ;; + --neovim-only) + run_vim_80_tests=0 + run_vim_82_tests=0 + run_linters=0 + shift + ;; + --neovim-02-only) + run_neovim_04_tests=0 + run_neovim_05_tests=0 + run_vim_80_tests=0 + run_vim_82_tests=0 + run_linters=0 + shift + ;; + --neovim-04-only) + run_neovim_02_tests=0 + run_neovim_05_tests=0 + run_vim_80_tests=0 + run_vim_82_tests=0 + run_linters=0 + shift + ;; + --neovim-05-only) + run_neovim_02_tests=0 + run_neovim_04_tests=0 + run_vim_80_tests=0 + run_vim_82_tests=0 + run_linters=0 + shift + ;; + --vim-only) + run_neovim_02_tests=0 + run_neovim_04_tests=0 + run_neovim_05_tests=0 + run_linters=0 + shift + ;; + --vim-80-only) + run_neovim_02_tests=0 + run_neovim_04_tests=0 + run_neovim_05_tests=0 + run_vim_82_tests=0 + run_linters=0 + shift + ;; + --vim-82-only) + run_neovim_02_tests=0 + run_neovim_04_tests=0 + run_neovim_05_tests=0 + run_vim_80_tests=0 + run_linters=0 + shift + ;; + --linters-only) + run_vim_80_tests=0 + run_vim_82_tests=0 + run_neovim_02_tests=0 + run_neovim_04_tests=0 + run_neovim_05_tests=0 + shift + ;; + --fast) + run_vim_80_tests=0 + run_vim_82_tests=0 + run_neovim_02_tests=0 + run_neovim_04_tests=0 + run_neovim_05_tests=1 + shift + ;; + --help) + echo 'Usage: ./run-tests [OPTION]... [FILE]...' + echo + echo 'Filenames can be given as arguments to run a subset of tests.' + echo 'For example: ./run-tests test/test_ale_var.vader' + echo + echo 'Options:' + echo ' -v Enable verbose output' + echo ' -q Hide output for successful tests' + echo ' --build-image Run docker image build only.' + echo ' --neovim-only Run tests only for NeoVim' + echo ' --neovim-02-only Run tests only for NeoVim 0.2' + echo ' --neovim-04-only Run tests only for NeoVim 0.4' + echo ' --neovim-05-only Run tests only for NeoVim 0.5' + echo ' --vim-only Run tests only for Vim' + echo ' --vim-80-only Run tests only for Vim 8.0' + echo ' --vim-82-only Run tests only for Vim 8.2' + echo ' --linters-only Run only Vint and custom checks' + echo ' --fast Run only the fastest Vim and custom checks' + echo ' --help Show this help text' + echo ' -- Stop parsing options after this' + exit 0 + ;; + --) + shift + break + ;; + -?*) + echo "Invalid argument: $1" 1>&2 + exit 1 + ;; + *) + break + ;; + esac +done + +# Allow tests to be passed as arguments. +if [ $# -ne 0 ]; then + # This doesn't perfectly handle work splitting, but none of our files + # have spaces in the names. + tests="$*" + + # Don't run other tools when targeting tests. + run_linters=0 +fi + +# Delete .swp files in the test directory, which cause Vim 8 to hang. +find test -name '*.swp' -delete + +# Check if docker un image is available locally +has_image=$(docker images ls --filter reference="${image}:${image_tag}" --quiet | wc -l) + +if [ "$has_image" -eq 0 ] +then + + echo "Downloading run image ${image}:${image_tag}" + docker pull "${image}:${image_tag}" &> /dev/null + + if [ $? -eq 1 ] + then + echo "Could not pull image ${image}:${image_tag}" + echo "Building run image ${image}:${image_tag}" + docker build --build-arg GIT_VERSION="$git_version" -t "${image}:${image_tag}" . + docker tag "${image}:${image_tag}" "${image}:latest" + + if [[ -z "${DOCKER_HUB_USER:-}" || -z "${DOCKER_HUB_PASS:-}" ]] + then + echo "Docker Hub credentials not set, skip push" + else + echo "Push ${image}:${image_tag} to Docker Hub" + echo "$DOCKER_HUB_PASS" | docker login -u "$DOCKER_HUB_USER" --password-stdin + docker push "${image}:${image_tag}" + fi + fi +else + echo "Docker run image ${image}:${image_tag} ready" +fi + +set -e +set -u + +docker tag "${image}:${image_tag}" "${image}:latest" + +output_dir=$(mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir') + +trap '{ rm -rf "$output_dir"; }' EXIT + +file_number=0 +pid_list='' + +# Used for killing tests when you kill the script. +cancel_tests() { + set +e + + if [ -n "$pid_list" ]; then + for pid in $pid_list; do + kill "$pid" + wait "$pid" + done + fi + + # shellcheck disable=SC2046 + docker kill $(docker ps -a -q --filter ancestor="$image" --format='{{.ID}}') &> /dev/null + + if [ -d "$output_dir" ]; then + rm -rf "$output_dir" + fi + + echo + exit 1 +} + +trap cancel_tests INT TERM + +for vim in $(docker run --rm "$DOCKER_RUN_IMAGE" ls /vim-build/bin | grep '^neovim\|^vim' ); do + if ( [[ $vim =~ ^vim-v8.0 ]] && ((run_vim_80_tests)) ) \ + || ( [[ $vim =~ ^vim-v8.2 ]] && ((run_vim_82_tests)) ) \ + || ( [[ $vim =~ ^neovim-v0.2 ]] && ((run_neovim_02_tests)) ) \ + || ( [[ $vim =~ ^neovim-v0.4 ]] && ((run_neovim_04_tests)) ) \ + || ( [[ $vim =~ ^neovim-v0.5 ]] && ((run_neovim_05_tests)) ); then + echo "Starting Vim: $vim..." + file_number=$((file_number+1)) + test/script/run-vader-tests $quiet_flag $verbose_flag "$vim" "$tests" \ + > "$output_dir/$file_number" 2>&1 & + pid_list="$pid_list $!" + fi +done + +if ((run_linters)); then + echo "Starting Vint..." + file_number=$((file_number+1)) + test/script/run-vint > "$output_dir/$file_number" 2>&1 & + pid_list="$pid_list $!" + + echo "Starting Custom checks..." + file_number=$((file_number+1)) + test/script/custom-checks &> "$output_dir/$file_number" 2>&1 & + pid_list="$pid_list $!" +fi + +echo + +failed=0 +index=0 + +for pid in $pid_list; do + this_failed=0 + index=$((index+1)) + + if ! wait "$pid"; then + failed=1 + this_failed=1 + fi + + # Hide output for things that passed if -q is set. + if [ "$quiet_flag" != '-q' ] || ((this_failed)); then + cat "$output_dir/$index" + fi +done + +if ((failed)); then + echo 'Something went wrong!' +else + echo 'All tests passed!' +fi + +exit $failed diff --git a/vim-config/plugins/ale/run-tests.bat b/vim-config/plugins/ale/run-tests.bat new file mode 100644 index 00000000..9ba6b554 --- /dev/null +++ b/vim-config/plugins/ale/run-tests.bat @@ -0,0 +1,30 @@ +@echo off +REM Run tests on Windows. +REM +REM To run these tests, you should set up your Windows machine with the same +REM paths that are used in AppVeyor. + +set tests=test/*.vader test/*/*.vader test/*/*/*.vader test/*/*/*/*.vader + +REM Use the first argument for selecting tests to run. +if not "%1"=="" set tests=%1 + +set VADER_OUTPUT_FILE=%~dp0\vader_output +REM Automatically re-run Windows tests, which can fail some times. +set tries=0 + +:RUN_TESTS +set /a tries=%tries%+1 +type nul > "%VADER_OUTPUT_FILE%" +C:\vim\vim\vim80\vim.exe -u test/vimrc "+Vader! %tests%" +set code=%ERRORLEVEL% + +IF %code% EQU 0 GOTO :SHOW_RESULTS +IF %tries% GEQ 2 GOTO :SHOW_RESULTS +GOTO :RUN_TESTS + +:SHOW_RESULTS +type "%VADER_OUTPUT_FILE%" +del "%VADER_OUTPUT_FILE%" + +exit /B %code% diff --git a/vim-config/plugins/ale/supported-tools.md b/vim-config/plugins/ale/supported-tools.md new file mode 100644 index 00000000..b2c0ec48 --- /dev/null +++ b/vim-config/plugins/ale/supported-tools.md @@ -0,0 +1,616 @@ +# 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: | May only run on files on disk (see: `help ale-lint-file-linters` | +| :warning: | Disabled by default | + +--- + +* Ada + * [ada_language_server](https://github.com/AdaCore/ada_language_server) + * [gcc](https://gcc.gnu.org) + * [gnatpp](https://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ugn/gnat_utility_programs.html#the-gnat-pretty-printer-gnatpp) :floppy_disk: +* Ansible + * [ansible-lint](https://github.com/willthames/ansible-lint) :floppy_disk: +* API Blueprint + * [drafter](https://github.com/apiaryio/drafter) +* APKBUILD + * [apkbuild-lint](https://gitlab.alpinelinux.org/Leo/atools) + * [secfixes-check](https://gitlab.alpinelinux.org/Leo/atools) +* AsciiDoc + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [languagetool](https://languagetool.org/) :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 + * [bashate](https://github.com/openstack/bashate) + * [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) +* Bats + * [shellcheck](https://www.shellcheck.net/) +* Bazel + * [buildifier](https://github.com/bazelbuild/buildtools) +* 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 + * [astyle](http://astyle.sourceforge.net/) + * [ccls](https://github.com/MaskRay/ccls) + * [clang](http://clang.llvm.org/) + * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) + * [clangd](https://clang.llvm.org/extra/clangd.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# + * [csc](http://www.mono-project.com/docs/about-mono/languages/csharp/) :floppy_disk: see:`help ale-cs-csc` for details and configuration + * [dotnet-format](https://github.com/dotnet/format) + * [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) + * [astyle](http://astyle.sourceforge.net/) + * [ccls](https://github.com/MaskRay/ccls) + * [clang](http://clang.llvm.org/) + * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) + * [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) :floppy_disk: + * [clangd](https://clang.llvm.org/extra/clangd.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/) :floppy_disk: +* 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 + * [clangd](https://clang.llvm.org/extra/clangd.html) + * [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) :floppy_disk: +* Cypher + * [cypher-lint](https://github.com/cleishm/libcypher-parser) +* Cython (pyrex filetype) + * [cython](http://cython.org/) +* D + * [dfmt](https://github.com/dlang-community/dfmt) + * [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 + * [analysis_server](https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server) + * [dart-analyze](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) :floppy_disk: + * [dart-format](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) :floppy_disk: + * [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) :floppy_disk: + * [language_server](https://github.com/natebosch/dart_language_server) +* desktop + * [desktop-file-validate](https://www.freedesktop.org/wiki/Software/desktop-file-utils/) +* Dhall + * [dhall-format](https://github.com/dhall-lang/dhall-lang) + * [dhall-freeze](https://github.com/dhall-lang/dhall-lang) + * [dhall-lint](https://github.com/dhall-lang/dhall-lang) +* 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) :floppy_disk: + * [elixir-ls](https://github.com/elixir-lsp/elixir-ls) :warning: + * [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk: +* Elm + * [elm-format](https://github.com/avh4/elm-format) + * [elm-ls](https://github.com/elm-tooling/elm-language-server) + * [elm-make](https://github.com/elm/compiler) +* Erb + * [erb](https://apidock.com/ruby/ERB) + * [erblint](https://github.com/Shopify/erb-lint) + * [erubi](https://github.com/jeremyevans/erubi) + * [erubis](https://github.com/kwatch/erubis) + * [ruumba](https://github.com/ericqweinstein/ruumba) +* Erlang + * [SyntaxErl](https://github.com/ten0s/syntaxerl) + * [dialyzer](http://erlang.org/doc/man/dialyzer.html) :floppy_disk: + * [elvis](https://github.com/inaka/elvis) :floppy_disk: + * [erlc](http://erlang.org/doc/man/erlc.html) + * [erlfmt](https://github.com/WhatsApp/erlfmt) +* Fish + * fish [-n flag](https://linux.die.net/man/1/fish) + * [fish_indent](https://fishshell.com/docs/current/cmds/fish_indent.html) +* 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: + * [go mod](https://golang.org/cmd/go/) :warning: :floppy_disk: + * [go vet](https://golang.org/cmd/vet/) :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: + * [golines](https://github.com/segmentio/golines) + * [golint](https://godoc.org/github.com/golang/lint) + * [gometalinter](https://github.com/alecthomas/gometalinter) :warning: :floppy_disk: + * [gopls](https://github.com/golang/go/wiki/gopls) + * [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: + * [revive](https://github.com/mgechev/revive) :warning: :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) + * [hindent](https://hackage.haskell.org/package/hindent) + * [hlint](https://hackage.haskell.org/package/hlint) + * [hls](https://github.com/haskell/haskell-language-server) + * [ormolu](https://github.com/tweag/ormolu) + * [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: + * [angular](https://www.npmjs.com/package/@angular/language-server) + * [fecs](http://fecs.baidu.com/) + * [html-beautify](https://beautifier.io/) + * [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/) +* Ink + * [ink-language-server](https://github.com/ephread/ink-language-server) +* Inko + * [inko](https://inko-lang.org/) :floppy_disk: +* ISPC + * [ispc](https://ispc.github.io/) :floppy_disk: +* Java + * [PMD](https://pmd.github.io/) + * [checkstyle](http://checkstyle.sourceforge.net) :floppy_disk: + * [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) + * [uncrustify](https://github.com/uncrustify/uncrustify) +* JavaScript + * [deno](https://deno.land/) + * [eslint](http://eslint.org/) + * [fecs](http://fecs.baidu.com/) + * [flow](https://flowtype.org/) + * [jscs](https://jscs-dev.github.io/) + * [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 + * [eslint](http://eslint.org/) + * [fixjson](https://github.com/rhysd/fixjson) + * [jq](https://stedolan.github.io/jq/) + * [jsonlint](https://github.com/zaach/jsonlint) + * [prettier](https://github.com/prettier/prettier) + * [spectral](https://github.com/stoplightio/spectral) +* JSON5 + * [eslint](http://eslint.org/) +* JSONC + * [eslint](http://eslint.org/) +* Jsonnet + * [jsonnet-lint](https://jsonnet.org/learning/tools.html) + * [jsonnetfmt](https://jsonnet.org/learning/tools.html) +* Julia + * [languageserver](https://github.com/JuliaEditorSupport/LanguageServer.jl) +* Kotlin + * [kotlinc](https://kotlinlang.org) :floppy_disk: + * [ktlint](https://ktlint.github.io) + * [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) + * [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 + * [lua-format](https://github.com/Koihik/LuaFormatter) + * [luac](https://www.lua.org/manual/5.1/luac.html) + * [luacheck](https://github.com/mpeterv/luacheck) + * [luafmt](https://github.com/trixnz/lua-fmt) + * [stylua](https://github.com/johnnymorganz/stylua) +* 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) + * [pandoc](https://pandoc.org) + * [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: + * [nimlsp](https://github.com/PMunch/nimlsp) + * nimpretty +* nix + * [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) + * [nixfmt](https://github.com/serokell/nixfmt) + * [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt) + * [rnix-lsp](https://github.com/nix-community/rnix-lsp) +* 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) + * [ocamllsp](https://github.com/ocaml/ocaml-lsp) + * [ocp-indent](https://github.com/OCamlPro/ocp-indent) + * [ols](https://github.com/freebroccolo/ocaml-language-server) +* OpenApi + * [ibm_validator](https://github.com/IBM/openapi-validator) + * [prettier](https://github.com/prettier/prettier) + * [yamllint](https://yamllint.readthedocs.io/) +* Pascal + * [ptop](https://www.freepascal.org/tools/ptop.var) +* 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 + * [intelephense](https://github.com/bmewburn/intelephense-docs) + * [langserver](https://github.com/felixfbecker/php-language-server) + * [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions + * [php -l](https://secure.php.net/) + * [php-cs-fixer](http://cs.sensiolabs.org/) + * [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer) + * [phpcs](https://github.com/squizlabs/PHP_CodeSniffer) + * [phpmd](https://phpmd.org) + * [phpstan](https://github.com/phpstan/phpstan) + * [psalm](https://getpsalm.org) :floppy_disk: + * [tlint](https://github.com/tightenco/tlint) +* 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) + * [psscriptanalyzer](https://github.com/PowerShell/PSScriptAnalyzer) +* Prolog + * [swipl](https://github.com/SWI-Prolog/swipl-devel) +* proto + * [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) :floppy_disk: + * [protolint](https://github.com/yoheimuta/protolint) :floppy_disk: +* 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) +* PureScript + * [purescript-language-server](https://github.com/nwolverson/purescript-language-server) + * [purs-tidy](https://github.com/natefaubion/purescript-tidy) + * [purty](https://gitlab.com/joneshf/purty) +* Python + * [autoflake](https://github.com/myint/autoflake) :floppy_disk: + * [autoimport](https://lyz-code.github.io/autoimport/) + * [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/) + * [flakehell](https://github.com/flakehell/flakehell) + * [isort](https://github.com/timothycrosley/isort) + * [mypy](http://mypy-lang.org/) + * [prospector](https://github.com/PyCQA/prospector) :warning: :floppy_disk: + * [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: + * [pylsp](https://github.com/python-lsp/python-lsp-server) :warning: + * [pyre](https://github.com/facebook/pyre-check) :warning: + * [pyright](https://github.com/microsoft/pyright) + * [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 + * [languageserver](https://github.com/REditorSupport/languageserver) + * [lintr](https://github.com/jimhester/lintr) + * [styler](https://github.com/r-lib/styler) +* Racket + * [racket-langserver](https://github.com/jeapostrophe/racket-langserver/tree/master) + * [raco](https://docs.racket-lang.org/raco/) +* Re:VIEW + * [redpen](http://redpen.cc/) +* 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) +* Robot + * [rflint](https://github.com/boakley/robotframework-lint) +* RPM spec + * [rpmlint](https://github.com/rpm-software-management/rpmlint) :warning: (see `:help ale-integration-spec`) +* Ruby + * [brakeman](http://brakemanscanner.org/) :floppy_disk: + * [debride](https://github.com/seattlerb/debride) + * [prettier](https://github.com/prettier/plugin-ruby) + * [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) + * [sorbet](https://github.com/sorbet/sorbet) + * [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: + * [rust-analyzer](https://github.com/rust-analyzer/rust-analyzer) :warning: + * [rustc](https://www.rust-lang.org/) :warning: + * [rustfmt](https://github.com/rust-lang-nursery/rustfmt) +* Salt + * [salt-lint](https://github.com/warpnet/salt-lint) +* 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) + * [metals](https://scalameta.org/metals/) + * [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 + * [solc](https://solidity.readthedocs.io/) + * [solhint](https://github.com/protofire/solhint) + * [solium](https://github.com/duaraghav8/Solium) +* SQL + * [pgformatter](https://github.com/darold/pgFormatter) + * [sql-lint](https://github.com/joereynolds/sql-lint) + * [sqlfmt](https://github.com/jackc/sqlfmt) + * [sqlformat](https://github.com/andialbrecht/sqlparse) + * [sqlint](https://github.com/purcell/sqlint) +* Stylus + * [stylelint](https://github.com/stylelint/stylelint) +* SugarSS + * [stylelint](https://github.com/stylelint/stylelint) +* Svelte + * [prettier](https://github.com/prettier/prettier) + * [svelteserver](https://github.com/sveltejs/language-tools/tree/master/packages/language-server) +* Swift + * [Apple swift-format](https://github.com/apple/swift-format) + * [sourcekit-lsp](https://github.com/apple/sourcekit-lsp) + * [swiftformat](https://github.com/nicklockwood/SwiftFormat) + * [swiftlint](https://github.com/realm/SwiftLint) +* systemd + * [systemd-analyze](https://www.freedesktop.org/software/systemd/man/systemd-analyze.html) :floppy_disk: +* Tcl + * [nagelfar](http://nagelfar.sourceforge.net) :floppy_disk: +* Terraform + * [terraform](https://github.com/hashicorp/terraform) + * [terraform-fmt-fixer](https://github.com/hashicorp/terraform) + * [terraform-ls](https://github.com/hashicorp/terraform-ls) + * [terraform-lsp](https://github.com/juliosueiras/terraform-lsp) + * [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/) + * [thriftcheck](https://github.com/pinterest/thriftcheck) +* TypeScript + * [deno](https://deno.land/) + * [eslint](http://eslint.org/) + * [fecs](http://fecs.baidu.com/) + * [prettier](https://github.com/prettier/prettier) + * [standard](http://standardjs.com/) + * [tslint](https://github.com/palantir/tslint) + * [tsserver](https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29) + * typecheck +* V + * [v](https://github.com/vlang/v/) :floppy_disk: + * [vfmt](https://github.com/vlang/v/) +* VALA + * [uncrustify](https://github.com/uncrustify/uncrustify) + * [vala_lint](https://github.com/vala-lang/vala-lint) :floppy_disk: +* Verilog + * [hdl-checker](https://pypi.org/project/hdl-checker) + * [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) + * [yosys](http://www.clifford.at/yosys/) :floppy_disk: +* 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 + * [vimls](https://github.com/iamcco/vim-language-server) + * [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 + * [circleci](https://circleci.com/docs/2.0/local-cli) :floppy_disk: + * [prettier](https://github.com/prettier/prettier) + * [spectral](https://github.com/stoplightio/spectral) + * [swaglint](https://github.com/byCedric/swaglint) + * [yamlfix](https://lyz-code.github.io/yamlfix) + * [yamllint](https://yamllint.readthedocs.io/) +* YANG + * [yang-lsp](https://github.com/theia-ide/yang-lsp) +* Zeek + * [zeek](http://zeek.org) :floppy_disk: +* Zig + * [zls](https://github.com/zigtools/zls) diff --git a/vim-config/plugins/ale/syntax/ale-fix-suggest.vim b/vim-config/plugins/ale/syntax/ale-fix-suggest.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/syntax/ale-preview-selection.vim b/vim-config/plugins/ale/syntax/ale-preview-selection.vim old mode 100755 new mode 100644 diff --git a/vim-config/plugins/ale/test/completion/test_ale_import_command.vader b/vim-config/plugins/ale/test/completion/test_ale_import_command.vader new file mode 100644 index 00000000..d36caae2 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_ale_import_command.vader @@ -0,0 +1,562 @@ +Before: + Save g:ale_enabled + Save b:ale_enabled + Save g:ale_lint_on_text_changed + Save g:ale_completion_enabled + Save g:ale_completion_autoimport + Save g:ale_completion_max_suggestions + Save g:ale_linters + Save b:ale_linters + + let g:ale_enabled = 0 + let b:ale_enabled = 0 + let g:ale_lint_on_text_changed = 'always' + let g:ale_completion_enabled = 0 + let g:ale_completion_autoimport = 0 + let g:ale_completion_max_suggestions = 50 + let g:ale_linters = {'typescript': ['tsserver'], 'python': ['pyre']} + unlet! b:ale_linters + + let g:server_started_value = 1 + let g:request_id = 0 + let g:LastCallback = v:null + let g:LastHandleCallback = v:null + let g:sent_message_list = [] + let g:code_action_list = [] + let g:execute_list = [] + let g:ale_queue_call_list = [] + + runtime autoload/ale.vim + runtime autoload/ale/util.vim + runtime autoload/ale/code_action.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim + + function! ale#util#Execute(expr) abort + call add(g:execute_list, a:expr) + endfunction + + function! ale#Queue(...) abort + call add(g:ale_queue_call_list, a:000) + endfunction + + function! ale#lsp#RegisterCallback(id, Callback) abort + let g:LastHandleCallback = a:Callback + endfunction + + function! ale#lsp#NotifyForChanges(id, buffer) abort + endfunction + + function! ale#lsp#HasCapability(id, capability) abort + return 1 + endfunction + + function! ale#lsp#Send(id, message) abort + let g:request_id += 1 + + call add(g:sent_message_list, a:message) + + return g:request_id + endfunction + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:LastCallback = a:Callback + + return g:server_started_value + endfunction + + function! ale#code_action#HandleCodeAction(code_action, options) abort + Assert !get(a:options, 'should_save') + + call add(g:code_action_list, a:code_action) + endfunction + + function GetLastMessage() + return get(g:execute_list, -1, '') + endfunction + + function CheckLintStates(conn_id, message) + " Check that we request more linter results after adding completions. + AssertEqual [[0, '']], g:ale_queue_call_list + + let g:ale_enabled = 0 + + let g:ale_queue_call_list = [] + call g:LastHandleCallback(a:conn_id, a:message) + AssertEqual [], g:ale_queue_call_list + + let g:ale_enabled = 1 + let g:ale_lint_on_text_changed = 1 + + let g:ale_queue_call_list = [] + call g:LastHandleCallback(a:conn_id, a:message) + AssertEqual [[0, '']], g:ale_queue_call_list + + let g:ale_lint_on_text_changed = 'normal' + + let g:ale_queue_call_list = [] + call g:LastHandleCallback(a:conn_id, a:message) + AssertEqual [[0, '']], g:ale_queue_call_list + + let g:ale_lint_on_text_changed = 'insert' + + let g:ale_queue_call_list = [] + call g:LastHandleCallback(a:conn_id, a:message) + AssertEqual [[0, '']], g:ale_queue_call_list + + let g:ale_queue_call_list = [] + let g:ale_lint_on_text_changed = 'never' + + call g:LastHandleCallback(a:conn_id, a:message) + AssertEqual [], g:ale_queue_call_list + + let g:ale_lint_on_text_changed = '0' + + call g:LastHandleCallback(a:conn_id, a:message) + AssertEqual [], g:ale_queue_call_list + + let g:ale_lint_on_text_changed = 0 + + call g:LastHandleCallback(a:conn_id, a:message) + AssertEqual [], g:ale_queue_call_list + + let g:ale_lint_on_text_changed = 'xxx' + + call g:LastHandleCallback(a:conn_id, a:message) + AssertEqual [], g:ale_queue_call_list + endfunction + +After: + call ale#linter#Reset() + + Restore + + delfunction GetLastMessage + delfunction CheckLintStates + + unlet! g:LastCallback + unlet! g:LastHandleCallback + unlet! g:request_id + unlet! g:server_started_value + unlet! g:sent_message_list + unlet! g:code_action_list + unlet! g:ale_queue_call_list + unlet! g:execute_list + unlet! g:received_message + unlet! b:ale_old_omnifunc + unlet! b:ale_old_completeopt + unlet! b:ale_completion_info + unlet! b:ale_completion_result + unlet! b:ale_complete_done_time + + runtime autoload/ale.vim + runtime autoload/ale/util.vim + runtime autoload/ale/code_action.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim + +Given typescript(Some example TypeScript code): + let xyz = 123 + let foo = missingword + + let abc = 456 + +Execute(ALEImport should complain when there's no word at the cursor): + call setpos('.', [bufnr(''), 3, 1, 0]) + ALEImport + + AssertEqual 'echom ''Nothing to complete at cursor!''', GetLastMessage() + +Execute(ALEImport should tell the user if no LSP is available): + let g:server_started_value = 0 + + call setpos('.', [bufnr(''), 2, 16, 0]) + ALEImport + + AssertEqual + \ 'echom ''No completion providers are available.''', + \ GetLastMessage() + +Execute(ALEImport should request imports correctly for tsserver): + call setpos('.', [bufnr(''), 2, 16, 0]) + + ALEImport + + AssertEqual + \ { + \ 'conn_id': 0, + \ 'request_id': 0, + \ 'source': 'ale-import', + \ 'column': 11, + \ 'line': 2, + \ 'line_length': 21, + \ 'prefix': 'missingword', + \ 'additional_edits_only': 1, + \ }, + \ b:ale_completion_info + Assert g:LastCallback isnot v:null + + call g:LastCallback(ale#linter#Get(&filetype)[0], { + \ 'connection_id': 347, + \ 'buffer': bufnr(''), + \}) + + AssertEqual + \ { + \ 'conn_id': 347, + \ 'request_id': 1, + \ 'source': 'ale-import', + \ 'column': 11, + \ 'line': 2, + \ 'line_length': 21, + \ 'prefix': 'missingword', + \ 'additional_edits_only': 1, + \ }, + \ b:ale_completion_info + Assert g:LastHandleCallback isnot v:null + + call g:LastHandleCallback(347, { + \ 'request_seq': 1, + \ 'command': 'completions', + \ 'body': [ + \ {'name': 'missingwordIgnoreMe'}, + \ {'name': 'missingword'}, + \ ], + \}) + + AssertEqual + \ [ + \ [0, 'ts@completions', { + \ 'file': expand('%:p'), + \ 'includeExternalModuleExports': 1, + \ 'offset': 11, + \ 'line': 2, + \ 'prefix': 'missingword', + \ }], + \ [0, 'ts@completionEntryDetails', { + \ 'file': expand('%:p'), + \ 'entryNames': [{'name': 'missingword'}], + \ 'offset': 11, + \ 'line': 2, + \ }] + \ ], + \ g:sent_message_list + AssertEqual 2, b:ale_completion_info.request_id + + let g:ale_enabled = 1 + let g:received_message = { + \ 'request_seq': 2, + \ 'command': 'completionEntryDetails', + \ 'body': [ + \ { + \ 'name': 'missingword', + \ 'kind': 'className', + \ 'displayParts': [], + \ 'codeActions': [{ + \ 'description': 'import { missingword } from "./Something";', + \ 'changes': [], + \ }], + \ }, + \ ], + \} + call g:LastHandleCallback(347, g:received_message) + + AssertEqual + \ [ + \ { + \ 'description': 'import { missingword } from "./Something";', + \ 'changes': [], + \ }, + \ ], + \ g:code_action_list + + call CheckLintStates(347, g:received_message) + +Execute(ALEImport should tell the user when no completions were found from tsserver): + call setpos('.', [bufnr(''), 2, 16, 0]) + + ALEImport + + AssertEqual + \ { + \ 'conn_id': 0, + \ 'request_id': 0, + \ 'source': 'ale-import', + \ 'column': 11, + \ 'line': 2, + \ 'line_length': 21, + \ 'prefix': 'missingword', + \ 'additional_edits_only': 1, + \ }, + \ b:ale_completion_info + Assert g:LastCallback isnot v:null + + call g:LastCallback(ale#linter#Get(&filetype)[0], { + \ 'connection_id': 347, + \ 'buffer': bufnr(''), + \}) + + AssertEqual + \ { + \ 'conn_id': 347, + \ 'request_id': 1, + \ 'source': 'ale-import', + \ 'column': 11, + \ 'line': 2, + \ 'line_length': 21, + \ 'prefix': 'missingword', + \ 'additional_edits_only': 1, + \ }, + \ b:ale_completion_info + Assert g:LastHandleCallback isnot v:null + + call g:LastHandleCallback(347, { + \ 'request_seq': 1, + \ 'command': 'completions', + \ 'body': [ + \ {'name': 'missingwordIgnoreMe'}, + \ ], + \}) + + AssertEqual 'echom ''No possible imports found.''', GetLastMessage() + +Given python(Some example Python code): + xyz = 123 + foo = missingword + + abc = 456 + +Execute(ALEImport should request imports correctly for language servers): + call setpos('.', [bufnr(''), 2, 12, 0]) + + ALEImport + + AssertEqual + \ { + \ 'conn_id': 0, + \ 'request_id': 0, + \ 'source': 'ale-import', + \ 'column': 7, + \ 'line': 2, + \ 'line_length': 17, + \ 'prefix': 'missingword', + \ 'additional_edits_only': 1, + \ }, + \ b:ale_completion_info + Assert g:LastCallback isnot v:null + + call g:LastCallback(ale#linter#Get(&filetype)[0], { + \ 'connection_id': 347, + \ 'buffer': bufnr(''), + \}) + + AssertEqual + \ { + \ 'conn_id': 347, + \ 'request_id': 1, + \ 'source': 'ale-import', + \ 'column': 7, + \ 'line': 2, + \ 'line_length': 17, + \ 'prefix': 'missingword', + \ 'additional_edits_only': 1, + \ 'completion_filter': 'ale#completion#python#CompletionItemFilter', + \ }, + \ b:ale_completion_info + Assert g:LastHandleCallback isnot v:null + + AssertEqual + \ [ + \ [0, 'textDocument/completion', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'character': 6, 'line': 1} + \ }], + \ ], + \ g:sent_message_list + AssertEqual 1, b:ale_completion_info.request_id + + let g:ale_enabled = 1 + let g:received_message = { + \ 'id': 1, + \ 'jsonrpc': '2.0', + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'detail': 'Some other word we should ignore', + \ 'filterText': 'missingwordIgnoreMe', + \ 'insertText': 'missingwordIgnoreMe', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' missingwordIgnoreMe', + \ 'sortText': '3ee19999missingword', + \ 'additionalTextEdits': [ + \ { + \ 'range': { + \ 'start': {'line': 1, 'character': 1}, + \ 'end': {'line': 2, 'character': 1}, + \ }, + \ 'newText': 'from something import missingwordIgnoreMe', + \ }, + \ ], + \ }, + \ { + \ 'detail': 'Some word without text edits', + \ 'filterText': 'missingword', + \ 'insertText': 'missingword', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' missingword', + \ 'sortText': '3ee19999missingword', + \ }, + \ { + \ 'detail': 'The word we should use', + \ 'filterText': 'missingword', + \ 'insertText': 'missingword', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' missingword', + \ 'sortText': '3ee19999missingword', + \ 'additionalTextEdits': [ + \ { + \ 'range': { + \ 'start': {'line': 1, 'character': 1}, + \ 'end': {'line': 2, 'character': 1}, + \ }, + \ 'newText': 'from something import missingword', + \ }, + \ ], + \ }, + \ { + \ 'detail': 'The other word we should not use', + \ 'filterText': 'missingword', + \ 'insertText': 'missingword', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' missingword', + \ 'sortText': '3ee19999missingword', + \ 'additionalTextEdits': [ + \ { + \ 'range': { + \ 'start': {'line': 1, 'character': 1}, + \ 'end': {'line': 2, 'character': 1}, + \ }, + \ 'newText': 'from something_else import missingword', + \ }, + \ ], + \ }, + \ ], + \ }, + \} + call g:LastHandleCallback(347, g:received_message) + + AssertEqual + \ [ + \ { + \ 'description': 'completion', + \ 'changes': [ + \ { + \ 'fileName': expand('%:p'), + \ 'textChanges': [ + \ { + \ 'start': {'line': 2, 'offset': 2}, + \ 'end': {'line': 3, 'offset': 2}, + \ 'newText': 'from something import missingword', + \ }, + \ ], + \ }, + \ ], + \ }, + \ ], + \ g:code_action_list + + call CheckLintStates(347, g:received_message) + +Execute(ALEImport should tell the user when no completions were found from a language server): + call setpos('.', [bufnr(''), 2, 12, 0]) + + ALEImport + + AssertEqual + \ { + \ 'conn_id': 0, + \ 'request_id': 0, + \ 'source': 'ale-import', + \ 'column': 7, + \ 'line': 2, + \ 'line_length': 17, + \ 'prefix': 'missingword', + \ 'additional_edits_only': 1, + \ }, + \ b:ale_completion_info + Assert g:LastCallback isnot v:null + + call g:LastCallback(ale#linter#Get(&filetype)[0], { + \ 'connection_id': 347, + \ 'buffer': bufnr(''), + \}) + + AssertEqual + \ { + \ 'conn_id': 347, + \ 'request_id': 1, + \ 'source': 'ale-import', + \ 'column': 7, + \ 'line': 2, + \ 'line_length': 17, + \ 'prefix': 'missingword', + \ 'additional_edits_only': 1, + \ 'completion_filter': 'ale#completion#python#CompletionItemFilter', + \ }, + \ b:ale_completion_info + Assert g:LastHandleCallback isnot v:null + + AssertEqual + \ [ + \ [0, 'textDocument/completion', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'character': 6, 'line': 1} + \ }], + \ ], + \ g:sent_message_list + AssertEqual 1, b:ale_completion_info.request_id + + let g:received_message = { + \ 'id': 1, + \ 'jsonrpc': '2.0', + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'detail': 'Some other word we should ignore', + \ 'filterText': 'missingwordIgnoreMe', + \ 'insertText': 'missingwordIgnoreMe', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' missingwordIgnoreMe', + \ 'sortText': '3ee19999missingword', + \ 'additionalTextEdits': [ + \ { + \ 'range': { + \ 'start': {'line': 1, 'character': 1}, + \ 'end': {'line': 2, 'character': 1}, + \ }, + \ 'newText': 'from something import missingwordIgnoreMe', + \ }, + \ ], + \ }, + \ { + \ 'detail': 'Some word without text edits', + \ 'filterText': 'missingword', + \ 'insertText': 'missingword', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' missingword', + \ 'sortText': '3ee19999missingword', + \ }, + \ ], + \ }, + \} + call g:LastHandleCallback(347, g:received_message) + + AssertEqual 'echom ''No possible imports found.''', GetLastMessage() diff --git a/vim-config/plugins/ale/test/completion/test_complete_events.vader b/vim-config/plugins/ale/test/completion/test_complete_events.vader new file mode 100644 index 00000000..cee15985 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_complete_events.vader @@ -0,0 +1,35 @@ +Before: + let g:complete_post_triggered = 0 + + augroup VaderTest + autocmd! + autocmd User ALECompletePost let g:complete_post_triggered = 1 + augroup END + +After: + unlet! b:ale_completion_info + unlet! g:complete_post_triggered + + augroup VaderTest + autocmd! + augroup END + + augroup! VaderTest + +Execute(ALECompletePost should not be triggered when completion is cancelled): + call ale#completion#HandleUserData({}) + + Assert !g:complete_post_triggered + +Execute(ALECompletePost should not be triggered when tools other than ALE insert completions): + call ale#completion#HandleUserData({'user_data': ''}) + call ale#completion#HandleUserData({'user_data': '{}'}) + + Assert !g:complete_post_triggered + +Execute(ALECompletePost should be triggered when ALE inserts completions): + call ale#completion#HandleUserData({ + \ 'user_data': json_encode({'_ale_completion_item': 1}), + \}) + + Assert g:complete_post_triggered diff --git a/vim-config/plugins/ale/test/completion/test_completion_events.vader b/vim-config/plugins/ale/test/completion/test_completion_events.vader new file mode 100644 index 00000000..ed6dbea3 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_completion_events.vader @@ -0,0 +1,486 @@ +Before: + Save g:ale_completion_enabled + Save g:ale_completion_delay + Save g:ale_completion_max_suggestions + Save &l:omnifunc + Save &l:completeopt + + unlet! b:ale_completion_enabled + let g:ale_completion_enabled = 1 + let g:get_completions_called = 0 + let g:feedkeys_calls = [] + let g:fake_mode = 'i' + + let b:ale_linters = { + \ 'typescript': ['tsserver'], + \} + + let &l:completeopt = 'menu,menuone,preview,noselect,noinsert' + + runtime autoload/ale/util.vim + + function! ale#util#FeedKeys(string) abort + call add(g:feedkeys_calls, [a:string]) + endfunction + + " Pretend we're in insert mode for most tests. + function! ale#util#Mode(...) abort + return g:fake_mode + endfunction + + function! CheckCompletionCalled(expect_success) abort + let g:get_completions_called = 0 + + " We just want to check if the function is called. + function! ale#completion#GetCompletions(source) + let g:get_completions_called = 1 + endfunction + + let g:ale_completion_delay = 0 + + " Run this check a few times, as it can fail randomly. + for l:i in range(has('nvim-0.3') || has('win32') ? 5 : 1) + call ale#completion#Queue() + sleep 1m + + if g:get_completions_called is a:expect_success + break + endif + endfor + + AssertEqual a:expect_success, g:get_completions_called + endfunction + + let g:handle_code_action_called = 0 + function! MockHandleCodeAction() abort + " delfunction! ale#code_action#HandleCodeAction + function! ale#code_action#HandleCodeAction(action, options) abort + Assert !get(a:options, 'should_save') + let g:handle_code_action_called += 1 + endfunction + endfunction + +After: + Restore + + unlet! b:ale_completion_enabled + unlet! g:output + unlet! g:fake_mode + unlet! g:get_completions_called + unlet! g:handle_code_action_called + unlet! b:ale_old_omnifunc + unlet! b:ale_old_completeopt + unlet! b:ale_completion_info + unlet! b:ale_completion_result + unlet! b:ale_complete_done_time + unlet! b:ale_linters + + delfunction CheckCompletionCalled + delfunction ale#code_action#HandleCodeAction + delfunction MockHandleCodeAction + + if exists('*CompleteCallback') + delfunction CompleteCallback + endif + + " Stop any timers we left behind. + " This stops the tests from failing randomly. + call ale#completion#StopTimer() + + " Reset the function. The runtime command below should fix this, but doesn't + " seem to fix it. + function! ale#util#Mode(...) abort + return call('mode', a:000) + endfunction + + runtime autoload/ale/completion.vim + runtime autoload/ale/code_action.vim + runtime autoload/ale/util.vim + +Execute(ale#completion#GetCompletions should be called when the cursor position stays the same): + call CheckCompletionCalled(1) + +Execute(ale#completion#GetCompletions should not be called if the global setting is disabled): + let g:ale_completion_enabled = 0 + call CheckCompletionCalled(0) + +Execute(ale#completion#GetCompletions should not be called if the buffer setting is disabled): + let b:ale_completion_enabled = 0 + call CheckCompletionCalled(0) + +Given typescript(): + let abc = y. + let foo = ab + let foo = (ab) + +Execute(ale#completion#GetCompletions should not be called when the cursor position changes): + call setpos('.', [bufnr(''), 1, 2, 0]) + + " We just want to check if the function is called. + function! ale#completion#GetCompletions(source) + let g:get_completions_called = 1 + endfunction + + let g:ale_completion_delay = 0 + call ale#completion#Queue() + + " Change the cursor position before the callback is triggered. + call setpos('.', [bufnr(''), 2, 2, 0]) + + sleep 1m + + Assert !g:get_completions_called + +Execute(ale#completion#GetCompletions should not be called if you switch to normal mode): + let &l:completeopt = 'menu,preview' + let g:fake_mode = 'n' + + " We just want to check if the function is called. + function! ale#completion#GetCompletions(source) + let g:get_completions_called = 1 + endfunction + + let g:ale_completion_delay = 0 + call ale#completion#Queue() + + sleep 1m + + Assert !g:get_completions_called + +Execute(Completion should not be done shortly after the CompleteDone function): + call CheckCompletionCalled(1) + call ale#completion#Done() + call CheckCompletionCalled(0) + +Execute(ale#completion#Show() should remember the omnifunc setting and replace it): + let &l:omnifunc = 'FooBar' + + let b:ale_completion_info = {'source': 'ale-automatic'} + call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}]) + + AssertEqual 'FooBar', b:ale_old_omnifunc + AssertEqual 'ale#completion#AutomaticOmniFunc', &l:omnifunc + + AssertEqual [], g:feedkeys_calls + sleep 1ms + AssertEqual [["\(ale_show_completion_menu)"]], g:feedkeys_calls + +Execute(ale#completion#Show() should remember the completeopt setting and replace it): + let &l:completeopt = 'menu' + + let b:ale_completion_info = {'source': 'ale-automatic'} + call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}]) + + AssertEqual 'menu', b:ale_old_completeopt + AssertEqual 'menu,menuone,noinsert', &l:completeopt + + AssertEqual [], g:feedkeys_calls + sleep 1ms + AssertEqual [["\(ale_show_completion_menu)"]], g:feedkeys_calls + +Execute(ale#completion#Show() should set the preview option if it's set): + let &l:completeopt = 'menu,preview' + + let b:ale_completion_info = {'source': 'ale-automatic'} + call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}]) + + AssertEqual 'menu,preview', b:ale_old_completeopt + AssertEqual 'menu,menuone,noinsert,preview', &l:completeopt + + AssertEqual [], g:feedkeys_calls + sleep 1ms + AssertEqual [["\(ale_show_completion_menu)"]], g:feedkeys_calls + +Execute(ale#completion#Show() should not replace the completeopt setting for manual completion): + let b:ale_completion_info = {'source': 'ale-manual'} + + let &l:completeopt = 'menu,preview' + + call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}]) + + Assert !exists('b:ale_old_completeopt') + + AssertEqual [], g:feedkeys_calls + sleep 1ms + AssertEqual [["\(ale_show_completion_menu)"]], g:feedkeys_calls + +Execute(ale#completion#AutomaticOmniFunc() should also remember the completeopt setting and replace it): + let &l:completeopt = 'menu,noselect' + + let b:ale_completion_info = {'source': 'ale-automatic'} + call ale#completion#AutomaticOmniFunc(0, '') + + AssertEqual 'menu,noselect', b:ale_old_completeopt + AssertEqual 'menu,menuone,noinsert,noselect', &l:completeopt + +Execute(ale#completion#AutomaticOmniFunc() should set the preview option if it's set): + let &l:completeopt = 'menu,preview' + + let b:ale_completion_info = {'source': 'ale-automatic'} + call ale#completion#AutomaticOmniFunc(0, '') + + AssertEqual 'menu,preview', b:ale_old_completeopt + AssertEqual 'menu,menuone,noinsert,preview', &l:completeopt + +Execute(ale#completion#Show() should make the correct feedkeys() call for automatic completion): + let b:ale_completion_info = {'source': 'ale-automatic'} + call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}]) + + AssertEqual [], g:feedkeys_calls + sleep 1ms + AssertEqual [["\(ale_show_completion_menu)"]], g:feedkeys_calls + +Execute(ale#completion#Show() should make the correct feedkeys() call for manual completion): + let b:ale_completion_info = {'source': 'ale-automatic'} + call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}]) + + AssertEqual [], g:feedkeys_calls + sleep 1ms + AssertEqual [["\(ale_show_completion_menu)"]], g:feedkeys_calls + +Execute(ale#completion#Show() should not call feedkeys() for other sources): + let b:ale_completion_info = {'source': 'other-source'} + call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}]) + + sleep 1ms + AssertEqual [], g:feedkeys_calls + +Execute(ale#completion#Show() shouldn't do anything if you switch back to normal mode): + let &l:completeopt = 'menu,preview' + let g:fake_mode = 'n' + + call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}]) + + AssertEqual 'menu,preview', &l:completeopt + Assert !exists('b:ale_old_omnifunc') + Assert !exists('b:ale_old_completeopt') + Assert !exists('b:ale_completion_result') + AssertEqual [], g:feedkeys_calls + +Execute(ale#completion#Show() should save the result it is given): + call ale#completion#Show([]) + + AssertEqual [], b:ale_completion_result + + call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}]) + + AssertEqual [{'word': 'x', 'kind': 'v', 'icase': 1}], b:ale_completion_result + +Execute(ale#completion#Done() should restore old omnifunc values): + let b:ale_old_omnifunc = 'FooBar' + + call ale#completion#Done() + + " We reset the old omnifunc setting and remove the buffer variable. + AssertEqual 'FooBar', &l:omnifunc + Assert !has_key(b:, 'ale_old_omnifunc') + +Execute(ale#completion#Done() should restore the old completeopt setting): + let b:ale_old_completeopt = 'menu' + + call ale#completion#Done() + + AssertEqual 'menu', &l:completeopt + Assert !has_key(b:, 'ale_old_completeopt') + +Execute(ale#completion#Done() should leave settings alone when none were remembered): + let &l:omnifunc = 'BazBoz' + let &l:completeopt = 'menu' + + call ale#completion#Done() + + AssertEqual 'BazBoz', &l:omnifunc + AssertEqual 'menu', &l:completeopt + +Execute(The completion request_id should be reset when queuing again): + let b:ale_completion_info = {'request_id': 123} + + let g:ale_completion_delay = 0 + call ale#completion#Queue() + sleep 1m + + AssertEqual 0, b:ale_completion_info.request_id + +Execute(b:ale_completion_info should be set up correctly when requesting completions automatically): + let b:ale_completion_result = [] + call setpos('.', [bufnr(''), 3, 14, 0]) + call ale#completion#GetCompletions('ale-automatic') + + AssertEqual + \ { + \ 'request_id': 0, + \ 'conn_id': 0, + \ 'column': 14, + \ 'line_length': 14, + \ 'line': 3, + \ 'prefix': 'ab', + \ 'source': 'ale-automatic', + \ }, + \ b:ale_completion_info + Assert !exists('b:ale_completion_result') + +Execute(b:ale_completion_info should be set up correctly when requesting completions manually): + let b:ale_completion_result = [] + call setpos('.', [bufnr(''), 3, 14, 0]) + ALEComplete + + AssertEqual + \ { + \ 'request_id': 0, + \ 'conn_id': 0, + \ 'column': 14, + \ 'line_length': 14, + \ 'line': 3, + \ 'prefix': 'ab', + \ 'source': 'ale-manual', + \ }, + \ b:ale_completion_info + Assert !exists('b:ale_completion_result') + +Execute(b:ale_completion_info should be set up correctly for other sources): + let b:ale_completion_result = [] + call setpos('.', [bufnr(''), 3, 14, 0]) + call ale#completion#GetCompletions('ale-callback') + + AssertEqual + \ { + \ 'request_id': 0, + \ 'conn_id': 0, + \ 'column': 14, + \ 'line_length': 14, + \ 'line': 3, + \ 'prefix': 'ab', + \ 'source': 'ale-callback', + \ }, + \ b:ale_completion_info + Assert !exists('b:ale_completion_result') + +Execute(b:ale_completion_info should be set up correctly when requesting completions via callback): + let b:ale_completion_result = [] + call setpos('.', [bufnr(''), 3, 14, 0]) + + function! CompleteCallback() abort + echo 'Called' + endfunction + + + call ale#completion#GetCompletions('ale-callback', {'callback': funcref('CompleteCallback')}) + + AssertEqual + \ { + \ 'request_id': 0, + \ 'conn_id': 0, + \ 'column': 14, + \ 'line_length': 14, + \ 'line': 3, + \ 'prefix': 'ab', + \ 'source': 'ale-callback', + \ }, + \ b:ale_completion_info + Assert !exists('b:ale_completion_result') + +Execute(The correct keybinds should be configured): + redir => g:output + silent map (ale_show_completion_menu) + redir END + + AssertEqual + \ [ + \ 'n (ale_show_completion_menu) * :call ale#completion#RestoreCompletionOptions()', + \ 'o (ale_show_completion_menu) * ', + \ 'v (ale_show_completion_menu) * ', + \ ], + \ sort(split(g:output, "\n")) + +Execute(Running the normal mode keybind should reset the settings): + let b:ale_old_omnifunc = 'FooBar' + let b:ale_old_completeopt = 'menu' + + " We can't run the keybind, but we can call the function. + call ale#completion#RestoreCompletionOptions() + + AssertEqual 'FooBar', &l:omnifunc + AssertEqual 'menu', &l:completeopt + Assert !has_key(b:, 'ale_old_omnifunc') + Assert !has_key(b:, 'ale_old_completeopt') + +Execute(HandleUserData should call ale#code_action#HandleCodeAction): + let b:ale_completion_info = {'source': 'ale-manual'} + call MockHandleCodeAction() + + call ale#completion#HandleUserData({}) + AssertEqual g:handle_code_action_called, 0 + + call ale#completion#HandleUserData({ + \ 'user_data': '' + \}) + AssertEqual g:handle_code_action_called, 0 + + call ale#completion#HandleUserData({ + \ 'user_data': json_encode({}), + \}) + AssertEqual g:handle_code_action_called, 0 + + call ale#completion#HandleUserData({ + \ 'user_data': json_encode({ + \ '_ale_completion_item': 1, + \ 'code_actions': [], + \ }), + \}) + AssertEqual g:handle_code_action_called, 0 + + call ale#completion#HandleUserData({ + \ 'user_data': json_encode({ + \ '_ale_completion_item': 1, + \ 'code_actions': [ + \ {'description': '', 'changes': []}, + \ ], + \ }), + \}) + AssertEqual g:handle_code_action_called, 1 + + let b:ale_completion_info = {'source': 'ale-automatic'} + call ale#completion#HandleUserData({ + \ 'user_data': json_encode({ + \ '_ale_completion_item': 1, + \ 'code_actions': [ + \ {'description': '', 'changes': []}, + \ ], + \ }), + \}) + AssertEqual g:handle_code_action_called, 2 + + let b:ale_completion_info = {'source': 'ale-callback'} + call ale#completion#HandleUserData({ + \ 'user_data': json_encode({ + \ '_ale_completion_item': 1, + \ 'code_actions': [ + \ {'description': '', 'changes': []}, + \ ], + \ }), + \}) + AssertEqual g:handle_code_action_called, 3 + + let b:ale_completion_info = {'source': 'ale-omnifunc'} + call ale#completion#HandleUserData({ + \ 'user_data': json_encode({ + \ '_ale_completion_item': 1, + \ 'code_actions': [ + \ {'description': '', 'changes': []}, + \ ], + \ }), + \}) + AssertEqual g:handle_code_action_called, 4 + +Execute(ale#code_action#HandleCodeAction should not be called when when source is not ALE): + call MockHandleCodeAction() + let b:ale_completion_info = {'source': 'syntastic'} + call ale#completion#HandleUserData({ + \ 'user_data': json_encode({ + \ '_ale_completion_item': 1, + \ 'code_actions': [ + \ {'description': '', 'changes': []}, + \ ], + \ }), + \}) + AssertEqual g:handle_code_action_called, 0 diff --git a/vim-config/plugins/ale/test/completion/test_completion_filtering.vader b/vim-config/plugins/ale/test/completion/test_completion_filtering.vader new file mode 100644 index 00000000..172203a4 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_completion_filtering.vader @@ -0,0 +1,142 @@ +Before: + Save g:ale_completion_excluded_words + + let g:ale_completion_excluded_words = [] + +After: + Restore + + unlet! b:ale_completion_excluded_words + unlet! b:suggestions + +Execute(Prefix filtering should work for Lists of strings): + AssertEqual + \ ['FooBar', 'foo'], + \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 0) + AssertEqual + \ ['FooBar', 'FongBar', 'baz', 'foo'], + \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 0) + AssertEqual + \ ['FooBar', 'FongBar', 'baz', 'foo'], + \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '', 0) + +Execute(Exact filtering should work): + AssertEqual + \ ['foo'], + \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 1) + AssertEqual + \ ['FooBar', 'FongBar', 'baz', 'foo'], + \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 1) + AssertEqual + \ ['Foo'], + \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'Foo', 'foo'], 'Foo', 1) + +Execute(Prefix filtering should work for completion items): + AssertEqual + \ [{'word': 'FooBar'}, {'word': 'foo'}], + \ ale#completion#Filter( + \ bufnr(''), + \ '', + \ [ + \ {'word': 'FooBar'}, + \ {'word': 'FongBar'}, + \ {'word': 'baz'}, + \ {'word': 'foo'}, + \ ], + \ 'foo', + \ 0, + \ ) + + AssertEqual + \ [ + \ {'word': 'FooBar'}, + \ {'word': 'FongBar'}, + \ {'word': 'baz'}, + \ {'word': 'foo'}, + \ ], + \ ale#completion#Filter( + \ bufnr(''), + \ '', + \ [ + \ {'word': 'FooBar'}, + \ {'word': 'FongBar'}, + \ {'word': 'baz'}, + \ {'word': 'foo'}, + \ ], + \ '.', + \ 0, + \ ) + +Execute(Excluding words from completion results should work): + let b:ale_completion_excluded_words = ['it', 'describe'] + + AssertEqual + \ [{'word': 'Italian'}], + \ ale#completion#Filter( + \ bufnr(''), + \ '', + \ [ + \ {'word': 'Italian'}, + \ {'word': 'it'}, + \ ], + \ 'it', + \ 0, + \ ) + + AssertEqual + \ [{'word': 'Deutsch'}], + \ ale#completion#Filter( + \ bufnr(''), + \ '', + \ [ + \ {'word': 'describe'}, + \ {'word': 'Deutsch'}, + \ ], + \ 'de', + \ 0, + \ ) + + AssertEqual + \ [{'word': 'Deutsch'}], + \ ale#completion#Filter( + \ bufnr(''), + \ '', + \ [ + \ {'word': 'describe'}, + \ {'word': 'Deutsch'}, + \ ], + \ '.', + \ 0, + \ ) + +Execute(Excluding words from completion results should work with lists of Strings): + let b:ale_completion_excluded_words = ['it', 'describe'] + + AssertEqual + \ ['Italian'], + \ ale#completion#Filter(bufnr(''), '', ['Italian', 'it'], 'it', 0) + AssertEqual + \ ['Deutsch'], + \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], 'de', 0) + AssertEqual + \ ['Deutsch'], + \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], '.', 0) + AssertEqual + \ ['Deutsch'], + \ ale#completion#Filter(bufnr(''), '', ['Deutsch'], '', 0) + +Execute(Filtering shouldn't modify the original list): + let b:ale_completion_excluded_words = ['it', 'describe'] + let b:suggestions = [{'word': 'describe'}] + + AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0) + AssertEqual b:suggestions, [{'word': 'describe'}] + AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, 'de', 0) + AssertEqual b:suggestions, [{'word': 'describe'}] + +Execute(Filtering should respect filetype triggers): + let b:suggestions = [{'word': 'describe'}] + + AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0) + AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '.', 0) + AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '::', 0) diff --git a/vim-config/plugins/ale/test/completion/test_completion_prefixes.vader b/vim-config/plugins/ale/test/completion/test_completion_prefixes.vader new file mode 100644 index 00000000..3f2cab15 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_completion_prefixes.vader @@ -0,0 +1,65 @@ +Given typescript(): + let abc = y. + let foo = ab + let foo = (ab) + let string1 = ' + let string2 = " + +Execute(Completion should be done after dots in TypeScript): + AssertEqual '.', ale#completion#GetPrefix(&filetype, 1, 13) + +Execute(Completion should be done after words in TypeScript): + AssertEqual 'ab', ale#completion#GetPrefix(&filetype, 2, 13) + +Execute(Completion should be done after words in parens in TypeScript): + AssertEqual 'ab', ale#completion#GetPrefix(&filetype, 3, 14) + +Execute(Completion should not be done after parens in TypeScript): + AssertEqual '', ale#completion#GetPrefix(&filetype, 3, 15) + +Execute(Completion should be done after strings in TypeScript): + AssertEqual '''', ale#completion#GetPrefix(&filetype, 4, 16) + AssertEqual '"', ale#completion#GetPrefix(&filetype, 5, 16) + +Execute(Completion prefixes should work for other filetypes): + AssertEqual 'ab', ale#completion#GetPrefix('xxxyyyzzz', 3, 14) + +Execute(Completion prefixes should work for other filetypes): + AssertEqual 'ab', ale#completion#GetPrefix('xxxyyyzzz', 3, 14) + +Given rust(): + let abc = y. + let abc = String:: + let foo = (ab) + +Execute(Completion should be done after dots in Rust): + AssertEqual '.', ale#completion#GetPrefix(&filetype, 1, 13) + +Execute(Completion should be done after colons in Rust): + AssertEqual '::', ale#completion#GetPrefix(&filetype, 2, 19) + +Execute(Completion should be done after words in parens in Rust): + AssertEqual 'ab', ale#completion#GetPrefix(&filetype, 3, 14) + +Execute(Completion should not be done after parens in Rust): + AssertEqual '', ale#completion#GetPrefix(&filetype, 3, 15) + +Given lisp(): + (minus-name + (full-name) + +Execute(Completion should be done for function names with minuses in Lisp): + AssertEqual 'minus-name', ale#completion#GetPrefix(&filetype, 1, 12) + +Execute(Completion should not be done after parens in Lisp): + AssertEqual '', ale#completion#GetPrefix(&filetype, 2, 12) + +Given clojure(): + (minus-name + (full-name) + +Execute(Completion should be done for function names with minuses in Clojure): + AssertEqual 'minus-name', ale#completion#GetPrefix(&filetype, 1, 12) + +Execute(Completion should not be done after parens in Clojure): + AssertEqual '', ale#completion#GetPrefix(&filetype, 2, 12) diff --git a/vim-config/plugins/ale/test/completion/test_lsp_completion_messages.vader b/vim-config/plugins/ale/test/completion/test_lsp_completion_messages.vader new file mode 100644 index 00000000..87847777 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_lsp_completion_messages.vader @@ -0,0 +1,307 @@ +Before: + Save g:ale_completion_delay + Save g:ale_completion_max_suggestions + Save g:ale_completion_info + Save &l:omnifunc + Save &l:completeopt + + let g:ale_completion_enabled = 1 + + call ale#test#SetDirectory('/testplugin/test/completion') + call ale#test#SetFilename('dummy.txt') + + runtime autoload/ale/lsp.vim + + let g:message_list = [] + let g:capability_checked = '' + let g:conn_id = v:null + let g:Callback = '' + let g:init_callback_list = [] + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {}) + call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer) + + let l:details = { + \ 'command': 'foobar', + \ 'buffer': a:buffer, + \ 'connection_id': g:conn_id, + \ 'project_root': '/foo/bar', + \} + + call add(g:init_callback_list, {-> a:Callback(a:linter, l:details)}) + endfunction + + " Pretend we're in insert mode for most tests. + function! ale#util#Mode(...) abort + return 'i' + endfunction + + function! ale#lsp#HasCapability(conn_id, capability) abort + let g:capability_checked = a:capability + + return 1 + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + + " Replace the Send function for LSP, so we can monitor calls to it. + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + + return 1 + endfunction + +After: + Restore + + if g:conn_id isnot v:null + call ale#lsp#RemoveConnectionWithID(g:conn_id) + endif + + unlet! g:message_list + unlet! g:capability_checked + unlet! g:init_callback_list + unlet! g:conn_id + unlet! g:Callback + unlet! b:ale_old_omnifunc + unlet! b:ale_old_completeopt + unlet! b:ale_completion_info + unlet! b:ale_complete_done_time + unlet! b:ale_linters + unlet! b:ale_tsserver_completion_names + + " Reset the function. + function! ale#util#Mode(...) abort + return call('mode', a:000) + endfunction + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + " Stop any timers we left behind. + " This stops the tests from failing randomly. + call ale#completion#StopTimer() + + runtime autoload/ale/completion.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim + +Given typescript(Some typescript file): + foo + somelongerline + bazxyzxyzxyz + +Execute(The right message should be sent for the initial tsserver request): + runtime ale_linters/typescript/tsserver.vim + let b:ale_linters = ['tsserver'] + " The cursor position needs to match what was saved before. + call setpos('.', [bufnr(''), 1, 3, 0]) + + call ale#completion#GetCompletions('ale-automatic') + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual 1, len(g:init_callback_list) + call map(g:init_callback_list, 'v:val()') + + AssertEqual 'completion', g:capability_checked + + " We should send the right callback. + AssertEqual + \ 'function(''ale#completion#HandleTSServerResponse'')', + \ string(g:Callback) + " We should send the right message. + AssertEqual + \ [[0, 'ts@completions', { + \ 'file': expand('%:p'), + \ 'line': 1, + \ 'offset': 3, + \ 'prefix': 'fo', + \ 'includeExternalModuleExports': g:ale_completion_autoimport, + \ }]], + \ g:message_list + " We should set up the completion info correctly. + AssertEqual + \ { + \ 'line_length': 3, + \ 'conn_id': g:conn_id, + \ 'column': 3, + \ 'request_id': 1, + \ 'line': 1, + \ 'prefix': 'fo', + \ 'source': 'ale-automatic', + \ }, + \ get(b:, 'ale_completion_info', {}) + +Execute(The right message sent to the tsserver LSP when the first completion message is received): + " The cursor position needs to match what was saved before. + call setpos('.', [bufnr(''), 1, 1, 0]) + let b:ale_completion_info = { + \ 'conn_id': 123, + \ 'prefix': 'f', + \ 'request_id': 4, + \ 'line': 1, + \ 'column': 1, + \} + " We should only show up to this many suggestions. + let g:ale_completion_max_suggestions = 3 + + " Handle the response for completions. + call ale#completion#HandleTSServerResponse(123, { + \ 'request_seq': 4, + \ 'command': 'completions', + \ 'body': [ + \ {'name': 'Baz'}, + \ {'name': 'dingDong'}, + \ {'name': 'Foo', 'source': '/path/to/foo.ts'}, + \ {'name': 'FooBar'}, + \ {'name': 'frazzle'}, + \ {'name': 'FFS'}, + \ ], + \}) + + " We should save the names we got in the buffer, as TSServer doesn't return + " details for every name. + AssertEqual [{ + \ 'word': 'Foo', + \ 'source': '/path/to/foo.ts', + \ }, { + \ 'word': 'FooBar', + \ 'source': '', + \ }, { + \ 'word': 'frazzle', + \ 'source': '', + \}], + \ get(b:, 'ale_tsserver_completion_names', []) + + " The entry details messages should have been sent. + AssertEqual + \ [[ + \ 0, + \ 'ts@completionEntryDetails', + \ { + \ 'file': expand('%:p'), + \ 'entryNames': [{ + \ 'name': 'Foo', + \ 'source': '/path/to/foo.ts', + \ }, { + \ 'name': 'FooBar', + \ }, { + \ 'name': 'frazzle', + \ }], + \ 'offset': 1, + \ 'line': 1, + \ }, + \ ]], + \ g:message_list + +Given python(Some Python file): + foo + somelongerline + bazxyzxyzxyz + +Execute(The right message should be sent for the initial LSP request): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + " The cursor position needs to match what was saved before. + call setpos('.', [bufnr(''), 1, 5, 0]) + + call ale#completion#GetCompletions('ale-automatic') + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual 1, len(g:init_callback_list) + call map(g:init_callback_list, 'v:val()') + + AssertEqual 'completion', g:capability_checked + + " We should send the right callback. + AssertEqual + \ 'function(''ale#completion#HandleLSPResponse'')', + \ string(g:Callback) + " We should send the right message. + " The character index needs to be at most the index of the last character on + " the line, or integration with pylsp will be broken. + " + " We need to send the message for changing the document first. + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}] + \ }], + \ [0, 'textDocument/completion', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'line': 0, 'character': 2}, + \ }], + \ ], + \ g:message_list + " We should set up the completion info correctly. + AssertEqual + \ { + \ 'line_length': 3, + \ 'conn_id': g:conn_id, + \ 'column': 3, + \ 'request_id': 1, + \ 'line': 1, + \ 'prefix': 'fo', + \ 'source': 'ale-automatic', + \ 'completion_filter': 'ale#completion#python#CompletionItemFilter', + \ }, + \ get(b:, 'ale_completion_info', {}) + +Execute(Two completion requests shouldn't be sent in a row): + call ale#linter#PreventLoading('python') + call ale#linter#Define('python', { + \ 'name': 'foo', + \ 'lsp': 'stdio', + \ 'executable': 'foo', + \ 'command': 'foo', + \ 'project_root': {-> '/foo/bar'}, + \}) + call ale#linter#Define('python', { + \ 'name': 'bar', + \ 'lsp': 'stdio', + \ 'executable': 'foo', + \ 'command': 'foo', + \ 'project_root': {-> '/foo/bar'}, + \}) + let b:ale_linters = ['foo', 'bar'] + + " The cursor position needs to match what was saved before. + call setpos('.', [bufnr(''), 1, 5, 0]) + + call ale#completion#GetCompletions('ale-automatic') + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual 2, len(g:init_callback_list) + call map(g:init_callback_list, 'v:val()') + + AssertEqual 'completion', g:capability_checked + + " We should only send one completion message for two LSP servers. + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}] + \ }], + \ [0, 'textDocument/completion', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'line': 0, 'character': 2}, + \ }], + \ ], + \ g:message_list diff --git a/vim-config/plugins/ale/test/completion/test_lsp_completion_parsing.vader b/vim-config/plugins/ale/test/completion/test_lsp_completion_parsing.vader new file mode 100644 index 00000000..a334d945 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_lsp_completion_parsing.vader @@ -0,0 +1,704 @@ +Before: + Save g:ale_completion_autoimport + Save g:ale_completion_max_suggestions + + let g:ale_completion_max_suggestions = 50 + +After: + Restore + + unlet! b:ale_completion_info + +Execute(Should handle Rust completion results correctly): + let g:ale_completion_autoimport = 0 + + AssertEqual + \ [ + \ {'word': 'new', 'dup': 0, 'menu': 'pub fn new() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'with_capacity', 'dup': 0, 'menu': 'pub fn with_capacity(capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_utf8', 'dup': 0, 'menu': 'pub fn from_utf8(vec: Vec) -> Result', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_utf8_lossy', 'dup': 0, 'menu': 'pub fn from_utf8_lossy<''a>(v: &''a [u8]) -> Cow<''a, str>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_utf16', 'dup': 0, 'menu': 'pub fn from_utf16(v: &[u16]) -> Result', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_utf16_lossy', 'dup': 0, 'menu': 'pub fn from_utf16_lossy(v: &[u16]) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_raw_parts', 'dup': 0, 'menu': 'pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_utf8_unchecked', 'dup': 0, 'menu': 'pub unsafe fn from_utf8_unchecked(bytes: Vec) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Searcher', 'dup': 0, 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'default', 'dup': 0, 'menu': 'fn default() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = String;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Target', 'dup': 0, 'menu': 'type Target = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'Err', 'dup': 0, 'menu': 'type Err = ParseError;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from_str', 'dup': 0, 'menu': 'fn from_str(s: &str) -> Result', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from', 'dup': 0, 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from', 'dup': 0, 'menu': 'fn from(s: Box) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'from', 'dup': 0, 'menu': 'fn from(s: Cow<''a, str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'to_vec', 'dup': 0, 'menu': 'pub fn to_vec(&self) -> Vec where T: Clone,', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \], + \ ale#completion#ParseLSPCompletions({ + \ "jsonrpc":"2.0", + \ "id":65, + \ "result":[ + \ { + \ "label":"new", + \ "kind":3, + \ "detail":"pub fn new() -> String" + \ }, + \ { + \ "label":"with_capacity", + \ "kind":3, + \ "detail":"pub fn with_capacity(capacity: usize) -> String" + \ }, + \ { + \ "label":"from_utf8", + \ "kind":3, + \ "detail":"pub fn from_utf8(vec: Vec) -> Result" + \ }, + \ { + \ "label":"from_utf8_lossy", + \ "kind":3, + \ "detail":"pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str>" + \ }, + \ { + \ "label":"from_utf16", + \ "kind":3, + \ "detail":"pub fn from_utf16(v: &[u16]) -> Result" + \ }, + \ { + \ "label":"from_utf16_lossy", + \ "kind":3, + \ "detail":"pub fn from_utf16_lossy(v: &[u16]) -> String" + \ }, + \ { + \ "label":"from_raw_parts", + \ "kind":3, + \ "detail":"pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String" + \ }, + \ { + \ "label":"from_utf8_unchecked", + \ "kind":3, + \ "detail":"pub unsafe fn from_utf8_unchecked(bytes: Vec) -> String" + \ }, + \ { + \ "label":"from_iter", + \ "kind":3, + \ "detail":"fn from_iter>(iter: I) -> String" + \ }, + \ { + \ "label":"from_iter", + \ "kind":3, + \ "detail":"fn from_iter>(iter: I) -> String" + \ }, + \ { + \ "label":"from_iter", + \ "kind":3, + \ "detail":"fn from_iter>(iter: I) -> String" + \ }, + \ { + \ "label":"from_iter", + \ "kind":3, + \ "detail":"fn from_iter>(iter: I) -> String" + \ }, + \ { + \ "label":"from_iter", + \ "kind":3, + \ "detail":"fn from_iter>>(iter: I) -> String" + \ }, + \ { + \ "label":"Searcher", + \ "kind":8, + \ "detail":"type Searcher = <&'b str as Pattern<'a>>::Searcher;" + \ }, + \ { + \ "label":"default", + \ "kind":3, + \ "detail":"fn default() -> String" + \ }, + \ { + \ "label":"Output", + \ "kind":8, + \ "detail":"type Output = String;" + \ }, + \ { + \ "label":"Output", + \ "kind":8, + \ "detail":"type Output = str;" + \ }, + \ { + \ "label":"Output", + \ "kind":8, + \ "detail":"type Output = str;" + \ }, + \ { + \ "label":"Output", + \ "kind":8, + \ "detail":"type Output = str;" + \ }, + \ { + \ "label":"Output", + \ "kind":8, + \ "detail":"type Output = str;" + \ }, + \ { + \ "label":"Output", + \ "kind":8, + \ "detail":"type Output = str;" + \ }, + \ { + \ "label":"Output", + \ "kind":8, + \ "detail":"type Output = str;" + \ }, + \ { + \ "label":"Target", + \ "kind":8, + \ "detail":"type Target = str;" + \ }, + \ { + \ "label":"Err", + \ "kind":8, + \ "detail":"type Err = ParseError;" + \ }, + \ { + \ "label":"from_str", + \ "kind":3, + \ "detail":"fn from_str(s: &str) -> Result" + \ }, + \ { + \ "label":"from", + \ "kind":3, + \ "detail":"fn from(s: &'a str) -> String" + \ }, + \ { + \ "label":"from", + \ "kind":3, + \ "detail":"fn from(s: Box) -> String" + \ }, + \ { + \ "label":"from", + \ "kind":3, + \ "detail":"fn from(s: Cow<'a, str>) -> String" + \ }, + \ { + \ "label":"to_vec", + \ "kind":3, + \ "detail":"pub fn to_vec(&self) -> Vec\nwhere\n T: Clone," + \ } + \ ] + \ }) + +Execute(Should handle Python completion results correctly): + let g:ale_completion_autoimport = 0 + let b:ale_completion_info = { + \ 'completion_filter': 'ale#completion#python#CompletionItemFilter', + \} + + AssertEqual + \ [ + \ {'word': 'what', 'dup': 0, 'menu': 'example-python-project.bar.Bar', 'info': "what()\n\n", 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ ], + \ ale#completion#ParseLSPCompletions({ + \ "jsonrpc":"2.0", + \ "id":6, + \ "result":{ + \ "isIncomplete":v:false, + \ "items":[ + \ { + \ "label":"what()", + \ "kind":3, + \ "detail":"example-python-project.bar.Bar", + \ "documentation":"what()\n\n", + \ "sortText":"awhat", + \ "insertText":"what" + \ }, + \ { + \ "label":"__class__", + \ "kind":7, + \ "detail":"object", + \ "documentation":"type(object_or_name, bases, dict)\ntype(object) -> the object's type\ntype(name, bases, dict) -> a new type", + \ "sortText":"z__class__", + \ "insertText":"__class__" + \ }, + \ { + \ "label":"__delattr__(name)", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Implement delattr(self, name).", + \ "sortText":"z__delattr__", + \ "insertText":"__delattr__" + \ }, + \ { + \ "label":"__dir__()", + \ "kind":3, + \ "detail":"object", + \ "documentation":"__dir__() -> list\ndefault dir() implementation", + \ "sortText":"z__dir__", + \ "insertText":"__dir__" + \ }, + \ { + \ "label":"__doc__", + \ "kind":18, + \ "detail":"object", + \ "documentation":"str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'.", + \ "sortText":"z__doc__", + \ "insertText":"__doc__" + \ }, + \ { + \ "label":"__eq__(value)", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Return self==value.", + \ "sortText":"z__eq__", + \ "insertText":"__eq__" + \ }, + \ { + \ "label":"__format__()", + \ "kind":3, + \ "detail":"object", + \ "documentation":"default object formatter", + \ "sortText":"z__format__", + \ "insertText":"__format__" + \ }, + \ { + \ "label":"__ge__(value)", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Return self>=value.", + \ "sortText":"z__ge__", + \ "insertText":"__ge__" + \ }, + \ { + \ "label":"__getattribute__(name)", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Return getattr(self, name).", + \ "sortText":"z__getattribute__", + \ "insertText":"__getattribute__" + \ }, + \ { + \ "label":"__gt__(value)", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Return self>value.", + \ "sortText":"z__gt__", + \ "insertText":"__gt__" + \ }, + \ { + \ "label":"__hash__()", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Return hash(self).", + \ "sortText":"z__hash__", + \ "insertText":"__hash__" + \ }, + \ { + \ "label":"__init__(args, kwargs)", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Initialize self.\u00a0\u00a0See help(type(self)) for accurate signature.", + \ "sortText":"z__init__", + \ "insertText":"__init__" + \ }, + \ { + \ "label":"__init_subclass__()", + \ "kind":3, + \ "detail":"object", + \ "documentation":"This method is called when a class is subclassed.\n\nThe default implementation does nothing. It may be\noverridden to extend subclasses.", + \ "sortText":"z__init_subclass__", + \ "insertText":"__init_subclass__" + \ }, + \ { + \ "label":"__le__(value)", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Return self<=value.", + \ "sortText":"z__le__", + \ "insertText":"__le__" + \ }, + \ { + \ "label":"__lt__(value)", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Return self int\nsize of object in memory, in bytes", + \ "sortText":"z__sizeof__", + \ "insertText":"__sizeof__" + \ }, + \ { + \ "label":"__str__()", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Return str(self).", + \ "sortText":"z__str__", + \ "insertText":"__str__" + \ }, + \ { + \ "label":"__subclasshook__()", + \ "kind":3, + \ "detail":"object", + \ "documentation":"Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented.\u00a0\u00a0If it returns\nNotImplemented, the normal algorithm is used.\u00a0\u00a0Otherwise, it\noverrides the normal algorithm (and the outcome is cached).", + \ "sortText":"z__subclasshook__", + \ "insertText":"__subclasshook__" + \ } + \ ] + \ } + \ }) + +Execute(Should handle extra Python completion results correctly): + let g:ale_completion_autoimport = 0 + + let b:ale_completion_info = { + \ 'completion_filter': 'ale#completion#python#CompletionItemFilter', + \ 'prefix': 'mig', + \} + + AssertEqual + \ [ + \ {'word': 'migrations', 'dup': 0, 'menu': 'xxx', 'info': 'migrations', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'MigEngine', 'dup': 0, 'menu': 'xxx', 'info': 'mig engine', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ ], + \ ale#completion#ParseLSPCompletions({ + \ 'jsonrpc': '2.0', + \ 'id': 6, + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'label': 'migrations', + \ 'kind': 3, + \ 'detail': 'xxx', + \ 'documentation': 'migrations', + \ }, + \ { + \ 'label': 'MigEngine', + \ 'kind': 3, + \ 'detail': 'xxx', + \ 'documentation': 'mig engine', + \ }, + \ { + \ 'label': 'ignore me', + \ 'kind': 3, + \ 'detail': 'nope', + \ 'documentation': 'nope', + \ }, + \ ] + \ } + \ }) + +Execute(Should handle missing keys): + let g:ale_completion_autoimport = 0 + + AssertEqual + \ [ + \ {'word': 'x', 'dup': 0, 'menu': '', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ ], + \ ale#completion#ParseLSPCompletions({ + \ 'jsonrpc': '2.0', + \ 'id': 6, + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'label': 'x', + \ }, + \ ] + \ } + \ }) + +Execute(Should handle documentation in the markdown format): + let g:ale_completion_autoimport = 0 + + AssertEqual + \ [ + \ {'word': 'migrations', 'dup': 0, 'menu': 'xxx', 'info': 'Markdown documentation', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ ], + \ ale#completion#ParseLSPCompletions({ + \ 'jsonrpc': '2.0', + \ 'id': 6, + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'label': 'migrations', + \ 'kind': 3, + \ 'detail': 'xxx', + \ 'documentation': { + \ 'kind': 'markdown', + \ 'value': 'Markdown documentation', + \ }, + \ }, + \ ], + \ }, + \ }) + +Execute(Should handle completion messages with textEdit objects): + let g:ale_completion_autoimport = 0 + + AssertEqual + \ [ + \ {'word': 'next_callback', 'dup': 0, 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ ], + \ ale#completion#ParseLSPCompletions({ + \ 'id': 226, + \ 'jsonrpc': '2.0', + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'detail': 'PlayTimeCallback', + \ 'filterText': 'next_callback', + \ 'insertText': 'ignoreme', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' next_callback', + \ 'sortText': '3ee19999next_callback', + \ 'textEdit': { + \ 'newText': 'next_callback', + \ 'range': { + \ 'end': {'character': 13, 'line': 12}, + \ 'start': {'character': 4, 'line': 12}, + \ }, + \ }, + \ }, + \ ], + \ }, + \ }) + +Execute(Should handle completion messages with the deprecated insertText attribute): + let g:ale_completion_autoimport = 0 + + AssertEqual + \ [ + \ {'word': 'next_callback', 'dup': 0, 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ ], + \ ale#completion#ParseLSPCompletions({ + \ 'id': 226, + \ 'jsonrpc': '2.0', + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'detail': 'PlayTimeCallback', + \ 'filterText': 'next_callback', + \ 'insertText': 'next_callback', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' next_callback', + \ 'sortText': '3ee19999next_callback', + \ }, + \ ], + \ }, + \ }) + +Execute(Should handle completion messages with additionalTextEdits when ale_completion_autoimport is turned on): + let g:ale_completion_autoimport = 1 + + AssertEqual + \ [ + \ { + \ 'word': 'next_callback', + \ 'dup': 1, + \ 'menu': 'PlayTimeCallback', + \ 'info': '', + \ 'kind': 'v', + \ 'icase': 1, + \ 'user_data': json_encode({ + \ '_ale_completion_item': 1, + \ 'code_actions': [ + \ { + \ 'description': 'completion', + \ 'changes': [ + \ { + \ 'fileName': expand('#' . bufnr('') . ':p'), + \ 'textChanges': [ + \ { + \ 'start': { + \ 'line': 11, + \ 'offset': 2, + \ }, + \ 'end': { + \ 'line': 13, + \ 'offset': 4, + \ }, + \ 'newText': 'from "module" import next_callback', + \ }, + \ ], + \ }, + \ ], + \ }, + \ ], + \ }), + \ }, + \ ], + \ ale#completion#ParseLSPCompletions({ + \ 'id': 226, + \ 'jsonrpc': '2.0', + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'detail': 'PlayTimeCallback', + \ 'filterText': 'next_callback', + \ 'insertText': 'next_callback', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' next_callback', + \ 'sortText': '3ee19999next_callback', + \ 'additionalTextEdits': [ + \ { + \ 'range': { + \ 'start': { + \ 'line': 10, + \ 'character': 1, + \ }, + \ 'end': { + \ 'line': 12, + \ 'character': 3, + \ }, + \ }, + \ 'newText': 'from "module" import next_callback', + \ }, + \ ], + \ }, + \ ], + \ }, + \ }) + +Execute(Should not handle completion messages with additionalTextEdits when ale_completion_autoimport is turned off): + let g:ale_completion_autoimport = 0 + let b:ale_completion_info = {'line': 30} + + AssertEqual + \ [], + \ ale#completion#ParseLSPCompletions({ + \ 'id': 226, + \ 'jsonrpc': '2.0', + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'detail': 'PlayTimeCallback', + \ 'filterText': 'next_callback', + \ 'insertText': 'next_callback', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' next_callback', + \ 'sortText': '3ee19999next_callback', + \ 'additionalTextEdits': [ + \ { + \ 'range': { + \ 'start': { + \ 'line': 10, + \ 'character': 1, + \ }, + \ 'end': { + \ 'line': 12, + \ 'character': 3, + \ }, + \ }, + \ 'newText': 'from "module" import next_callback', + \ }, + \ ], + \ }, + \ ], + \ }, + \ }) + +Execute(Should still handle completion messages with empty additionalTextEdits with ale_completion_autoimport turned off): + let g:ale_completion_autoimport = 0 + + AssertEqual + \ [ + \ { + \ 'word': 'next_callback', + \ 'dup': 0, + \ 'menu': 'PlayTimeCallback', + \ 'info': '', + \ 'kind': 'v', + \ 'icase': 1, + \ 'user_data': json_encode({'_ale_completion_item': 1}), + \ } + \ ], + \ ale#completion#ParseLSPCompletions({ + \ 'id': 226, + \ 'jsonrpc': '2.0', + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'detail': 'PlayTimeCallback', + \ 'filterText': 'next_callback', + \ 'insertText': 'next_callback', + \ 'insertTextFormat': 1, + \ 'kind': 6, + \ 'label': ' next_callback', + \ 'sortText': '3ee19999next_callback', + \ 'additionalTextEdits': [], + \ }, + \ ], + \ }, + \ }) diff --git a/vim-config/plugins/ale/test/completion/test_omnifunc_completion.vader b/vim-config/plugins/ale/test/completion/test_omnifunc_completion.vader new file mode 100644 index 00000000..1db64705 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_omnifunc_completion.vader @@ -0,0 +1,60 @@ +Before: + unlet! b:ale_completion_info + unlet! b:ale_completion_result + + let b:lsp_started = 0 + + runtime autoload/ale/lsp_linter.vim + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + return b:lsp_started + endfunction + + function! SetCompletionResult(...) abort + let b:ale_completion_result = ['foo'] + endfunction + + function! SetCompletionResponse(...) abort + let b:ale_completion_result = ['foo'] + endfunction + +After: + unlet! b:ale_completion_info + unlet! b:ale_completion_result + unlet! b:lsp_started + + delfunction SetCompletionResult + delfunction SetCompletionResponse + + runtime autoload/ale/lsp_linter.vim + + call ale#linter#Reset() + +Given typescript(): + let abc = y. + let foo = ab + let foo = (ab) + +Execute(-3 should be returned when completion results cannot be requested): + AssertEqual -3, ale#completion#OmniFunc(1, '') + +Execute(The start position should be returned when results can be requested): + let b:lsp_started = 1 + call setpos('.', [bufnr(''), 3, 14, 0]) + + AssertEqual 11, ale#completion#OmniFunc(1, '') + +Execute(The omnifunc function should return async results): + " Neovim 0.2.0 and 0.4.4 struggles at running these tests. + if !has('nvim') + call timer_start(0, function('SetCompletionResult')) + + AssertEqual ['foo'], ale#completion#OmniFunc(0, '') + endif + +Execute(The omnifunc function should parse and return async responses): + if !has('nvim') + call timer_start(0, function('SetCompletionResponse')) + + AssertEqual ['foo'], ale#completion#OmniFunc(0, '') + endif diff --git a/vim-config/plugins/ale/test/completion/test_public_completion_api.vader b/vim-config/plugins/ale/test/completion/test_public_completion_api.vader new file mode 100644 index 00000000..03394820 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_public_completion_api.vader @@ -0,0 +1,47 @@ +Before: + call ale#linter#Reset() + + unlet! b:ale_linters + unlet! b:ale_completion_info + unlet! b:ale_completion_result + +After: + call ale#linter#Reset() + + unlet! b:ale_linters + unlet! b:ale_completion_info + unlet! b:ale_completion_result + +Execute(ale#completion#GetCompletionResult() should return v:null when there are no results): + AssertEqual v:null, ale#completion#GetCompletionResult() + +Execute(ale#completion#GetCompletionResult() should return a result computed previously): + let b:ale_completion_result = [1] + + AssertEqual [1], ale#completion#GetCompletionResult() + +Execute(ale#completion#GetCompletionPosition() should return 0 when there is no completion information): + AssertEqual 0, ale#completion#GetCompletionPosition() + +Given python(Some Python file): + foo bar + +Execute(ale#completion#GetCompletionPosition() should return the position in the file when information is available): + let b:ale_completion_info = {'line': 1, 'column': 6} + + " This is the first character of 'bar' + AssertEqual 4, ale#completion#GetCompletionPosition() + +Execute(ale#completion#GetCompletionPositionForDeoplete() should return the position on the given input string): + " This is the first character of 'bar' + AssertEqual 4, ale#completion#GetCompletionPositionForDeoplete('foo bar') + +Execute(ale#completion#CanProvideCompletions should return 0 when no completion sources are available): + let b:ale_linters = ['flake8'] + AssertEqual 0, ale#completion#CanProvideCompletions() + +Execute(ale#completion#CanProvideCompletions should return 1 when at least one completion source is available): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + + AssertEqual 1, ale#completion#CanProvideCompletions() diff --git a/vim-config/plugins/ale/test/completion/test_tsserver_completion_parsing.vader b/vim-config/plugins/ale/test/completion/test_tsserver_completion_parsing.vader new file mode 100644 index 00000000..231c0f95 --- /dev/null +++ b/vim-config/plugins/ale/test/completion/test_tsserver_completion_parsing.vader @@ -0,0 +1,309 @@ +Before: + Save g:ale_completion_tsserver_remove_warnings + + let g:ale_completion_tsserver_remove_warnings = 0 + +After: + Restore + + unlet! b:ale_tsserver_completion_names + +Execute(TypeScript completions responses should be parsed correctly): + AssertEqual [], + \ ale#completion#ParseTSServerCompletions({ + \ 'body': [], + \}) + AssertEqual + \ [ + \ { + \ 'word': 'foo', + \ 'source': '/path/to/foo.ts', + \ }, + \ { + \ 'word': 'bar', + \ 'source': '', + \ }, + \ { + \ 'word': 'baz', + \ 'source': '', + \ } + \ ], + \ ale#completion#ParseTSServerCompletions({ + \ 'body': [ + \ {'name': 'foo', 'source': '/path/to/foo.ts'}, + \ {'name': 'bar'}, + \ {'name': 'baz'}, + \ ], + \}) + +Execute(TypeScript completions responses should include warnings): + AssertEqual + \ [ + \ { + \ 'word': 'foo', + \ 'source': '/path/to/foo.ts', + \ }, + \ { + \ 'word': 'bar', + \ 'source': '', + \ }, + \ { + \ 'word': 'baz', + \ 'source': '', + \ } + \ ], + \ ale#completion#ParseTSServerCompletions({ + \ 'body': [ + \ {'name': 'foo', 'source': '/path/to/foo.ts'}, + \ {'name': 'bar', 'kind': 'warning'}, + \ {'name': 'baz'}, + \ ], + \}) + +Execute(TypeScript completions responses should not include warnings if excluded): + let g:ale_completion_tsserver_remove_warnings = 1 + AssertEqual + \ [ + \ { + \ 'word': 'foo', + \ 'source': '/path/to/foo.ts', + \ }, + \ { + \ 'word': 'baz', + \ 'source': '', + \ } + \ ], + \ ale#completion#ParseTSServerCompletions({ + \ 'body': [ + \ {'name': 'foo', 'source': '/path/to/foo.ts'}, + \ {'name': 'bar', 'kind': 'warning'}, + \ {'name': 'baz'}, + \ ], + \}) + +Execute(TypeScript completion details responses should be parsed correctly): + AssertEqual + \ [ + \ { + \ 'word': 'abc', + \ 'menu': '(property) Foo.abc: number', + \ 'info': '', + \ 'kind': 'v', + \ 'icase': 1, + \ 'user_data': json_encode({'_ale_completion_item': 1}), + \ 'dup': g:ale_completion_autoimport, + \ }, + \ { + \ 'word': 'def', + \ 'menu': '(property) Foo.def: number', + \ 'info': 'foo bar baz', + \ 'kind': 'v', + \ 'icase': 1, + \ 'user_data': json_encode({'_ale_completion_item': 1}), + \ 'dup': g:ale_completion_autoimport, + \ }, + \ { + \ 'word': 'ghi', + \ 'menu': '(class) Foo', + \ 'info': '', + \ 'kind': 'v', + \ 'icase': 1, + \ 'user_data': json_encode({'_ale_completion_item': 1}), + \ 'dup': g:ale_completion_autoimport, + \ }, + \ ], + \ ale#completion#ParseTSServerCompletionEntryDetails({ + \ 'body': [ + \ { + \ 'name': 'abc', + \ 'kind': 'parameterName', + \ 'displayParts': [ + \ {'text': '('}, + \ {'text': 'property'}, + \ {'text': ')'}, + \ {'text': ' '}, + \ {'text': 'Foo'}, + \ {'text': '.'}, + \ {'text': 'abc'}, + \ {'text': ':'}, + \ {'text': ' '}, + \ {'text': 'number'}, + \ ], + \ }, + \ { + \ 'name': 'def', + \ 'kind': 'parameterName', + \ 'displayParts': [ + \ {'text': '('}, + \ {'text': 'property'}, + \ {'text': ')'}, + \ {'text': ' '}, + \ {'text': 'Foo'}, + \ {'text': '.'}, + \ {'text': 'def'}, + \ {'text': ':'}, + \ {'text': ' '}, + \ {'text': 'number'}, + \ ], + \ 'documentation': [ + \ {'text': 'foo'}, + \ {'text': ' '}, + \ {'text': 'bar'}, + \ {'text': ' '}, + \ {'text': 'baz'}, + \ ], + \ }, + \ { + \ 'name': 'ghi', + \ 'kind': 'className', + \ 'displayParts': [ + \ {'text': '('}, + \ {'text': 'class'}, + \ {'text': ')'}, + \ {'text': ' '}, + \ {'text': 'Foo'}, + \ ], + \ }, + \ ], + \}) + +Execute(Entries without details should be included in the responses): + let b:ale_tsserver_completion_names = [{ + \ 'word': 'xyz', + \ 'source': '/path/to/xyz.ts', + \ }] + + AssertEqual + \ [ + \ { + \ 'word': 'abc', + \ 'menu': 'import { def } from "./Foo"; (property) Foo.abc: number', + \ 'info': '', + \ 'kind': 'v', + \ 'icase': 1, + \ 'user_data': json_encode({ + \ '_ale_completion_item': 1, + \ 'code_actions': [{ + \ 'description': 'import { def } from "./Foo";', + \ 'changes': [], + \ }], + \ }), + \ 'dup': g:ale_completion_autoimport, + \ }, + \ { + \ 'word': 'def', + \ 'menu': '(property) Foo.def: number', + \ 'info': 'foo bar baz', + \ 'kind': 'v', + \ 'icase': 1, + \ 'user_data': json_encode({'_ale_completion_item': 1}), + \ 'dup': g:ale_completion_autoimport, + \ }, + \ { + \ 'word': 'xyz', + \ 'menu': '', + \ 'info': '', + \ 'kind': 'v', + \ 'user_data': json_encode({'_ale_completion_item': 1}), + \ 'icase': 1, + \ }, + \ ], + \ ale#completion#ParseTSServerCompletionEntryDetails({ + \ 'body': [ + \ { + \ 'name': 'abc', + \ 'kind': 'parameterName', + \ 'displayParts': [ + \ {'text': '('}, + \ {'text': 'property'}, + \ {'text': ')'}, + \ {'text': ' '}, + \ {'text': 'Foo'}, + \ {'text': '.'}, + \ {'text': 'abc'}, + \ {'text': ':'}, + \ {'text': ' '}, + \ {'text': 'number'}, + \ ], + \ 'codeActions': [{ + \ 'description': 'import { def } from "./Foo";', + \ 'changes': [], + \ }], + \ }, + \ { + \ 'name': 'def', + \ 'kind': 'parameterName', + \ 'displayParts': [ + \ {'text': '('}, + \ {'text': 'property'}, + \ {'text': ')'}, + \ {'text': ' '}, + \ {'text': 'Foo'}, + \ {'text': '.'}, + \ {'text': 'def'}, + \ {'text': ':'}, + \ {'text': ' '}, + \ {'text': 'number'}, + \ ], + \ 'documentation': [ + \ {'text': 'foo'}, + \ {'text': ' '}, + \ {'text': 'bar'}, + \ {'text': ' '}, + \ {'text': 'baz'}, + \ ], + \ }, + \ ], + \}) + +Execute(Default imports should be handled correctly): + AssertEqual + \ [ + \ { + \ 'word': 'abcd', + \ 'menu': 'Import default ''abcd'' from module "./foo" (alias) const abcd: 3', + \ 'info': '', + \ 'kind': 't', + \ 'icase': 1, + \ 'user_data': json_encode({ + \ '_ale_completion_item': 1, + \ 'code_actions': [{ + \ 'description': 'Import default ''abcd'' from module "./foo"', + \ 'changes': [], + \ }], + \ }), + \ 'dup': g:ale_completion_autoimport, + \ }, + \ ], + \ ale#completion#ParseTSServerCompletionEntryDetails({ + \ 'body': [ + \ { + \ 'name': 'default', + \ 'kind': 'alias', + \ 'displayParts': [ + \ {'kind': 'punctuation', 'text': '('}, + \ {'kind': 'text', 'text': 'alias'}, + \ {'kind': 'punctuation', 'text': ')'}, + \ {'kind': 'space', 'text': ' '}, + \ {'kind': 'keyword', 'text': 'const'}, + \ {'kind': 'space', 'text': ' '}, + \ {'kind': 'localName', 'text': 'abcd'}, + \ {'kind': 'punctuation', 'text': ':'}, + \ {'kind': 'space', 'text': ' '}, + \ {'kind': 'stringLiteral', 'text': '3'}, + \ {'kind': 'lineBreak', 'text': '^@'}, + \ {'kind': 'keyword', 'text': 'export'}, + \ {'kind': 'space', 'text': ' '}, + \ {'kind': 'keyword', 'text': 'default'}, + \ {'kind': 'space', 'text': ' '}, + \ {'kind': 'aliasName', 'text': 'abcd'} + \ ], + \ 'codeActions': [ + \ { + \ 'description': 'Import default ''abcd'' from module "./foo"', + \ 'changes': [], + \ }, + \ ], + \ }, + \ ], + \ }) diff --git a/vim-config/plugins/ale/test/fix/test_ale_fix.vader b/vim-config/plugins/ale/test/fix/test_ale_fix.vader new file mode 100644 index 00000000..128e3a14 --- /dev/null +++ b/vim-config/plugins/ale/test/fix/test_ale_fix.vader @@ -0,0 +1,884 @@ +Before: + Save g:ale_fixers + Save &shell + Save g:ale_enabled + Save g:ale_fix_on_save + Save g:ale_lint_on_save + Save g:ale_echo_cursor + Save g:ale_command_wrapper + Save g:ale_filename_mappings + + silent! cd /testplugin/test/fix + + unlet! b:ale_lint_on_save + let g:ale_enabled = 0 + let g:ale_echo_cursor = 0 + let g:ale_command_wrapper = '' + let g:ale_run_synchronously = 1 + let g:ale_set_lists_synchronously = 1 + let g:ale_fix_buffer_data = {} + let g:ale_fixers = { + \ 'testft': [], + \} + let g:ale_filename_mappings = {} + + let g:pre_success = 0 + let g:post_success = 0 + augroup VaderTest + autocmd! + autocmd User ALEFixPre let g:pre_success = 1 + autocmd User ALEFixPost let g:post_success = 1 + augroup END + + if !has('win32') + let &shell = '/bin/bash' + endif + + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('test.txt') + call ale#linter#PreventLoading('testft') + + function AddCarets(buffer, lines) abort + " map() is applied to the original lines here. + " This way, we can ensure that defensive copies are made. + return map(a:lines, '''^'' . v:val') + endfunction + + function Capitalize(buffer, lines) abort + return map(a:lines, 'toupper(v:val)') + endfunction + + function DoNothing(buffer, lines) abort + return 0 + endfunction + + function CatLine(buffer, lines) abort + return {'command': 'cat - <(echo d)'} + endfunction + + function CatLineOneArg(buffer) abort + return {'command': 'cat - <(echo d)'} + endfunction + + function CatLineDeferred(buffer, lines) abort + return ale#command#Run(a:buffer, 'echo', { + \ -> ale#command#Run(a:buffer, 'echo', {-> {'command': 'cat - <(echo d)'}}) + \}) + endfunction + + function ReplaceWithTempFile(buffer, lines) abort + return {'command': 'echo x > %t', 'read_temporary_file': 1} + endfunction + + function CatWithTempFile(buffer, lines) abort + return {'command': 'cat %t <(echo d)'} + endfunction + + function EchoFilename(buffer, lines) abort + return {'command': 'echo %s'} + endfunction + + function RemoveLastLine(buffer, lines) abort + return ['a', 'b'] + endfunction + + function RemoveLastLineOneArg(buffer) abort + return ['a', 'b'] + endfunction + + function! TestCallback(buffer, output) + return [{'lnum': 1, 'col': 1, 'text': 'xxx'}] + endfunction + + " echo will output a single blank line, and we should ingore it. + function! IgnoredEmptyOutput(buffer, output) + return {'command': has('win32') ? 'echo(' : 'echo'} + endfunction + + function! EchoLineNoPipe(buffer, output) + return {'command': 'echo new line', 'read_buffer': 0} + endfunction + + function! SetUpLinters() + call ale#linter#Define('testft', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': 'true', + \ 'command': 'true', + \}) + endfunction + + function GetLastMessage() + redir => l:output + silent mess + redir END + + let l:lines = split(l:output, "\n") + + return empty(l:lines) ? '' : l:lines[-1] + endfunction + + function! FixWithJSONPostProcessing(buffer) abort + let l:ProcessWith = 'JSONPostProcessor' + + " Test with lambdas where support is available. + if has('lambda') + let l:ProcessWith = {buffer, output -> JSONPostProcessor(buffer, output)} + endif + + " Escaping needs to be handled specially for CMD on Windows. + let l:json_string = has('win32') + \ ? '{"output":["x","y","z"]}' + \ : ale#Escape('{"output": ["x", "y", "z"]}') + + return { + \ 'command': 'echo ' . l:json_string, + \ 'read_buffer': 0, + \ 'process_with': l:ProcessWith, + \} + endfunction + + function! JSONPostProcessor(buffer, output) abort + return json_decode(a:output[0]).output + endfunction + +After: + Restore + unlet! g:test_filename + unlet! g:ale_run_synchronously + unlet! g:ale_set_lists_synchronously + unlet! g:ale_run_synchronously_callbacks + unlet! g:ale_emulate_job_failure + unlet! b:ale_fixers + unlet! b:ale_lint_on_save + unlet! b:ale_fix_on_save + unlet! b:ale_quitting + delfunction AddCarets + delfunction Capitalize + delfunction DoNothing + delfunction CatLine + delfunction CatLineOneArg + delfunction CatLineDeferred + delfunction ReplaceWithTempFile + delfunction CatWithTempFile + delfunction EchoFilename + delfunction RemoveLastLine + delfunction RemoveLastLineOneArg + delfunction TestCallback + delfunction SetUpLinters + delfunction GetLastMessage + delfunction IgnoredEmptyOutput + delfunction EchoLineNoPipe + delfunction FixWithJSONPostProcessing + delfunction JSONPostProcessor + + augroup VaderTest + autocmd! + augroup END + + augroup! VaderTest + + call ale#test#RestoreDirectory() + + call ale#fix#registry#ResetToDefaults() + call ale#linter#Reset() + + setlocal buftype=nofile + + if exists('g:test_filename') && filereadable(g:test_filename) + call delete(g:test_filename) + endif + + call setloclist(0, []) + + let g:ale_fix_buffer_data = {} + + " Clear the messages between tests. + echomsg '' + + if !exists('g:ale_command_wrapper') + let g:ale_command_wrapper = '' + endif + +Given testft (A file with three lines): + a + b + c + +Execute(ALEFix should complain when there are no functions to call): + ALEFix + call ale#test#FlushJobs() + AssertEqual 'No fixers have been defined. Try :ALEFixSuggest', GetLastMessage() + +Execute(ALEFix should not complain when the command is run with a bang): + echom 'none' + + ALEFix! + call ale#test#FlushJobs() + AssertEqual 'none', GetLastMessage() + +Execute(ALEFix should apply simple functions): + let g:ale_fixers.testft = ['AddCarets'] + ALEFix + call ale#test#FlushJobs() + +Expect(The first function should be used): + ^a + ^b + ^c + +Execute(Should apply filename mpapings): + " The command echos %s, and we'll map the current path so we can check + " that ALEFix applies filename mappings, end-to-end. + let g:ale_filename_mappings = { + \ 'echo_filename': [ + \ [expand('%:p:h') . '/', '/some/fake/path/'], + \ ], + \} + + call ale#fix#registry#Add('echo_filename', 'EchoFilename', [], 'echo filename') + let g:ale_fixers.testft = ['echo_filename'] + ALEFix + call ale#test#FlushJobs() + " Remote trailing whitespace from the line. + call setline(1, substitute(getline(1), '[ \r]\+$', '', '')) + +Expect(The mapped filename should be printed): + /some/fake/path/test.txt + +Execute(ALEFix should apply simple functions in a chain): + let g:ale_fixers.testft = ['AddCarets', 'Capitalize'] + ALEFix + call ale#test#FlushJobs() + +Expect(Both functions should be used): + ^A + ^B + ^C + +Execute(ALEFix should allow 0 to be returned to skip functions): + let g:ale_fixers.testft = ['DoNothing', 'Capitalize'] + ALEFix + call ale#test#FlushJobs() + +Expect(Only the second function should be applied): + A + B + C + +Execute(The * fixers shouldn't be used if an empty list is set for fixers): + let g:ale_fixers.testft = [] + let g:ale_fixers['*'] = ['Capitalize'] + ALEFix + call ale#test#FlushJobs() + +Expect(Nothing should be changed): + a + b + c + +Execute(* fixers should be used if no filetype is matched): + let g:ale_fixers = {'*': ['Capitalize']} + ALEFix + call ale#test#FlushJobs() + +Expect(The file should be changed): + A + B + C + +Execute(ALEFix should allow commands to be run): + if has('win32') + " Just skip this test on Windows, we can't run it. + call setline(1, ['a', 'b', 'c', 'd']) + else + let g:ale_fixers.testft = ['CatLine'] + ALEFix + call ale#test#FlushJobs() + endif + +Expect(An extra line should be added): + a + b + c + d + +Execute(ALEFix should use fixers passed in commandline when provided): + let g:ale_fixers.testft = ['RemoveLastLine'] + ALEFix AddCarets Capitalize + call ale#test#FlushJobs() + +Expect(Only fixers passed via command line should be run): + ^A + ^B + ^C + +Execute(ALEFix should allow temporary files to be read): + if has('win32') + " Just skip this test on Windows, we can't run it. + call setline(1, ['x']) + 2,3d + else + let g:ale_fixers.testft = ['ReplaceWithTempFile'] + ALEFix + call ale#test#FlushJobs() + endif + +Expect(The line we wrote to the temporary file should be used here): + x + +Execute(ALEFix should not read the temporary file when the option is not set): + if has('win32') + " Just skip this test on Windows, we can't run it. + call setline(1, ['a', 'b', 'c', 'd']) + else + let g:ale_fixers.testft = ['CatWithTempFile'] + ALEFix + call ale#test#FlushJobs() + endif + +Expect(An extra line should be added): + a + b + c + d + +Execute(ALEFix should allow jobs and simple functions to be combined): + if has('win32') + " Just skip this test on Windows, we can't run it. + call setline(1, ['X']) + 2,3d + else + let g:ale_fixers.testft = ['ReplaceWithTempFile', 'Capitalize'] + ALEFix + call ale#test#FlushJobs() + endif + +Expect(The lines from the temporary file should be modified): + X + +Execute(ALEFix should send lines modified by functions to jobs): + if has('win32') + " Just skip this test on Windows, we can't run it. + call setline(1, ['A', 'B', 'C', 'd']) + else + let g:ale_fixers.testft = ['Capitalize', 'CatLine'] + ALEFix + call ale#test#FlushJobs() + endif + +Expect(The lines should first be modified by the function, then the job): + A + B + C + d + +Execute(ALEFix should skip commands when jobs fail to run): + let g:ale_emulate_job_failure = 1 + let g:ale_fixers.testft = ['CatLine', 'Capitalize'] + ALEFix + call ale#test#FlushJobs() + +Expect(Only the second function should be applied): + A + B + C + +Execute(ALEFix should handle strings for selecting a single function): + let g:ale_fixers.testft = 'AddCarets' + ALEFix + call ale#test#FlushJobs() + +Expect(The first function should be used): + ^a + ^b + ^c + +Execute(ALEFix should use functions from the registry): + call ale#fix#registry#Add('add_carets', 'AddCarets', [], 'Add some carets') + let g:ale_fixers.testft = ['add_carets'] + ALEFix + call ale#test#FlushJobs() + +Expect(The registry function should be used): + ^a + ^b + ^c + +Execute(ALEFix should be able to remove the last line for files): + let g:ale_fixers.testft = ['RemoveLastLine'] + ALEFix + call ale#test#FlushJobs() + +Expect(There should be only two lines): + a + b + +Execute(ALEFix should accept funcrefs): + let g:ale_fixers.testft = [function('RemoveLastLine')] + ALEFix + call ale#test#FlushJobs() + +Expect(There should be only two lines): + a + b + +Execute(ALEFix should accept lambdas): + if has('nvim') + " NeoVim 0.1.7 can't interpret lambdas correctly, so just set the lines + " to make the test pass. + call setline(1, ['a', 'b', 'c', 'd']) + else + let g:ale_fixers.testft = [{buffer, lines -> lines + ['d']}] + ALEFix + call ale#test#FlushJobs() + endif + +Expect(There should be an extra line): + a + b + c + d + +Execute(ALEFix should user buffer-local fixer settings): + let g:ale_fixers.testft = ['AddCarets', 'Capitalize'] + let b:ale_fixers = {'testft': ['RemoveLastLine']} + ALEFix + call ale#test#FlushJobs() + +Expect(There should be only two lines): + a + b + +Execute(ALEFix should allow Lists to be used for buffer-local fixer settings): + let g:ale_fixers.testft = ['AddCarets', 'Capitalize'] + let b:ale_fixers = ['RemoveLastLine'] + ALEFix + call ale#test#FlushJobs() + +Expect(There should be only two lines): + a + b + +Given testft (A file with three lines): + a + b + c + +Execute(ALEFix should fix files on the save event): + let g:ale_fix_on_save = 1 + let g:ale_lint_on_save = 1 + let g:ale_enabled = 1 + + let g:test_filename = tempname() + execute 'noautocmd silent file ' . fnameescape(g:test_filename) + call writefile(getline(1, '$'), g:test_filename) + + let g:ale_fixers.testft = ['Capitalize'] + + " We have to set the buftype to empty so the file will be written. + setlocal buftype= + + call SetUpLinters() + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + " We should save the file. + AssertEqual ['A', 'B', 'C'], readfile(g:test_filename) + Assert !&modified, 'The file was marked as ''modified''' + + if !has('win32') + " We should have run the linter. + AssertEqual [{ + \ 'bufnr': bufnr('%'), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 1, + \ 'text': 'xxx', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \}], ale#test#GetLoclistWithoutModule() + endif + +Expect(The buffer should be modified): + A + B + C + +Given testft (A file with three lines): + a + b + c + +Execute(ALEFix should run the linters with b:ale_lint_on_save = 1): + let g:ale_fix_on_save = 0 + let b:ale_fix_on_save = 1 + let g:ale_lint_on_save = 1 + let g:ale_enabled = 1 + + let g:test_filename = tempname() + execute 'noautocmd silent file ' . fnameescape(g:test_filename) + call writefile(getline(1, '$'), g:test_filename) + + let g:ale_fixers.testft = ['Capitalize'] + + " We have to set the buftype to empty so the file will be written. + setlocal buftype= + + call SetUpLinters() + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + " We should save the file. + AssertEqual ['A', 'B', 'C'], readfile(g:test_filename) + Assert !&modified, 'The file was marked as ''modified''' + + if !has('win32') + " We should have run the linter. + AssertEqual [{ + \ 'bufnr': bufnr('%'), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 1, + \ 'text': 'xxx', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \}], ale#test#GetLoclistWithoutModule() + endif + +Expect(The buffer should be modified): + A + B + C + +Execute(ALEFix should not fix files on :wq): + let g:ale_fix_on_save = 1 + let g:ale_lint_on_save = 1 + let g:ale_enabled = 1 + + let g:test_filename = tempname() + execute 'noautocmd silent file ' . fnameescape(g:test_filename) + call writefile(getline(1, '$'), g:test_filename) + + let g:ale_fixers.testft = ['Capitalize'] + + " We have to set the buftype to empty so the file will be written. + setlocal buftype= + + call ale#events#QuitEvent(bufnr('')) + + call SetUpLinters() + call ale#events#SaveEvent(bufnr('')) + + " We should save the file. + AssertEqual ['a', 'b', 'c'], readfile(g:test_filename) + Assert &modified, 'The was not marked as ''modified''' + + " We should not run the linter. + AssertEqual [], ale#test#GetLoclistWithoutModule() + +Expect(The buffer should not be modified): + a + b + c + +Given testft (A file with three lines): + a + b + c + +Execute(ALEFix should still lint with no linters to be applied): + let g:ale_fix_on_save = 1 + let g:ale_lint_on_save = 1 + let g:ale_enabled = 1 + + let g:test_filename = tempname() + execute 'noautocmd silent file ' . fnameescape(g:test_filename) + + let g:ale_fixers.testft = [] + + call SetUpLinters() + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + Assert !filereadable(g:test_filename), 'The file should not have been saved' + + if !has('win32') + " We have run the linter. + AssertEqual [{ + \ 'bufnr': bufnr('%'), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 1, + \ 'text': 'xxx', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \}], ale#test#GetLoclistWithoutModule() + endif + +Expect(The buffer should be the same): + a + b + c + +Execute(ALEFix should still lint when nothing was fixed on save): + let g:ale_fix_on_save = 1 + let g:ale_lint_on_save = 1 + let g:ale_enabled = 1 + + let g:test_filename = tempname() + execute 'noautocmd silent file ' . fnameescape(g:test_filename) + + let g:ale_fixers.testft = ['DoNothing'] + + call SetUpLinters() + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + Assert !filereadable(g:test_filename), 'The file should not have been saved' + + if !has('win32') + " We should have run the linter. + AssertEqual [{ + \ 'bufnr': bufnr('%'), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 1, + \ 'text': 'xxx', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \}], ale#test#GetLoclistWithoutModule() + endif + +Expect(The buffer should be the same): + a + b + c + +Execute(ALEFix should not lint the buffer on save if linting on save is disabled globally): + let g:ale_fix_on_save = 1 + let g:ale_lint_on_save = 0 + let g:ale_enabled = 1 + + let g:test_filename = tempname() + execute 'noautocmd silent file ' . fnameescape(g:test_filename) + + let g:ale_fixers.testft = ['DoNothing'] + + call SetUpLinters() + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + Assert !filereadable(g:test_filename), 'The file should not have been saved' + + AssertEqual [], ale#test#GetLoclistWithoutModule() + +Expect(The buffer should be the same): + a + b + c + +Execute(ALEFix should not lint the buffer on save if linting on save is disabled locally): + let g:ale_fix_on_save = 1 + let b:ale_lint_on_save = 0 + let g:ale_enabled = 1 + + let g:test_filename = tempname() + execute 'noautocmd silent file ' . fnameescape(g:test_filename) + + let g:ale_fixers.testft = ['DoNothing'] + + call SetUpLinters() + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + Assert !filereadable(g:test_filename), 'The file should not have been saved' + + AssertEqual [], ale#test#GetLoclistWithoutModule() + +Expect(The buffer should be the same): + a + b + c + +Given testft (A file with three lines): + a + b + c + +Execute(ale#fix#InitBufferData() should set up the correct data): + let g:test_filename = tempname() + execute 'noautocmd silent file ' . fnameescape(g:test_filename) + + call ale#fix#InitBufferData(bufnr(''), 'save_file') + + AssertEqual { + \ bufnr(''): { + \ 'temporary_directory_list': [], + \ 'done': 0, + \ 'lines_before': ['a', 'b', 'c'], + \ 'should_save': 1, + \ 'ignore_file_changed_errors': 0, + \ }, + \}, g:ale_fix_buffer_data + + call ale#fix#InitBufferData(bufnr(''), '!') + + AssertEqual { + \ bufnr(''): { + \ 'temporary_directory_list': [], + \ 'done': 0, + \ 'lines_before': ['a', 'b', 'c'], + \ 'should_save': 0, + \ 'ignore_file_changed_errors': 1, + \ }, + \}, g:ale_fix_buffer_data + +Execute(ALEFix simple functions should be able to accept one argument, the buffer): + let g:ale_fixers.testft = ['RemoveLastLineOneArg'] + ALEFix + call ale#test#FlushJobs() + +Expect(There should be only two lines): + a + b + +Execute(ALEFix should modify a buffer that is not modifiable, if it becomes modifiable later): + let g:ale_fixers.testft = ['RemoveLastLineOneArg'] + + set nomodifiable + ALEFix + call ale#test#FlushJobs() + set modifiable + call ale#fix#ApplyQueuedFixes(bufnr('')) + +Expect(There should be only two lines): + a + b + +Execute(b:ale_fix_on_save = 1 should override g:ale_fix_on_save = 0): + let g:ale_fix_on_save = 0 + let b:ale_fix_on_save = 1 + + let g:ale_fixers.testft = ['RemoveLastLineOneArg'] + call ale#events#SaveEvent(bufnr('')) + +Expect(There should be only two lines): + a + b + +Execute(b:ale_fix_on_save = 0 should override g:ale_fix_on_save = 1): + let g:ale_fix_on_save = 1 + let b:ale_fix_on_save = 0 + + let g:ale_fixers.testft = ['RemoveLastLineOneArg'] + call ale#events#SaveEvent(bufnr('')) + +Expect(The lines should be the same): + a + b + c + +Execute(ALEFix functions returning jobs should be able to accept one argument): + if has('win32') + " Just skip this test on Windows, we can't run it. + call setline(1, ['a', 'b', 'c', 'd']) + else + let g:ale_fixers.testft = ['CatLine'] + ALEFix + call ale#test#FlushJobs() + endif + +Expect(An extra line should be added): + a + b + c + d + +Execute(ALE should print a message telling you something isn't a valid fixer when you type some nonsense): + let g:ale_fixers.testft = ['CatLine', 'invalidname'] + ALEFix + call ale#test#FlushJobs() + + AssertEqual 'There is no fixer named `invalidname`. Check :ALEFixSuggest', GetLastMessage() + +Execute(ALE should complain about invalid fixers with minuses in the name): + let g:ale_fixers.testft = ['foo-bar'] + ALEFix + call ale#test#FlushJobs() + + AssertEqual 'There is no fixer named `foo-bar`. Check :ALEFixSuggest', GetLastMessage() + +Execute(ALE should tolerate valid fixers with minuses in the name): + let g:ale_fixers.testft = ['prettier-standard'] + ALEFix + call ale#test#FlushJobs() + +Execute(Empty output should be ignored): + let g:ale_fixers.testft = ['IgnoredEmptyOutput'] + ALEFix + call ale#test#FlushJobs() + +Expect(The lines should be the same): + a + b + c + +Execute(A temporary file shouldn't be piped into the command when disabled): + let g:ale_fixers.testft = ['EchoLineNoPipe'] + ALEFix + call ale#test#FlushJobs() + + AssertEqual + \ string(ale#job#PrepareCommand(bufnr(''), 'echo new line')), + \ string(ale#history#Get(bufnr(''))[-1].command) + + " Remove trailing whitespace for Windows. + if has('win32') + %s/[[:space:]]*$//g + endif + +Expect(The new line should be used): + new line + +Execute(Post-processing should work): + let g:ale_fixers.testft = ['FixWithJSONPostProcessing'] + ALEFix + call ale#test#FlushJobs() + +Expect(The lines in the JSON should be used): + x + y + z + +Execute(ALEFix should apply autocmds): + let g:ale_fixers.testft = ['AddCarets'] + ALEFix + call ale#test#FlushJobs() + + AssertEqual g:pre_success, 1 + AssertEqual g:post_success, 1 + +Execute(ALEFix should support ale#command#Run): + if has('win32') + " Just skip this test on Windows, we can't run it. + call setline(1, ['a', 'b', 'c', 'd']) + else + let g:ale_fixers.testft = ['CatLineDeferred'] + ALEFix + call ale#test#FlushJobs() + endif + +Expect(The extra line should be added): + a + b + c + d diff --git a/vim-config/plugins/ale/test/fix/test_ale_fix_aliases.vader b/vim-config/plugins/ale/test/fix/test_ale_fix_aliases.vader new file mode 100644 index 00000000..d3c47b34 --- /dev/null +++ b/vim-config/plugins/ale/test/fix/test_ale_fix_aliases.vader @@ -0,0 +1,5 @@ +Execute(prettier-eslint should be aliased): + AssertEqual 'ale#fixers#prettier_eslint#Fix', ale#fix#registry#GetFunc('prettier-eslint') + +Execute(prettier-standard should be aliased): + AssertEqual 'ale#fixers#prettier_standard#Fix', ale#fix#registry#GetFunc('prettier-standard') diff --git a/vim-config/plugins/ale/test/fix/test_ale_fix_completion.vader b/vim-config/plugins/ale/test/fix/test_ale_fix_completion.vader new file mode 100644 index 00000000..6c38bb8d --- /dev/null +++ b/vim-config/plugins/ale/test/fix/test_ale_fix_completion.vader @@ -0,0 +1,23 @@ +Execute (List of available fixers is empty): + call ale#fix#registry#Clear() + +Then (List of applicable fixers for python file is empty): + AssertEqual [], ale#fix#registry#GetApplicableFixers('python') + +Execute (Add ruby fixer): + call ale#fix#registry#Add('ruby_fixer', 'fixer_fun', ['ruby'], 'ruby fixer') + +Then (List of applicable fixers for python file is still empty): + AssertEqual [], ale#fix#registry#GetApplicableFixers('python') + +Execute (Add generic fixer): + call ale#fix#registry#Add('generic_fixer', 'fixer_fun', [], 'generic fixer') + +Then (Generic fixer should be returned as applicable for python file): + AssertEqual ['generic_fixer'], ale#fix#registry#GetApplicableFixers('python') + +Execute (Add python fixer): + call ale#fix#registry#Add('python_fixer', 'fixer_func', ['python'], 'python fixer') + +Then (List of fixers should contain both generic and python fixers): + AssertEqual ['generic_fixer', 'python_fixer'], ale#fix#registry#GetApplicableFixers('python') diff --git a/vim-config/plugins/ale/test/fix/test_ale_fix_completion_filter.vader b/vim-config/plugins/ale/test/fix/test_ale_fix_completion_filter.vader new file mode 100644 index 00000000..536b7138 --- /dev/null +++ b/vim-config/plugins/ale/test/fix/test_ale_fix_completion_filter.vader @@ -0,0 +1,14 @@ +Before: + call ale#fix#registry#Clear() + call ale#test#SetFilename('test.js') + call ale#fix#registry#Add('prettier', '', ['javascript'], 'prettier') + call ale#fix#registry#Add('eslint', '', ['javascript'], 'eslint') + setfiletype javascript + +Execute(completeFixers returns all of the applicable fixers without an arglead): + AssertEqual ['eslint', 'prettier'], + \ ale#fix#registry#CompleteFixers('', 'ALEFix ', 7) + +Execute(completeFixers returns all of the applicable fixers without an arglead): + AssertEqual ['prettier'], + \ ale#fix#registry#CompleteFixers('pre', 'ALEFix ', 10) diff --git a/vim-config/plugins/ale/test/fix/test_ale_fix_ignore.vader b/vim-config/plugins/ale/test/fix/test_ale_fix_ignore.vader new file mode 100644 index 00000000..5eb9b9ab --- /dev/null +++ b/vim-config/plugins/ale/test/fix/test_ale_fix_ignore.vader @@ -0,0 +1,110 @@ +Before: + Save g:ale_fixers + Save g:ale_fix_on_save + Save g:ale_fix_on_save_ignore + + let g:ale_fix_on_save = 1 + let g:ale_fixers = {'abc': ['a', 'b'], 'xyz': ['c', 'd']} + unlet! b:ale_fixers + unlet! b:ale_fix_on_save_ignore + + function FixerA(buffer, lines) abort + return a:lines + ['a'] + endfunction + + function FixerB(buffer, lines) abort + return a:lines + ['b'] + endfunction + + function FixerC(buffer, lines) abort + return a:lines + ['c'] + endfunction + + function FixerD(buffer, lines) abort + return a:lines + ['d'] + endfunction + + set filetype=abc.xyz + let g:test_filename = tempname() + execute 'noautocmd silent file ' . fnameescape(g:test_filename) + + call ale#fix#registry#Add('a', 'FixerA', ['abc'], '') + call ale#fix#registry#Add('b', 'FixerB', ['abc'], '') + call ale#fix#registry#Add('c', 'FixerC', ['xyz'], '') + call ale#fix#registry#Add('d', 'FixerD', ['xyz'], '') + +After: + Restore + + if exists('g:test_filename') && filereadable(g:test_filename) + call delete(g:test_filename) + endif + + unlet! b:ale_fixers + unlet! b:ale_fix_on_save_ignore + unlet! g:test_filename + + delfunction FixerA + delfunction FixerB + delfunction FixerC + delfunction FixerD + + call ale#fix#registry#ResetToDefaults() + +Given abc.xyz (An empty file): +Execute(Ignoring with a filetype in a global Dictionary should work): + let g:ale_fix_on_save_ignore = {'abc': ['b'], 'xyz': ['c']} + + call ale#events#SaveEvent(bufnr('')) + + AssertEqual ['', 'a', 'd'], getline(1, '$') + +Execute(Ignoring with a filetype in a global List should work): + let g:ale_fix_on_save_ignore = ['b', 'c'] + + call ale#events#SaveEvent(bufnr('')) + + AssertEqual ['', 'a', 'd'], getline(1, '$') + +Execute(Ignoring with a filetype in a local Dictionary should work): + let g:ale_fix_on_save_ignore = {'abc': ['b'], 'xyz': ['c']} + " The local Dictionary should entirely replace the global one. + let b:ale_fix_on_save_ignore = {'abc': ['b']} + + call ale#events#SaveEvent(bufnr('')) + + AssertEqual ['', 'a', 'c', 'd'], getline(1, '$') + +Execute(Ignoring with a filetype in a local List should work): + let g:ale_fix_on_save_ignore = {'abc': ['b'], 'xyz': ['c']} + " The local List should entirely replace the global Dictionary. + let b:ale_fix_on_save_ignore = ['b'] + + call ale#events#SaveEvent(bufnr('')) + + AssertEqual ['', 'a', 'c', 'd'], getline(1, '$') + +Execute(Ignoring functions by reference with a Dictionary should work): + let g:ale_fixers = { + \ 'abc': [function('FixerA'), function('FixerB')], + \ 'xyz': [function('FixerC'), function('FixerD')], + \} + let b:ale_fix_on_save_ignore = { + \ 'abc': [function('FixerB')], + \ 'xyz': [function('FixerC')], + \} + + call ale#events#SaveEvent(bufnr('')) + + AssertEqual ['', 'a', 'd'], getline(1, '$') + +Execute(Ignoring functions by reference with a List should work): + let g:ale_fixers = { + \ 'abc': [function('FixerA'), function('FixerB')], + \ 'xyz': [function('FixerC'), function('FixerD')], + \} + let b:ale_fix_on_save_ignore = [function('FixerB'), function('FixerC')] + + call ale#events#SaveEvent(bufnr('')) + + AssertEqual ['', 'a', 'd'], getline(1, '$') diff --git a/vim-config/plugins/ale/test/fix/test_ale_fix_suggest.vader b/vim-config/plugins/ale/test/fix/test_ale_fix_suggest.vader new file mode 100644 index 00000000..1100aeed --- /dev/null +++ b/vim-config/plugins/ale/test/fix/test_ale_fix_suggest.vader @@ -0,0 +1,102 @@ +Before: + call ale#fix#registry#Clear() + + let g:buffer = bufnr('') + + function GetSuggestions() + silent ALEFixSuggest + + if bufnr('') != g:buffer + let l:lines = getline(1, '$') + else + let l:lines = [] + endif + + return l:lines + endfunction + +After: + if bufnr('') != g:buffer + :q! + endif + + unlet! g:buffer + + call ale#fix#registry#ResetToDefaults() + delfunction GetSuggestions + +Execute(ALEFixSuggest should return something sensible with no suggestions): + AssertEqual + \ [ + \ 'There is nothing in the registry to suggest.', + \ '', + \ 'Press q to close this window', + \ ], + \ GetSuggestions() + +Execute(ALEFixSuggest should set the appropriate settings): + silent ALEFixSuggest + + AssertEqual 'ale-fix-suggest', &filetype + Assert !&modified, 'The buffer was marked as modified' + Assert !&modifiable, 'The buffer was modifiable' + +Execute(ALEFixSuggest output should be correct for only generic handlers): + call ale#fix#registry#Add('zed', 'XYZ', [], 'Zedify things.') + call ale#fix#registry#Add('alpha', 'XYZ', [], 'Alpha things.') + + AssertEqual + \ [ + \ 'Try the following generic fixers:', + \ '', + \ '''alpha'' - Alpha things.', + \ '''zed'' - Zedify things.', + \ '', + \ 'See :help ale-fix-configuration', + \ '', + \ 'Press q to close this window', + \ ], + \ GetSuggestions() + +Execute(ALEFixSuggest output should be correct for only filetype handlers): + let &filetype = 'testft2.testft' + + call ale#fix#registry#Add('zed', 'XYZ', ['testft2'], 'Zedify things.') + call ale#fix#registry#Add('alpha', 'XYZ', ['testft'], 'Alpha things.') + + AssertEqual + \ [ + \ 'Try the following fixers appropriate for the filetype:', + \ '', + \ '''alpha'' - Alpha things.', + \ '''zed'' - Zedify things.', + \ '', + \ 'See :help ale-fix-configuration', + \ '', + \ 'Press q to close this window', + \ ], + \ GetSuggestions() + +Execute(ALEFixSuggest should suggest filetype and generic handlers): + let &filetype = 'testft2.testft' + + call ale#fix#registry#Add('zed', 'XYZ', ['testft2'], 'Zedify things.', ['foobar']) + call ale#fix#registry#Add('alpha', 'XYZ', ['testft'], 'Alpha things.') + call ale#fix#registry#Add('generic', 'XYZ', [], 'Generic things.') + + AssertEqual + \ [ + \ 'Try the following fixers appropriate for the filetype:', + \ '', + \ '''alpha'' - Alpha things.', + \ '''zed'', ''foobar'' - Zedify things.', + \ '', + \ 'Try the following generic fixers:', + \ '', + \ '''generic'' - Generic things.', + \ '', + \ 'See :help ale-fix-configuration', + \ '', + \ 'Press q to close this window', + \ ], + \ GetSuggestions() diff --git a/vim-config/plugins/ale/test/fixers/test_appleswiftformat_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_appleswiftformat_fixer_callback.vader new file mode 100644 index 00000000..72465f4f --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_appleswiftformat_fixer_callback.vader @@ -0,0 +1,47 @@ +Before: + call ale#assert#SetUpFixerTest('swift', 'apple-swift-format') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The swiftformat callback should return the correct default values): + call ale#test#SetFilename('../test-files/swift/dummy.swift') + let g:ale_swift_appleswiftformat_executable = 'xxxinvalid' + let g:ale_swift_appleswiftformat_use_swiftpm = 0 + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_swift_appleswiftformat_executable) + \ . ' format --in-place %t', + \ }, + \ ale#fixers#appleswiftformat#Fix(bufnr('')) + +Execute(The swiftformat callback should return the correct default values and located configuration): + call ale#test#SetDirectory('/testplugin/test/test-files/swift/swift-package-project-with-config') + call ale#test#SetFilename('src/folder/dummy.swift') + + let g:ale_swift_appleswiftformat_executable = 'xxxinvalid' + let g:ale_swift_appleswiftformat_use_swiftpm = 0 + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_swift_appleswiftformat_executable) + \ . ' format --in-place %t --configuration ' . glob(g:dir . '/.swift-format'), + \ }, + \ ale#fixers#appleswiftformat#Fix(bufnr('')) + + call ale#test#RestoreDirectory() + +Execute(The swiftformat callback should use swiftpm is use_swiftpm is set to 1): + call ale#test#SetFilename('../test-files/swift/swift-package-project/src/folder/dummy.swift') + let g:ale_swift_appleswiftformat_use_swiftpm = 1 + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('swift') + \ . ' run swift-format format --in-place %t', + \ }, + \ ale#fixers#appleswiftformat#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_astyle_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_astyle_fixer_callback.vader new file mode 100644 index 00000000..9d2e4c80 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_astyle_fixer_callback.vader @@ -0,0 +1,96 @@ +Before: + Save g:ale_c_astyle_executable + Save g:ale_c_astyle_project_options + Save g:ale_cpp_astyle_project_options + + " Use an invalid global executable, so we don't match it. + let g:ale_c_astyle_executable = 'xxxinvalid' + let g:ale_cpp_astyle_executable = 'invalidpp' + let g:ale_c_astyle_project_options = '' + let g:ale_cpp_astyle_project_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The astyle callback should return the correct default values): + " Because this file doesn't exist, no astylrc config + " exists near it. Therefore, project_options is empty. + call ale#test#SetFilename('../c_files/testfile.c') + let targetfile = bufname(bufnr('%')) + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_c_astyle_executable) + \ . ' --stdin=' . ale#Escape(targetfile) + \ }, + \ ale#fixers#astyle#Fix(bufnr('')) + +Execute(The astyle callback should support cpp files): + " Because this file doesn't exist, no astylrc config + " exists near it. Therefore, project_options is empty. + call ale#test#SetFilename('../cpp_files/dummy.cpp') + set filetype=cpp " The test fails without this + let targetfile = bufname(bufnr('%')) + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_cpp_astyle_executable) + \ . ' --stdin=' . ale#Escape(targetfile) + \ }, + \ ale#fixers#astyle#Fix(bufnr('')) + +Execute(The astyle callback should support cpp files with option file set): + call ale#test#SetFilename('../cpp_files/dummy.cpp') + let g:ale_cpp_astyle_project_options = '.astylerc_cpp' + let targetfile = bufname(bufnr('%')) + set filetype=cpp " The test fails without this + + AssertEqual + \ { + \ 'command': ale#Escape('invalidpp') + \ . ' --project=' . g:ale_cpp_astyle_project_options + \ . ' --stdin=' . ale#Escape(targetfile) + \ }, + \ ale#fixers#astyle#Fix(bufnr('')) + +Execute(The astyle callback should return the correct default values with a specified option file): + call ale#test#SetFilename('../c_files/testfile.c') + let g:ale_c_astyle_project_options = '.astylerc_c' + let targetfile = bufname(bufnr('%')) + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' --project=' . g:ale_c_astyle_project_options + \ . ' --stdin=' . ale#Escape(targetfile) + \ }, + \ ale#fixers#astyle#Fix(bufnr('')) + +Execute(The astyle callback should find nearest default option file _astylrc): + call ale#test#SetFilename('../test-files/c/makefile_project/subdir/file.c') + let targetfile = bufname(bufnr('%')) + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' --project=_astylerc' + \ . ' --stdin=' . ale#Escape(targetfile) + \ }, + \ ale#fixers#astyle#Fix(bufnr('')) + +Execute(The astyle callback should find .astylrc in the same directory as src): + call ale#test#SetFilename('../test-files/cpp/dummy.cpp') + set filetype=cpp " The test fails without this + let targetfile = bufname(bufnr('%')) + + AssertEqual + \ { + \ 'command': ale#Escape('invalidpp') + \ . ' --project=.astylerc' + \ . ' --stdin=' . ale#Escape(targetfile) + \ }, + \ ale#fixers#astyle#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_autoflake_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_autoflake_fixer_callback.vader new file mode 100644 index 00000000..91fc62b5 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_autoflake_fixer_callback.vader @@ -0,0 +1,49 @@ +Before: + Save g:ale_python_autoflake_executable + Save g:ale_python_autoflake_options + + " Use an invalid global executable, so we don't match it. + let g:ale_python_autoflake_executable = 'xxxinvalid' + let g:ale_python_autoflake_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + let g:dir = getcwd() + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + Restore + + unlet! b:bin_dir + + call ale#test#RestoreDirectory() + +Execute(The autoflake callback should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#autoflake#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ { + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/autoflake')) + \ . ' --in-place ' + \ . ' %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#autoflake#Fix(bufnr('')) + + +Execute(The autoflake callback should include options): + let g:ale_python_autoflake_options = '--some-option' + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ { + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/autoflake')) + \ . ' --some-option' + \ . ' --in-place ' + \ . ' %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#autoflake#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_autoimport_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_autoimport_fixer_callback.vader new file mode 100644 index 00000000..edca5c38 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_autoimport_fixer_callback.vader @@ -0,0 +1,47 @@ +Before: + Save g:ale_python_autoimport_executable + Save g:ale_python_autoimport_options + + " Use an invalid global executable, so we don't match it. + let g:ale_python_autoimport_executable = 'xxxinvalid' + let g:ale_python_autoimport_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + Restore + + unlet! b:bin_dir + + call ale#test#RestoreDirectory() + +Execute(The autoimport callback should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#autoimport#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/autoimport')) . ' -', + \ }, + \ ale#fixers#autoimport#Fix(bufnr('')) + +Execute(The autoimport callback should respect custom options): + let g:ale_python_autoimport_options = '--multi-line=3 --trailing-comma' + + AssertEqual + \ 0, + \ ale#fixers#autoimport#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/autoimport')) + \ . ' --multi-line=3 --trailing-comma -', + \ }, + \ ale#fixers#autoimport#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_autopep8_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_autopep8_fixer_callback.vader new file mode 100644 index 00000000..46671eda --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_autopep8_fixer_callback.vader @@ -0,0 +1,37 @@ +Before: + Save g:ale_python_autopep8_executable + Save g:ale_python_autopep8_options + + " Use an invalid global executable, so we don't match it. + let g:ale_python_autopep8_executable = 'xxxinvalid' + let g:ale_python_autopep8_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + let g:dir = getcwd() + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + Restore + + unlet! b:bin_dir + + call ale#test#RestoreDirectory() + +Execute(The autopep8 callback should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#autopep8#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/autopep8')) . ' -'}, + \ ale#fixers#autopep8#Fix(bufnr('')) + +Execute(The autopep8 callback should include options): + let g:ale_python_autopep8_options = '--some-option' + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/autopep8')) . ' --some-option -' }, + \ ale#fixers#autopep8#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_bibclean_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_bibclean_fixer_callback.vader new file mode 100644 index 00000000..88412eca --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_bibclean_fixer_callback.vader @@ -0,0 +1,30 @@ +Before: + Save g:ale_bib_bibclean_executable + Save g:ale_bib_bibclean_options + + let g:ale_bib_bibclean_executable = 'xxxinvalid' + let g:ale_bib_bibclean_options = '-align-equals' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + call ale#test#RestoreDirectory() + +Execute(The bibclean callback should return the correct default values): + call ale#test#SetFilename('../test-files/bib/dummy.bib') + + AssertEqual + \ {'command': ale#Escape(g:ale_bib_bibclean_executable) . ' -align-equals'}, + \ ale#fixers#bibclean#Fix(bufnr('')) + +Execute(The bibclean callback should include custom bibclean options): + let g:ale_bib_bibclean_options = '-author -check-values' + call ale#test#SetFilename('../test-files/bib/dummy.bib') + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_bib_bibclean_executable) . ' -author -check-values' + \ }, + \ ale#fixers#bibclean#Fix(bufnr('')) + diff --git a/vim-config/plugins/ale/test/fixers/test_black_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_black_fixer_callback.vader new file mode 100644 index 00000000..bb76a1fe --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_black_fixer_callback.vader @@ -0,0 +1,67 @@ +Before: + call ale#assert#SetUpFixerTest('python', 'black') + + let g:dir = getcwd() + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + call ale#assert#TearDownFixerTest() + + unlet! g:dir + unlet! b:bin_dir + +Execute(The black callback should return the correct default values): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/black')) . ' -'}, + \ ale#fixers#black#Fix(bufnr('')) + +Execute(The black callback should include options): + let g:ale_python_black_options = '--some-option' + let g:ale_python_black_change_directory = 0 + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/black')) . ' --some-option -' }, + \ ale#fixers#black#Fix(bufnr('')) + +Execute(The black callback should include --pyi for .pyi files): + let g:ale_python_black_change_directory = 0 + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.pyi') + + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/black')) . ' --pyi -' }, + \ ale#fixers#black#Fix(bufnr('')) + +Execute(The black callback should not concatenate options): + let g:ale_python_black_options = '--some-option' + let g:ale_python_black_change_directory = 0 + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.pyi') + + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/black')) . ' --some-option --pyi -' }, + \ ale#fixers#black#Fix(bufnr('')) + +Execute(Pipenv is detected when python_black_auto_pipenv is set): + let g:ale_python_black_auto_pipenv = 1 + let g:ale_python_black_change_directory = 0 + + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertEqual + \ {'command': ale#Escape('pipenv') . ' run black -'}, + \ ale#fixers#black#Fix(bufnr('')) + +Execute(Poetry is detected when python_black_auto_poetry is set): + let g:ale_python_black_auto_poetry = 1 + let g:ale_python_black_change_directory = 0 + + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertEqual + \ {'command': ale#Escape('poetry') . ' run black -'}, + \ ale#fixers#black#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_break_up_long_lines_python_fixer.vader b/vim-config/plugins/ale/test/fixers/test_break_up_long_lines_python_fixer.vader new file mode 100644 index 00000000..c7809acd --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_break_up_long_lines_python_fixer.vader @@ -0,0 +1,39 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + call ale#test#RestoreDirectory() + +Execute(Long lines with basic function calls should be broken up correctly): + AssertEqual + \ [ + \ 'def foo():', + \ ' some_variable = this_is_a_longer_function(', + \ 'first_argument,', + \ ' second_argument,', + \ ' third_with_function_call(', + \ 'foo,', + \ ' bar,', + \ '))', + \ ], + \ ale#fixers#generic_python#BreakUpLongLines(bufnr(''), [ + \ 'def foo():', + \ ' some_variable = this_is_a_longer_function(first_argument, second_argument, third_with_function_call(foo, bar))', + \ ]) + +Execute(Longer lines should be permitted if a configuration file allows it): + call ale#test#SetFilename('../test-files/long-line/foo/bar.py') + + AssertEqual + \ [ + \ 'x = this_line_is_between_79_and_90_characters(first, second, third, fourth, fifth)', + \ 'y = this_line_is_longer_than_90_characters(', + \ 'much_longer_word,', + \ ' another_longer_word,', + \ ' a_third_long_word,', + \ ')' + \ ], + \ ale#fixers#generic_python#BreakUpLongLines(bufnr(''), [ + \ 'x = this_line_is_between_79_and_90_characters(first, second, third, fourth, fifth)', + \ 'y = this_line_is_longer_than_90_characters(much_longer_word, another_longer_word, a_third_long_word)', + \ ]) diff --git a/vim-config/plugins/ale/test/fixers/test_brittany_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_brittany_fixer_callback.vader new file mode 100644 index 00000000..073e368c --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_brittany_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_haskell_brittany_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_haskell_brittany_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The brittany callback should return the correct default values): + call ale#test#SetFilename('../haskell_files/testfile.hs') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' --write-mode inplace' + \ . ' %t', + \ }, + \ ale#fixers#brittany#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_buildifier_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_buildifier_fixer_callback.vader new file mode 100644 index 00000000..f82e8e6e --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_buildifier_fixer_callback.vader @@ -0,0 +1,29 @@ +Before: + let g:ale_bazel_buildifier_options = '' + call ale#assert#SetUpFixerTest('bzl', 'buildifier') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The buildifier callback should return the correct default values): + call ale#test#SetFilename('../test-files/bazel/WORKSPACE') + + AssertFixer + \ { + \ 'command': ale#Escape(g:ale_bazel_buildifier_executable) + \ . ' -mode fix -lint fix -path ' + \ . ale#Escape(ale#test#GetFilename('../test-files/bazel/WORKSPACE')) + \ . ' -' + \ } + +Execute(The buildifier callback should include any additional options): + call ale#test#SetFilename('../test-files/bazel/WORKSPACE') + let g:ale_bazel_buildifier_options = '--some-option' + + AssertFixer + \ { + \ 'command': ale#Escape(g:ale_bazel_buildifier_executable) + \ . ' -mode fix -lint fix -path ' + \ . ale#Escape(ale#test#GetFilename('../test-files/bazel/WORKSPACE')) + \ . ' --some-option -' + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_clangformat_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_clangformat_fixer_callback.vader new file mode 100644 index 00000000..130ca7f7 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_clangformat_fixer_callback.vader @@ -0,0 +1,64 @@ +Before: + Save g:ale_c_clangformat_executable + Save g:c_clangformat_style_option + Save g:c_clangformat_use_local_file + + " Use an invalid global executable, so we don't match it. + let g:ale_c_clangformat_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + let g:dir = getcwd() + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The clang-format callback should return the correct default values): + call ale#test#SetFilename('../test-files/c/dummy.c') + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_c_clangformat_executable) + \ . ' --assume-filename=' . ale#Escape(bufname(bufnr(''))) + \ }, + \ ale#fixers#clangformat#Fix(bufnr('')) + +Execute(The clangformat callback should include any additional options): + call ale#test#SetFilename('../test-files/c/dummy.c') + let g:ale_c_clangformat_options = '--some-option' + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_c_clangformat_executable) + \ . ' --assume-filename=' . ale#Escape(bufname(bufnr(''))) + \ . ' --some-option', + \ }, + \ ale#fixers#clangformat#Fix(bufnr('')) + +Execute(The clangformat callback should include style options as well): + call ale#test#SetFilename('../test-files/c/dummy.c') + let g:ale_c_clangformat_options = '--some-option' + let g:ale_c_clangformat_style_option = '{BasedOnStyle: Microsoft, ColumnLimit:80,}' + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_c_clangformat_executable) + \ . ' --assume-filename=' . ale#Escape(bufname(bufnr(''))) + \ . ' --some-option' . " -style='{BasedOnStyle: Microsoft, ColumnLimit:80,}'", + \ }, + \ ale#fixers#clangformat#Fix(bufnr('')) + +Execute(The clangformat callback should use local file instead of style options): + call ale#test#SetFilename('../test-files/clangformat/with_clangformat/dummy.c') + let g:ale_c_clangformat_options = '--some-option' + let g:ale_c_clangformat_style_option = '{BasedOnStyle: Microsoft, ColumnLimit:80,}' + let g:ale_c_clangformat_use_local_file = 1 + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_c_clangformat_executable) + \ . ' --assume-filename=' . ale#Escape(bufname(bufnr(''))) + \ . ' --some-option' . ' -style=file', + \ }, + \ ale#fixers#clangformat#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_clangtidy_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_clangtidy_fixer_callback.vader new file mode 100644 index 00000000..d6678bd9 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_clangtidy_fixer_callback.vader @@ -0,0 +1,47 @@ +Before: + Save g:ale_c_build_dir + Save g:ale_c_clangtidy_executable + Save g:ale_c_clangtidy_checks + Save g:ale_c_clangtidy_extra_options + Save g:ale_cpp_clangtidy_executable + Save g:ale_cpp_clangtidy_checks + Save g:ale_cpp_clangtidy_extra_options + + " Use an invalid global executable, so we don't match it. + let g:ale_c_clangtidy_executable = 'xxxinvalid' + let g:ale_c_clangtidy_checks = [] + let g:ale_c_clangtidy_extra_options = '' + let g:ale_cpp_clangtidy_executable = 'xxxinvalidpp' + let g:ale_cpp_clangtidy_checks = [] + let g:ale_cpp_clangtidy_extra_options = '' + let g:ale_c_build_dir = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The clangtidy callback should return the correct default values): + call ale#test#SetFilename('../test-files/c/dummy.c') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_c_clangtidy_executable) + \ . ' -fix -fix-errors %t' + \ }, + \ ale#fixers#clangtidy#Fix(bufnr('')) + +Execute(The clangtidy callback should include any additional options): + call ale#test#SetFilename('../test-files/c/dummy.c') + let g:ale_c_clangtidy_extra_options = '--some-option' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_c_clangtidy_executable) + \ . ' -fix -fix-errors --some-option %t', + \ }, + \ ale#fixers#clangtidy#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_cmakeformat_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_cmakeformat_fixer_callback.vader new file mode 100644 index 00000000..545fe067 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_cmakeformat_fixer_callback.vader @@ -0,0 +1,36 @@ +Before: + Save g:ale_cmake_cmakeformat_executable + Save g:ale_cmake_cmakeformat_options + + " Use an invalid global executable, so we don't match it. + let g:ale_cmake_cmakeformat_executable = 'xxxinvalid' + let g:ale_cmake_cmakeformat_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The cmakeformat callback should return the correct default values): + call ale#test#SetFilename('../cmake_files/CMakeList.txt') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' -' + \ }, + \ ale#fixers#cmakeformat#Fix(bufnr('')) + +Execute(The cmakeformat callback should include custom cmakeformat options): + let g:ale_cmake_cmakeformat_options = "-r '(a) -> a'" + call ale#test#SetFilename('../cmake_files/CMakeList.txt') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_cmake_cmakeformat_options + \ . ' -', + \ }, + \ ale#fixers#cmakeformat#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_dart_format_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_dart_format_fixer_callback.vader new file mode 100644 index 00000000..8dfd20b6 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_dart_format_fixer_callback.vader @@ -0,0 +1,40 @@ +Before: + Save g:ale_dart_format_executable + Save g:ale_dart_format_options + + " Use an invalid global executable, so we don't match it. + let g:ale_dart_format_executable = 'xxxinvalid' + let g:ale_dart_format_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The dart format callback should return the correct default values): + call ale#test#SetFilename('../test-files/dart/testfile.dart') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' format' + \ . ' %t', + \ }, + \ ale#fixers#dart_format#Fix(bufnr('')) + +Execute(The dart format callback should include custom dart format options): + let g:ale_dart_format_options = "-l 80" + call ale#test#SetFilename('../test-files/dart/testfile.dart') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' format' + \ . ' ' . g:ale_dart_format_options + \ . ' %t', + \ }, + \ ale#fixers#dart_format#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_dartfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_dartfmt_fixer_callback.vader new file mode 100644 index 00000000..c783c9a4 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_dartfmt_fixer_callback.vader @@ -0,0 +1,40 @@ +Before: + Save g:ale_dart_dartfmt_executable + Save g:ale_dart_dartfmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_dart_dartfmt_executable = 'xxxinvalid' + let g:ale_dart_dartfmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The dartfmt callback should return the correct default values): + call ale#test#SetFilename('../test-files/dart/testfile.dart') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -w' + \ . ' %t', + \ }, + \ ale#fixers#dartfmt#Fix(bufnr('')) + +Execute(The dartfmt callback should include custom dartfmt options): + let g:ale_dart_dartfmt_options = "-l 80" + call ale#test#SetFilename('../test-files/dart/testfile.dart') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -w' + \ . ' ' . g:ale_dart_dartfmt_options + \ . ' %t', + \ }, + \ ale#fixers#dartfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_dfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_dfmt_fixer_callback.vader new file mode 100644 index 00000000..5749224e --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_dfmt_fixer_callback.vader @@ -0,0 +1,40 @@ +Before: + Save g:ale_d_dfmt_executable + Save g:ale_d_dfmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_d_dfmt_executable = 'xxxinvalid' + let g:ale_d_dfmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The dfmt callback should return the correct default values): + call ale#test#SetFilename('../test-files/d/test.d') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -i' + \ . ' %t', + \ }, + \ ale#fixers#dfmt#Fix(bufnr('')) + +Execute(The dfmt callback should include custom dfmt options): + let g:ale_d_dfmt_options = "--space-after-cast" + call ale#test#SetFilename('../test-files/d/test.d') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -i' + \ . ' ' . g:ale_d_dfmt_options + \ . ' %t', + \ }, + \ ale#fixers#dfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_dhall_format_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_dhall_format_fixer_callback.vader new file mode 100644 index 00000000..8fa2fe7c --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_dhall_format_fixer_callback.vader @@ -0,0 +1,22 @@ +Before: + Save g:ale_dhall_executable + Save g:ale_dhall_options + + " Use an invalid global executable, so we don’t match it. + let g:ale_dhall_executable = 'odd-dhall' + let g:ale_dhall_options = '--ascii' + + call ale#assert#SetUpFixerTest('dhall', 'dhall-format') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The dhall-format callback should return the correct options): + call ale#test#SetFilename('../dhall_files/testfile.dhall') + + AssertFixer + \ { + \ 'command': ale#Escape('odd-dhall') + \ . ' --ascii' + \ . ' format' + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_dhall_freeze_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_dhall_freeze_fixer_callback.vader new file mode 100644 index 00000000..02473697 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_dhall_freeze_fixer_callback.vader @@ -0,0 +1,22 @@ +Before: + Save g:ale_dhall_executable + Save g:ale_dhall_options + + " Use an invalid global executable, so we don’t match it. + let g:ale_dhall_executable = 'odd-dhall' + let g:ale_dhall_options = '--ascii' + let g:ale_dhall_freeze_options = '--all' + + call ale#assert#SetUpFixerTest('dhall', 'dhall-freeze') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The dhall-freeze callback should return the correct options): + AssertFixer + \ { + \ 'command': ale#Escape('odd-dhall') + \ . ' --ascii' + \ . ' freeze' + \ . ' --all' + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_dhall_lint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_dhall_lint_fixer_callback.vader new file mode 100644 index 00000000..e2054eb0 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_dhall_lint_fixer_callback.vader @@ -0,0 +1,20 @@ +Before: + Save g:ale_dhall_executable + Save g:ale_dhall_options + + " Use an invalid global executable, so we don’t match it. + let g:ale_dhall_executable = 'odd-dhall' + let g:ale_dhall_options = '--ascii' + + call ale#assert#SetUpFixerTest('dhall', 'dhall-lint') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The dhall-lint callback should return the correct options): + AssertFixer + \ { + \ 'command': ale#Escape('odd-dhall') + \ . ' --ascii' + \ . ' lint' + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_dotnet_format_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_dotnet_format_fixer_callback.vader new file mode 100644 index 00000000..a3993573 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_dotnet_format_fixer_callback.vader @@ -0,0 +1,41 @@ +Before: + Save g:ale_cs_dotnet_format_executable + Save g:ale_cs_dotnet_format_options + + " Use an invalid global executable, so we don't match it. + let g:ale_cs_dotnet_format_executable = 'xxxinvalid' + let g:ale_cs_dotnet_format_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The dotnet format callback should return the correct default values): + call ale#test#SetFilename('../test-files/cs/testfile.cs') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' format' + \ . ' --folder --include %t "$(dirname %t)"', + \ }, + \ ale#fixers#dotnet_format#Fix(bufnr('')) + +Execute(The dotnet format callback should include custom dotnet format options): + let g:ale_cs_dotnet_format_options = "-l 80" + call ale#test#SetFilename('../test-files/cs/testfile.cs') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' format' + \ . ' ' . g:ale_cs_dotnet_format_options + \ . ' --folder --include %t "$(dirname %t)"', + \ }, + \ ale#fixers#dotnet_format#Fix(bufnr('')) + diff --git a/vim-config/plugins/ale/test/fixers/test_elm_format_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_elm_format_fixer_callback.vader new file mode 100644 index 00000000..35244737 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_elm_format_fixer_callback.vader @@ -0,0 +1,74 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + unlet! b:ale_elm_format_executable + unlet! b:ale_elm_format_use_global + unlet! b:ale_elm_format_options + + call ale#test#RestoreDirectory() + +Execute(The elm-format command should have default params): + call ale#test#SetFilename('../test-files/elm/src/subdir/testfile.elm') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/elm/node_modules/.bin/elm-format')) + \ . ' %t --yes', + \ }, + \ ale#fixers#elm_format#Fix(bufnr('')) + +Execute(The elm-format command should manage use_global = 1 param): + call ale#test#SetFilename('../test-files/elm/src/subdir/testfile.elm') + let b:ale_elm_format_use_global = 1 + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape('elm-format') + \ . ' %t --yes', + \ }, + \ ale#fixers#elm_format#Fix(bufnr('')) + +Execute(The elm-format command should manage executable param): + call ale#test#SetFilename('../test-files/elm/src/subdir/testfile.elm') + let b:ale_elm_format_use_global = 1 + let b:ale_elm_format_executable = 'elmformat' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape('elmformat') + \ . ' %t --yes', + \ }, + \ ale#fixers#elm_format#Fix(bufnr('')) + +Execute(The elm-format command should manage empty options): + call ale#test#SetFilename('../test-files/elm/src/subdir/testfile.elm') + let b:ale_elm_format_options = '' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/elm/node_modules/.bin/elm-format')) + \ . ' %t', + \ }, + \ ale#fixers#elm_format#Fix(bufnr('')) + +Execute(The elm-format command should manage custom options): + call ale#test#SetFilename('../test-files/elm/src/subdir/testfile.elm') + let b:ale_elm_format_options = '--param1 --param2' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/elm/node_modules/.bin/elm-format')) + \ . ' %t --param1 --param2', + \ }, + \ ale#fixers#elm_format#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_erblint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_erblint_fixer_callback.vader new file mode 100644 index 00000000..7b56e3a9 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_erblint_fixer_callback.vader @@ -0,0 +1,55 @@ +Before: + Save g:ale_eruby_erblint_executable + Save g:ale_eruby_erblint_options + + " Use an invalid global executable, so we don't match it. + let g:ale_eruby_erblint_executable = 'xxxinvalid' + let g:ale_eruby_erblint_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The erblint callback should return the correct default values): + call ale#test#SetFilename('../test-files/eruby/dummy.html.erb') + + AssertEqual + \ { + \ 'process_with': 'ale#fixers#erblint#PostProcess', + \ 'command': ale#Escape(g:ale_eruby_erblint_executable) + \ . ' --autocorrect --stdin %s', + \ }, + \ ale#fixers#erblint#Fix(bufnr('')) + +Execute(The erblint callback should include custom erblint options): + let g:ale_eruby_erblint_options = '--lint-all' + call ale#test#SetFilename('../test-files/ruby/with_config/dummy.rb') + + AssertEqual + \ { + \ 'process_with': 'ale#fixers#erblint#PostProcess', + \ 'command': ale#Escape(g:ale_eruby_erblint_executable) + \ . ' --lint-all' + \ . ' --autocorrect --stdin %s', + \ }, + \ ale#fixers#erblint#Fix(bufnr('')) + +Execute(The erblint post-processor should remove diagnostics content): + AssertEqual + \ [ + \ '
', + \ '', + \ '
', + \ ], + \ ale#fixers#erblint#PostProcess(bufnr(''), [ + \ 'Linting 1 files with 11 autocorrectable linters...', + \ '', + \ '1 error(s) corrected in ERB files', + \ '================ /home/user/demo.html.erb ==================', + \ '
', + \ '', + \ '
', + \ ]) diff --git a/vim-config/plugins/ale/test/fixers/test_erlfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_erlfmt_fixer_callback.vader new file mode 100644 index 00000000..132cd6ee --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_erlfmt_fixer_callback.vader @@ -0,0 +1,25 @@ +Before: + Save b:ale_elm_format_executable + Save b:ale_elm_format_options + + let b:ale_elm_format_executable = 'erlfmt' + let b:ale_elm_format_options = '' + +After: + Restore + +Execute(The erlfmt command should handle empty options): + AssertEqual + \ { + \ 'command': ale#Escape('erlfmt') . ' %s' + \ }, + \ ale#fixers#erlfmt#Fix(bufnr('')) + +Execute(The erlfmt command should handle custom options): + let b:ale_erlang_erlfmt_options = '--insert-pragma' + + AssertEqual + \ { + \ 'command': ale#Escape('erlfmt') . ' --insert-pragma %s' + \ }, + \ ale#fixers#erlfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_eslint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_eslint_fixer_callback.vader new file mode 100644 index 00000000..4a1dc47c --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_eslint_fixer_callback.vader @@ -0,0 +1,339 @@ +Before: + call ale#assert#SetUpFixerTest('javascript', 'eslint') + Save g:ale_command_wrapper + + runtime autoload/ale/handlers/eslint.vim + + let g:ale_command_wrapper = '' + +After: + call ale#assert#TearDownFixerTest() + +Execute(The executable path should be correct): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir/testfile.js') + + " eslint_d output with an older eslint version is used here. + GivenCommandOutput ['v4.4.1 (eslint_d v5.1.0)'] + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/.eslintrc.js')) + \ . ' --fix %t', + \ } + +Execute(The ESLint fixer shouldn't run if no configuration file can be found): + call ale#test#SetFilename('../no-configuration') + AssertFixerNotExecuted + +Execute(The ESLint fixer should use a config file option if set for old versions): + call ale#test#SetFilename('../no-configuration') + let b:ale_javascript_eslint_options = '-c /foo.cfg' + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': '', + \ 'command': ale#Escape('eslint') . ' -c /foo.cfg --fix %t', + \ } + + let b:ale_javascript_eslint_options = '--bar -c /foo.cfg' + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': '', + \ 'command': ale#Escape('eslint') . ' --bar -c /foo.cfg --fix %t', + \ } + + let b:ale_javascript_eslint_options = '--config /foo.cfg' + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': '', + \ 'command': ale#Escape('eslint') . ' --config /foo.cfg --fix %t', + \ } + + let b:ale_javascript_eslint_options = '--bar --config /foo.cfg' + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': '', + \ 'command': ale#Escape('eslint') . ' --bar --config /foo.cfg --fix %t', + \ } + +Execute(The ESLint fixer should use a -c file option if set for eslint_d): + let b:ale_javascript_eslint_executable = '/bin/eslint_d' + GivenCommandOutput ['v3.19.0 (eslint_d v4.2.0)'] + call ale#test#SetFilename('../no-configuration') + let b:ale_javascript_eslint_options = '-c /foo.cfg' + + AssertFixer + \ { + \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ 'cwd': '', + \ 'command': ale#Escape('/bin/eslint_d') + \ . ' -c /foo.cfg' + \ . ' --stdin-filename %s --stdin --fix-to-stdout' + \ } + + let b:ale_javascript_eslint_options = '--bar -c /foo.cfg' + + AssertFixer + \ { + \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ 'cwd': '', + \ 'command': ale#Escape('/bin/eslint_d') + \ . ' --bar -c /foo.cfg' + \ . ' --stdin-filename %s --stdin --fix-to-stdout' + \ } + + let b:ale_javascript_eslint_options = '--config /foo.cfg' + + AssertFixer + \ { + \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ 'cwd': '', + \ 'command': ale#Escape('/bin/eslint_d') + \ . ' --config /foo.cfg' + \ . ' --stdin-filename %s --stdin --fix-to-stdout' + \ } + + let b:ale_javascript_eslint_options = '--bar --config /foo.cfg' + + AssertFixer + \ { + \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ 'cwd': '', + \ 'command': ale#Escape('/bin/eslint_d') + \ . ' --bar --config /foo.cfg' + \ . ' --stdin-filename %s --stdin --fix-to-stdout' + \ } + +Execute(The ESLint fixer should use a config file option if set for new versions): + GivenCommandOutput ['4.9.0'] + call ale#test#SetFilename('../no-configuration') + let b:ale_javascript_eslint_options = '-c /foo.cfg' + + AssertFixer + \ { + \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ 'cwd': '', + \ 'command': ale#Escape('eslint') + \ . ' -c /foo.cfg' + \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json' + \ } + + let b:ale_javascript_eslint_options = '--bar -c /foo.cfg' + + AssertFixer + \ { + \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ 'cwd': '', + \ 'command': ale#Escape('eslint') + \ . ' --bar -c /foo.cfg' + \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json' + \ } + + let b:ale_javascript_eslint_options = '--config /foo.cfg' + + AssertFixer + \ { + \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ 'cwd': '', + \ 'command': ale#Escape('eslint') + \ . ' --config /foo.cfg' + \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json' + \ } + + let b:ale_javascript_eslint_options = '--bar --config /foo.cfg' + + AssertFixer + \ { + \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ 'cwd': '', + \ 'command': ale#Escape('eslint') + \ . ' --bar --config /foo.cfg' + \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json' + \ } + +Execute(The lower priority configuration file in a nested directory should be preferred): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir-with-config/testfile.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/subdir-with-config/.eslintrc')) + \ . ' --fix %t', + \ } + +Execute(--config in options should override configuration file detection for old versions): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir-with-config/testfile.js') + + let b:ale_javascript_eslint_options = '--config /foo.cfg' + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' --config /foo.cfg' + \ . ' --fix %t', + \ } + + let b:ale_javascript_eslint_options = '-c /foo.cfg' + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' -c /foo.cfg' + \ . ' --fix %t', + \ } + +Execute(package.json should be used as a last resort): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir-with-package-json/testfile.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/.eslintrc.js')) + \ . ' --fix %t', + \ } + + call ale#test#SetFilename('../test-files/eslint/package.json') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint'), + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/node_modules/.bin/eslint')) + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/package.json')) + \ . ' --fix %t', + \ } + +Execute(The version check should be correct): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir-with-config/testfile.js') + + " We should run the command to get the version the first time. + GivenCommandOutput ['4.9.0'] + AssertFixer [ + \ (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' --version', + \ { + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', + \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ }, + \] + + AssertFixer [ + \ { + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', + \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ }, + \] + +Execute(--fix-dry-run should be used for 4.9.0 and up): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir/testfile.js') + + GivenCommandOutput ['4.9.0'] + AssertFixer + \ { + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', + \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ } + +Execute(--fix-to-stdout should be used for eslint_d): + call ale#test#SetFilename('../test-files/eslint/app-with-eslint-d/testfile.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/app-with-eslint-d'), + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/package.json')) + \ . ' --fix %t', + \ } + + " The option should be used when eslint_d is new enough. + " We look at the ESLint version instead of the eslint_d version. + GivenCommandOutput ['v3.19.0 (eslint_d v4.2.0)'] + AssertFixer + \ { + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/app-with-eslint-d'), + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ . ' --stdin-filename %s --stdin --fix-to-stdout', + \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ } + + " The option should be used for new versions too. + GivenCommandOutput ['4.9.0'] + AssertFixer + \ { + \ 'cwd': ale#path#Simplify(g:dir . '/../test-files/eslint/app-with-eslint-d'), + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ . ' --stdin-filename %s --stdin --fix-to-stdout', + \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ } + +Execute(The --fix-dry-run post-processor should handle JSON output correctly): + AssertEqual + \ [], + \ ale#fixers#eslint#ProcessFixDryRunOutput(bufnr(''), []) + AssertEqual + \ [], + \ ale#fixers#eslint#ProcessFixDryRunOutput(bufnr(''), ['']) + AssertEqual + \ [], + \ ale#fixers#eslint#ProcessFixDryRunOutput(bufnr(''), ['[{}]']) + AssertEqual + \ ['foo', 'bar'], + \ ale#fixers#eslint#ProcessFixDryRunOutput(bufnr(''), ['[{"output": "foo\nbar"}]']) + +Execute(The eslint_d post-processor should permit regular JavaScript content): + AssertEqual + \ [ + \ 'const x = ''Error: foo''', + \ 'const y = 3', + \ ], + \ ale#fixers#eslint#ProcessEslintDOutput(bufnr(''), [ + \ 'const x = ''Error: foo''', + \ 'const y = 3', + \ ]) + +Execute(The eslint_d post-processor should handle error messages correctly): + AssertEqual + \ [], + \ ale#fixers#eslint#ProcessEslintDOutput(bufnr(''), [ + \ 'Error: No ESLint configuration found.', + \ ]) + +Execute(The eslint_d post-processor should handle failing to connect properly): + AssertEqual + \ [], + \ ale#fixers#eslint#ProcessEslintDOutput(bufnr(''), [ + \ 'Could not connect', + \ ]) diff --git a/vim-config/plugins/ale/test/fixers/test_fecs_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_fecs_fixer_callback.vader new file mode 100644 index 00000000..146c0a87 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_fecs_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + call ale#assert#SetUpFixerTest('javascript', 'fecs') + runtime autoload/ale/handlers/fecs.vim + +After: + call ale#assert#TearDownFixerTest() + +Execute(The fecs fixer should respect to g:ale_javascript_fecs_executable): + let g:ale_javascript_fecs_executable = '../test-files/fecs/fecs' + let g:ale_javascript_fecs_use_global = 1 + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_javascript_fecs_executable) . ' format --replace=true %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#fecs#Fix(bufnr('')) + +Execute(The fecs fixer should return 0 when executable not found): + let g:ale_javascript_fecs_executable = 'fecs-invalid' + let g:ale_javascript_fecs_use_global = 1 + AssertEqual + \ 0, + \ ale#fixers#fecs#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_fish_indent_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_fish_indent_fixer_callback.vader new file mode 100644 index 00000000..3555a974 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_fish_indent_fixer_callback.vader @@ -0,0 +1,40 @@ +Before: + Save g:ale_fish_fish_indent_executable + Save g:ale_fish_fish_indent_options + + " Use an invalid global executable, so we don't match it. + let g:ale_fish_fish_indent_executable = 'xxxinvalid' + let g:ale_fish_fish_indent_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The fish_indent callback should return the correct default values): + call ale#test#SetFilename('../test-files/fish/testfile.fish') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -w ' + \ . ' %t', + \ }, + \ ale#fixers#fish_indent#Fix(bufnr('')) + +Execute(The fish_indent callback should include custom fish_indent options): + let g:ale_fish_fish_indent_options = "-d" + call ale#test#SetFilename('../test-files/fish/testfile.fish') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -w ' + \ . ' -d' + \ . ' %t', + \ }, + \ ale#fixers#fish_indent#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_fixjson_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_fixjson_fixer_callback.vader new file mode 100644 index 00000000..2b023fad --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_fixjson_fixer_callback.vader @@ -0,0 +1,50 @@ +Before: + Save g:ale_json_fixjson_executable + Save g:ale_json_fixjson_options + + let g:ale_json_fixjson_executable = '/path/to/fixjson' + let g:ale_json_fixjson_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + +Execute(The fixjson callback should return the correct default command): + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/fixjson') + \ . ' --stdin-filename ' + \ . ale#Escape(bufname(bufnr(''))) + \ }, + \ ale#fixers#fixjson#Fix(bufnr('')) + +Execute(The fixjson callback should set the buffer name as file name): + call ale#test#SetFilename('../test-files/json/testfile.json') + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/fixjson') + \ . ' --stdin-filename ' + \ . ale#Escape(bufname(bufnr(''))) + \ }, + \ ale#fixers#fixjson#Fix(bufnr('')) + + AssertNotEqual + \ stridx( + \ ale#fixers#fixjson#Fix(bufnr('')).command, + \ 'testfile.json', + \ ), + \ -1 + +Execute(The fixjson callback should include additional options): + let g:ale_json_fixjson_options = '-i 2' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/fixjson') + \ . ' --stdin-filename ' + \ . ale#Escape(bufname(bufnr(''))) + \ . ' -i 2' + \ }, + \ ale#fixers#fixjson#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_floskell_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_floskell_fixer_callback.vader new file mode 100644 index 00000000..66fe9200 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_floskell_fixer_callback.vader @@ -0,0 +1,23 @@ +Before: + Save g:ale_haskell_floskell_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_haskell_floskell_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The floskell callback should return the correct default values): + call ale#test#SetFilename('../haskell_files/testfile.hs') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' %t', + \ }, + \ ale#fixers#floskell#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_gnatpp_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_gnatpp_fixer_callback.vader new file mode 100644 index 00000000..7a3ed517 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_gnatpp_fixer_callback.vader @@ -0,0 +1,28 @@ +Before: + call ale#assert#SetUpFixerTest('ada', 'gnatpp') + +After: + " Reset fixers, variables, etc. + " + " Vader's 'Restore' command will be called here. + call ale#assert#TearDownFixerTest() + +Execute(The default command should be correct): + call ale#test#SetFilename('../test-files/ada/testfile.adb') + + AssertFixer + \ { + \ 'command': ale#Escape(g:ale_ada_gnatpp_executable) .' %t', + \ 'read_temporary_file': 1, + \ } + +Execute(The version check should be correct): + call ale#test#SetFilename('../test-files/ada/testfile.adb') + let g:ale_ada_gnatpp_options = '--no-alignment' + + AssertFixer + \ { + \ 'command': ale#Escape(g:ale_ada_gnatpp_executable) + \ . ' --no-alignment %t', + \ 'read_temporary_file': 1, + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_gofmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_gofmt_fixer_callback.vader new file mode 100644 index 00000000..579dd3db --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_gofmt_fixer_callback.vader @@ -0,0 +1,50 @@ +Before: + Save g:ale_go_gofmt_executable + Save g:ale_go_gofmt_options + Save g:ale_go_go111module + + " Use an invalid global executable, so we don't match it. + let g:ale_go_gofmt_executable = 'xxxinvalid' + let g:ale_go_gofmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#test#RestoreDirectory() + +Execute(The gofmt callback should return the correct default values): + call ale#test#SetFilename('../test-files/go/testfile.go') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid'), + \ }, + \ ale#fixers#gofmt#Fix(bufnr('')) + +Execute(The gofmt callback should include custom gofmt options): + let g:ale_go_gofmt_options = "-r '(a) -> a'" + + call ale#test#SetFilename('../test-files/go/testfile.go') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_go_gofmt_options, + \ }, + \ ale#fixers#gofmt#Fix(bufnr('')) + +Execute(The gofmt callback should support Go environment variables): + let g:ale_go_go111module = 'off' + + call ale#test#SetFilename('../test-files/go/testfile.go') + + AssertEqual + \ { + \ 'command': ale#Env('GO111MODULE', 'off') + \ . ale#Escape('xxxinvalid') + \ }, + \ ale#fixers#gofmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_goimports_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_goimports_fixer_callback.vader new file mode 100644 index 00000000..64c75b2d --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_goimports_fixer_callback.vader @@ -0,0 +1,57 @@ +Before: + Save g:ale_go_goimports_executable + Save g:ale_go_goimports_options + Save g:ale_go_go111module + + " Use an invalid global executable, so we don't match it. + let g:ale_go_goimports_executable = 'xxxinvalid' + let g:ale_go_goimports_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + call ale#test#SetFilename('../test-files/go/testfile.go') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#test#RestoreDirectory() + +Execute(The goimports callback should return 0 when the executable isn't executable): + AssertEqual + \ 0, + \ ale#fixers#goimports#Fix(bufnr('')) + +Execute(The goimports callback should the command when the executable test passes): + let g:ale_go_goimports_executable = has('win32') ? 'cmd' : 'echo' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_go_goimports_executable) . ' -l -w -srcdir %s %t' + \ }, + \ ale#fixers#goimports#Fix(bufnr('')) + +Execute(The goimports callback should include extra options): + let g:ale_go_goimports_executable = has('win32') ? 'cmd' : 'echo' + let g:ale_go_goimports_options = '--xxx' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_go_goimports_executable) . ' -l -w -srcdir %s --xxx %t' + \ }, + \ ale#fixers#goimports#Fix(bufnr('')) + +Execute(The goimports callback should support Go environment variables): + let g:ale_go_goimports_executable = has('win32') ? 'cmd' : 'echo' + let g:ale_go_go111module = 'on' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Env('GO111MODULE', 'on') + \ . ale#Escape(g:ale_go_goimports_executable) + \ . ' -l -w -srcdir %s %t' + \ }, + \ ale#fixers#goimports#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_golines_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_golines_fixer_callback.vader new file mode 100644 index 00000000..87e53c88 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_golines_fixer_callback.vader @@ -0,0 +1,54 @@ +Before: + Save g:ale_go_golines_executable + Save g:ale_go_golines_options + Save g:ale_go_go111module + + " Use an invalid global executable, so we don't match it. + let g:ale_go_golines_executable = 'xxxinvalid' + let g:ale_go_golines_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#test#RestoreDirectory() + +Execute(The golines callback should return 0 when the executable isn't executable): + AssertEqual + \ 0, + \ ale#fixers#golines#Fix(bufnr('')) + + +Execute(The golines callback should return the correct default values): + let g:ale_go_golines_executable = has('win32') ? 'cmd' : 'echo' + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_go_golines_executable), + \ }, + \ ale#fixers#golines#Fix(bufnr('')) + +Execute(The golines callback should include custom golines options): + let g:ale_go_golines_executable = has('win32') ? 'cmd' : 'echo' + let g:ale_go_golines_options = "--max-len --shorten-comments" + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_go_golines_executable) + \ . ' ' . g:ale_go_golines_options, + \ }, + \ ale#fixers#golines#Fix(bufnr('')) + +Execute(The golines callback should support Go environment variables): + let g:ale_go_golines_executable = has('win32') ? 'cmd' : 'echo' + let g:ale_go_go111module = 'off' + + AssertEqual + \ { + \ 'command': ale#Env('GO111MODULE', 'off') + \ . ale#Escape(g:ale_go_golines_executable) + \ }, + \ ale#fixers#golines#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_gomod_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_gomod_fixer_callback.vader new file mode 100644 index 00000000..56fb9854 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_gomod_fixer_callback.vader @@ -0,0 +1,41 @@ +Before: + Save g:ale_go_go_executable + Save g:ale_go_go111module + + " Use an invalid global executable, so we don't match it. + let g:ale_go_go_executable = 'xxxinvalid' + let g:ale_go_go111module = '' + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#test#RestoreDirectory() + +Execute(The gomod callback should return the correct default values): + call ale#test#SetFilename('../test-files/go/go.mod') + setl filetype=gomod + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' mod edit -fmt' + \ . ' %t', + \ }, + \ ale#fixers#gomod#Fix(bufnr('')) + +Execute(The gomod callback should support Go environment variables): + call ale#test#SetFilename('../test-files/go/go.mod') + setl filetype=gomod + let g:ale_go_go111module = 'on' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Env('GO111MODULE', 'on') + \ . ale#Escape('xxxinvalid') . ' mod edit -fmt %t' + \ }, + \ ale#fixers#gomod#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_goofle_java_format_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_goofle_java_format_fixer_callback.vader new file mode 100644 index 00000000..4c28b330 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_goofle_java_format_fixer_callback.vader @@ -0,0 +1,27 @@ +Before: + Save g:ale_java_google_java_format_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_java_google_java_format_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The google-java-format callback should return 0 when the executable isn't executable): + AssertEqual + \ 0, + \ ale#fixers#google_java_format#Fix(bufnr('')) + +Execute(The google-java-format callback should run the command when the executable test passes): + let g:ale_java_google_java_format_executable = has('win32') ? 'cmd' : 'echo' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(ale_java_google_java_format_executable) . ' --replace %t' + \ }, + \ ale#fixers#google_java_format#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_hackfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_hackfmt_fixer_callback.vader new file mode 100644 index 00000000..d294c15e --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_hackfmt_fixer_callback.vader @@ -0,0 +1,37 @@ +Before: + Save g:ale_hack_hackfmt_executable + Save g:ale_hack_hackfmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_hack_hackfmt_executable = 'xxxinvalid' + let g:ale_hack_hackfmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The hackfmt callback should return the correct default values): + call ale#test#SetFilename('../hack_files/testfile.hack') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -i %t', + \ }, + \ ale#fixers#hackfmt#Fix(bufnr('')) + +Execute(The hackfmt callback should include custom hackfmt options): + let g:ale_hack_hackfmt_options = "--some-option" + call ale#test#SetFilename('../hack_files/testfile.hack') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -i --some-option %t', + \ }, + \ ale#fixers#hackfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_hfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_hfmt_fixer_callback.vader new file mode 100644 index 00000000..69cd03f8 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_hfmt_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_haskell_hfmt_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_haskell_hfmt_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The hfmt callback should return the correct default values): + call ale#test#SetFilename('../haskell_files/testfile.hs') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -w' + \ . ' %t', + \ }, + \ ale#fixers#hfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_hindent_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_hindent_fixer_callback.vader new file mode 100644 index 00000000..2e5a8b9f --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_hindent_fixer_callback.vader @@ -0,0 +1,18 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The hindent callback should return the correct default values): + call ale#test#SetFilename('../haskell_files/testfile.hs') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('hindent') + \ . ' %t', + \ }, + \ ale#fixers#hindent#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_hlint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_hlint_fixer_callback.vader new file mode 100644 index 00000000..08f08fae --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_hlint_fixer_callback.vader @@ -0,0 +1,20 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The hlint callback should return the correct default values): + call ale#test#SetFilename('../haskell_files/testfile.hs') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('hlint') + \ . ' --refactor' + \ . ' --refactor-options="--inplace"' + \ . ' %t', + \ }, + \ ale#fixers#hlint#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_html_beautify_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_html_beautify_fixer_callback.vader new file mode 100644 index 00000000..3012c7f1 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_html_beautify_fixer_callback.vader @@ -0,0 +1,12 @@ +Before: + call ale#assert#SetUpFixerTest('html', 'html-beautify', 'beautify') + +After: + Restore + + call ale#assert#TearDownFixerTest() + +Execute(The html-beautify callback should return the correct default command): + AssertEqual + \ {'command': ale#Escape('html-beautify') . ' -'}, + \ ale#fixers#html_beautify#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_importjs_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_importjs_fixer_callback.vader new file mode 100644 index 00000000..727e6a16 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_importjs_fixer_callback.vader @@ -0,0 +1,35 @@ +Before: + Save g:ale_javascript_importjs_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_javascript_importjs_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + call ale#test#SetFilename('../test-files/javascript/test.js') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The importjs callback should return 0 when the executable isn't executable): + AssertEqual + \ 0, + \ ale#fixers#importjs#Fix(bufnr('')) + +Execute(The importjs callback should run the command when the executable test passes): + let g:ale_javascript_importjs_executable = has('win32') ? 'cmd' : 'echo' + + AssertEqual + \ { + \ 'process_with': 'ale#fixers#importjs#ProcessOutput', + \ 'command': ale#Escape(g:ale_javascript_importjs_executable) . ' fix %s' + \ }, + \ ale#fixers#importjs#Fix(bufnr('')) + +Execute(The ProcessOutput callback should return the expected output): + let g:testOutput = '{"messages":[],"fileContent":"one\ntwo","unresolvedImports":{}}' + + AssertEqual + \ ['one', 'two'], + \ ale#fixers#importjs#ProcessOutput(bufnr(''), g:testOutput) diff --git a/vim-config/plugins/ale/test/fixers/test_isort_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_isort_fixer_callback.vader new file mode 100644 index 00000000..8b665d6b --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_isort_fixer_callback.vader @@ -0,0 +1,70 @@ +Before: + call ale#assert#SetUpFixerTest('python', 'isort') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + call ale#assert#TearDownFixerTest() + + unlet! g:dir + unlet! b:bin_dir + +Execute(The isort callback should return the correct default values): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + + " --filename option exists only after 5.7.0 + GivenCommandOutput ['VERSION 5.7.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/isort')) . ' --filename %s' . ' -', + \ } + +Execute(The isort callback should respect custom options): + let g:ale_python_isort_options = '--multi-line=3 --trailing-comma' + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + + " --filename option exists only after 5.7.0 + GivenCommandOutput ['VERSION 5.7.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/isort')) + \ . ' --filename %s' . ' --multi-line=3 --trailing-comma -', + \ } + +Execute(Pipenv is detected when python_isort_auto_pipenv is set): + let g:ale_python_isort_auto_pipenv = 1 + + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + GivenCommandOutput ['VERSION 5.7.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape('pipenv') . ' run isort' . ' --filename %s' . ' -' + \ } + +Execute(Poetry is detected when python_isort_auto_poetry is set): + let g:ale_python_isort_auto_poetry = 1 + + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + GivenCommandOutput ['VERSION 5.7.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape('poetry') . ' run isort' . ' --filename %s' . ' -' + \ } + +Execute(The isort callback should not use --filename for older versions): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + + " --filename option exists only after 5.7.0 + GivenCommandOutput ['VERSION 5.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/isort')) . ' -', + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_jq_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_jq_fixer_callback.vader new file mode 100644 index 00000000..74580d3b --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_jq_fixer_callback.vader @@ -0,0 +1,26 @@ +Before: + Save g:ale_json_jq_executable + Save g:ale_json_jq_options + Save g:ale_json_jq_filters + +After: + Restore + +Execute(The jq fixer should use the options you set): + let g:ale_json_jq_executable = 'foo' + let g:ale_json_jq_options = '--bar' + let g:ale_json_jq_filters = '.baz' + + AssertEqual + \ {'command': ale#Escape('foo') . ' .baz --bar'}, + \ ale#fixers#jq#Fix(bufnr('')) + +Execute(The jq fixer should return 0 when there are no filters): + let g:ale_json_jq_executable = 'jq' + let g:ale_json_jq_options = '' + + let g:ale_json_jq_filters = '' + + AssertEqual + \ 0, + \ ale#fixers#jq#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_jsonnetfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_jsonnetfmt_fixer_callback.vader new file mode 100644 index 00000000..204d6583 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_jsonnetfmt_fixer_callback.vader @@ -0,0 +1,38 @@ +Before: + Save g:ale_jsonnet_jsonnetfmt_executable + Save g:ale_jsonnet_jsonnetfmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_jsonnet_jsonnetfmt_executable = 'xxxinvalid' + let g:ale_jsonnet_jsonnetfmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + call ale#assert#SetUpFixerTest('jsonnet', 'jsonnetfmt') + +After: + call ale#test#RestoreDirectory() + call ale#assert#TearDownFixerTest() + +Execute(The jsonnetfmt callback should return the correct default values): + call ale#test#SetFilename('../jsonnet_files/testfile.jsonnet') + + AssertFixer { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_jsonnet_jsonnetfmt_executable) + \ . ' -i' + \ . ' %t', + \} + +Execute(The jsonnetfmt callback should include custom options): + let g:ale_jsonnet_jsonnetfmt_options = '--pad-arrays' + + call ale#test#SetFilename('../jsonnet_files/testfile.jsonnet') + + AssertFixer { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_jsonnet_jsonnetfmt_executable) + \ . ' -i' + \ . ' ' . g:ale_jsonnet_jsonnetfmt_options + \ . ' %t', + \} + diff --git a/vim-config/plugins/ale/test/fixers/test_ktlint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_ktlint_fixer_callback.vader new file mode 100644 index 00000000..cfe39205 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_ktlint_fixer_callback.vader @@ -0,0 +1,42 @@ +Before: + Save g:ale_kotlin_ktlint_executable + Save g:ale_kotlin_ktlint_options + Save g:ale_kotlin_ktlint_rulesets + + " Use an invalid global executable, so we don't match it. + let g:ale_kotlin_ktlint_executable = 'xxxinvalid' + let g:ale_kotlin_ktlint_options = '' + let g:ale_kotlin_ktlint_rulesets = [] + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The ktlint callback should return the correct default values): + call ale#test#SetFilename('../test-files/kotlin/testfile.kt') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' --stdin' + \ . ' --format', + \ }, + \ ale#fixers#ktlint#Fix(bufnr('')) + +Execute(The ktlint callback should include custom ktlint options): + let g:ale_kotlin_ktlint_options = "--android" + let g:ale_kotlin_ktlint_rulesets = ['/path/to/custom/ruleset.jar'] + call ale#test#SetFilename('../test-files/kotlin/testfile.kt') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_kotlin_ktlint_options + \ . ' --ruleset /path/to/custom/ruleset.jar' + \ . ' --stdin' + \ . ' --format', + \ }, + \ ale#fixers#ktlint#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_latexindent_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_latexindent_fixer_callback.vader new file mode 100644 index 00000000..bd4ac69a --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_latexindent_fixer_callback.vader @@ -0,0 +1,36 @@ +Before: + Save g:ale_tex_latexindent_executable + Save g:ale_tex_latexindent_options + + " Use an invalid global executable, so we don't match it. + let g:ale_tex_latexindent_executable = 'xxxinvalid' + let g:ale_tex_latexindent_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The latexindent callback should return the correct default values): + call ale#test#SetFilename('../test-files/tex/testfile.tex') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' -l' + \ }, + \ ale#fixers#latexindent#Fix(bufnr('')) + +Execute(The latexindent callback should include custom gofmt options): + let g:ale_tex_latexindent_options = "-l '~/.indentconfig.yaml'" + call ale#test#SetFilename('../test-files/tex/testfile.tex') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' -l' + \ . ' ' . g:ale_tex_latexindent_options + \ }, + \ ale#fixers#latexindent#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_lua_format_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_lua_format_fixer_callback.vader new file mode 100644 index 00000000..29cafde6 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_lua_format_fixer_callback.vader @@ -0,0 +1,35 @@ +Before: + Save g:ale_lua_lua_format_executable + Save g:ale_lua_lua_format_options + + " Use an invalid global executable, so we don't match it. + let g:ale_lua_lua_format_executable = 'xxxinvalid' + let g:ale_lua_lua_format_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The lua_format callback should return the correct default values): + call ale#test#SetFilename('../test-files/lua/testfile.lua') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') . ' -i', + \ }, + \ ale#fixers#lua_format#Fix(bufnr('')) + +Execute(The lua_format callback should include custom lua_format options): + let g:ale_lua_lua_format_options = "--no-chop-down-table" + call ale#test#SetFilename('../test-files/lua/testfile.lua') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_lua_lua_format_options + \ . ' -i', + \ }, + \ ale#fixers#lua_format#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_luafmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_luafmt_fixer_callback.vader new file mode 100644 index 00000000..ef69f297 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_luafmt_fixer_callback.vader @@ -0,0 +1,35 @@ +Before: + Save g:ale_lua_luafmt_executable + Save g:ale_lua_luafmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_lua_luafmt_executable = 'xxxinvalid' + let g:ale_lua_luafmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The luafmt callback should return the correct default values): + call ale#test#SetFilename('../test-files/lua/testfile.lua') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') . ' --stdin', + \ }, + \ ale#fixers#luafmt#Fix(bufnr('')) + +Execute(The luafmt callback should include custom luafmt options): + let g:ale_lua_luafmt_options = "--skip-children" + call ale#test#SetFilename('../test-files/lua/testfile.lua') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_lua_luafmt_options + \ . ' --stdin', + \ }, + \ ale#fixers#luafmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_mix_format_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_mix_format_fixer_callback.vader new file mode 100644 index 00000000..cd492e81 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_mix_format_fixer_callback.vader @@ -0,0 +1,36 @@ +Before: + Save g:ale_elixir_mix_executable + Save g:ale_elixir_mix_format_options + + let g:ale_elixir_mix_executable = 'xxxinvalid' + let g:ale_elixir_mix_format_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The mix_format callback should return the correct default values): + call ale#test#SetFilename('../test-files/elixir/testfile.ex') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' format %t', + \ }, + \ ale#fixers#mix_format#Fix(bufnr('')) + +Execute(The mix_format callback should include the correct format options): + let g:ale_elixir_mix_format_options = 'invalid_options' + call ale#test#SetFilename('../test-files/elixir/testfile.ex') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' format invalid_options %t', + \ }, + \ ale#fixers#mix_format#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_nimpretty_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_nimpretty_fixer_callback.vader new file mode 100644 index 00000000..a26f649a --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_nimpretty_fixer_callback.vader @@ -0,0 +1,23 @@ +Before: + call ale#assert#SetUpFixerTest('nim', 'nimpretty') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The nimpretty callback should return the correct default values): + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('nimpretty') . ' %t --maxLineLen:80' + \ }, + \ ale#fixers#nimpretty#Fix(bufnr('')) + +Execute(The nimpretty callback should include any additional options): + let g:ale_nim_nimpretty_options = '--some-option' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('nimpretty') . ' %t --some-option' + \ }, + \ ale#fixers#nimpretty#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_nixfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_nixfmt_fixer_callback.vader new file mode 100644 index 00000000..880ac83e --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_nixfmt_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_nix_nixfmt_executable + Save g:ale_nix_nixfmt_options + +After: + Restore + +Execute(The nixfmt callback should return the correct default values): + AssertEqual + \ { + \ 'command': ale#Escape('nixfmt') + \ }, + \ ale#fixers#nixfmt#Fix(bufnr('')) + +Execute(The nixfmt executable and options should be configurable): + let g:ale_nix_nixfmt_executable = '/path/to/nixfmt' + let g:ale_nix_nixfmt_options = '--help' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/nixfmt') + \ . ' --help', + \ }, + \ ale#fixers#nixfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_nixpkgsfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_nixpkgsfmt_fixer_callback.vader new file mode 100644 index 00000000..0065f77b --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_nixpkgsfmt_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_nix_nixpkgsfmt_executable + Save g:ale_nix_nixpkgsfmt_options + +After: + Restore + +Execute(The nixpkgs-fmt callback should return the correct default values): + AssertEqual + \ { + \ 'command': ale#Escape('nixpkgs-fmt') + \ }, + \ ale#fixers#nixpkgsfmt#Fix(bufnr('')) + +Execute(The nixpkgs-fmt executable and options should be configurable): + let g:ale_nix_nixpkgsfmt_executable = '/path/to/nixpkgs-fmt' + let g:ale_nix_nixpkgsfmt_options = '-h' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/nixpkgs-fmt') + \ . ' -h', + \ }, + \ ale#fixers#nixpkgsfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_ocamlformat_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_ocamlformat_fixer_callback.vader new file mode 100644 index 00000000..587fcf56 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_ocamlformat_fixer_callback.vader @@ -0,0 +1,36 @@ +Before: + Save g:ale_ocaml_ocamlformat_executable + Save g:ale_ocaml_ocamlformat_options + + " Use an invalid global executable, so we don't match it. + let g:ale_ocaml_ocamlformat_executable = 'xxxinvalid' + let g:ale_ocaml_ocamlformat_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The ocamlformat callback should return the correct default values): + call ale#test#SetFilename('../test-files/ocaml/testfile.re') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' --name=%s -', + \ }, + \ ale#fixers#ocamlformat#Fix(bufnr('')) + +Execute(The ocamlformat callback should include custom ocamlformat options): + let g:ale_ocaml_ocamlformat_options = "-m 78" + call ale#test#SetFilename('../test-files/ocaml/testfile.re') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_ocaml_ocamlformat_options + \ . ' --name=%s -', + \ }, + \ ale#fixers#ocamlformat#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_ocp_indent_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_ocp_indent_fixer_callback.vader new file mode 100644 index 00000000..fc336b2d --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_ocp_indent_fixer_callback.vader @@ -0,0 +1,34 @@ +Before: + Save g:ale_ocaml_ocp_indent_executable + Save g:ale_ocaml_ocpindent_options + + " Use an invalid global executable + let g:ale_ocaml_ocp_indent_executable = 'xxxinvalid' + let g:ale_ocaml_ocp_indent_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The ocp_indent callback should return the correct default values): + call ale#test#SetFilename('../test-files/ocaml/ocp_inden_testfile.re') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ }, + \ ale#fixers#ocp_indent#Fix(bufnr('')) + +Execute(The ocp_indent callback should include custom ocp_indent options): + let g:ale_ocaml_ocp_indent_config = "base=4, type=4" + call ale#test#SetFilename('../test-files/ocaml/ocp_inden_testfile.re') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' --config=' . ale#Escape(g:ale_ocaml_ocp_indent_config) + \ }, + \ ale#fixers#ocp_indent#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_ormolu_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_ormolu_fixer_callback.vader new file mode 100644 index 00000000..8df3fca9 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_ormolu_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_haskell_ormolu_executable + Save g:ale_haskell_ormolu_options + +After: + Restore + +Execute(The ormolu callback should return the correct default values): + AssertEqual + \ { + \ 'command': ale#Escape('ormolu') + \ }, + \ ale#fixers#ormolu#Fix(bufnr('')) + +Execute(The ormolu executable and options should be configurable): + let g:ale_nix_nixpkgsfmt_executable = '/path/to/ormolu' + let g:ale_nix_nixpkgsfmt_options = '-h' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/ormolu') + \ . ' -h', + \ }, + \ ale#fixers#nixpkgsfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_pandoc_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_pandoc_fixer_callback.vader new file mode 100644 index 00000000..a364ee56 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_pandoc_fixer_callback.vader @@ -0,0 +1,23 @@ +Before: + Save g:ale_markdown_pandoc_executable + Save g:ale_markdown_pandoc_options + +After: + Restore + +Execute(The pandoc callback should return 'pandoc' as default command): + setlocal noexpandtab + Assert + \ ale#fixers#pandoc#Fix(bufnr('')).command =~# '^' . ale#Escape('pandoc'), + \ "Default command name is expected to be 'pandoc'" + +Execute(The pandoc executable and options should be configurable): + let g:ale_markdown_pandoc_executable = 'foobar' + let g:ale_markdown_pandoc_options = '--some-option' + + AssertEqual + \ { + \ 'command': ale#Escape('foobar') + \ . ' --some-option', + \ }, + \ ale#fixers#pandoc#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_perltidy_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_perltidy_fixer_callback.vader new file mode 100644 index 00000000..c7430bfa --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_perltidy_fixer_callback.vader @@ -0,0 +1,40 @@ +Before: + Save g:ale_perl_perltidy_executable + Save g:ale_perl_perltidy_options + + " Use an invalid global executable, so we don't match it. + let g:ale_perl_perltidy_executable = 'xxxinvalid' + let g:ale_perl_perltidy_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The perltidy callback should return the correct default values): + call ale#test#SetFilename('../pl_files/testfile.pl') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -b' + \ . ' %t', + \ }, + \ ale#fixers#perltidy#Fix(bufnr('')) + +Execute(The perltidy callback should include custom perltidy options): + let g:ale_perl_perltidy_options = "-r '(a) -> a'" + call ale#test#SetFilename('../pl_files/testfile.pl') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' -b' + \ . ' ' . g:ale_perl_perltidy_options + \ . ' %t', + \ }, + \ ale#fixers#perltidy#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_pgformatter_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_pgformatter_fixer_callback.vader new file mode 100644 index 00000000..5baa6f6f --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_pgformatter_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_sql_pgformatter_executable + Save g:ale_sql_pgformatter_options + +After: + Restore + +Execute(The pgFormatter callback should return the correct default values): + AssertEqual + \ { + \ 'command': ale#Escape('pg_format') + \ }, + \ ale#fixers#pgformatter#Fix(bufnr('')) + +Execute(The pgFormatter executable and options should be configurable): + let g:ale_sql_pgformatter_executable = '/path/to/pg_format' + let g:ale_sql_pgformatter_options = '-n' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/pg_format') + \ . ' -n', + \ }, + \ ale#fixers#pgformatter#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_php_cs_fixer.vader b/vim-config/plugins/ale/test/fixers/test_php_cs_fixer.vader new file mode 100644 index 00000000..eb4d78f8 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_php_cs_fixer.vader @@ -0,0 +1,62 @@ +Before: + Save g:ale_php_cs_fixer_executable + Save g:ale_php_cs_fixer_options + let g:ale_php_cs_fixer_executable = 'php-cs-fixer' + let g:ale_php_cs_fixer_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + + +Execute(project with php-cs-fixer should use local by default): + call ale#test#SetFilename('../test-files/php/project-with-php-cs-fixer/test.php') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/php/project-with-php-cs-fixer/vendor/bin/php-cs-fixer'), + \ ale#fixers#php_cs_fixer#GetExecutable(bufnr('')) + +Execute(use-global should override local detection): + let g:ale_php_cs_fixer_use_global = 1 + call ale#test#SetFilename('../test-files/php/project-with-php-cs-fixer/test.php') + + AssertEqual + \ 'php-cs-fixer', + \ ale#fixers#php_cs_fixer#GetExecutable(bufnr('')) + +Execute(project without php-cs-fixer should use global): + call ale#test#SetFilename('../test-files/php/project-without-php-cs-fixer/test.php') + + AssertEqual + \ 'php-cs-fixer', + \ ale#fixers#php_cs_fixer#GetExecutable(bufnr('')) + + + + +Execute(The php-cs-fixer callback should return the correct default values): + call ale#test#SetFilename('../test-files/php/project-without-php-cs-fixer/foo/test.php') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('php-cs-fixer') + \ . ' ' . g:ale_php_cs_fixer_options + \ . ' fix %t' + \ }, + \ ale#fixers#php_cs_fixer#Fix(bufnr('')) + +Execute(The php-cs-fixer callback should include custom php-cs-fixer options): + let g:ale_php_cs_fixer_options = '--config="$HOME/.php_cs"' + call ale#test#SetFilename('../test-files/php/project-without-php-cs-fixer/test.php') + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_php_cs_fixer_executable) + \ . ' --config="$HOME/.php_cs" fix %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#php_cs_fixer#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_phpcbf_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_phpcbf_fixer_callback.vader new file mode 100644 index 00000000..45229a1b --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_phpcbf_fixer_callback.vader @@ -0,0 +1,117 @@ +Before: + Save g:ale_php_phpcbf_executable + Save g:ale_php_phpcbf_standard + Save g:ale_php_phpcbf_use_global + + let g:ale_php_phpcbf_executable = 'phpcbf_test' + let g:ale_php_phpcbf_standard = '' + let g:ale_php_phpcbf_options = '' + let g:ale_php_phpcbf_use_global = 0 + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(project with phpcbf should use local by default): + call ale#test#SetFilename('../test-files/php/project-with-phpcbf/foo/test.php') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/php/project-with-phpcbf/vendor/bin/phpcbf'), + \ ale#fixers#phpcbf#GetExecutable(bufnr('')) + +Execute(use-global should override local detection): + let g:ale_php_phpcbf_use_global = 1 + call ale#test#SetFilename('../test-files/php/project-with-phpcbf/foo/test.php') + + AssertEqual + \ 'phpcbf_test', + \ ale#fixers#phpcbf#GetExecutable(bufnr('')) + +Execute(project without phpcbf should use global): + call ale#test#SetFilename('../test-files/php/project-without-phpcbf/foo/test.php') + + AssertEqual + \ 'phpcbf_test', + \ ale#fixers#phpcbf#GetExecutable(bufnr('')) + +Execute(The phpcbf callback should return the correct default values): + call ale#test#SetFilename('../test-files/php/project-with-phpcbf/foo/test.php') + + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/php/project-with-phpcbf/vendor/bin/phpcbf')) . ' --stdin-path=%s -' }, + \ ale#fixers#phpcbf#Fix(bufnr('')) + +Execute(The phpcbf callback should include the phpcbf_standard option): + let g:ale_php_phpcbf_standard = 'phpcbf_ruleset.xml' + call ale#test#SetFilename('../test-files/php/project-with-phpcbf/foo/test.php') + + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/php/project-with-phpcbf/vendor/bin/phpcbf')) . ' --stdin-path=%s ' . '--standard=phpcbf_ruleset.xml' . ' -'}, + \ ale#fixers#phpcbf#Fix(bufnr('')) + +Execute(User provided options should be used): + let g:ale_php_phpcbf_options = '--my-user-provided-option my-value' + call ale#test#SetFilename('../test-files/php/project-with-phpcbf/foo/test.php') + + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/php/project-with-phpcbf/vendor/bin/phpcbf')) . ' --stdin-path=%s ' . ale#Pad('--my-user-provided-option my-value') . ' -'}, + \ ale#fixers#phpcbf#Fix(bufnr('')) + + +Before: + Save g:ale_php_phpcbf_executable + Save g:ale_php_phpcbf_standard + Save g:ale_php_phpcbf_use_global + + let g:ale_php_phpcbf_executable = 'phpcbf_test' + let g:ale_php_phpcbf_standard = '' + let g:ale_php_phpcbf_options = '' + let g:ale_php_phpcbf_use_global = 0 + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(project with phpcbf should use local by default): + call ale#test#SetFilename('../test-files/php/project-with-phpcbf/foo/test.php') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/php/project-with-phpcbf/vendor/bin/phpcbf'), + \ ale#fixers#phpcbf#GetExecutable(bufnr('')) + +Execute(use-global should override local detection): + let g:ale_php_phpcbf_use_global = 1 + call ale#test#SetFilename('../test-files/php/project-with-phpcbf/foo/test.php') + + AssertEqual + \ 'phpcbf_test', + \ ale#fixers#phpcbf#GetExecutable(bufnr('')) + +Execute(project without phpcbf should use global): + call ale#test#SetFilename('../test-files/php/project-without-phpcbf/foo/test.php') + + AssertEqual + \ 'phpcbf_test', + \ ale#fixers#phpcbf#GetExecutable(bufnr('')) + +Execute(The phpcbf callback should return the correct default values): + call ale#test#SetFilename('../test-files/php/project-with-phpcbf/foo/test.php') + + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/php/project-with-phpcbf/vendor/bin/phpcbf')) . ' --stdin-path=%s -' }, + \ ale#fixers#phpcbf#Fix(bufnr('')) + +Execute(The phpcbf callback should include the phpcbf_standard option): + let g:ale_php_phpcbf_standard = 'phpcbf_ruleset.xml' + call ale#test#SetFilename('../test-files/php/project-with-phpcbf/foo/test.php') + + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/php/project-with-phpcbf/vendor/bin/phpcbf')) . ' --stdin-path=%s ' . '--standard=phpcbf_ruleset.xml' . ' -'}, + \ ale#fixers#phpcbf#Fix(bufnr('')) + diff --git a/vim-config/plugins/ale/test/fixers/test_prettier_eslint_fixer.callback.vader b/vim-config/plugins/ale/test/fixers/test_prettier_eslint_fixer.callback.vader new file mode 100644 index 00000000..cfdd1c78 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_prettier_eslint_fixer.callback.vader @@ -0,0 +1,97 @@ +Before: + call ale#assert#SetUpFixerTest('javascript', 'prettier_eslint') + Save g:ale_command_wrapper + + let g:ale_command_wrapper = '' + +After: + call ale#assert#TearDownFixerTest() + +Execute(The default command should be correct): + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape('prettier-eslint') + \ . ' %t' + \ . ' --write' + \ } + +Execute(Additional options should be used when set): + let b:ale_javascript_prettier_eslint_options = '--foobar' + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape('prettier-eslint') + \ . ' %t' + \ . ' --foobar --write' + \ } + +Execute(--eslint-config-path should be set for 4.2.0 and up): + call ale#test#SetFilename('../test-files/eslint/react-app/foo/bar.js') + + GivenCommandOutput ['4.2.0'] + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape('prettier-eslint') + \ . ' %t' + \ . ' --eslint-config-path ' . ale#Escape(ale#test#GetFilename('../test-files/eslint/react-app/.eslintrc.js')) + \ . ' --write' + \ } + +Execute(--eslint-config-path shouldn't be used for older versions): + call ale#test#SetFilename('../test-files/eslint/react-app/foo/bar.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape('prettier-eslint') + \ . ' %t' + \ . ' --write' + \ } + +Execute(The version check should be correct): + AssertFixer [ + \ ale#Escape('prettier-eslint') . ' --version', + \ { + \ 'read_temporary_file': 1, + \ 'command': + \ ale#Escape('prettier-eslint') + \ . ' %t' + \ . ' --write' + \ } + \] + +Execute(The new --stdin-filepath option should be used when the version is new enough): + call ale#test#SetFilename('../test-files/eslint/react-app/foo/bar.js') + + GivenCommandOutput ['4.4.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape('prettier-eslint') + \ . ' --eslint-config-path ' . ale#Escape(ale#test#GetFilename('../test-files/eslint/react-app/.eslintrc.js')) + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(The version number should be cached): + GivenCommandOutput ['4.4.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape('prettier-eslint') + \ . ' --stdin-filepath %s --stdin', + \ } + + GivenCommandOutput [] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape('prettier-eslint') + \ . ' --stdin-filepath %s --stdin', + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_prettier_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_prettier_fixer_callback.vader new file mode 100644 index 00000000..8da13fcd --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_prettier_fixer_callback.vader @@ -0,0 +1,337 @@ +Before: + call ale#assert#SetUpFixerTest('javascript', 'prettier') + Save g:ale_command_wrapper + + let g:ale_command_wrapper = '' + +After: + call ale#assert#TearDownFixerTest() + +Execute(The prettier callback should return the correct default values): + call ale#test#SetFilename('../test-files/prettier/testfile.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' %t' + \ . ' --write', + \ } + +Execute(The --config option should not be set automatically): + let g:ale_javascript_prettier_use_local_config = 1 + call ale#test#SetFilename('../test-files/prettier/with_config/testfile.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' %t' + \ . ' --write', + \ } + +Execute(The prettier callback should include custom prettier options): + let g:ale_javascript_prettier_options = '--no-semi' + call ale#test#SetFilename('../test-files/prettier/with_config/testfile.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' %t' + \ . ' --no-semi' + \ . ' --write', + \ } + +Execute(The version check should be correct): + call ale#test#SetFilename('../test-files/prettier/testfile.js') + + AssertFixer [ + \ ale#Escape('prettier') . ' --version', + \ {'read_temporary_file': 1, 'command': ale#Escape('prettier') . ' %t --write'} + \] + +Execute(--stdin-filepath should be used when prettier is new enough): + let g:ale_javascript_prettier_options = '--no-semi' + call ale#test#SetFilename('../test-files/prettier/with_config/testfile.js') + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --no-semi' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(The version number should be cached): + call ale#test#SetFilename('../test-files/prettier/with_config/testfile.js') + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --stdin-filepath %s --stdin', + \ } + + GivenCommandOutput [] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser to `babylon` by default, < 1.16.0): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=javascript + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser babylon' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser to `babel` by default, >= 1.16.0): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=javascript + + GivenCommandOutput ['1.16.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser babel' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, TypeScript): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=typescript + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser typescript' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, CSS): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=css + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser css' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, LESS): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=less + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser less' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, SCSS): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=scss + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser scss' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, JSON): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=json + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser json' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, JSON5): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=json5 + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser json5' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, GraphQL): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=graphql + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser graphql' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, Markdown): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=markdown + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser markdown' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, Vue): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=vue + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser vue' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, YAML): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=yaml + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser yaml' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, HTML): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=html + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser html' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on filetype, Ruby): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=ruby + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser ruby' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser based on first filetype of multiple filetypes): + call ale#test#SetFilename('../test-files/prettier/testfile') + + set filetype=css.scss + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser css' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Should set --parser for experimental language, Handlebars): + call ale#test#SetFilename('../test-files/prettier/testfile.hbs') + + set filetype=html.handlebars + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --parser glimmer' + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(Changes to directory where .prettierignore is found): + call ale#test#SetFilename('../test-files/prettier/with_prettierignore/src/testfile.js') + + GivenCommandOutput ['1.6.0'] + AssertFixer + \ { + \ 'cwd': expand('%:p:h:h'), + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) + \ . ' --stdin-filepath %s --stdin', + \ } + +Execute(The prettier_d post-processor should permit regular JavaScript content): + AssertEqual + \ [ + \ 'const x = ''Error: foo''', + \ 'const y = 3', + \ ], + \ ale#fixers#prettier#ProcessPrettierDOutput(bufnr(''), [ + \ 'const x = ''Error: foo''', + \ 'const y = 3', + \ ]) + +Execute(The prettier_d post-processor should handle error messages correctly): + AssertEqual + \ [], + \ ale#fixers#prettier#ProcessPrettierDOutput(bufnr(''), [ + \ 'SyntaxError: Unexpected token, expected "," (36:28)', + \ ]) diff --git a/vim-config/plugins/ale/test/fixers/test_prettier_standard_callback.vader b/vim-config/plugins/ale/test/fixers/test_prettier_standard_callback.vader new file mode 100644 index 00000000..f5037ed6 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_prettier_standard_callback.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpFixerTest('javascript', 'prettier_standard') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The prettier callback should return the correct default values): + call ale#test#SetFilename('../test-files/prettier/testfile.js') + + AssertFixer + \ { + \ 'command': ale#Escape(g:ale_javascript_prettier_standard_executable) + \ . ' --stdin' + \ . ' --stdin-filepath=%s ', + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_protolint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_protolint_fixer_callback.vader new file mode 100644 index 00000000..5a6931d7 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_protolint_fixer_callback.vader @@ -0,0 +1,28 @@ +Before: + call ale#assert#SetUpFixerTest('proto', 'protolint') + call ale#test#SetFilename('test.proto') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The default command should be correct): + AssertFixer + \ { + \ 'command': ale#Escape('protolint') + \ . ' -fix' + \ . ' %t', + \ 'read_temporary_file': 1, + \ } + +Execute(The callback should include any additional options): + let b:ale_proto_protolint_executable = '/tmp/protolint' + let b:ale_proto_protolint_config = '/tmp/protolint.yaml' + + AssertFixer + \ { + \ 'command': ale#Escape('/tmp/protolint') + \ . ' -config_path=' . ale#Escape('/tmp/protolint.yaml') + \ . ' -fix' + \ . ' %t', + \ 'read_temporary_file': 1, + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_ptop_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_ptop_fixer_callback.vader new file mode 100644 index 00000000..7cf632e3 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_ptop_fixer_callback.vader @@ -0,0 +1,38 @@ +Before: + Save g:ale_pascal_ptop_executable + Save g:ale_pascal_ptop_options + + " Use an invalid global executable, so we don't match it. + let g:ale_pascal_ptop_executable = 'xxxinvalid' + let g:ale_pascal_ptop_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The ptop callback should return the correct default values): + call ale#test#SetFilename('../test-files/pascal/test.pas') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' %s %t', + \ }, + \ ale#fixers#ptop#Fix(bufnr('')) + +Execute(The ptop callback should include custom ptop options): + let g:ale_pascal_ptop_options = "-i 2" + call ale#test#SetFilename('../test-files/pascal/test.pas') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_pascal_ptop_options + \ . ' %s %t', + \ }, + \ ale#fixers#ptop#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_puppetlint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_puppetlint_fixer_callback.vader new file mode 100644 index 00000000..1a5a6cea --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_puppetlint_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_puppet_puppetlint_executable + Save g:ale_puppet_puppetlint_options + + " Use an invalid global executable, so we don't match it. + let g:ale_puppet_puppetlint_executable = 'xxxinvalid' + let g:ale_puppet_puppetlint_options = '--invalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The puppetlint callback should return the correct default values): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/puppet/dummy.pp') + + AssertEqual + \ {'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_puppet_puppetlint_executable) + \ . ' ' . g:ale_puppet_puppetlint_options + \ . ' --fix %t' }, + \ ale#fixers#puppetlint#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_purs_tidy_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_purs_tidy_fixer_callback.vader new file mode 100644 index 00000000..fdeb3f21 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_purs_tidy_fixer_callback.vader @@ -0,0 +1,20 @@ +Before: + Save g:ale_purescript_tidy_executable + Save g:ale_purescript_tidy_options + + " Use an invalid global executable, so we don’t match it. + let g:ale_purescript_tidy_executable = 'odd-purs-tidy' + let g:ale_purescript_tidy_options = '--indent 3' + + call ale#assert#SetUpFixerTest('purescript', 'purs-tidy') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The purs-tidy callback should return the correct custom options): + AssertFixer + \ { + \ 'command': ale#Escape('odd-purs-tidy') + \ . ' format' + \ . ' --indent 3' + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_purty_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_purty_fixer_callback.vader new file mode 100644 index 00000000..e83b8c18 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_purty_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_purescript_purty_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_purescript_purty_executable = 'my-special-purty' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The purty callback should return the correct options): + call ale#test#SetFilename('../purescript_files/testfile.purs') + + AssertEqual + \ { + \ 'command': ale#Escape('my-special-purty') + \ . ' --write' + \ . ' %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#purty#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_python_add_blank_lines_fixer.vader b/vim-config/plugins/ale/test/fixers/test_python_add_blank_lines_fixer.vader new file mode 100644 index 00000000..7d042c8a --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_python_add_blank_lines_fixer.vader @@ -0,0 +1,167 @@ +Before: + Save g:ale_fixers + +After: + Restore + +Given python(Some Python without blank lines): + def foo(): + """ This is a simple test docstring """ + return 1 + + + def bar(): + '''This is another simple test docstring''' + return 1 + return 4 + + + def bar(): + """ + This is a multi-line + docstring + """ + + if x: + pass + for l in x: + pass + for l in x: + pass + break + continue + elif x: + pass + while x: + pass + while x: + pass + else: + pass + if x: + pass + elif x: + pass + else: + pass + +Execute(Blank lines should be added appropriately): + let g:ale_fixers = {'python': ['add_blank_lines_for_python_control_statements']} + ALEFix + +Expect python(Newlines should be added): + def foo(): + """ This is a simple test docstring """ + + return 1 + + + def bar(): + '''This is another simple test docstring''' + + return 1 + + return 4 + + + def bar(): + """ + This is a multi-line + docstring + """ + + if x: + pass + + for l in x: + pass + + for l in x: + pass + + break + + continue + elif x: + pass + + while x: + pass + + while x: + pass + else: + pass + + if x: + pass + elif x: + pass + else: + pass + +Given python(A file with a main block): + import os + + + def main(): + print('hello') + + + if __name__ == '__main__': + main() + +Execute(Fix the file): + let g:ale_fixers = {'python': ['add_blank_lines_for_python_control_statements']} + ALEFix + +Expect python(extra newlines shouldn't be added to the main block): + import os + + + def main(): + print('hello') + + + if __name__ == '__main__': + main() + + +Given python(A file with variables/docstring that start with a control statement): + def some(): + """ + This is a docstring that contains an + break control statement and also contains a + return something funny. + """ + + continue_some_var = True + forward_something = False + + if ( + continue_some_var and + forwarded_something + ): + return True + + +Execute(Fix the file): + let g:ale_fixers = {'python': ['add_blank_lines_for_python_control_statements']} + ALEFix + +Expect python(Extra new lines are not added to the file): + def some(): + """ + This is a docstring that contains an + break control statement and also contains a + return something funny. + """ + + continue_some_var = True + forward_something = False + + if ( + continue_some_var and + forwarded_something + ): + return True diff --git a/vim-config/plugins/ale/test/fixers/test_qmlfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_qmlfmt_fixer_callback.vader new file mode 100644 index 00000000..e216f2e1 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_qmlfmt_fixer_callback.vader @@ -0,0 +1,12 @@ +Before: + Save g:ale_qml_qmlfmt_executable + +After: + Restore + +Execute(The qmlfmt fixer should use the options you set): + let g:ale_qml_qmlfmt_executable = 'foo-exe' + + AssertEqual + \ {'command': ale#Escape('foo-exe')}, + \ ale#fixers#qmlfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_refmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_refmt_fixer_callback.vader new file mode 100644 index 00000000..01b56bee --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_refmt_fixer_callback.vader @@ -0,0 +1,41 @@ +Before: + Save g:ale_reasonml_refmt_executable + Save g:ale_reasonml_refmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_reasonml_refmt_executable = 'xxxinvalid' + let g:ale_reasonml_refmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The refmt callback should return the correct default values): + call ale#test#SetFilename('../test-files/reasonml/testfile.re') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' --in-place' + \ . ' %t', + \ }, + \ ale#fixers#refmt#Fix(bufnr('')) + +Execute(The refmt callback should include custom refmt options): + let g:ale_reasonml_refmt_options = "-w 80" + call ale#test#SetFilename('../test-files/reasonml/testfile.re') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_reasonml_refmt_options + \ . ' --in-place' + \ . ' %t', + \ }, + \ ale#fixers#refmt#Fix(bufnr('')) + diff --git a/vim-config/plugins/ale/test/fixers/test_remark_lint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_remark_lint_fixer_callback.vader new file mode 100644 index 00000000..5e2e342d --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_remark_lint_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_markdown_remark_lint_executable + Save g:ale_markdown_remark_lint_options + +After: + Restore + +Execute(The remark callback should return the correct default values): + AssertEqual + \ { + \ 'command': ale#Escape('remark') + \ }, + \ ale#fixers#remark_lint#Fix(bufnr('')) + +Execute(The remark executable and options should be configurable): + let g:ale_markdown_remark_lint_executable = '/path/to/remark' + let g:ale_markdown_remark_lint_options = '-h' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/remark') + \ . ' -h', + \ }, + \ ale#fixers#remark_lint#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_reorder_python_imports_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_reorder_python_imports_fixer_callback.vader new file mode 100644 index 00000000..ead2da77 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_reorder_python_imports_fixer_callback.vader @@ -0,0 +1,46 @@ +Before: + Save g:ale_python_reorder_python_imports_executable + Save g:ale_python_reorder_python_imports_options + + " Use an invalid global executable, so we don't match it. + let g:ale_python_reorder_python_imports_executable = 'xxxinvalid' + let g:ale_python_reorder_python_imports_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + Restore + + unlet! b:bin_dir + + call ale#test#RestoreDirectory() + +Execute(The reorder_python_imports callback should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#reorder_python_imports#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ { + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' + \ . b:bin_dir . '/reorder-python-imports')) . ' -', + \ }, + \ ale#fixers#reorder_python_imports#Fix(bufnr('')) + +Execute(The reorder_python_imports callback should respect custom options): + let g:ale_python_reorder_python_imports_options = '--py3-plus' + + AssertEqual + \ 0, + \ ale#fixers#reorder_python_imports#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ { + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' + \ . b:bin_dir . '/reorder-python-imports')) . ' --py3-plus -', + \ }, + \ ale#fixers#reorder_python_imports#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_rubocop_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_rubocop_fixer_callback.vader new file mode 100644 index 00000000..f7b0eb60 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_rubocop_fixer_callback.vader @@ -0,0 +1,89 @@ +Before: + Save g:ale_ruby_rubocop_executable + Save g:ale_ruby_rubocop_options + + " Use an invalid global executable, so we don't match it. + let g:ale_ruby_rubocop_executable = 'xxxinvalid' + let g:ale_ruby_rubocop_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The rubocop callback should return the correct default values): + call ale#test#SetFilename('../test-files/ruby/dummy.rb') + + AssertEqual + \ { + \ 'process_with': 'ale#fixers#rubocop#PostProcess', + \ 'command': ale#Escape(g:ale_ruby_rubocop_executable) + \ . ' --auto-correct --force-exclusion --stdin %s', + \ }, + \ ale#fixers#rubocop#Fix(bufnr('')) + +Execute(The rubocop callback should include custom rubocop options): + let g:ale_ruby_rubocop_options = '--except Lint/Debugger' + call ale#test#SetFilename('../test-files/ruby/with_config/dummy.rb') + + AssertEqual + \ { + \ 'process_with': 'ale#fixers#rubocop#PostProcess', + \ 'command': ale#Escape(g:ale_ruby_rubocop_executable) + \ . ' --except Lint/Debugger' + \ . ' --auto-correct --force-exclusion --stdin %s', + \ }, + \ ale#fixers#rubocop#Fix(bufnr('')) + +Execute(The rubocop callback should use auto-correct-all option when set): + let g:ale_ruby_rubocop_auto_correct_all = 1 + call ale#test#SetFilename('../test-files/ruby/with_config/dummy.rb') + + AssertEqual + \ { + \ 'process_with': 'ale#fixers#rubocop#PostProcess', + \ 'command': ale#Escape(g:ale_ruby_rubocop_executable) + \ . ' --auto-correct-all --force-exclusion --stdin %s' + \ }, + \ ale#fixers#rubocop#Fix(bufnr('')) + +Execute(The rubocop post-processor should remove diagnostics content): + AssertEqual + \ [ + \ 'class MyModel < ApplicationRecord', + \ ' # rubocop:disable Rails/InverseOf', + \ ' has_one :something', + \ ' # rubocop:enable Rails/InverseOf', + \ 'end', + \ '', + \ 'array = [1, 2, 3,', + \ ' 4, 5, 6]', + \ 'array = [''run'',', + \ ' ''forrest'',', + \ ' ''run'']', + \ ], + \ ale#fixers#rubocop#PostProcess(bufnr(''), [ + \ 'Inspecting 1 file', + \ 'C', + \ '', + \ 'Offenses:', + \ 'app/models/my_model.rb:8:3: C: [Corrected] Layout/ArrayAlignment: ', + \ '4, 5, 6]', + \ '^', + \ '', + \ '1 file inspected, 3 offenses detected, 3 offenses corrected', + \ '====================', + \ 'class MyModel < ApplicationRecord', + \ ' # rubocop:disable Rails/InverseOf', + \ ' has_one :something', + \ ' # rubocop:enable Rails/InverseOf', + \ 'end', + \ '', + \ 'array = [1, 2, 3,', + \ ' 4, 5, 6]', + \ 'array = [''run'',', + \ ' ''forrest'',', + \ ' ''run'']', + \ ]) diff --git a/vim-config/plugins/ale/test/fixers/test_rufo_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_rufo_fixer_callback.vader new file mode 100644 index 00000000..3d539f7a --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_rufo_fixer_callback.vader @@ -0,0 +1,30 @@ +Before: + Save g:ale_ruby_rufo_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_ruby_rufo_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The rufo command should contain `bundle exec` when executable is `bundle`): + let g:ale_ruby_rufo_executable = 'bundle' + call ale#test#SetFilename('../test-files/ruby/dummy.rb') + + AssertEqual + \ ale#Escape('bundle') . ' exec rufo %t', + \ ale#fixers#rufo#GetCommand(bufnr('')) + +Execute(The rufo callback should return the correct default values): + call ale#test#SetFilename('../test-files/ruby/dummy.rb') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') . ' %t' + \ }, + \ ale#fixers#rufo#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_rustfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_rustfmt_fixer_callback.vader new file mode 100644 index 00000000..98761c94 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_rustfmt_fixer_callback.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpFixerTest('rust', 'rustfmt') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The rustfmt callback should return the correct default values): + call ale#test#SetFilename('../test-files/rust/testfile.rs') + + AssertFixer {'command': ale#Escape('rustfmt')} + +Execute(The rustfmt callback should include custom rustfmt options): + let g:ale_rust_rustfmt_options = "--skip-children" + call ale#test#SetFilename('../test-files/rust/testfile.rs') + + AssertFixer {'command': ale#Escape('rustfmt') . ' ' . g:ale_rust_rustfmt_options} diff --git a/vim-config/plugins/ale/test/fixers/test_scalafmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_scalafmt_fixer_callback.vader new file mode 100644 index 00000000..2b8dc3eb --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_scalafmt_fixer_callback.vader @@ -0,0 +1,66 @@ +Before: + Save g:ale_scala_scalafmt_executable + Save g:ale_scala_scalafmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_scala_scalafmt_executable = 'xxxinvalid' + let g:ale_scala_scalafmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The scalafmt callback should return the correct default values): + call ale#test#SetFilename('../test-files/scala/dummy.scala') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_scala_scalafmt_executable) + \ . ' %t', + \ }, + \ ale#fixers#scalafmt#Fix(bufnr('')) + +Execute(The scalafmt callback should use ng with scalafmt automatically): + let g:ale_scala_scalafmt_executable = 'ng' + call ale#test#SetFilename('../test-files/scala/dummy.scala') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('ng') + \ . ' scalafmt' + \ . ' %t', + \ }, + \ ale#fixers#scalafmt#Fix(bufnr('')) + +Execute(The scalafmt callback should include custom scalafmt options): + let g:ale_scala_scalafmt_options = '--diff' + call ale#test#SetFilename('../test-files/scala/dummy.scala') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_scala_scalafmt_executable) + \ . ' --diff' + \ . ' %t', + \ }, + \ ale#fixers#scalafmt#Fix(bufnr('')) + +Execute(The scalafmt callback should include custom scalafmt options and use ng with scalafmt): + let g:ale_scala_scalafmt_options = '--diff' + let g:ale_scala_scalafmt_executable = 'ng' + call ale#test#SetFilename('../test-files/scala/dummy.scala') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('ng') + \ . ' scalafmt' + \ . ' --diff' + \ . ' %t', + \ }, + \ ale#fixers#scalafmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_shfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_shfmt_fixer_callback.vader new file mode 100644 index 00000000..99cb0987 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_shfmt_fixer_callback.vader @@ -0,0 +1,59 @@ +Before: + Save g:ale_sh_shfmt_executable + Save g:ale_sh_shfmt_options + Save &l:expandtab + Save &l:shiftwidth + Save &l:tabstop + +After: + Restore + +Execute(The shfmt callback should return 'shfmt' as default command): + setlocal noexpandtab + Assert + \ ale#fixers#shfmt#Fix(bufnr('')).command =~# '^' . ale#Escape('shfmt'), + \ "Default command name is expected to be 'shfmt'" + +Execute(The shfmt callback should return the command with no option as default when noexpandtab is set): + let g:ale_sh_shfmt_executable = 'shfmt' + let g:ale_sh_shfmt_options = '' + setlocal noexpandtab + AssertEqual + \ { + \ 'command': ale#Escape('shfmt'), + \ }, + \ ale#fixers#shfmt#Fix(bufnr('')) + +Execute(The shfmt callback should return the command specifying indent width by looking shiftwidth as default): + let g:ale_sh_shfmt_executable = 'shfmt' + let g:ale_sh_shfmt_options = '' + setlocal expandtab + setlocal shiftwidth=4 + AssertEqual + \ { + \ 'command': ale#Escape('shfmt') . ' -i 4', + \ }, + \ ale#fixers#shfmt#Fix(bufnr('')) + +Execute(The shfmt callback should return the command specifying indent width by looking tabstop when shiftwidth is 0 as default): + let g:ale_sh_shfmt_executable = 'shfmt' + let g:ale_sh_shfmt_options = '' + setlocal expandtab + setlocal shiftwidth=0 + setlocal tabstop=8 + AssertEqual + \ { + \ 'command': ale#Escape('shfmt') . ' -i 8', + \ }, + \ ale#fixers#shfmt#Fix(bufnr('')) + +Execute(The shfmt executable and options should be configurable): + let g:ale_sh_shfmt_executable = 'foobar' + let g:ale_sh_shfmt_options = '--some-option' + + AssertEqual + \ { + \ 'command': ale#Escape('foobar') + \ . ' --some-option', + \ }, + \ ale#fixers#shfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_sorbet_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_sorbet_fixer_callback.vader new file mode 100644 index 00000000..2694a3dc --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_sorbet_fixer_callback.vader @@ -0,0 +1,38 @@ +Before: + Save g:ale_ruby_sorbet_executable + Save g:ale_ruby_sorbet_options + + " Use an invalid global executable, so we don't match it. + let g:ale_ruby_sorbet_executable = 'xxxinvalid' + let g:ale_ruby_sorbet_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The sorbet callback should return the correct default values): + call ale#test#SetFilename('../test-files/ruby/dummy.rb') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_ruby_sorbet_executable) + \ . ' tc --autocorrect --file %t', + \ }, + \ ale#fixers#sorbet#Fix(bufnr('')) + +Execute(The sorbet callback should include custom sorbet options): + let g:ale_ruby_sorbet_options = '--enable-experimental-lsp-hover' + call ale#test#SetFilename('../test-files/ruby/with_config/dummy.rb') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_ruby_sorbet_executable) + \ . ' tc --enable-experimental-lsp-hover' + \ . ' --autocorrect --file %t', + \ }, + \ ale#fixers#sorbet#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_sqlfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_sqlfmt_fixer_callback.vader new file mode 100644 index 00000000..3046edb3 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_sqlfmt_fixer_callback.vader @@ -0,0 +1,26 @@ +Before: + Save g:ale_sql_sqlfmt_executable + Save g:ale_sql_sqlfmt_options + +After: + Restore + +Execute(The sqlfmt callback should return the correct default values): + AssertEqual + \ { + \ 'command': ale#Escape('sqlfmt') + \ . ' -w', + \ }, + \ ale#fixers#sqlfmt#Fix(bufnr('')) + +Execute(The sqlfmt executable and options should be configurable): + let g:ale_sql_sqlfmt_executable = '/path/to/sqlfmt' + let g:ale_sql_sqlfmt_options = '-u' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/sqlfmt') + \ . ' -w' + \ . ' -u', + \ }, + \ ale#fixers#sqlfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_sqlformat_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_sqlformat_fixer_callback.vader new file mode 100644 index 00000000..4bace089 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_sqlformat_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_sql_sqlformat_executable + Save g:ale_sql_sqlformat_options + +After: + Restore + +Execute(The sqlformat callback should return the correct default values): + AssertEqual + \ { + \ 'command': ale#Escape('sqlformat') . ' -' + \ }, + \ ale#fixers#sqlformat#Fix(bufnr('')) + +Execute(The sqlformat executable and options should be configurable): + let g:ale_sql_sqlformat_executable = '/path/to/sqlformat' + let g:ale_sql_sqlformat_options = '-a' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/sqlformat') + \ . ' -a -' + \ }, + \ ale#fixers#sqlformat#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_standard_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_standard_fixer_callback.vader new file mode 100644 index 00000000..9f5eb0e9 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_standard_fixer_callback.vader @@ -0,0 +1,31 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/fixers') + + unlet! b:ale_javascript_standard_executable + unlet! b:ale_javascript_standard_options + +After: + call ale#test#RestoreDirectory() + +Execute(The executable path should be correct): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir/testfile.js') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/standard/bin/cmd.js')) + \ . ' --fix --stdin < %s > %t', + \ }, + \ ale#fixers#standard#Fix(bufnr('')) + +Execute(Custom options should be supported): + let b:ale_javascript_standard_use_global = 1 + let b:ale_javascript_standard_options = '--foo-bar' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('standard') . ' --foo-bar --fix --stdin < %s > %t', + \ }, + \ ale#fixers#standard#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_standardrb_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_standardrb_fixer_callback.vader new file mode 100644 index 00000000..ff82b8f1 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_standardrb_fixer_callback.vader @@ -0,0 +1,51 @@ +Before: + Save g:ale_ruby_standardrb_executable + Save g:ale_ruby_standardrb_options + + " Use an invalid global executable, so we don't match it. + let g:ale_ruby_standardrb_executable = 'xxxinvalid' + let g:ale_ruby_standardrb_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The standardrb callback should return the correct default values): + call ale#test#SetFilename('../test-files/ruby/dummy.rb') + + AssertEqual + \ { + \ 'process_with': 'ale#fixers#rubocop#PostProcess', + \ 'command': ale#Escape(g:ale_ruby_standardrb_executable) + \ . ' --fix --force-exclusion --stdin %s', + \ }, + \ ale#fixers#standardrb#Fix(bufnr('')) + +Execute(The standardrb callback should include configuration files): + call ale#test#SetFilename('../test-files/ruby/with_config/dummy.rb') + + AssertEqual + \ { + \ 'process_with': 'ale#fixers#rubocop#PostProcess', + \ 'command': ale#Escape(g:ale_ruby_standardrb_executable) + \ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/ruby/with_config/.standard.yml')) + \ . ' --fix --force-exclusion --stdin %s', + \ }, + \ ale#fixers#standardrb#Fix(bufnr('')) + +Execute(The standardrb callback should include custom rubocop options): + let g:ale_ruby_standardrb_options = '--except Lint/Debugger' + call ale#test#SetFilename('../test-files/ruby/with_config/dummy.rb') + + AssertEqual + \ { + \ 'process_with': 'ale#fixers#rubocop#PostProcess', + \ 'command': ale#Escape(g:ale_ruby_standardrb_executable) + \ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/ruby/with_config/.standard.yml')) + \ . ' --except Lint/Debugger' + \ . ' --fix --force-exclusion --stdin %s', + \ }, + \ ale#fixers#standardrb#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_stylelint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_stylelint_fixer_callback.vader new file mode 100644 index 00000000..ee7cfdd4 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_stylelint_fixer_callback.vader @@ -0,0 +1,34 @@ +Before: + Save g:ale_stylelint_options + + let g:ale_stylelint_options = '' + + call ale#assert#SetUpFixerTest('css', 'stylelint') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The stylelint callback should return the correct default values): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir/testfile.css') + + AssertFixer + \ { + \ 'read_temporary_file': 0, + \ 'cwd': '%s:h', + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/stylelint/bin/stylelint.js')) + \ . ' --fix --stdin --stdin-filename %s', + \ } + +Execute(The stylelint callback should include custom stylelint options): + let g:ale_stylelint_options = '--cache' + call ale#test#SetFilename('../test-files/eslint/react-app/subdir/testfile.css') + + AssertFixer + \ { + \ 'read_temporary_file': 0, + \ 'cwd': '%s:h', + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/stylelint/bin/stylelint.js')) + \ . ' --cache --fix --stdin --stdin-filename %s', + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_styler_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_styler_fixer_callback.vader new file mode 100644 index 00000000..79f71ba9 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_styler_fixer_callback.vader @@ -0,0 +1,21 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The styler callback should include custom styler options): + let g:ale_r_styler_options = "a_custom_option" + + AssertEqual + \ { + \ 'command': 'Rscript --vanilla -e ' + \ . '"suppressPackageStartupMessages(library(styler));' + \ . 'style_file(commandArgs(TRUE), transformers = ' + \ . 'a_custom_option)"' + \ . ' %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#styler#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_stylish_haskell_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_stylish_haskell_fixer_callback.vader new file mode 100644 index 00000000..755d3430 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_stylish_haskell_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_haskell_stylish_haskell_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_haskell_stylish_haskell_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The stylish-haskell callback should return the correct default values): + call ale#test#SetFilename('../haskell_files/testfile.hs') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' --inplace' + \ . ' %t', + \ }, + \ ale#fixers#stylish_haskell#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_stylua_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_stylua_fixer_callback.vader new file mode 100644 index 00000000..8621c498 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_stylua_fixer_callback.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpFixerTest('lua', 'stylua') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The default command should be correct): + AssertFixer {'command': ale#Escape('stylua') . ' -'} + +Execute(The stylua callback should include custom stylua options): + let g:ale_lua_stylua_executable = 'xxxinvalid' + let g:ale_lua_stylua_options = '--search-parent-directories' + + AssertFixer + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_lua_stylua_options + \ . ' -', + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_swiftformat_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_swiftformat_fixer_callback.vader new file mode 100644 index 00000000..755c30f6 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_swiftformat_fixer_callback.vader @@ -0,0 +1,35 @@ +Before: + Save g:ale_swift_swiftformat_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_swift_swiftformat_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The swiftformat callback should return the correct default values): + call ale#test#SetFilename('../test-files/swift/dummy.swift') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_swift_swiftformat_executable) + \ . ' %t ', + \ }, + \ ale#fixers#swiftformat#Fix(bufnr('')) + +Execute(The swiftformat callback should include any additional options): + call ale#test#SetFilename('../test-files/swift/dummy.swift') + let g:ale_swift_swiftformat_options = '--some-option' + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(g:ale_swift_swiftformat_executable) + \ . ' %t --some-option', + \ }, + \ ale#fixers#swiftformat#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_terraform_fmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_terraform_fmt_fixer_callback.vader new file mode 100644 index 00000000..15377a7e --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_terraform_fmt_fixer_callback.vader @@ -0,0 +1,34 @@ +Before: + Save g:ale_terraform_fmt_executable + Save g:ale_terraform_fmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_terraform_fmt_executable = 'xxxinvalid' + let g:ale_terraform_fmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The terraform fmt callback should return the correct default values): + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') . ' fmt -', + \ }, + \ ale#fixers#terraform#Fix(bufnr('')) + +Execute(The terraform fmt callback should include custom options): + let g:ale_terraform_fmt_options = "-list=true" + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' fmt' + \ . ' ' . g:ale_terraform_fmt_options + \ . ' -', + \ }, + \ ale#fixers#terraform#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_textlint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_textlint_fixer_callback.vader new file mode 100644 index 00000000..5b6c5b7a --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_textlint_fixer_callback.vader @@ -0,0 +1,42 @@ +Before: + Save g:ale_textlint_executable + Save g:ale_textlint_options + Save g:ale_textlint_use_global + + " Use an invalid global executable, so we don't match it. + let g:ale_textlint_executable = 'xxxinvalid' + let g:ale_textlint_options = '' + let g:ale_textlint_use_global = 0 + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The textlint callback should return the correct default values): + call ale#test#SetFilename('../test-files/markdown/testfile.md') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' --fix' + \ . ' %t', + \ }, + \ ale#fixers#textlint#Fix(bufnr('')) + +Execute(The textlint callback should include custom textlint options): + let g:ale_textlint_options = "--quiet" + call ale#test#SetFilename('../test-files/markdown/testfile.md') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' --fix' + \ . ' ' . g:ale_textlint_options + \ . ' %t', + \ }, + \ ale#fixers#textlint#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_tidy_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_tidy_fixer_callback.vader new file mode 100644 index 00000000..25d3d6c3 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_tidy_fixer_callback.vader @@ -0,0 +1,25 @@ +Before: + Save g:ale_html_tidy_executable + + let g:ale_html_tidy_executable = '../test-files/tidy/tidy' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The tidy callback should return 0 if tidy not found): + let g:ale_html_tidy_executable = 'xxxinvalidpath' + AssertEqual + \ 0, + \ ale#fixers#tidy#Fix(bufnr('')) + +Execute(The tidy callback should return the correct default command): + AssertEqual + \ { + \ 'command': ale#Escape('../test-files/tidy/tidy') + \ . ' -q --tidy-mark no --show-errors 0 --show-warnings 0' + \ }, + \ ale#fixers#tidy#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_trim_whitespace.vader b/vim-config/plugins/ale/test/fixers/test_trim_whitespace.vader new file mode 100644 index 00000000..2ffbcb04 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_trim_whitespace.vader @@ -0,0 +1,28 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + call ale#test#RestoreDirectory() + +Execute(Should delete all whitespace at the end of different lines): + AssertEqual + \ [ + \ 'def foo():', + \ ' some_variable = this_is_a_longer_function(', + \ 'first_argument,', + \ ' second_argument,', + \ ' third_with_function_call(', + \ 'foo,', + \ ' bar,', + \ '))', + \ ], + \ ale#fixers#generic#TrimWhitespace(bufnr(''), [ + \ 'def foo():', + \ ' some_variable = this_is_a_longer_function(', + \ 'first_argument,', + \ ' second_argument,', + \ ' third_with_function_call(', + \ 'foo,', + \ ' bar,', + \ '))', + \ ]) diff --git a/vim-config/plugins/ale/test/fixers/test_tslint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_tslint_fixer_callback.vader new file mode 100644 index 00000000..43fcc5a4 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_tslint_fixer_callback.vader @@ -0,0 +1,42 @@ +Before: + Save g:ale_typescript_tslint_executable + Save g:ale_typescript_tslint_config_path + + unlet! g:ale_typescript_tslint_executable + unlet! g:ale_typescript_tslint_config_path + unlet! b:ale_typescript_tslint_executable + unlet! b:ale_typescript_tslint_config_path + + call ale#handlers#tslint#InitVariables() + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The tslint callback should return the correct default values): + let g:ale_typescript_tslint_config_path = 'tslint.json' + call ale#test#SetFilename('../test-files/prettier/testfile.ts') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('tslint') + \ . ' -c ' . ale#Escape('tslint.json') + \ . ' --outputAbsolutePaths --fix %t', + \ }, + \ ale#fixers#tslint#Fix(bufnr('')) + +Execute(The tslint callback should include custom tslint config option): + let g:ale_typescript_tslint_config_path = '.tslintrc' + call ale#test#SetFilename('../test-files/prettier/testfile.ts') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('tslint') + \ . ' -c ' . ale#Escape('.tslintrc') + \ . ' --outputAbsolutePaths --fix %t', + \ }, + \ ale#fixers#tslint#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_uncrustify_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_uncrustify_fixer_callback.vader new file mode 100644 index 00000000..26b5f892 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_uncrustify_fixer_callback.vader @@ -0,0 +1,33 @@ +Before: + Save g:ale_c_uncrustify_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_c_uncrustify_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The clang-format callback should return the correct default values): + call ale#test#SetFilename('../test-files/c/dummy.c') + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_c_uncrustify_executable) + \ . ' --no-backup' + \ }, + \ ale#fixers#uncrustify#Fix(bufnr('')) + +Execute(The uncrustify callback should include any additional options): + call ale#test#SetFilename('../test-files/c/dummy.c') + let b:ale_c_uncrustify_options = '--some-option' + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_c_uncrustify_executable) + \ . ' --no-backup --some-option', + \ }, + \ ale#fixers#uncrustify#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_vfmt_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_vfmt_fixer_callback.vader new file mode 100644 index 00000000..cbab1189 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_vfmt_fixer_callback.vader @@ -0,0 +1,44 @@ +Before: + Save g:ale_v_v_executable + Save g:ale_v_vfmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_v_v_executable = 'xxxinvalid' + let g:ale_v_vfmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The vfmt callback should return the correct default values): + call ale#test#SetFilename('../v_files/testfile.v') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') . ' fmt', + \ }, + \ ale#fixers#vfmt#Fix(bufnr('')) + +Execute(The vfmt callback should include custom vfmt options): + let g:ale_v_vfmt_options = "-r '(a) -> a'" + + call ale#test#SetFilename('../v_files/testfile.v') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' fmt ' . g:ale_v_vfmt_options, + \ }, + \ ale#fixers#vfmt#Fix(bufnr('')) + +Execute(The vfmt callback should support Go environment variables): + call ale#test#SetFilename('../v_files/testfile.v') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') . ' fmt', + \ }, + \ ale#fixers#vfmt#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_vim_help_tags_alignment_fixer.vader b/vim-config/plugins/ale/test/fixers/test_vim_help_tags_alignment_fixer.vader new file mode 100644 index 00000000..7e18a771 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_vim_help_tags_alignment_fixer.vader @@ -0,0 +1,19 @@ +Before: + Save g:ale_fixers + +After: + Restore + +Given help(A vim help file with badly aligned tags): + foo *foo* + bar *bar* + baz *bar* + +Execute(Tags should be aligned at the right margin): + let g:ale_fixers = {'help': ['align_help_tags']} + ALEFix + +Expect help(Tags should be aligned): + foo *foo* + bar *bar* + baz *bar* diff --git a/vim-config/plugins/ale/test/fixers/test_xmllint_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_xmllint_fixer_callback.vader new file mode 100644 index 00000000..54fe05bd --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_xmllint_fixer_callback.vader @@ -0,0 +1,46 @@ +Before: + Save g:ale_xml_xmllint_executable + Save g:ale_xml_xmllint_indentsize + Save g:ale_xml_xmllint_options + + let g:ale_xml_xmllint_executable = '/path/to/xmllint' + let g:ale_xml_xmllint_indentsize = '' + let g:ale_xml_xmllint_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + +Execute(The xmllint callback should return the correct default command): + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/xmllint') + \ . ' --format ' + \ . ale#Escape(bufname(bufnr(''))) + \ }, + \ ale#fixers#xmllint#Fix(bufnr('')) + +Execute(The xmllint callback should include the XMLLINT_INDENT variable): + let g:ale_xml_xmllint_indentsize = 2 + + AssertEqual + \ { + \ 'command': ale#Env('XMLLINT_INDENT', ' ') + \ . ale#Escape('/path/to/xmllint') + \ . ' --format ' + \ . ale#Escape(bufname(bufnr(''))) + \ }, + \ ale#fixers#xmllint#Fix(bufnr('')) + +Execute(The xmllint callback should include additional options): + let g:ale_xml_xmllint_options = '--nonet' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/xmllint') + \ . ' --format ' + \ . ale#Escape(bufname(bufnr(''))) + \ . ' --nonet' + \ }, + \ ale#fixers#xmllint#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_xo_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_xo_fixer_callback.vader new file mode 100644 index 00000000..fe2da8cc --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_xo_fixer_callback.vader @@ -0,0 +1,45 @@ +Before: + call ale#assert#SetUpFixerTest('javascript', 'xo') + runtime autoload/ale/handlers/xo.vim + set filetype=javascript + +After: + call ale#assert#TearDownFixerTest() + +Execute(The xo callback should return the correct default values): + call ale#test#SetFilename('../test-files/xo/monorepo/packages/a/index.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/xo/monorepo/node_modules/xo/cli.js')) + \ . ' --fix %t', + \ } + +Execute(The xo callback should include custom xo options): + let g:ale_javascript_xo_options = '--space' + call ale#test#SetFilename('../test-files/xo/monorepo/packages/a/index.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/xo/monorepo/node_modules/xo/cli.js')) + \ . ' --fix %t' + \ . ' --space', + \ } + +Execute(--stdin should be used when xo is new enough): + let g:ale_javascript_xo_options = '--space' + call ale#test#SetFilename('../test-files/xo/monorepo/packages/a/index.js') + + GivenCommandOutput ['0.30.0'] + AssertFixer + \ { + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/xo/monorepo/node_modules/xo/cli.js')) + \ . ' --stdin --stdin-filename %s' + \ . ' --fix' + \ . ' --space', + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_xots_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_xots_fixer_callback.vader new file mode 100644 index 00000000..61a22e62 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_xots_fixer_callback.vader @@ -0,0 +1,45 @@ +Before: + call ale#assert#SetUpFixerTest('typescript', 'xo') + runtime autoload/ale/handlers/xo.vim + set filetype=typescript + +After: + call ale#assert#TearDownFixerTest() + +Execute(The xo callback should return the correct default values): + call ale#test#SetFilename('../test-files/xo/monorepo/packages/a/index.ts') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/xo/monorepo/node_modules/xo/cli.js')) + \ . ' --fix %t', + \ } + +Execute(The xo callback should include custom xo options): + let g:ale_typescript_xo_options = '--space' + call ale#test#SetFilename('../test-files/xo/monorepo/packages/a/index.ts') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/xo/monorepo/node_modules/xo/cli.js')) + \ . ' --fix %t' + \ . ' --space', + \ } + +Execute(--stdin should be used when xo is new enough): + let g:ale_typescript_xo_options = '--space' + call ale#test#SetFilename('../test-files/xo/monorepo/packages/a/index.ts') + + GivenCommandOutput ['0.30.0'] + AssertFixer + \ { + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/xo/monorepo/node_modules/xo/cli.js')) + \ . ' --stdin --stdin-filename %s' + \ . ' --fix' + \ . ' --space', + \ } diff --git a/vim-config/plugins/ale/test/fixers/test_yamlfix_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_yamlfix_fixer_callback.vader new file mode 100644 index 00000000..1ae5e335 --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_yamlfix_fixer_callback.vader @@ -0,0 +1,33 @@ +Before: + call ale#assert#SetUpFixerTest('yaml', 'yamlfix') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + unlet! b:bin_dir + call ale#assert#TearDownFixerTest() + +Execute(The yamlfix callback should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#yamlfix#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.yaml') + AssertEqual + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/yamlfix')) . ' -', + \ }, + \ ale#fixers#yamlfix#Fix(bufnr('')) + +Execute(The yamlfix callback should respect custom options): + let g:ale_yaml_yamlfix_options = '--multi-line=3 --trailing-comma' + + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.yaml') + AssertEqual + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/yamlfix')) + \ . ' --multi-line=3 --trailing-comma -', + \ }, + \ ale#fixers#yamlfix#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/fixers/test_yapf_fixer_callback.vader b/vim-config/plugins/ale/test/fixers/test_yapf_fixer_callback.vader new file mode 100644 index 00000000..a7fcc07b --- /dev/null +++ b/vim-config/plugins/ale/test/fixers/test_yapf_fixer_callback.vader @@ -0,0 +1,39 @@ +Before: + Save g:ale_python_yapf_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_python_yapf_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + Restore + + unlet! b:bin_dir + + call ale#test#RestoreDirectory() + +Execute(The yapf callback should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#yapf#Fix(bufnr('')) + + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/yapf'))}, + \ ale#fixers#yapf#Fix(bufnr('')) + \ +Execute(The yapf should include the .style.yapf file if present): + call ale#test#SetFilename('../test-files/python/with_virtualenv/dir_with_yapf_config/foo/bar.py') + + AssertEqual + \ { + \ 'command': + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/yapf')) + \ . ' --no-local-style' + \ . ' --style ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/dir_with_yapf_config/.style.yapf')), + \ }, + \ ale#fixers#yapf#Fix(bufnr('')) diff --git a/vim-config/plugins/ale/test/handler/test_ada_gcc_handler.vader b/vim-config/plugins/ale/test/handler/test_ada_gcc_handler.vader new file mode 100644 index 00000000..06ddfe1f --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ada_gcc_handler.vader @@ -0,0 +1,36 @@ +Before: + runtime ale_linters/ada/gcc.vim + +After: + call ale#linter#Reset() + +Execute(The gcc handler for Ada should parse input correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 0, + \ 'lnum': 8, + \ 'col': 5, + \ 'type': 'W', + \ 'text': 'variable "X" is assigned but never read', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 6, + \ 'col': 22, + \ 'type': 'E', + \ 'text': 'type definition expected', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 8, + \ 'col': 9, + \ 'type': 'E', + \ 'text': 'aspect specifications not allowed here', + \ }, + \ ], + \ ale_linters#ada#gcc#Handle(0, [ + \ 'foobar.adb:8:05: warning: variable "X" is assigned but never read', + \ 'foobar.ads:6:22: type definition expected', + \ 'foobar.ads:8:09: aspect specifications not allowed here', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_alex_handler.vader b/vim-config/plugins/ale/test/handler/test_alex_handler.vader new file mode 100644 index 00000000..eb241f80 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_alex_handler.vader @@ -0,0 +1,54 @@ +Execute(The alex handler should handle the example from the alex README): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 5, + \ 'end_lnum': 1, + \ 'end_col': 13, + \ 'type': 'W', + \ 'text': '`boogeyman` may be insensitive, use `boogey` instead (retext-equality)', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 42, + \ 'end_lnum': 1, + \ 'end_col': 47, + \ 'type': 'W', + \ 'text': '`master` / `slaves` may be insensitive, use `primary` / `replica` instead (retext-equality)', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 69, + \ 'end_lnum': 1, + \ 'end_col': 74, + \ 'type': 'W', + \ 'text': 'Don’t use “slaves”, it’s profane (retext-profanities)', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 52, + \ 'end_lnum': 2, + \ 'end_col': 53, + \ 'type': 'W', + \ 'text': '`he` may be insensitive, use `they`, `it` instead (retext-equality)', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 61, + \ 'end_lnum': 2, + \ 'end_col': 67, + \ 'type': 'W', + \ 'text': '`cripple` may be insensitive, use `person with a limp` instead (retext-equality)', + \ }, + \ ], + \ ale#handlers#alex#Handle(bufnr(''), [ + \ 'example.md', + \ ' 1:5-1:14 warning `boogeyman` may be insensitive, use `boogey` instead boogeyman-boogeywoman retext-equality', + \ ' 1:42-1:48 warning `master` / `slaves` may be insensitive, use `primary` / `replica` instead master-slave retext-equality', + \ ' 1:69-1:75 warning Don’t use “slaves”, it’s profane slaves retext-profanities', + \ ' 2:52-2:54 warning `he` may be insensitive, use `they`, `it` instead he-she retext-equality', + \ ' 2:61-2:68 warning `cripple` may be insensitive, use `person with a limp` instead cripple retext-equality', + \ '', + \ '⚠ 5 warnings', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_ameba_handler.vader b/vim-config/plugins/ale/test/handler/test_ameba_handler.vader new file mode 100644 index 00000000..a6f43170 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ameba_handler.vader @@ -0,0 +1,44 @@ +Before: + runtime ale_linters/crystal/ameba.vim + +After: + unlet! g:lines + call ale#linter#Reset() + +Execute(The ameba handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 24, + \ 'col': 28, + \ 'end_col': 29, + \ 'text': 'Trailing whitespace detected', + \ 'code': 'Layout/TrailingWhitespace', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#crystal#ameba#HandleAmebaOutput(123, [ + \ '{"sources":[{"path":"my_file_with_issues.cr","issues":[{"rule_name":"Layout/TrailingWhitespace","message":"Trailing whitespace detected","location":{"line":24,"column":28},"end_location":{"line":null,"column":null}}]},{"path":"my_file_without_issues.cr","issues":[]}],"metadata":{"ameba_version":"0.8.1","crystal_version":"0.26.1"},"summary":{"target_sources_count":2,"issues_count":1}}' + \ ]) + +Execute(The ameba handler should handle when files are checked and no offenses are found): + AssertEqual + \ [], + \ ale_linters#crystal#ameba#HandleAmebaOutput(123, [ + \ '{"sources":[{"path":"my_file_with_issues.cr",issues":[]},{"path":"my_file_without_issues.cr",issues":[]}],"metadata":{ameba_version":"0.8.1",crystal_version":"0.26.1"},"summary":{target_sources_count":2,issues_count":0}}' + \ ]) + +Execute(The ameba handler should handle when no files are checked): + AssertEqual + \ [], + \ ale_linters#crystal#ameba#HandleAmebaOutput(123, [ + \ '{"sources":[],"metadata":{ameba_version":"0.8.1",crystal_version":"0.26.1"},"summary":{target_sources_count":0,issues_count":0}}' + \ ]) + +Execute(The ameba handler should handle blank output without any errors): + AssertEqual + \ [], + \ ale_linters#crystal#ameba#HandleAmebaOutput(123, ['{}']) + AssertEqual + \ [], + \ ale_linters#crystal#ameba#HandleAmebaOutput(123, []) diff --git a/vim-config/plugins/ale/test/handler/test_ansible_lint_handler.vader b/vim-config/plugins/ale/test/handler/test_ansible_lint_handler.vader new file mode 100644 index 00000000..28dbba30 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ansible_lint_handler.vader @@ -0,0 +1,95 @@ +Before: + runtime ale_linters/ansible/ansible_lint.vim + call ale#test#SetFilename('test_playbook.yml') + + let b:ale_warn_about_trailing_whitespace = 1 + +After: + unlet! b:ale_warn_about_trailing_whitespace + call ale#linter#Reset() + +Execute(The ansible-lint handler for version group <5 should handle basic errors): + AssertEqual + \ [ + \ { + \ 'lnum': 35, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'Trailing whitespace', + \ 'code': 'EANSIBLE0002', + \ }, + \ ], + \ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [4, 1, 2], [ + \ fnamemodify(tempname(), ':h') . '/test_playbook.yml:35: [EANSIBLE0002] Trailing whitespace', + \ ]) + +Execute(The ansible-lint handler for version group <5 should supress trailing whitespace output when the option is used): + let b:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [ + \ ], + \ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [4, 1, 2], [ + \ fnamemodify(tempname(), ':h') . '/test_playbook.yml:35: [EANSIBLE0002] Trailing whitespace', + \ ]) + + +Execute(The ansible-lint handler for version group >=5 should handle basic errors): + AssertEqual + \ [ + \ { + \ 'lnum': 35, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'File permissions unset or incorrect', + \ 'code': 'risky-file-permissions', + \ }, + \ ], + \ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [5, 1, 2], [ + \ fnamemodify(tempname(), ':h') . '/test_playbook.yml:35: [risky-file-permissions] [VERY_HIGH] File permissions unset or incorrect', + \ ]) + +Before: + runtime ale_linters/ansible/ansible_lint.vim + call ale#test#SetFilename('test playbook.yml') + +After: + call ale#linter#Reset() + +Execute (The ansible-lint handler for version group <5 should handle names with spaces): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 6, + \ 'type': 'E', + \ 'text': 'indentation is not a multiple of four', + \ 'code': 'E111', + \ }, + \ ], + \ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [4, 1, 2], [ + \ fnamemodify(tempname(), ':h') . '/test playbook.yml:6:6: E111 indentation is not a multiple of four', + \ ]) + +Execute (The ansible-lint handler for version group >=5 should handle names with spaces): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'col': 148, + \ 'type': 'E', + \ 'text': "'var' is not a valid attribute for a Play", + \ 'code': 'syntax-check', + \ }, + \ ], + \ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [5, 1, 2], [ + \ fnamemodify(tempname(), ':h') . "/test playbook.yml:3:148: [syntax-check] [VERY_HIGH] 'var' is not a valid attribute for a Play", + \ ]) + +Execute (The ansible-lint handler should ignore errors from other files): + AssertEqual + \ [ + \ ], + \ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [5, 1, 2], [ + \ '/foo/bar/roles/test_playbook.yml:6: [command-instead-of-module] [VERY_LOW] curl used in place of get_url or uri module', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_appleswiftformat_handler.vader b/vim-config/plugins/ale/test/handler/test_appleswiftformat_handler.vader new file mode 100644 index 00000000..818bd9c5 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_appleswiftformat_handler.vader @@ -0,0 +1,28 @@ +Before: + runtime ale_linters/swift/appleswiftformat.vim + +After: + call ale#linter#Reset() + +Execute(The appleswiftformat handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 21, + \ 'type': 'W', + \ 'code': 'DoNotUseSemicolons', + \ 'text': 'remove '';'' and move the next statement to the new line', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 12, + \ 'type': 'W', + \ 'code': 'Spacing', + \ 'text': 'remove 1 space' + \ }, + \ ], + \ ale_linters#swift#appleswiftformat#Handle(bufnr(''), [ + \ 'Sources/main.swift:4:21: warning: [DoNotUseSemicolons] remove '';'' and move the next statement to the new line', + \ 'Sources/main.swift:3:12: warning: [Spacing] remove 1 space', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_asm_handler.vader b/vim-config/plugins/ale/test/handler/test_asm_handler.vader new file mode 100644 index 00000000..4ab99992 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_asm_handler.vader @@ -0,0 +1,26 @@ +Before: + runtime ale_linters/asm/gcc.vim + +After: + call ale#linter#Reset() + +Execute(The asm GCC handler should parse lines from GCC 6.3.1 correctly): + + AssertEqual + \ [ + \ { + \ 'lnum': 38, + \ 'text': "too many memory references for `mov'", + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 42, + \ 'text': "incorrect register `%ax' used with `l' suffix", + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#asm#gcc#Handle(357, [ + \ "{standard input}: Assembler messages:", + \ "{standard_input}:38: Error: too many memory references for `mov'", + \ "{standard input}:42: Error: incorrect register `%ax' used with `l' suffix", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_atools_handler.vader b/vim-config/plugins/ale/test/handler/test_atools_handler.vader new file mode 100644 index 00000000..1bb9ca00 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_atools_handler.vader @@ -0,0 +1,85 @@ +Before: + runtime autoload/ale/handlers/atools.vim + +After: + call ale#linter#Reset() + +Execute(The atools handler should handle basic errors or warings): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'text': 'trailing whitespace', + \ 'type': 'E', + \ 'code': 'AL8', + \ }, + \ { + \ 'lnum': 15, + \ 'text': '$pkgname should not be used in the source url', + \ 'type': 'W', + \ 'code': 'AL29', + \ }, + \ ], + \ ale#handlers#atools#Handle(bufnr(''), [ + \ 'IC:[AL8]:APKBUILD:2:trailing whitespace', + \ 'MC:[AL29]:APKBUILD:15:$pkgname should not be used in the source url', + \ ]) + +" Regardless of the severity, if the certainty is [P]ossible and not [C]ertain +" or if regardless of the Certainity the Severity is not [I]mportant or [S]erious +" then it must be a [W]arning +Execute(If we are not Certain or Importantly Serious, be a Warning): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'text': 'This violation is Serious but Possible false positive, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 4, + \ 'text': 'This violation is Important but Possible false positive, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 5, + \ 'text': 'This violation is Minor, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 6, + \ 'text': 'This violation is Style, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ ], + \ ale#handlers#atools#Handle(bufnr(''), [ + \ 'SP:[AL]:APKBUILD:3:This violation is Serious but Possible false positive, I am a Warning!', + \ 'IP:[AL]:APKBUILD:4:This violation is Important but Possible false positive, I am a Warning!', + \ 'MC:[AL]:APKBUILD:5:This violation is Minor, I am a Warning!', + \ 'TC:[AL]:APKBUILD:6:This violation is Style, I am a Warning!', + \ ]) + +Execute(We should be error if we are Certain it is Serious or Important): + AssertEqual + \ [ + \ { + \ 'lnum': 7, + \ 'text': 'This is Certainly Serious, I am an Error!', + \ 'type': 'E', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 8, + \ 'text': 'This is Certainly Important, I am an Error!', + \ 'type': 'E', + \ 'code': 'AL', + \ }, + \ ], + \ ale#handlers#atools#Handle(bufnr(''), [ + \ 'SC:[AL]:APKBUILD:7:This is Certainly Serious, I am an Error!', + \ 'IC:[AL]:APKBUILD:8:This is Certainly Important, I am an Error!', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_bandit_handler.vader b/vim-config/plugins/ale/test/handler/test_bandit_handler.vader new file mode 100644 index 00000000..a2793a46 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_bandit_handler.vader @@ -0,0 +1,42 @@ +Before: + runtime ale_linters/python/bandit.vim + +After: + call ale#linter#Reset() + +Execute(The bandit handler for Python should parse input correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 0, + \ 'lnum': 2, + \ 'code': 'B404', + \ 'type': 'I', + \ 'text': 'Consider possible security implications associated with subprocess module.', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 4, + \ 'code': 'B305', + \ 'type': 'W', + \ 'text': 'Use of insecure cipher mode cryptography.hazmat.primitives.ciphers.modes.ECB.', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 6, + \ 'code': 'B609', + \ 'type': 'E', + \ 'text': 'Possible wildcard injection in call: subprocess.Popen', + \ }, + \ ], + \ ale_linters#python#bandit#Handle(0, [ + \ '[main] INFO profile include tests: None', + \ '[main] INFO profile exclude tests: None', + \ '[main] INFO cli include tests: None', + \ '[main] INFO cli exclude tests: None', + \ '[main] INFO running on Python 3.7.2', + \ '[node_visitor] INFO Unable to find qualified name for module: ', + \ '2:B404:LOW:Consider possible security implications associated with subprocess module.', + \ '4:B305:MEDIUM:Use of insecure cipher mode cryptography.hazmat.primitives.ciphers.modes.ECB.', + \ '6:B609:HIGH:Possible wildcard injection in call: subprocess.Popen', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_bashate_handler.vader b/vim-config/plugins/ale/test/handler/test_bashate_handler.vader new file mode 100644 index 00000000..b61bb956 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_bashate_handler.vader @@ -0,0 +1,36 @@ +Before: + runtime ale_linters/sh/bashate.vim + +After: + call ale#linter#Reset() + +Execute(The bashate handler should handle basic errors): + AssertEqual + \ [ + \ { + \ 'lnum': 777, + \ 'col': 1, + \ 'text': 'E003 Indent not multiple of 4', + \ }, + \ { + \ 'lnum': 783, + \ 'col': 1, + \ 'text': 'E020 Function declaration not in format ^function name {$', + \ }, + \ { + \ 'lnum': 786, + \ 'col': 1, + \ 'text': 'E010 The "do" should be on same line as for', + \ }, + \ { + \ 'lnum': 791, + \ 'col': 1, + \ 'text': 'E006 Line too long', + \ }, + \ ], + \ ale_linters#sh#bashate#Handle(bufnr(''), [ + \ 'run:777:1: E003 Indent not multiple of 4', + \ 'run:783:1: E020 Function declaration not in format ^function name {$', + \ 'run:786:1: E010 The "do" should be on same line as for', + \ 'run:791:1: E006 Line too long', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_bibclean_handler.vader b/vim-config/plugins/ale/test/handler/test_bibclean_handler.vader new file mode 100644 index 00000000..9da52a92 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_bibclean_handler.vader @@ -0,0 +1,88 @@ +Before: + runtime ale_linters/bib/bibclean.vim + +After: + call ale#linter#Reset() + +Execute(The bibclean handler should parse lines from bibclean <= v2.11.4 correctly): + + AssertEqual + \ [ + \ { + \ 'lnum': '60', + \ 'type': 'W', + \ 'text': 'Unexpected value in ``month = "09"''''.', + \ 'col': '17' + \ }, + \ { + \ 'lnum': '63', + \ 'type': 'E', + \ 'text': 'Expected comma after last field ``keywords''''.', + \ 'col': ' 1' + \ }, + \ { + \ 'lnum': '176', + \ 'type': 'W', + \ 'text': 'Unexpected DOI in URL value ``"https://doi.org/DOI"'''': move to separate DOI = "..." key/value in this entry.', + \ 'col': '14' + \ } + \ ], + \ ale_linters#bib#bibclean#Handle(255, [ + \ "%% \"stdin\", line 60: Unexpected value in ``month = \"09\"''.", + \ "%% File positions: input [main.bib] output [stdout]", + \ "%% Entry input byte=1681 line=50 column= 1 output byte=1680 line=50 column= 0", + \ "%% Value input byte=2137 line=60 column=17 output byte=2137 line=60 column=17", + \ "%% Current input byte=2139 line=60 column=19 output byte=2137 line=60 column=17", + \ "?? \"stdin\", line 71: Expected comma after last field ``keywords''.", + \ "?? File positions: input [main.bib] output [stdout]", + \ "?? Entry input byte=2145 line=63 column= 1 output byte=2146 line=63 column= 0", + \ "?? Value input byte=2528 line=71 column= 2 output byte=2527 line=70 column=49", + \ "?? Current input byte=2529 line=71 column= 3 output byte=2528 line=70 column=50", + \ "%% \"stdin\", line 176: Unexpected DOI in URL value ``\"https://doi.org/DOI\"'': move to separate DOI = \"...\" key/value in this entry.", + \ "%% File positions: input [stdin] output [stdout]", + \ "%% Entry input byte=6813 line=174 column= 1 output byte=8543 line=227 column= 0", + \ "%% Value input byte=6890 line=176 column=14 output byte=8641 line=229 column=17", + \ "%% Current input byte=6938 line=176 column=62 output byte=8641 line=229 column=17" + \ ]) + +Execute(The bibclean handler should parse lines of bibclean > v2.11.4 correctly): + + AssertEqual + \ [ + \ { + \ 'lnum': '60', + \ 'type': 'W', + \ 'text': 'Unexpected value in ``month = "09"''''.', + \ 'col': '17' + \ }, + \ { + \ 'lnum': '63', + \ 'type': 'E', + \ 'text': 'Expected comma after last field ``keywords''''.', + \ 'col': ' 1' + \ }, + \ { + \ 'lnum': '176', + \ 'type': 'W', + \ 'text': 'Unexpected DOI in URL value ``"https://doi.org/DOI"'''': move to separate DOI = "..." key/value in this entry.', + \ 'col': '14' + \ } + \ ], + \ ale_linters#bib#bibclean#Handle(255, [ + \ "%% stdin:60:Unexpected value in ``month = \"09\"''.", + \ "%% File positions: input [main.bib] output [stdout]", + \ "%% Entry input byte=1681 line=50 column= 1 output byte=1680 line=50 column= 0", + \ "%% Value input byte=2137 line=60 column=17 output byte=2137 line=60 column=17", + \ "%% Current input byte=2139 line=60 column=19 output byte=2137 line=60 column=17", + \ "?? stdin:71:Expected comma after last field ``keywords''.", + \ "?? File positions: input [main.bib] output [stdout]", + \ "?? Entry input byte=2145 line=63 column= 1 output byte=2146 line=63 column= 0", + \ "?? Value input byte=2528 line=71 column= 2 output byte=2527 line=70 column=49", + \ "?? Current input byte=2529 line=71 column= 3 output byte=2528 line=70 column=50", + \ "%% stdin:176:Unexpected DOI in URL value ``\"https://doi.org/DOI\"'': move to separate DOI = \"...\" key/value in this entry.", + \ "%% File positions: input [stdin] output [stdout]", + \ "%% Entry input byte=6813 line=174 column= 1 output byte=8543 line=227 column= 0", + \ "%% Value input byte=6890 line=176 column=14 output byte=8641 line=229 column=17", + \ "%% Current input byte=6938 line=176 column=62 output byte=8641 line=229 column=17" + \ ]) + diff --git a/vim-config/plugins/ale/test/handler/test_brakeman_handler.vader b/vim-config/plugins/ale/test/handler/test_brakeman_handler.vader new file mode 100644 index 00000000..ad5376f7 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_brakeman_handler.vader @@ -0,0 +1,83 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/handler') + + runtime ale_linters/ruby/brakeman.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The brakeman handler should parse JSON correctly): + call ale#test#SetFilename('../test-files/ruby/valid_rails_app/app/models/thing.rb') + + AssertEqual + \ [ + \ { + \ 'filename': expand('%:p'), + \ 'lnum': 84, + \ 'text': 'SQL Injection Possible SQL injection (Medium)', + \ 'type': 'W', + \ }, + \ { + \ 'filename': expand('%:p'), + \ 'lnum': 1, + \ 'text': 'Mass Assignment Potentially dangerous attribute available for mass assignment (Weak)', + \ 'type': 'W', + \ } + \ ], + \ ale_linters#ruby#brakeman#Handle(bufnr(''), [ + \ '{', + \ '"warnings": [', + \ '{', + \ '"warning_type": "SQL Injection",', + \ '"warning_code": 0,', + \ '"fingerprint": "1234",', + \ '"check_name": "SQL",', + \ '"message": "Possible SQL injection",', + \ '"file": "' . substitute(ale#path#Simplify('app/models/thing.rb'), '\\', '\\\\', 'g') . '",', + \ '"line": 84,', + \ '"link": "http://brakemanscanner.org/docs/warning_types/sql_injection/",', + \ '"code": "Thing.connection.execute(params[:data])",', + \ '"render_path": null,', + \ '"location": {', + \ '"type": "method",', + \ '"class": "Thing",', + \ '"method": "run_raw_sql_from_internet"', + \ '},', + \ '"user_input": "whatever",', + \ '"confidence": "Medium"', + \ '},', + \ '{', + \ '"warning_type": "Mass Assignment",', + \ '"warning_code": 60,', + \ '"fingerprint": "1235",', + \ '"check_name": "ModelAttrAccessible",', + \ '"message": "Potentially dangerous attribute available for mass assignment",', + \ '"file": "' . substitute(ale#path#Simplify('app/models/thing.rb'), '\\', '\\\\', 'g') . '",', + \ '"line": null,', + \ '"link": "http://brakemanscanner.org/docs/warning_types/mass_assignment/",', + \ '"code": ":name",', + \ '"render_path": null,', + \ '"location": {', + \ '"type": "model",', + \ '"model": "Thing"', + \ '},', + \ '"user_input": null,', + \ '"confidence": "Weak"', + \ '}', + \ ']', + \ '}' + \ ]) + +Execute(The brakeman handler should parse JSON correctly when there is no output from brakeman): + AssertEqual + \ [], + \ ale_linters#ruby#brakeman#Handle(347, [ + \ ]) + \ +Execute(The brakeman handler should handle garbage output): + AssertEqual + \ [], + \ ale_linters#ruby#brakeman#Handle(347, [ + \ 'No such command in 2.4.1 of ruby', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_cfn_python_lint_handler.vader b/vim-config/plugins/ale/test/handler/test_cfn_python_lint_handler.vader new file mode 100644 index 00000000..2c7ddc62 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_cfn_python_lint_handler.vader @@ -0,0 +1,33 @@ +Before: + runtime! ale_linters/cloudformation/cfn_python_lint.vim + call ale#test#SetFilename('sample.template.yaml') + +After: + call ale#linter#Reset() + +Execute(The cfn_python_lint handler should parse items correctly): + AssertEqual + \ [ + \ { + \ 'lnum': '96', + \ 'col': '7', + \ 'end_lnum': '96', + \ 'end_col': '15', + \ 'text': 'Property Resources/Sample/Properties/FromPort should be of type Integer', + \ 'code': 'E3012', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': '97', + \ 'col': '7', + \ 'end_lnum': '97', + \ 'end_col': '15', + \ 'text': 'AllowedPattern and/or AllowedValues for Parameter should be specified at Parameters/SampleIpAddress. Example for AllowedPattern "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$"', + \ 'code': 'W2509', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#cloudformation#cfn_python_lint#Handle(bufnr(''), [ + \ fnamemodify(tempname(), ':h') . '/sample.template.yaml:96:7:96:15:E3012:Property Resources/Sample/Properties/FromPort should be of type Integer', + \ fnamemodify(tempname(), ':h') . '/sample.template.yaml:97:7:97:15:W2509:AllowedPattern and/or AllowedValues for Parameter should be specified at Parameters/SampleIpAddress. Example for AllowedPattern "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$"', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_checkmake_handler.vader b/vim-config/plugins/ale/test/handler/test_checkmake_handler.vader new file mode 100644 index 00000000..e2e18425 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_checkmake_handler.vader @@ -0,0 +1,23 @@ +Before: + runtime ale_linters/make/checkmake.vim + +After: + call ale#linter#Reset() + +Execute(Parsing checkmake errors should work): + silent file Makefile + + AssertEqual + \ [ + \ { + \ 'bufnr': 42, + \ 'lnum': 1, + \ 'type': 'E', + \ 'code': 'woops', + \ 'text': 'an error has occurred', + \ } + \ ], + \ ale_linters#make#checkmake#Handle(42, [ + \ 'This shouldnt match', + \ '1:woops:an error has occurred', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_checkstyle_handler.vader b/vim-config/plugins/ale/test/handler/test_checkstyle_handler.vader new file mode 100644 index 00000000..ea90db3f --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_checkstyle_handler.vader @@ -0,0 +1,53 @@ +Before: + runtime ale_linters/java/checkstyle.vim + +After: + call ale#linter#Reset() + +Execute(The checkstyle handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 101, + \ 'col': 0, + \ 'text': '''method def rcurly'' has incorrect indentation level 4, expected level should be 2.', + \ 'code': 'Indentation', + \ 'type': 'W', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 63, + \ 'col': 3, + \ 'text': 'Missing a Javadoc comment.', + \ 'code': 'JavadocMethod', + \ 'type': 'W', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 11, + \ 'col': 7, + \ 'text': 'WhitespaceAround: ''if'' is not followed by whitespace.', + \ 'code': 'WhitespaceAround', + \ 'type': 'W', + \ 'sub_type': 'style', + \ }, + \ ], + \ ale_linters#java#checkstyle#Handle(666, [ + \ '[WARN] whatever:101: ''method def rcurly'' has incorrect indentation level 4, expected level should be 2. [Indentation]', + \ '[WARN] whatever:63:3: Missing a Javadoc comment. [JavadocMethod]', + \ '[WARN] whatever:11:7: WhitespaceAround: ''if'' is not followed by whitespace. [WhitespaceAround]', + \ ]) + +Execute(The checkstyle handler should parse lines from older checkstyle versions correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 289, + \ 'text': '''method def modifier'' have incorrect indentation level 4, expected level should be 2.', + \ 'type': 'W', + \ 'sub_type': 'style', + \ }, + \ ], + \ ale_linters#java#checkstyle#Handle(666, [ + \ '/home/languitar/src/rsb-java/rsb-java/src/main/java/rsb/Listener.java:289: warning: ''method def modifier'' have incorrect indentation level 4, expected level should be 2.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_circleci_handler.vader b/vim-config/plugins/ale/test/handler/test_circleci_handler.vader new file mode 100644 index 00000000..8ffba360 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_circleci_handler.vader @@ -0,0 +1,39 @@ +Before: + runtime ale_linters/yaml/circleci.vim + +After: + call ale#linter#Reset() + +Execute(The circlei handler should return nothing when configs are valid): + AssertEqual + \ [], + \ ale_linters#yaml#circleci#Handle(0, [ + \ 'Config input is valid.', + \ ]) + +Execute(The circlei handler put errors at the top when something is wrong): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': '[#/jobs] expected type: Mapping, found: Integer', + \ 'detail': join([ + \ '[#/jobs] expected type: Mapping, found: Integer', + \ 'Jobs is a map', + \ 'SCHEMA:', + \ ' type: object', + \ 'INPUT:', + \ ' 4', + \ ], "\n"), + \ }, + \ ], + \ ale_linters#yaml#circleci#Handle(0, [ + \ 'Error: ERROR IN CONFIG FILE:', + \ '[#/jobs] expected type: Mapping, found: Integer', + \ 'Jobs is a map', + \ 'SCHEMA:', + \ ' type: object', + \ 'INPUT:', + \ ' 4', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_clang_handler.vader b/vim-config/plugins/ale/test/handler/test_clang_handler.vader new file mode 100644 index 00000000..cc8eabd0 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_clang_handler.vader @@ -0,0 +1,30 @@ +Execute(clang errors from included files should be parsed correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'filename': './b.h', + \ 'type': 'E', + \ 'text': 'expected identifier or ''(''', + \ }, + \ { + \ 'lnum': 3, + \ 'text': 'Error found in header. See :ALEDetail', + \ 'detail': join([ + \ 'In file included from :3:', + \ 'In file included from ./a.h:1:', + \ './b.h:1:1: error: expected identifier or ''(''', + \ '{{{', + \ '^', + \ ], "\n"), + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ 'In file included from :3:', + \ 'In file included from ./a.h:1:', + \ './b.h:1:1: error: expected identifier or ''(''', + \ '{{{', + \ '^', + \ '1 error generated.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_clojure_clj_kondo_handler.vader b/vim-config/plugins/ale/test/handler/test_clojure_clj_kondo_handler.vader new file mode 100644 index 00000000..9ae70668 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_clojure_clj_kondo_handler.vader @@ -0,0 +1,89 @@ +Before: + runtime ale_linters/clojure/clj_kondo.vim + +After: + call ale#linter#Reset() + +Execute(the clojure clj-kondo handler should be able to handle errors): + AssertEqual + \ [ + \ { + \ 'lnum': 123, + \ 'col': 44, + \ 'type': 'E', + \ 'text': 'error: Unexpected )', + \ }, + \ ], + \ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [ + \ 'test.clj:123:44: error: Unexpected )', + \ ]) + +Execute(the clojure clj-kondo handler should be able to handle warnings): + AssertEqual + \ [ + \ { + \ 'lnum': 654, + \ 'col': 321, + \ 'type': 'W', + \ 'text': 'warning: inline def', + \ } + \ ], + \ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [ + \ 'test.clj:654:321: warning: inline def' + \ ]) + +Execute(the clojure clj-kondo handler should be able to handle exceptions): + AssertEqual + \ [ + \ { + \ 'lnum': 123, + \ 'col': 321, + \ 'type': 'E', + \ 'text': 'Exception: something horrible happen', + \ } + \ ], + \ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [ + \ 'test.clj:123:321: Exception: something horrible happen' + \ ]) + +Execute(the clojure clj-kondo handler should be able to handle errors from stdin): + AssertEqual + \ [ + \ { + \ 'lnum': 16, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'error: Unexpected )', + \ }, + \ ], + \ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [ + \ ':16:1: error: Unexpected )', + \ ]) + +Execute(the clojure clj-kondo handler should be able to handle windows files): + AssertEqual + \ [ + \ { + \ 'lnum': 123, + \ 'col': 44, + \ 'type': 'E', + \ 'text': 'error: Unexpected )', + \ } + \ ], + \ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [ + \ 'C:\my\operating\system\is\silly\core.clj:123:44: error: Unexpected )', + \ ]) + +Execute(the clojure clj-kondo handler should be able to lines without row/col): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'error: Unexpected )', + \ }, + \ ], + \ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [ + \ 'test.clj::: error: Unexpected )', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_clojure_joker_handler.vader b/vim-config/plugins/ale/test/handler/test_clojure_joker_handler.vader new file mode 100644 index 00000000..460c62e8 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_clojure_joker_handler.vader @@ -0,0 +1,75 @@ +Before: + runtime ale_linters/clojure/joker.vim + +After: + call ale#linter#Reset() + +Execute(the clojure joker handler should be able to handle errors): + AssertEqual + \ [ + \ { + \ 'lnum': 123, + \ 'col': 44, + \ 'type': 'E', + \ 'text': 'Read error: Unexpected )', + \ }, + \ ], + \ ale_linters#clojure#joker#HandleJokerFormat(0, [ + \ 'test.clj:123:44: Read error: Unexpected )', + \ ]) + +Execute(the clojure joker handler should be able to handle warnings): + AssertEqual + \ [ + \ { + \ 'lnum': 654, + \ 'col': 321, + \ 'type': 'W', + \ 'text': 'Parse warning: let form with empty body', + \ } + \ ], + \ ale_linters#clojure#joker#HandleJokerFormat(0, [ + \ 'test.clj:654:321: Parse warning: let form with empty body' + \ ]) + +Execute(the clojure joker handler should be able to handle exceptions): + AssertEqual + \ [ + \ { + \ 'lnum': 123, + \ 'col': 321, + \ 'type': 'E', + \ 'text': 'Exception: something horrible happen', + \ } + \ ], + \ ale_linters#clojure#joker#HandleJokerFormat(0, [ + \ 'test.clj:123:321: Exception: something horrible happen' + \ ]) + +Execute(the clojure joker handler should be able to handle errors from stdin): + AssertEqual + \ [ + \ { + \ 'lnum': 16, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Read error: Unexpected )', + \ }, + \ ], + \ ale_linters#clojure#joker#HandleJokerFormat(0, [ + \ ':16:1: Read error: Unexpected )', + \ ]) + +Execute(the clojure joker handler should be able to handle windows files): + AssertEqual + \ [ + \ { + \ 'lnum': 123, + \ 'col': 44, + \ 'type': 'E', + \ 'text': 'Read error: Unexpected )', + \ } + \ ], + \ ale_linters#clojure#joker#HandleJokerFormat(0, [ + \ 'C:\my\operating\system\is\silly\core.clj:123:44: Read error: Unexpected )', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_coffeelint_handler.vader b/vim-config/plugins/ale/test/handler/test_coffeelint_handler.vader new file mode 100644 index 00000000..a061f3a9 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_coffeelint_handler.vader @@ -0,0 +1,20 @@ +Before: + runtime ale_linters/coffee/coffeelint.vim + +After: + call ale#linter#Reset() + +Execute(The coffeelint handler should parse lines correctly): + + AssertEqual + \ [ + \ { + \ 'lnum': 125, + \ 'text': "Line exceeds maximum allowed length Length is 122, max is 120.", + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#coffee#coffeelint#Handle(347, [ + \ "path,lineNumber,lineNumberEnd,level,message", + \ "stdin,125,,error,Line exceeds maximum allowed length Length is 122, max is 120.", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_common_handlers.vader b/vim-config/plugins/ale/test/handler/test_common_handlers.vader new file mode 100644 index 00000000..ee29da36 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_common_handlers.vader @@ -0,0 +1,181 @@ +Execute(HandleCSSLintFormat should handle CSS errors): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Expected RBRACE at line 2, col 1.', + \ 'code': 'errors', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 5, + \ 'type': 'W', + \ 'text': 'Expected ... but found ''wat''.', + \ 'code': 'known-properties', + \ }, + \ ], + \ ale#handlers#css#HandleCSSLintFormat(42, [ + \ 'something.css: line 2, col 1, Error - Expected RBRACE at line 2, col 1. (errors)', + \ 'something.css: line 2, col 5, Warning - Expected ... but found ''wat''. (known-properties)', + \ ]) + +Execute(HandleCSSLintFormat should handle CSS errors without groups): + AssertEqual + \ [ + \ { + \ 'lnum': 7, + \ 'col': 3, + \ 'type': 'W', + \ 'text': 'Unknown property ''fill''.', + \ }, + \ { + \ 'lnum': 8, + \ 'col': 3, + \ 'type': 'W', + \ 'text': 'Unknown property ''fill-opacity''.', + \ }, + \ ], + \ ale#handlers#css#HandleCSSLintFormat(42, [ + \ 'something.css: line 7, col 3, Warning - Unknown property ''fill''.', + \ 'something.css: line 8, col 3, Warning - Unknown property ''fill-opacity''.', + \ ]) + +Execute (HandleGCCFormat should handle the correct lines of output): + AssertEqual + \ [ + \ { + \ 'lnum': 8, + \ 'col': 5, + \ 'type': 'W', + \ 'text': 'conversion lacks type at end of format [-Wformat=]', + \ }, + \ { + \ 'lnum': 10, + \ 'col': 27, + \ 'type': 'E', + \ 'text': 'invalid operands to binary - (have ''int'' and ''char *'')', + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormat(42, [ + \ ':8:5: warning: conversion lacks type at end of format [-Wformat=]', + \ ':10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’)', + \ ]) + +Execute (HandleGCCFormat should replace Unicode quotes): + AssertEqual + \ [ + \ { + \ 'lnum': 8, + \ 'col': 5, + \ 'type': 'W', + \ 'text': "'''' \"\"", + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormat(42, [':8:5: warning: `´‘’ “”']) + +Execute (HandleUnixFormatAsError should handle some example lines of output): + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'missing argument for Printf("%s"): format reads arg 2, have only 1 args', + \ }, + \ { + \ 'lnum': 53, + \ 'col': 10, + \ 'type': 'E', + \ 'text': '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)', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'E', + \ 'text': '".b" is not a valid class name. Class names must begin with "-", "_" or a letter and can only contain "_", "-", a-z and 0-9.', + \ }, + \ ], + \ ale#handlers#unix#HandleAsError(42, [ + \ '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)', + \ 'test.pug:1:1 ".b" is not a valid class name. Class names must begin with "-", "_" or a letter and can only contain "_", "-", a-z and 0-9.', + \ ]) + +Execute (HandleUnixFormatAsError should handle lines with no space after the colon): + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'foo', + \ }, + \ { + \ 'lnum': 53, + \ 'col': 10, + \ 'type': 'E', + \ 'text': 'bar', + \ }, + \ ], + \ ale#handlers#unix#HandleAsError(42, [ + \ 'some_file.xyz:27:foo', + \ 'some_file.xyz:53:10:bar', + \ ]) + +Execute (HandleUnixFormatAsError should handle names with spaces): + AssertEqual + \ [ + \ { + \ 'lnum': 13, + \ 'col': 90, + \ 'type': 'E', + \ 'text': 'leonard.exclamation.30ppm More than 30 ppm of exclamations. Keep them under control.', + \ }, + \ ], + \ ale#handlers#unix#HandleAsError(42, [ + \ '/Users/rrj/Notes/Astro/Taurus December SM.txt:13:90: leonard.exclamation.30ppm More than 30 ppm of exclamations. Keep them under control.', + \ ]) + +Execute (HandleUnixFormatAsWarning should handle some example lines of output): + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'missing argument for Printf("%s"): format reads arg 2, have only 1 args', + \ }, + \ { + \ 'lnum': 53, + \ 'col': 10, + \ 'type': 'W', + \ 'text': '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)', + \ }, + \ ], + \ ale#handlers#unix#HandleAsWarning(42, [ + \ '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)', + \ ]) + +Execute (Unix format functions should handle Windows paths): + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'foo', + \ }, + \ { + \ 'lnum': 53, + \ 'col': 10, + \ 'type': 'E', + \ 'text': 'foo', + \ }, + \ ], + \ ale#handlers#unix#HandleAsError(42, [ + \ 'C:\Users\w0rp\AppData\Local\Temp\Xyz123.go:27: foo', + \ 'C:\Users\w0rp\AppData\Local\Temp\Xyz123.go:53:10: foo', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_cookstyle_handler.vader b/vim-config/plugins/ale/test/handler/test_cookstyle_handler.vader new file mode 100644 index 00000000..7d705a19 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_cookstyle_handler.vader @@ -0,0 +1,22 @@ +Before: + runtime ale_linters/chef/cookstyle.vim + +After: + call ale#linter#Reset() + +Execute(Basic warnings should be handled): + AssertEqual + \ [ + \ { + \ 'lnum': 58, + \ 'col': 24, + \ 'code': 'Style/UnneededInterpolation', + \ 'type': 'W', + \ 'end_col': 40, + \ 'text': 'Style/UnneededInterpolation: Prefer `to_s` over string interpolation.', + \ } + \ ], + \ ale_linters#chef#cookstyle#Handle(bufnr(''), [ + \ '{"metadata":{"rubocop_version":"0.62.0","ruby_engine":"ruby","ruby_version":"2.6.0","ruby_patchlevel":"0","ruby_platform":"x86_64-linux"},"files":[{"path":"recipes/default.rb","offenses":[{"severity":"convention","message":"Style/UnneededInterpolation: Prefer `to_s` over string interpolation.","cop_name":"Style/UnneededInterpolation","corrected":false,"location":{"start_line":58,"start_column":24,"last_line":58,"last_column":40,"length":17,"line":58,"column":24}}]}],"summary":{"offense_count":1,"target_file_count":1,"inspected_file_count":1}}' + \ ]) + diff --git a/vim-config/plugins/ale/test/handler/test_cppcheck_handler.vader b/vim-config/plugins/ale/test/handler/test_cppcheck_handler.vader new file mode 100644 index 00000000..2a740722 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_cppcheck_handler.vader @@ -0,0 +1,76 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/handler') + +After: + call ale#test#RestoreDirectory() + +Execute(Basic errors should be handled by cppcheck): + call ale#test#SetFilename('test.cpp') + + AssertEqual + \ [ + \ { + \ 'lnum': 974, + \ 'col' : 6, + \ 'type': 'E', + \ 'sub_type': '', + \ 'text': 'Array ''n[3]'' accessed at index 3, which is out of bounds.', + \ 'code': 'arrayIndexOutOfBounds' + \ }, + \ { + \ 'lnum': 1185, + \ 'col' : 10, + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'The scope of the variable ''indxStr'' can be reduced.', + \ 'code': 'variableScope' + \ }, + \ ], + \ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [ + \ 'test.cpp:974:6: error: Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\', + \ ' n[3]=3;', + \ ' ^', + \ 'test.cpp:1185:10: style: The scope of the variable ''indxStr'' can be reduced. [variableScope]\', + \ ' char indxStr[16];', + \ ' ^', + \ ]) + + AssertEqual + \ [ + \ { + \ 'lnum': 974, + \ 'col' : 1, + \ 'type': 'E', + \ 'sub_type': '', + \ 'text': 'inconclusive Array ''n[3]'' accessed at index 3, which is out of bounds.', + \ 'code': 'arrayIndexOutOfBounds' + \ }, + \ { + \ 'lnum': 1185, + \ 'col' : 1, + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'The scope of the variable ''indxStr'' can be reduced.', + \ 'code': 'variableScope' + \ }, + \ ], + \ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [ + \ 'test.cpp:974:{column}: error:inconclusive Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\', + \ ' n[3]=3;', + \ ' ^', + \ 'test.cpp:1185:{column}: style:{inconclusive:inconclusive} The scope of the variable ''indxStr'' can be reduced. [variableScope]\', + \ ' char indxStr[16];', + \ ' ^', + \ ]) + +Execute(Problems from other files should be ignored by cppcheck): + call ale#test#SetFilename('test.cpp') + + AssertEqual + \ [ + \ ], + \ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [ + \ 'bar.cpp:974:6: error: Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\', + \ ' n[3]=3;', + \ ' ^', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_cpplint_handler.vader b/vim-config/plugins/ale/test/handler/test_cpplint_handler.vader new file mode 100644 index 00000000..d8d7b8b7 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_cpplint_handler.vader @@ -0,0 +1,29 @@ +Before: + runtime ale_linters/cpp/cpplint.vim + +After: + call ale#linter#Reset() + +Execute(cpplint warnings from included files should be parsed correctly): + + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 0, + \ 'text': 'Extra space after ( in function call', + \ 'code': 'whitespace/parents', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 120, + \ 'col': 0, + \ 'text': 'At least two spaces is best between code and comments', + \ 'code': 'whitespace/comments', + \ 'type': 'W', + \ }, + \ ], + \ ale#handlers#cpplint#HandleCppLintFormat(347, [ + \ 'test.cpp:5: Extra space after ( in function call [whitespace/parents] [4]', + \ 'keymap_keys.hpp:120: At least two spaces is best between code and comments [whitespace/comments] [2]', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_credo_handler.vader b/vim-config/plugins/ale/test/handler/test_credo_handler.vader new file mode 100644 index 00000000..1fd54bb5 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_credo_handler.vader @@ -0,0 +1,53 @@ +Before: + runtime ale_linters/elixir/credo.vim + +After: + call ale#linter#Reset() + +Execute(The credo handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 347, + \ 'lnum': 1, + \ 'col': 24, + \ 'text': 'This code can be refactored', + \ 'type': 'W', + \ }, + \ { + \ 'bufnr': 347, + \ 'lnum': 1, + \ 'col': 4, + \ 'text': 'There is no whitespace around parentheses/brackets most of the time, but here there is.', + \ 'type': 'W', + \ }, + \ { + \ 'bufnr': 347, + \ 'lnum': 5, + \ 'col': 21, + \ 'text': 'TODO comment', + \ 'type': 'I', + \ }, + \ { + \ 'bufnr': 347, + \ 'lnum': 26, + \ 'col': 0, + \ 'text': 'If/else blocks should not have a negated condition in `if`.', + \ 'type': 'I', + \ }, + \ { + \ 'bufnr': 347, + \ 'lnum': 15, + \ 'col': 1, + \ 'text': 'Warning in the code', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#elixir#credo#Handle(347, [ + \ 'This line should be ignored completely', + \ 'lib/my_code/test.ex:1:24: F: This code can be refactored', + \ 'lib/filename.ex:1:4: C: There is no whitespace around parentheses/brackets most of the time, but here there is.', + \ 'lib/my_code/test.ex:5:21: D: TODO comment', + \ 'lib/phoenix/channel.ex:26: R: If/else blocks should not have a negated condition in `if`.', + \ 'lib/my_code/test.ex:15:1: W: Warning in the code', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_crystal_handler.vader b/vim-config/plugins/ale/test/handler/test_crystal_handler.vader new file mode 100644 index 00000000..209632e9 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_crystal_handler.vader @@ -0,0 +1,28 @@ +Before: + runtime ale_linters/crystal/crystal.vim + +After: + call ale#linter#Reset() + +Execute(The crystal handler should parse lines correctly and add the column if it can): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'unexpected token: EOF' + \ } + \ ], + \ ale_linters#crystal#crystal#Handle(255, [ + \ '[{"file":"/tmp/test.cr","line":2,"column":1,"size":null,"message":"unexpected token: EOF"}]' + \ ]) + +Execute(The crystal handler should not fail when a missing file is required): + AssertEqual + \ [ { 'lnum':1, 'col': 1, 'text': 'while requiring "./nonexistent.cr"' } ], + \ ale_linters#crystal#crystal#Handle(255, + \ json_encode([ + \ { "file":"/tmp/file.cr","line":1,"column":1,"size":0,"message":"while requiring \"./nonexistent.cr\"" }, + \ { "message": "can't find file './nonexistent.cr' relative to '/tmp'" }, + \ ]) + \ ) diff --git a/vim-config/plugins/ale/test/handler/test_csc_handler.vader b/vim-config/plugins/ale/test/handler/test_csc_handler.vader new file mode 100644 index 00000000..3db5b6fd --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_csc_handler.vader @@ -0,0 +1,98 @@ +Before: + Save g:ale_cs_csc_source + + unlet! g:ale_cs_csc_source + + call ale#test#SetDirectory('/testplugin/test/handler') + call ale#test#SetFilename('Test.cs') + + runtime ale_linters/cs/csc.vim + +After: + unlet! g:ale_cs_csc_source + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The csc handler should work with the default of the buffer's directory): + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'col' : 29, + \ 'text': '; expected', + \ 'code': 'CS1001', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(g:dir . '/Test.cs'), + \ }, + \ ], + \ ale_linters#cs#csc#Handle(bufnr(''), [ + \ 'Test.cs(12,29): error CS1001: ; expected', + \ 'Compilation failed: 2 error(s), 1 warnings', + \ ]) + +Execute(The csc handler should handle cannot find symbol errors): + let g:ale_cs_csc_source = '/home/foo/project/bar' + + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'col' : 29, + \ 'text': '; expected', + \ 'code': 'CS1001', + \ 'type': 'E', + \ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'), + \ }, + \ { + \ 'lnum': 101, + \ 'col': 0, + \ 'text': 'Unexpected processor directive (no #if for this #endif)', + \ 'code': 'CS1028', + \ 'type': 'E', + \ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'), + \ }, + \ { + \ 'lnum': 10, + \ 'col': 12, + \ 'text': 'some warning', + \ 'code': 'CS0123', + \ 'type': 'W', + \ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'), + \ }, + \ ], + \ ale_linters#cs#csc#Handle(bufnr(''), [ + \ 'Test.cs(12,29): error CS1001: ; expected', + \ 'Test.cs(101,0): error CS1028: Unexpected processor directive (no #if for this #endif)', + \ 'Test.cs(10,12): warning CS0123: some warning', + \ 'Compilation failed: 2 error(s), 1 warnings', + \ ]) + +Execute(The csc handler should handle non file specific compiler errors without reporting overal status report as error): + let g:ale_cs_csc_source = '/home/foo/project/bar' + + AssertEqual + \ [ + \ { + \ 'lnum': -1, + \ 'col' : -1, + \ 'text': 'No source files specified.', + \ 'code': 'CS2008', + \ 'type': 'W', + \ 'filename': '', + \ }, + \ { + \ 'lnum': -1, + \ 'col': -1, + \ 'text': 'Outputs without source must have the /out option specified', + \ 'code': 'CS1562', + \ 'type': 'E', + \ 'filename': '', + \ }, + \ ], + \ ale_linters#cs#csc#Handle(bufnr(''), [ + \ 'Microsoft (R) Visual C# Compiler version 2.8.2.62916 (2ad4aabc)', + \ 'Copyright (C) Microsoft Corporation. All rights reserved.', + \ 'warning CS2008: No source files specified.', + \ 'error CS1562: Outputs without source must have the /out option specified', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_cucumber_handler.vader b/vim-config/plugins/ale/test/handler/test_cucumber_handler.vader new file mode 100644 index 00000000..2b69a784 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_cucumber_handler.vader @@ -0,0 +1,18 @@ +Before: + runtime ale_linters/cucumber/cucumber.vim + +After: + call ale#linter#Reset() + +Execute(The cucumber handler parses JSON correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 13, + \ 'code': 'E', + \ 'text': 'Undefined step' + \ } + \ ], + \ ale_linters#cucumber#cucumber#Handle(bufnr(''), [ + \ '[{"elements": [{"steps": [{"result": {"status": "undefined"},"match": {"location": "features/cuke.feature:13"},"line": 13,"name": "Something undefined","keyword": "Given "},{"result": {"status": "skipped"},"match": {"location": "/var/lib/gems/2.3.0/gems/cucumber-3.1.0/lib/cucumber/step_match.rb:103"},"line": 14,"name": "I visit the profile page for Alice","keyword": "When "}],"type": "scenario","line": 12,"description": "","name": "Another scenario","keyword": "Scenario","id": "a-user-can-view-another-users-profile;another-scenario"}],"line": 1,"description": "","name": "A user can view another users profile","keyword": "Feature","id": "a-user-can-view-another-users-profile","uri": "features/cuke.feature"}]' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_cuda_nvcc_handler.vader b/vim-config/plugins/ale/test/handler/test_cuda_nvcc_handler.vader new file mode 100644 index 00000000..40e31922 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_cuda_nvcc_handler.vader @@ -0,0 +1,41 @@ +Before: + runtime ale_linters/cuda/nvcc.vim + +After: + call ale#linter#Reset() + +Execute(The cuda nvcc handler should parse errors from multiple files for NVCC 8.0): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': 'this declaration has no storage class or type specifier', + \ 'filename': has('win32') + \ ? 'C:\tmp\cudatest\test.cu' + \ : '/tmp/cudatest/test.cu', + \ }, + \ { + \ 'lnum': 2, + \ 'type': 'E', + \ 'text': 'attribute "global" does not apply here', + \ 'filename': has('win32') + \ ? 'C:\tmp\cudatest\common.h' + \ : '/tmp/cudatest/common.h', + \ }, + \ { + \ 'lnum': 2, + \ 'type': 'E', + \ 'text': 'expected a ";"', + \ 'filename': has('win32') + \ ? 'C:\tmp\cudatest\common.h' + \ : '/tmp/cudatest/common.h', + \ }, + \ ], + \ ale_linters#cuda#nvcc#HandleNVCCFormat(0, [ + \ '/tmp/cudatest/test.cu(1): error: this declaration has no storage class or type specifier', + \ '/tmp/cudatest/common.h(2): error: attribute "global" does not apply here', + \ '/tmp/cudatest/common.h(2): error: expected a ";"', + \ 'At end of source: warning: parsing restarts here after previous syntax error', + \ '3 errors detected in the compilation of "/tmp/tmpxft_00003a9f_00000000-7_test.cpp1.ii".', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_cypher_lint_handler.vader b/vim-config/plugins/ale/test/handler/test_cypher_lint_handler.vader new file mode 100644 index 00000000..066adae4 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_cypher_lint_handler.vader @@ -0,0 +1,21 @@ +Before: + runtime ale_linters/cypher/cypher_lint.vim + +After: + call ale#linter#Reset() + +Execute(The cypher-lint handler should handle errors for the current file correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 75, + \ 'type': 'E', + \ 'text': "Invalid input ',': expected an identifier, shortestPath, allShortestPaths or '('", + \ }, + \ ], + \ ale_linters#cypher#cypher_lint#Handle(bufnr(''), [ + \ "shakespeare.cql:1:75: Invalid input ',': expected an identifier, shortestPath, allShortestPaths or '('", + \ "CREATE (shakespeare:Author {firstname:'William', lastname:'Shakespeare'}),,", + \ " ^", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_dafny_handler.vader b/vim-config/plugins/ale/test/handler/test_dafny_handler.vader new file mode 100644 index 00000000..4ca288d2 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_dafny_handler.vader @@ -0,0 +1,36 @@ +Before: + runtime ale_linters/dafny/dafny.vim + +After: + call ale#linter#Reset() + +Execute(The Dafny handler should parse output correctly): + AssertEqual + \ [ + \ { + \ 'filename': 'File.dfy', + \ 'col': 45, + \ 'lnum': 123, + \ 'text': 'A precondition for this call might not hold.', + \ 'type': 'E' + \ }, + \ { + \ 'filename': 'File.dfy', + \ 'col': 90, + \ 'lnum': 678, + \ 'text': 'This is the precondition that might not hold.', + \ 'type': 'W' + \ }, + \ { + \ 'filename': 'File.dfy', + \ 'col': 45, + \ 'lnum': 123, + \ 'text': "Verification of 'Impl$$_22_Proof.__default.PutKeepsMapsFull' timed out after 2 seconds", + \ 'type': 'E' + \ }, + \ ], + \ ale_linters#dafny#dafny#Handle(0, [ + \ 'File.dfy(123,45): Error BP5002: A precondition for this call might not hold.', + \ 'File.dfy(678,90): Related location: This is the precondition that might not hold.', + \ "File.dfy(123,45): Verification of 'Impl$$_22_Proof.__default.PutKeepsMapsFull' timed out after 2 seconds", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_dart_analyze_handler.vader b/vim-config/plugins/ale/test/handler/test_dart_analyze_handler.vader new file mode 100644 index 00000000..b3f20fb8 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_dart_analyze_handler.vader @@ -0,0 +1,28 @@ +Before: + runtime ale_linters/dart/dart_analyze.vim + +After: + call ale#linter#Reset() + +Execute(Basic problems should be parsed correctly): + AssertEqual + \ [ + \ { + \ 'type': 'E', + \ 'text': 'expected_token: Expected to find ''}''', + \ 'lnum': 5, + \ 'col': 1, + \ }, + \ { + \ 'type': 'W', + \ 'text': 'invalid_assignment: A value of type ''String'' can''t be assigned to a variable of type ''int''', + \ 'lnum': 2, + \ 'col': 16, + \ }, + \ ], + \ ale_linters#dart#dart_analyze#Handle(bufnr(''), [ + \ 'Analyzing main.dart...', + \ ' error - main.dart:5:1 - Expected to find ''}'' - expected_token', + \ ' warning - main.dart:2:16 - A value of type ''String'' can''t be assigned to a variable of type ''int'' - invalid_assignment', + \ '1 error and 1 warning found.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_dartanalyzer_handler.vader b/vim-config/plugins/ale/test/handler/test_dartanalyzer_handler.vader new file mode 100644 index 00000000..954850c5 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_dartanalyzer_handler.vader @@ -0,0 +1,28 @@ +Before: + runtime ale_linters/dart/dartanalyzer.vim + +After: + call ale#linter#Reset() + +Execute(Basic problems should be parsed correctly): + AssertEqual + \ [ + \ { + \ 'type': 'E', + \ 'text': 'expected_token: Expected to find ''}''', + \ 'lnum': 5, + \ 'col': 1, + \ }, + \ { + \ 'type': 'W', + \ 'text': 'invalid_assignment: A value of type ''String'' can''t be assigned to a variable of type ''int''', + \ 'lnum': 2, + \ 'col': 16, + \ }, + \ ], + \ ale_linters#dart#dartanalyzer#Handle(bufnr(''), [ + \ 'Analyzing main.dart...', + \ ' error • Expected to find ''}'' at main.dart:5:1 • expected_token', + \ ' warning • A value of type ''String'' can''t be assigned to a variable of type ''int'' at main.dart:2:16 • invalid_assignment', + \ '1 error and 1 warning found.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_debride_handler.vader b/vim-config/plugins/ale/test/handler/test_debride_handler.vader new file mode 100644 index 00000000..62851468 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_debride_handler.vader @@ -0,0 +1,27 @@ +Before: + runtime ale_linters/ruby/debride.vim + +After: + call ale#linter#Reset() + +Execute(The debride linter parses output correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'text': 'Possible unused method: image_tags', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 7, + \ 'text': 'Possible unused method: not_deleted', + \ 'type': 'W', + \ } + \ ], + \ ale_linters#ruby#debride#HandleOutput(0, [ + \ 'These methods MIGHT not be called:', + \ '', + \ 'Image', + \ ' image_tags app/models/image.rb:2', + \ ' not_deleted app/models/image.rb:7' + \]) diff --git a/vim-config/plugins/ale/test/handler/test_desktop_file_validate_handler.vader b/vim-config/plugins/ale/test/handler/test_desktop_file_validate_handler.vader new file mode 100644 index 00000000..88163433 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_desktop_file_validate_handler.vader @@ -0,0 +1,26 @@ +Before: + runtime ale_linters/desktop/desktop_file_validate.vim + +After: + call ale#linter#Reset() + +Execute(The desktop-file-validate handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'W', + \ 'text': 'key "TerminalOptions" in group "Desktop Entry" is deprecated', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'action "new-private-window" is defined, but there is no matching "Desktop Action new-private-window" group', + \ }, + \ ], + \ ale_linters#desktop#desktop_file_validate#Handle(bufnr(''), [ + \ 'foo.desktop: warning: key "TerminalOptions" in group "Desktop Entry" is deprecated', + \ 'foo.desktop: error: action "new-private-window" is defined, but there is no matching "Desktop Action new-private-window" group', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_dmd_handler.vader b/vim-config/plugins/ale/test/handler/test_dmd_handler.vader new file mode 100644 index 00000000..32a04982 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_dmd_handler.vader @@ -0,0 +1,41 @@ +Before: + runtime ale_linters/d/dmd.vim + call ale#test#SetDirectory('/testplugin/test/dmd') + call ale#test#SetFilename('test.d') + +After: + call ale#linter#Reset() + call ale#test#RestoreDirectory() + +Execute(Basic errors should be handled by dmd): + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Simplify(g:dir . '/test.d'), + \ 'lnum': '5', + \ 'col' : '8', + \ 'type': 'E', + \ 'text': 'module weak_reference is in file ''dstruct/weak_reference.d'' which cannot be read' + \ }, + \ { + \ 'filename': ale#path#Simplify(g:dir . '/test.d'), + \ 'lnum': '20', + \ 'col' : '10', + \ 'type': 'W', + \ 'text': 'function test.thisoldfunc is deprecated' + \ }, + \ { + \ 'filename': ale#path#Simplify(g:dir . '/foo.d'), + \ 'lnum': '230', + \ 'col' : '9', + \ 'type': 'W', + \ 'text': 'statement is not reachable' + \ } + \ ], + \ ale_linters#d#dmd#Handle(bufnr(''), [ + \ 'test.d(5,8): Error: module weak_reference is in file ''dstruct/weak_reference.d'' which cannot be read', + \ 'import path[0] = source', + \ 'import path[1] = /usr/include/dlang/dmd', + \ ale#path#Simplify(g:dir . '/test.d') . '(20,10): Deprecation: function test.thisoldfunc is deprecated', + \ 'foo.d(230,9): Warning: statement is not reachable', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_dockerfile_lint_handler.vader b/vim-config/plugins/ale/test/handler/test_dockerfile_lint_handler.vader new file mode 100644 index 00000000..a73db8cd --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_dockerfile_lint_handler.vader @@ -0,0 +1,112 @@ +Before: + runtime ale_linters/dockerfile/dockerfile_lint.vim + +After: + call ale#linter#Reset() + +Execute(The dockerfile_lint handler should handle broken JSON): + AssertEqual + \ [], + \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), ["{asdf"]) + +Execute(The dockerfile_lint handler should handle an empty string response): + AssertEqual + \ [], + \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), []) + +Execute(The dockerfile_lint handler should handle an empty result, even if it shouldn't happen): + AssertEqual + \ [], + \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), ["{}"]) + +Execute(The dockerfile_lint handler should handle a normal example): + AssertEqual + \ [ + \ { + \ 'lnum': -1, + \ 'type': 'E', + \ 'text': "Required LABEL name/key 'Name' is not defined", + \ 'detail': "Required LABEL name/key 'Name' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project", + \ }, + \ { + \ 'lnum': -1, + \ 'type': 'E', + \ 'text': "Required LABEL name/key 'Version' is not defined", + \ 'detail': "Required LABEL name/key 'Version' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project", + \ }, + \ { + \ 'lnum': 3, + \ 'type': 'I', + \ 'text': "the MAINTAINER command is deprecated", + \ 'detail': "the MAINTAINER command is deprecated\n\nMAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0\n\nhttps://github.com/docker/cli/blob/master/docs/deprecated.md#maintainer-in-dockerfile", + \ }, + \ { + \ 'lnum': -1, + \ 'type': 'I', + \ 'text': "There is no 'CMD' instruction", + \ 'detail': "There is no 'CMD' instruction\n\nhttps://docs.docker.com/engine/reference/builder/#cmd", + \ }, + \ ], + \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), [ + \ '{', + \ ' "error": {', + \ ' "count": 2,', + \ ' "data": [', + \ ' {', + \ " \"message\": \"Required LABEL name/key 'Name' is not defined\",", + \ ' "line": -1,', + \ ' "level": "error",', + \ ' "lineContent": "",', + \ ' "reference_url": [', + \ ' "http://docs.projectatomic.io/container-best-practices/#",', + \ ' "_recommended_labels_for_your_project"', + \ ' ]', + \ ' },', + \ ' {', + \ " \"message\": \"Required LABEL name/key 'Version' is not defined\",", + \ ' "line": -1,', + \ ' "level": "error",', + \ ' "lineContent": "",', + \ ' "reference_url": [', + \ ' "http://docs.projectatomic.io/container-best-practices/#",', + \ ' "_recommended_labels_for_your_project"', + \ ' ]', + \ ' }', + \ ' ]', + \ ' },', + \ ' "warn": {', + \ ' "count": 0,', + \ ' "data": []', + \ ' },', + \ ' "info": {', + \ ' "count": 2,', + \ ' "data": [', + \ ' {', + \ ' "label": "maintainer_deprecated",', + \ ' "regex": {},', + \ ' "level": "info",', + \ ' "message": "the MAINTAINER command is deprecated",', + \ ' "description": "MAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0",', + \ ' "reference_url": [', + \ ' "https://github.com/docker/cli/blob/master/docs/deprecated.md",', + \ ' "#maintainer-in-dockerfile"', + \ ' ],', + \ ' "lineContent": "MAINTAINER Alexander Olofsson ",', + \ ' "line": 3', + \ ' },', + \ ' {', + \ ' "instruction": "CMD",', + \ ' "count": 1,', + \ ' "level": "info",', + \ " \"message\": \"There is no 'CMD' instruction\",", + \ ' "description": "None",', + \ ' "reference_url": [', + \ ' "https://docs.docker.com/engine/reference/builder/",', + \ ' "#cmd"', + \ ' ]', + \ ' }', + \ ' ]', + \ ' },', + \ ' "summary": []', + \ '}', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_dogma_handler.vader b/vim-config/plugins/ale/test/handler/test_dogma_handler.vader new file mode 100644 index 00000000..ead6d09f --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_dogma_handler.vader @@ -0,0 +1,30 @@ +Before: + runtime ale_linters/elixir/dogma.vim + +After: + call ale#linter#Reset() + +Execute(The dogma handler should parse lines correctly): + + AssertEqual + \ [ + \ { + \ 'bufnr': 347, + \ 'lnum': 18, + \ 'col': 5, + \ 'text': 'Some error', + \ 'type': 'E', + \ }, + \ { + \ 'bufnr': 347, + \ 'lnum': 19, + \ 'col': 7, + \ 'text': 'Some warning', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#elixir#dogma#Handle(347, [ + \ 'This line should be ignored completely', + \ 'lib/filename.ex:18:5: C: Some error', + \ 'lib/filename.ex:19:7: R: Some warning', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_drafter_handler.vader b/vim-config/plugins/ale/test/handler/test_drafter_handler.vader new file mode 100644 index 00000000..1524dde1 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_drafter_handler.vader @@ -0,0 +1,37 @@ +Before: + runtime! ale_linters/apiblueprint/drafter.vim + +After: + call ale#linter#Reset() + +Execute(drafter handler should handle errors output): + AssertEqual + \ [ + \ { + \ 'lnum': 25, + \ 'col': 3, + \ 'text': "unable to parse response signature, expected 'response [] [()]'", + \ 'type': "W", + \ }, + \ { + \ 'lnum': 25, + \ 'col': 3, + \ 'text': "missing response HTTP status code, assuming 'Response 200'", + \ 'type': "W", + \ }, + \ { + \ 'lnum': 30, + \ 'col': 7, + \ 'end_lnum': 32, + \ 'end_col': 7, + \ 'text': "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", + \ 'type': "W", + \ }, + \ ], + \ ale_linters#apiblueprint#drafter#HandleErrors(bufnr(''), [ + \ "", + \ "OK.", + \ "warning: (3) unable to parse response signature, expected 'response [] [()]'; line 25, column 3 - line 25, column 29", + \ "warning: (6) missing response HTTP status code, assuming 'Response 200'; line 25, column 3 - line 25, column 29", + \ "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 7 - line 30, column 11; line 31, column 6 - line 31, column 7; line 32, column 6 - line 32, column 7" + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_elmmake_handler.vader b/vim-config/plugins/ale/test/handler/test_elmmake_handler.vader new file mode 100644 index 00000000..f5906a8b --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_elmmake_handler.vader @@ -0,0 +1,299 @@ +Before: + runtime ale_linters/elm/make.vim + +After: + unlet! g:config_error_lines + + call ale#linter#Reset() + + +" Elm 0.19 + +Execute(The elm-make handler should parse Elm 0.19 general problems correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': "error details\n\nstyled details" + \ } + \ ], + \ ale_linters#elm#make#Handle(347, [ + \ json_encode({ + \ 'type': 'error', + \ 'path': ale#util#Tempname() . '/Module.elm', + \ 'title': 'UNKNOWN IMPORT', + \ 'message': ["error details\n\n", { 'string': 'styled details' }] + \ }), + \ ]) + +Execute(The elm-make handler should parse Elm 0.19 compilation errors correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 404, + \ 'col': 1, + \ 'end_lnum': 408, + \ 'end_col': 18, + \ 'type': 'E', + \ 'text': "error details 1\n\nstyled details" + \ }, + \ { + \ 'lnum': 406, + \ 'col': 5, + \ 'end_lnum': 407, + \ 'end_col': 17, + \ 'type': 'E', + \ 'text': 'error details 2', + \ }, + \ { + \ 'lnum': 406, + \ 'col': 5, + \ 'end_lnum': 406, + \ 'end_col': 93, + \ 'type': 'E', + \ 'text': 'error details 3', + \ }, + \ ], + \ ale_linters#elm#make#Handle(347, [ + \ json_encode({ + \ 'type': 'compile-errors', + \ 'errors': [ + \ { + \ 'path': ale#util#Tempname() . '/Module.elm', + \ 'problems': [ + \ { + \ 'title': 'TYPE MISMATCH', + \ 'message': ["error details 1\n\n", { 'string': 'styled details' }], + \ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } } + \ }, + \ { + \ 'title': 'TYPE MISMATCH', + \ 'message': ['error details 2'], + \ 'region': { 'start': {'line': 406, 'column': 5}, 'end': {'line': 407, 'column': 17 } } + \ }, + \ { + \ 'title': 'TYPE MISMATCH', + \ 'message': ['error details 3'], + \ 'region': { 'start': { 'line': 406, 'column': 5}, 'end': {'line': 406, 'column': 93 } } + \ } + \ ] + \ } + \ ] + \ }), + \ ]) + +Execute(The elm-make handler should handle errors in Elm 0.19 imported modules): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': "src/Module.elm - error details\n\nstyled details", + \ 'detail': "src/Module.elm ----------\n\nerror details\n\nstyled details" + \ }, + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': "Elm - error details\n\nstyled details", + \ 'detail': "Elm ----------\n\nerror details\n\nstyled details" + \ }, + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': "src/Module.elm:404 - error details\n\nstyled details", + \ 'detail': "src/Module.elm:404 ----------\n\nerror details\n\nstyled details" + \ }, + \ ], + \ ale_linters#elm#make#Handle(347, [ + \ json_encode({ + \ 'type': 'error', + \ 'path': 'src/Module.elm', + \ 'title': 'UNKNOWN IMPORT', + \ 'message': ["error details\n\n", { 'string': 'styled details' }] + \ }), + \ json_encode({ + \ 'type': 'error', + \ 'path': v:null, + \ 'title': 'UNKNOWN IMPORT', + \ 'message': ["error details\n\n", { 'string': 'styled details' }] + \ }), + \ json_encode({ + \ 'type': 'compile-errors', + \ 'errors': [ + \ { + \ 'path': 'src/Module.elm', + \ 'problems': [ + \ { + \ 'title': 'TYPE MISMATCH', + \ 'message': ["error details\n\n", { 'string': 'styled details' }], + \ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } } + \ } + \ ] + \ } + \ ] + \ }), + \ ]) + + +" Elm 0.18 + +Execute(The elm-make handler should parse Elm 0.18 compilation errors correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 33, + \ 'col': 1, + \ 'end_lnum': 33, + \ 'end_col': 19, + \ 'type': 'W', + \ 'text': 'warning overview', + \ 'detail': "warning overview\n\nwarning details", + \ }, + \ { + \ 'lnum': 404, + \ 'col': 1, + \ 'end_lnum': 408, + \ 'end_col': 18, + \ 'type': 'E', + \ 'text': 'error overview 1', + \ 'detail': "error overview 1\n\nerror details 1", + \ }, + \ { + \ 'lnum': 406, + \ 'col': 5, + \ 'end_lnum': 407, + \ 'end_col': 17, + \ 'type': 'E', + \ 'text': 'error overview 2', + \ 'detail': "error overview 2\n\nerror details 2", + \ }, + \ { + \ 'lnum': 406, + \ 'col': 5, + \ 'end_lnum': 406, + \ 'end_col': 93, + \ 'type': 'E', + \ 'text': 'error overview 3', + \ 'detail': "error overview 3\n\nerror details 3", + \ }, + \ ], + \ ale_linters#elm#make#Handle(347, [ + \ json_encode([ + \ { + \ 'tag': 'unused import', + \ 'overview': 'warning overview', + \ 'details': 'warning details', + \ 'region': {'start': { 'line': 33, 'column': 1 }, 'end': { 'line': 33, 'column': 19 } }, + \ 'type': 'warning', + \ 'file': ale#util#Tempname() . '/Module.elm', + \ } + \ ]), + \ json_encode([ + \ { + \ 'tag': 'TYPE MISMATCH', + \ 'overview': 'error overview 1', + \ 'subregion': { 'start': { 'line': 406, 'column': 5 }, 'end': { 'line': 408, 'column': 18 } }, + \ 'details': 'error details 1', + \ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } }, + \ 'type': 'error', + \ 'file': ale#util#Tempname() . '/Module.elm', + \ }, + \ { + \ 'tag': 'TYPE MISMATCH', + \ 'overview': 'error overview 2', + \ 'subregion': { 'start': { 'line': 407, 'column': 12 }, 'end': { 'line': 407, 'column': 17 } }, + \ 'details': 'error details 2', + \ 'region': { 'start': { 'line': 406, 'column': 5}, 'end': { 'line': 407, 'column': 17 } }, + \ 'type':'error', + \ 'file': ale#util#Tempname() . '/Module.elm', + \ }, + \ { + \ 'tag': 'TYPE MISMATCH', + \ 'overview': 'error overview 3', + \ 'subregion': { 'start': { 'line': 406, 'column': 88 }, 'end': { 'line': 406, 'column': 93 } }, + \ 'details': 'error details 3', + \ 'region': { 'start': { 'line': 406, 'column': 5 }, 'end': { 'line': 406, 'column': 93 } }, + \ 'type':'error', + \ 'file': ale#util#Tempname() . '/Module.elm', + \ } + \ ]), + \ ]) + +Execute(The elm-make handler should handle errors in Elm 0.18 imported modules): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': 'src/Module.elm:33 - error overview', + \ 'detail': "src/Module.elm:33 ----------\n\nerror overview\n\nerror details" + \ } + \ ], + \ ale_linters#elm#make#Handle(347, [ + \ json_encode([ + \ { + \ 'tag': 'unused import', + \ 'overview': 'warning overview', + \ 'details': 'warning details', + \ 'region': {'start': { 'line': 33, 'column': 1 }, 'end': { 'line': 33, 'column': 19 } }, + \ 'type': 'warning', + \ 'file': 'src/Module.elm', + \ }, + \ { + \ 'tag': 'type error', + \ 'overview': 'error overview', + \ 'details': 'error details', + \ 'region': {'start': { 'line': 33, 'column': 1 }, 'end': { 'line': 33, 'column': 19 } }, + \ 'type': 'error', + \ 'file': 'src/Module.elm', + \ } + \ ]), + \ ]) + +" Generic + +Execute(The elm-make handler should put an error on the first line if a line cannot be parsed): + AssertEqual + \ [ + \ { + \ 'lnum': 404, + \ 'col': 1, + \ 'end_lnum': 408, + \ 'end_col': 18, + \ 'type': 'E', + \ 'text': "error details 1\n\nstyled details" + \ }, + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': 'Not JSON', + \ 'detail': "Not JSON\nAlso not JSON", + \ }, + \ ], + \ ale_linters#elm#make#Handle(347, [ + \ json_encode({ + \ 'type': 'compile-errors', + \ 'errors': [ + \ { + \ 'path': ale#util#Tempname() . '/Module.elm', + \ 'problems': [ + \ { + \ 'title': 'TYPE MISMATCH', + \ 'message': ["error details 1\n\n", { 'string': 'styled details' }], + \ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } } + \ } + \ ] + \ } + \ ] + \ }), + \ 'Not JSON', + \ 'Also not JSON', + \ ]) + +Execute(The elm-make handler should ignore success lines): + AssertEqual + \ [], + \ ale_linters#elm#make#Handle(347, [ + \ 'Successfully generated /dev/null', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_embertemplatelint_handler.vader b/vim-config/plugins/ale/test/handler/test_embertemplatelint_handler.vader new file mode 100644 index 00000000..97ca4390 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_embertemplatelint_handler.vader @@ -0,0 +1,81 @@ +" Author: Adrian Zalewski +Before: + runtime ale_linters/handlebars/embertemplatelint.vim + +After: + call ale#linter#Reset() + +Execute(The ember-template-lint handler should parse lines correctly): + let input_lines = split('{ + \ "/ember-project/app/templates/application.hbs": [ + \ { + \ "moduleId": "app/templates/application", + \ "rule": "bare-strings", + \ "severity": 2, + \ "message": "Non-translated string used", + \ "line": 1, + \ "column": 10, + \ "source": " Bare String\n" + \ }, + \ { + \ "moduleId": "app/templates/application", + \ "rule": "invalid-interactive", + \ "severity": 1, + \ "message": "Interaction added to non-interactive element", + \ "line": 3, + \ "column": 6, + \ "source": "" + \ } + \ ] + \ }', '\n') + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'text': 'bare-strings: Non-translated string used', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 6, + \ 'text': 'invalid-interactive: Interaction added to non-interactive element', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#handlebars#embertemplatelint#Handle(347, input_lines) + +Execute(The ember-template-lint handler should handle template parsing error correctly): + let input_lines = split('{ + \ "/ember-project/app/templates/application.hbs": [ + \ { + \ "fatal": true, + \ "moduleId": "app/templates/application", + \ "message": "Parse error on line 5 ...", + \ "line": 5, + \ "column": 3, + \ "source": "Error: Parse error on line 5 ...", + \ "severity": 2 + \ } + \ ] + \ }', '\n') + + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 3, + \ 'text': 'Parse error on line 5 ...', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#handlebars#embertemplatelint#Handle(347, input_lines) + +Execute(The ember-template-lint handler should handle no lint errors/warnings): + AssertEqual + \ [], + \ ale_linters#handlebars#embertemplatelint#Handle(347, []) + AssertEqual + \ [], + \ ale_linters#handlebars#embertemplatelint#Handle(347, ['{}']) diff --git a/vim-config/plugins/ale/test/handler/test_erblint_handler.vader b/vim-config/plugins/ale/test/handler/test_erblint_handler.vader new file mode 100644 index 00000000..01d4c0ab --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_erblint_handler.vader @@ -0,0 +1,70 @@ +Before: + runtime ale_linters/eruby/erblint.vim + +After: + unlet! g:lines + call ale#linter#Reset() + +Execute(The erblint handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'col': 0, + \ 'end_col': 0, + \ 'text': 'Extra blank line detected.', + \ 'code': 'ExtraNewline', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 6, + \ 'col': 0, + \ 'end_col': 0, + \ 'text': 'Remove multiple trailing newline at the end of the file.', + \ 'code': 'FinalNewline', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 9, + \ 'end_col': 11, + \ 'text': 'Use 1 space after `<%=` instead of 2 spaces.', + \ 'code': 'SpaceAroundErbTag', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 9, + \ 'end_col': 11, + \ 'text': 'Use 1 space before `%>` instead of 2 spaces.', + \ 'code': 'SpaceAroundErbTag', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 6, + \ 'end_col': 10, + \ 'text': 'Extra whitespace detected at end of line.', + \ 'code': 'TrailingWhitespace', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#eruby#erblint#Handle(347, [ + \ '{"metadata":{"erb_lint_version":"0.1.1","ruby_engine":"ruby","ruby_version":"3.0.2","ruby_patchlevel":"107","ruby_platform":"arm64-darwin20"},"files":[{"path":"demo.html.erb","offenses":[{"linter":"ExtraNewline","message":"Extra blank line detected.","location":{"start_line":3,"start_column":0,"last_line":4,"last_column":0,"length":1}},{"linter":"FinalNewline","message":"Remove multiple trailing newline at the end of the file.","location":{"start_line":6,"start_column":0,"last_line":8,"last_column":0,"length":2}},{"linter":"SpaceAroundErbTag","message":"Use 1 space after `<%=` instead of 2 spaces.","location":{"start_line":4,"start_column":9,"last_line":4,"last_column":11,"length":2}},{"linter":"SpaceAroundErbTag","message":"Use 1 space before `%>` instead of 2 spaces.","location":{"start_line":4,"start_column":9,"last_line":4,"last_column":11,"length":2}},{"linter":"TrailingWhitespace","message":"Extra whitespace detected at end of line.","location":{"start_line":5,"start_column":6,"last_line":5,"last_column":10,"length":4}}]}],"summary":{"offenses":5,"inspected_files":1,"corrected":0}}' + \ ]) + +Execute(The erblint handler should handle when files are checked and no offenses are found): + AssertEqual + \ [], + \ ale_linters#eruby#erblint#Handle(347, [ + \ '{"metadata":{"erb_lint_version":"0.1.1","ruby_engine":"ruby","ruby_version":"3.0.2","ruby_patchlevel":"107","ruby_platform":"arm64-darwin20"},"files":[{"path":"demo.html.erb","offenses":[]}],"summary":{"offenses":0,"inspected_files":1,"corrected":0}}' + \ ]) + +Execute(The erblint handler should handle output without any errors): + AssertEqual + \ [], + \ ale_linters#eruby#erblint#Handle(347, ['{}']) + + AssertEqual + \ [], + \ ale_linters#eruby#erblint#Handle(347, []) diff --git a/vim-config/plugins/ale/test/handler/test_erlang_dialyzer_handler.vader b/vim-config/plugins/ale/test/handler/test_erlang_dialyzer_handler.vader new file mode 100644 index 00000000..afd5c597 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_erlang_dialyzer_handler.vader @@ -0,0 +1,27 @@ +Before: + runtime ale_linters/erlang/dialyzer.vim + +After: + call ale#linter#Reset() + +Execute(The dialyzer handler should handle error messages.): + AssertEqual + \[ + \ { + \ 'lnum': 3, + \ 'lcol': 0, + \ 'text': 'Callback info about the provider behaviour is not available', + \ 'type': 'W' + \ } + \], + \ ale_linters#erlang#dialyzer#Handle(bufnr(''), ['erl_tidy_prv_fmt.erl:3: Callback info about the provider behaviour is not available']) + +Execute(The dialyzer handler should handle empty file.): + AssertEqual + \[], + \ ale_linters#erlang#dialyzer#Handle(bufnr(''), []) + +Execute(The dialyzer handler should handle empty lines.): + AssertEqual + \[], + \ ale_linters#erlang#dialyzer#Handle(bufnr(''), ['']) diff --git a/vim-config/plugins/ale/test/handler/test_erlang_elvis_handler.vader b/vim-config/plugins/ale/test/handler/test_erlang_elvis_handler.vader new file mode 100644 index 00000000..365376c8 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_erlang_elvis_handler.vader @@ -0,0 +1,37 @@ +Before: + runtime ale_linters/erlang/elvis.vim + +After: + call ale#linter#Reset() + +Execute(Warning messages should be handled): + AssertEqual + \ [ + \ { + \ 'lnum': 11, + \ 'text': "Replace the 'if' expression on line 11 with a 'case' expression or function clauses.", + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 20, + \ 'text': 'Remove the debug call to io:format/1 on line 20.', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#erlang#elvis#Handle(bufnr(''), [ + \ "src/foo.erl:11:no_if_expression:Replace the 'if' expression on line 11 with a 'case' expression or function clauses.", + \ 'src/foo.erl:20:no_debug_call:Remove the debug call to io:format/1 on line 20.', + \ ]) + +Execute(Line length message shouldn't contain the line itself): + AssertEqual + \ [ + \ { + \ 'lnum': 24, + \ 'text': 'Line 24 is too long.', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#erlang#elvis#Handle(bufnr(''), [ + \ 'src/foo.erl:24:line_length:Line 24 is too long: io:format("Look ma, too long!"),.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_eslint_handler.vader b/vim-config/plugins/ale/test/handler/test_eslint_handler.vader new file mode 100644 index 00000000..01dd2c8f --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_eslint_handler.vader @@ -0,0 +1,438 @@ +Before: + Save g:ale_javascript_eslint_suppress_eslintignore + Save g:ale_javascript_eslint_suppress_missing_config + Save g:ale_warn_about_trailing_whitespace + Save g:ale_warn_about_trailing_blank_lines + + let g:ale_javascript_eslint_suppress_eslintignore = 0 + let g:ale_javascript_eslint_suppress_missing_config = 0 + let g:ale_warn_about_trailing_whitespace = 1 + let g:ale_warn_about_trailing_blank_lines = 1 + unlet! b:ale_warn_about_trailing_whitespace + unlet! b:ale_warn_about_trailing_blank_lines + +After: + Restore + + unlet! b:ale_javascript_eslint_suppress_eslintignore + unlet! b:ale_javascript_eslint_suppress_missing_config + unlet! b:ale_warn_about_trailing_whitespace + unlet! b:ale_warn_about_trailing_blank_lines + unlet! g:config_error_lines + +Execute(The eslint handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 47, + \ 'col': 14, + \ 'text': 'Missing trailing comma.', + \ 'code': 'comma-dangle', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 56, + \ 'col': 41, + \ 'text': 'Missing semicolon.', + \ 'code': 'semi', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 13, + \ 'col': 3, + \ 'text': 'Parsing error: Unexpected token', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ 'This line should be ignored completely', + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]', + \ 'This line should be ignored completely', + \ '/path/to/some-filename.js:13:3: Parsing error: Unexpected token', + \ ]) + +Execute(The eslint handler should print a message about a missing configuration file): + let g:config_error_lines = [ + \ '', + \ 'Oops! Something went wrong! :(', + \ '', + \ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:', + \ ' eslint --init', + \ '', + \ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.', + \ '', + \ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint', + \ '', + \ ] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should allow the missing config error to be suppressed): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ '', + \ 'Oops! Something went wrong! :(', + \ '', + \ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:', + \ ' eslint --init', + \ '', + \ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.', + \ '', + \ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint', + \ '', + \ ] + + AssertEqual + \ [], + \ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should print a message for config parsing errors): + let g:config_error_lines = [ + \ 'Cannot read config file: /some/path/or/other/.eslintrc.js', + \ 'Error: Unexpected token <<', + \ '/some/path/or/other/.eslintrc.js:1', + \ '(function (exports, require, module, __filename, __dirname) { <<<>>>', + \ ' ^^', + \ 'SyntaxError: Unexpected token <<', + \ ' at Object.exports.runInThisContext (vm.js:76:16)', + \ ' at Module._compile (module.js:528:28)', + \ ' at Object.Module._extensions..js (module.js:565:10)', + \ ' at Module.load (module.js:473:32)', + \ ' at tryModuleLoad (module.js:432:12)', + \ ' at Function.Module._load (module.js:424:3)', + \ ' at Module.require (module.js:483:17)', + \ ' at require (internal/module.js:20:19)', + \ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)', + \ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:]) + +Execute(Suppressing missing configs shouldn't suppress parsing errors): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ 'Cannot read config file: /some/path/or/other/.eslintrc.js', + \ 'Error: Unexpected token <<', + \ '/some/path/or/other/.eslintrc.js:1', + \ '(function (exports, require, module, __filename, __dirname) { <<<>>>', + \ ' ^^', + \ 'SyntaxError: Unexpected token <<', + \ ' at Object.exports.runInThisContext (vm.js:76:16)', + \ ' at Module._compile (module.js:528:28)', + \ ' at Object.Module._extensions..js (module.js:565:10)', + \ ' at Module.load (module.js:473:32)', + \ ' at tryModuleLoad (module.js:432:12)', + \ ' at Function.Module._load (module.js:424:3)', + \ ' at Module.require (module.js:483:17)', + \ ' at require (internal/module.js:20:19)', + \ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)', + \ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should print a message for invalid configuration settings): + let g:config_error_lines = [ + \ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)', + \ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13', + \ ' at Array.forEach (native)', + \ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)', + \ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)', + \ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)', + \ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)', + \ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)', + \ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)', + \ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:]) + +Execute(Suppressing missing configs shouldn't suppress invalid config errors): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)', + \ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13', + \ ' at Array.forEach (native)', + \ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)', + \ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)', + \ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)', + \ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)', + \ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)', + \ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)', + \ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should print a message when import is not used in a module): + let g:config_error_lines = [ + \ 'ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)', + \ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)', + \ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)', + \ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)', + \ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)', + \ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:]) + +Execute(Suppressing missing configs shouldn't suppress module import errors): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ 'ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)', + \ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)', + \ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)', + \ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)', + \ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)', + \ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:]) + + +Execute(The eslint handler should output end_col values where appropriate): + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 3, + \ 'end_col': 15, + \ 'text': 'Parsing error: Unexpected token ''some string''', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 70, + \ 'col': 3, + \ 'end_col': 5, + \ 'text': '''foo'' is not defined.', + \ 'code': 'no-undef', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 71, + \ 'col': 2, + \ 'end_col': 6, + \ 'text': 'Unexpected `await` inside a loop.', + \ 'code': 'no-await-in-loop', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 72, + \ 'col': 6, + \ 'end_col': 10, + \ 'text': 'Redundant use of `await` on a return value.', + \ 'code': 'no-return-await', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 73, + \ 'col': 4, + \ 'end_col': 10, + \ 'text': 'Unexpected console statement', + \ 'code': 'no-console', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 74, + \ 'col': 4, + \ 'end_col': 11, + \ 'text': 'Unexpected ''debugger'' statement.', + \ 'code': 'no-debugger', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ 'app.js:4:3: Parsing error: Unexpected token ''some string'' [Error]', + \ 'app.js:70:3: ''foo'' is not defined. [Error/no-undef]', + \ 'app.js:71:2: Unexpected `await` inside a loop. [Error/no-await-in-loop]', + \ 'app.js:72:6: Redundant use of `await` on a return value. [Error/no-return-await]', + \ 'app.js:73:4: Unexpected console statement [Error/no-console]', + \ 'app.js:74:4: Unexpected ''debugger'' statement. [Error/no-debugger]', + \ ]) + +Execute(The eslint hint about using typescript-eslint-parser): + silent! noautocmd file foo.ts + + AssertEqual + \ [ + \ { + \ 'lnum': 451, + \ 'col': 2, + \ 'end_col': 2, + \ 'text': 'Parsing error (You may need configure typescript-eslint-parser): Unexpected token )', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ 'foo.ts:451:2: Parsing error: Unexpected token ) [Error]', + \ ]) + +Execute(eslint should warn about ignored files by default): + AssertEqual + \ [{ + \ 'lnum': 0, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'File ignored because of a matching ignore pattern. Use "--no-ignore" to override.' + \ }], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ '/path/to/some/ignored.js:0:0: File ignored because of a matching ignore pattern. Use "--no-ignore" to override. [Warning]', + \ ]) + + AssertEqual + \ [{ + \ 'lnum': 0, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'File ignored by default. Use "--ignore-pattern ''!node_modules/*''" to override.', + \ }], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ '/path/to/some/ignored.js:0:0: File ignored by default. Use "--ignore-pattern ''!node_modules/*''" to override. [Warning]', + \ ]) + +Execute(eslint should not warn about ignored files when explicitly disabled): + let g:ale_javascript_eslint_suppress_eslintignore = 1 + + AssertEqual + \ [], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ '/path/to/some/ignored.js:0:0: File ignored because of a matching ignore pattern. Use "--no-ignore" to override. [Warning]', + \ ]) + + AssertEqual + \ [], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ '/path/to/some/ignored.js:0:0: File ignored by default. Use "--ignore-pattern ''!node_modules/*''" to override. [Warning]', + \ ]) + +Execute(eslint should handle react errors correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 59, + \ 'col': 9, + \ 'type': 'E', + \ 'text': 'Property should be placed on the same line as the component declaration', + \ 'code': 'react/jsx-first-prop-new-line', + \ }, + \ ], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ '/path/editor-help.jsx:59:9: Property should be placed on the same line as the component declaration [Error/react/jsx-first-prop-new-line]', + \ ]) + +Execute(Failing to connect to eslint_d should be handled correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.', + \ }, + \ ], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ 'Could not connect', + \ ]) + +Execute(Disabling warnings about trailing spaces should work): + silent! noautocmd file foo.ts + + AssertEqual + \ [ + \ { + \ 'lnum': 182, + \ 'col': 22, + \ 'code': 'no-trailing-spaces', + \ 'type': 'E', + \ 'text': 'Trailing spaces not allowed.', + \ }, + \ ], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ 'foo.js:182:22: Trailing spaces not allowed. [Error/no-trailing-spaces]', + \ ]) + + let g:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ 'foo.js:182:22: Trailing spaces not allowed. [Error/no-trailing-spaces]', + \ ]) + + let g:ale_warn_about_trailing_whitespace = 1 + let b:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ 'foo.js:182:22: Trailing spaces not allowed. [Error/no-trailing-spaces]', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_eslint_json_handler.vader b/vim-config/plugins/ale/test/handler/test_eslint_json_handler.vader new file mode 100644 index 00000000..6235794a --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_eslint_json_handler.vader @@ -0,0 +1,376 @@ +Before: + Save g:ale_javascript_eslint_suppress_eslintignore + Save g:ale_javascript_eslint_suppress_missing_config + Save g:ale_warn_about_trailing_whitespace + Save g:ale_warn_about_trailing_blank_lines + + let g:ale_javascript_eslint_suppress_eslintignore = 0 + let g:ale_javascript_eslint_suppress_missing_config = 0 + let g:ale_warn_about_trailing_whitespace = 1 + let g:ale_warn_about_trailing_blank_lines = 1 + unlet! b:ale_warn_about_trailing_whitespace + unlet! b:ale_warn_about_trailing_blank_lines + +After: + Restore + + unlet! b:ale_javascript_eslint_suppress_eslintignore + unlet! b:ale_javascript_eslint_suppress_missing_config + unlet! b:ale_warn_about_trailing_whitespace + unlet! b:ale_warn_about_trailing_blank_lines + unlet! g:config_error_lines + +Execute(The eslint handler should parse json correctly): + call ale#test#SetFilename('foo.js') + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'end_lnum': 1, + \ 'col': 7, + \ 'end_col': 14, + \ 'text': '''variable'' is assigned a value but never used.', + \ 'code': 'no-unused-vars', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 15, + \ 'text': 'Missing semicolon.', + \ 'code': 'semi', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 7, + \ 'end_lnum': 7, + \ 'col': 7, + \ 'end_col': 14, + \ 'text': '''variable'' is already defined.', + \ 'code': 'no-redeclare', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.js","messages":[{"ruleId":"no-unused-vars","severity":1,"message":"''variable'' is assigned a value but never used.","line":1,"column":7,"nodeType":"Identifier","endLine":1,"endColumn":15},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":15,"nodeType":"ExpressionStatement","fix":{"range":[46,46],"text":";"}},{"ruleId":"no-redeclare","severity":2,"message":"''variable'' is already defined.","line":7,"column":7,"nodeType":"Identifier","endLine":7,"endColumn":15}],"errorCount":1,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":1,"source":"const variable = {\n a: 3\n};\n\nconsole.log(1)\n\nclass variable {\n}\n"}]' + \ ]) + +Execute(The eslint handler should suppress deprecation warnings): + call ale#test#SetFilename('foo.js') + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 9, + \ 'text': 'Parsing error: Unexpected token Controller', + \ 'type': 'E', + \ } + \ ], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.js","messages":[{"ruleId":null,"fatal":true,"severity":2 ,"message":"Parsing error: Unexpected token Controller","line":1,"column":9}],"errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount": 0,"source":"i:mport Controller from \"@ember/controller\";\nimport listViewControllerMixin from \"elearning/mixins/list-view-controller\";\nimport { inject as service } from \"@ember/service\";\n\nexport default Controller.extend(listViewControllerMixin(), {\n modelName: \"notification\",\n intl: service(),\n\n flatpickrLocale: computed(\"intl.locale\", function() {\n return this.intl.locale.firstObject.split(\"-\")[0];\n })\n});\n"}]', '(node:616989) [ESLINT_LEGACY_OBJECT_REST_SPREAD] DeprecationWarning: The ''parserOptions.ecmaFeatures.experimentalObjectRestSpread'' option is deprecated. Use ''parser Options.ecmaVersion'' instead. (found in "node_modules/eslint-plugin-ember/lib/config/base.js")]' + \ ]) + +Execute(The eslint handler should print a message about a missing configuration file): + let g:config_error_lines = [ + \ '', + \ 'Oops! Something went wrong! :(', + \ '', + \ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:', + \ ' eslint --init', + \ '', + \ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.', + \ '', + \ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint', + \ '', + \ ] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should allow the missing config error to be suppressed): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ '', + \ 'Oops! Something went wrong! :(', + \ '', + \ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:', + \ ' eslint --init', + \ '', + \ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.', + \ '', + \ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint', + \ '', + \ ] + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should print a message for config parsing errors): + let g:config_error_lines = [ + \ 'Cannot read config file: /some/path/or/other/.eslintrc.js', + \ 'Error: Unexpected token <<', + \ '/some/path/or/other/.eslintrc.js:1', + \ '(function (exports, require, module, __filename, __dirname) { <<<>>>', + \ ' ^^', + \ 'SyntaxError: Unexpected token <<', + \ ' at Object.exports.runInThisContext (vm.js:76:16)', + \ ' at Module._compile (module.js:528:28)', + \ ' at Object.Module._extensions..js (module.js:565:10)', + \ ' at Module.load (module.js:473:32)', + \ ' at tryModuleLoad (module.js:432:12)', + \ ' at Function.Module._load (module.js:424:3)', + \ ' at Module.require (module.js:483:17)', + \ ' at require (internal/module.js:20:19)', + \ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)', + \ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(Suppressing missing configs shouldn't suppress parsing errors): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ 'Cannot read config file: /some/path/or/other/.eslintrc.js', + \ 'Error: Unexpected token <<', + \ '/some/path/or/other/.eslintrc.js:1', + \ '(function (exports, require, module, __filename, __dirname) { <<<>>>', + \ ' ^^', + \ 'SyntaxError: Unexpected token <<', + \ ' at Object.exports.runInThisContext (vm.js:76:16)', + \ ' at Module._compile (module.js:528:28)', + \ ' at Object.Module._extensions..js (module.js:565:10)', + \ ' at Module.load (module.js:473:32)', + \ ' at tryModuleLoad (module.js:432:12)', + \ ' at Function.Module._load (module.js:424:3)', + \ ' at Module.require (module.js:483:17)', + \ ' at require (internal/module.js:20:19)', + \ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)', + \ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should print a message for invalid configuration settings): + let g:config_error_lines = [ + \ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)', + \ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13', + \ ' at Array.forEach (native)', + \ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)', + \ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)', + \ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)', + \ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)', + \ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)', + \ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)', + \ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(Suppressing missing configs shouldn't suppress invalid config errors): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)', + \ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13', + \ ' at Array.forEach (native)', + \ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)', + \ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)', + \ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)', + \ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)', + \ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)', + \ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)', + \ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should print a message when import is not used in a module): + let g:config_error_lines = [ + \ 'ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)', + \ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)', + \ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)', + \ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)', + \ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)', + \ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(Suppressing missing configs shouldn't suppress module import errors): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ 'ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)', + \ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)', + \ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)', + \ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)', + \ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)', + \ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should hint about using typescript-eslint-parser): + call ale#test#SetFilename('foo.ts') + + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'Parsing error (You may need configure typescript-eslint-parser): The keyword ''interface'' is reserved', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.ts","messages":[{"ruleId":null,"fatal":true,"severity":2,"message":"Parsing error: The keyword ''interface'' is reserved","line":2,"column":1}],"errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"\ninterface test {}\n"}]', + \ ]) + +Execute(eslint should warn about ignored files by default): + AssertEqual + \ [{ + \ 'lnum': 0, + \ 'type': 'W', + \ 'text': 'File ignored because of a matching ignore pattern. Use "--no-ignore" to override.' + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]', + \ ]) + + AssertEqual + \ [{ + \ 'lnum': 0, + \ 'type': 'W', + \ 'text': 'File ignored by default. Use "--ignore-pattern ''!node_modules/*''" to override.', + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored by default. Use \"--ignore-pattern ''!node_modules/*''\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]', + \ ]) + +Execute(eslint should not warn about ignored files when explicitly disabled): + let g:ale_javascript_eslint_suppress_eslintignore = 1 + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]', + \ ]) + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored by default. Use \"--ignore-pattern ''!node_modules/*''\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]', + \ ]) + +Execute(Failing to connect to eslint_d should be handled correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.', + \ }, + \ ], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ 'Could not connect', + \ ]) + +Execute(Disabling warnings about trailing spaces should work): + call ale#test#SetFilename('foo.js') + + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 16, + \ 'code': 'no-trailing-spaces', + \ 'type': 'W', + \ 'text': 'Trailing spaces not allowed.', + \ }, + \ ], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.js","messages":[{"ruleId":"no-trailing-spaces","severity":1,"message":"Trailing spaces not allowed.","line":2,"column":16,"nodeType":"Program","fix":{"range":[16,17],"text":""}}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"\nconsole.log(1); \n"}]' + \ ]) + + let g:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.js","messages":[{"ruleId":"no-trailing-spaces","severity":1,"message":"Trailing spaces not allowed.","line":2,"column":16,"nodeType":"Program","fix":{"range":[16,17],"text":""}}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"\nconsole.log(1); \n"}]' + \ ]) + + let g:ale_warn_about_trailing_whitespace = 1 + let b:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.js","messages":[{"ruleId":"no-trailing-spaces","severity":1,"message":"Trailing spaces not allowed.","line":2,"column":16,"nodeType":"Program","fix":{"range":[16,17],"text":""}}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"\nconsole.log(1); \n"}]' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_fecs_handler.vader b/vim-config/plugins/ale/test/handler/test_fecs_handler.vader new file mode 100644 index 00000000..7c216b8d --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_fecs_handler.vader @@ -0,0 +1,35 @@ +Before: + runtime autoload/ale/handlers/fecs.vim + +After: + call ale#linter#Reset() + +Execute(fecs should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 20, + \ 'col': 25, + \ 'text': 'Unexpected console statement.', + \ 'code': 'no-console', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 24, + \ 'col': 36, + \ 'text': 'Missing radix parameter.', + \ 'code': 'radix', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 25, + \ 'col': 6, + \ 'text': 'Missing static property value.', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#fecs#Handle(347, [ + \ 'fecs WARN → line 20, col 25: Unexpected console statement. (no-console)', + \ 'fecs ERROR → line 24, col 36: Missing radix parameter. (radix)', + \ 'fecs ERROR → line 25, col 6: Missing static property value.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_fish_handler.vader b/vim-config/plugins/ale/test/handler/test_fish_handler.vader new file mode 100644 index 00000000..ad3a963c --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_fish_handler.vader @@ -0,0 +1,61 @@ +Before: + runtime ale_linters/fish/fish.vim + +After: + call ale#linter#Reset() + +Execute(The fish handler should handle basic warnings and syntax errors): + AssertEqual + \ [ + \ { + \ 'lnum': 20, + \ 'col': 23, + \ 'text': "Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'.", + \ }, + \ { + \ 'lnum': 26, + \ 'col': 7, + \ 'text': "Illegal command name '(prompt_pwd)'", + \ }, + \ { + \ 'lnum': 36, + \ 'col': 1, + \ 'text': "'end' outside of a block", + \ }, + \ ], + \ ale_linters#fish#fish#Handle(1, [ + \ "fish_prompt.fish (line 20): Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'.", + \ 'if set -q SSH_CLIENT || set -q SSH_TTY', + \ ' ^', + \ "fish_prompt.fish (line 26): Illegal command name '(prompt_pwd)'", + \ ' (prompt_pwd) \', + \ ' ^', + \ "fish_prompt.fish (line 36): 'end' outside of a block", + \ 'end', + \ '^', + \ 'config.fish (line 45):', + \ "abbr --add p 'cd ~/Projects'", + \ '^', + \ ]) + +Execute(The fish handler should handle problems where the problem before before the line with the line number): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 23, + \ 'text': 'Unsupported use of ''||''. In fish, please use ''COMMAND; or COMMAND''.', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 1, + \ 'text': 'wat', + \ }, + \ ], + \ ale_linters#fish#fish#Handle(bufnr(''), [ + \ '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', + \ ' ^', + \ '/tmp/vLz620o/258/test.fish (line 5): wat', + \ ' ^', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_flake8_handler.vader b/vim-config/plugins/ale/test/handler/test_flake8_handler.vader new file mode 100644 index 00000000..1c9956fa --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_flake8_handler.vader @@ -0,0 +1,276 @@ +Before: + Save g:ale_warn_about_trailing_blank_lines + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_blank_lines = 1 + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/python/flake8.vim + +After: + Restore + + unlet! b:ale_warn_about_trailing_blank_lines + unlet! b:ale_warn_about_trailing_whitespace + + call ale#linter#Reset() + +Execute(The flake8 handler should handle basic warnings and syntax errors): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 6, + \ 'vcol': 1, + \ 'type': 'E', + \ 'text': 'indentation is not a multiple of four', + \ 'code': 'E111', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 6, + \ 'vcol': 1, + \ 'type': 'W', + \ 'text': 'some warning', + \ 'code': 'W123', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 8, + \ 'col': 3, + \ 'vcol': 1, + \ 'type': 'E', + \ 'text': 'SyntaxError: invalid syntax', + \ 'code': 'E999', + \ }, + \ ], + \ ale_linters#python#flake8#Handle(1, [ + \ 'stdin:6:6: E111 indentation is not a multiple of four', + \ 'stdin:7:6: W123 some warning', + \ 'stdin:8:3: E999 SyntaxError: invalid syntax', + \ ]) + +Execute(The flake8 handler should set end column indexes for certain errors): + AssertEqual + \ [ + \ { + \ 'lnum': 25, + \ 'col': 1, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 3, + \ 'text': 'undefined name ''foo''', + \ 'code': 'F821', + \ }, + \ { + \ 'lnum': 28, + \ 'col': 5, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 9, + \ 'text': 'hello may be undefined, or defined from star imports: x', + \ 'code': 'F405', + \ }, + \ { + \ 'lnum': 104, + \ 'col': 5, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 12, + \ 'text': '''continue'' not properly in loop', + \ 'code': 'F999', + \ }, + \ { + \ 'lnum': 106, + \ 'col': 5, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 9, + \ 'text': '''break'' outside loop', + \ 'code': 'F999', + \ }, + \ { + \ 'lnum': 109, + \ 'col': 5, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 8, + \ 'text': 'local variable ''test'' is assigned to but never used', + \ 'code': 'F841', + \ }, + \ ], + \ ale_linters#python#flake8#Handle(1, [ + \ 'foo.py:25:1: F821 undefined name ''foo''', + \ 'foo.py:28:5: F405 hello may be undefined, or defined from star imports: x', + \ 'foo.py:104:5: F999 ''continue'' not properly in loop', + \ 'foo.py:106:5: F999 ''break'' outside loop', + \ 'foo.py:109:5: F841 local variable ''test'' is assigned to but never used', + \ ]) + +Execute(The flake8 handler should handle stack traces): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'ImportError: No module named parser (See :ALEDetail)', + \ 'detail': join([ + \ 'Traceback (most recent call last):', + \ ' File "/usr/local/bin/flake8", line 7, in ', + \ ' from flake8.main.cli import main', + \ ' File "/usr/local/lib/python2.7/dist-packages/flake8/main/cli.py", line 2, in ', + \ ' from flake8.main import application', + \ ' File "/usr/local/lib/python2.7/dist-packages/flake8/main/application.py", line 17, in ', + \ ' from flake8.plugins import manager as plugin_manager', + \ ' File "/usr/local/lib/python2.7/dist-packages/flake8/plugins/manager.py", line 5, in ', + \ ' import pkg_resources', + \ ' File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 35, in ', + \ ' import email.parser', + \ 'ImportError: No module named parser', + \ ], "\n"), + \ }, + \ ], + \ ale_linters#python#flake8#Handle(42, [ + \ 'Traceback (most recent call last):', + \ ' File "/usr/local/bin/flake8", line 7, in ', + \ ' from flake8.main.cli import main', + \ ' File "/usr/local/lib/python2.7/dist-packages/flake8/main/cli.py", line 2, in ', + \ ' from flake8.main import application', + \ ' File "/usr/local/lib/python2.7/dist-packages/flake8/main/application.py", line 17, in ', + \ ' from flake8.plugins import manager as plugin_manager', + \ ' File "/usr/local/lib/python2.7/dist-packages/flake8/plugins/manager.py", line 5, in ', + \ ' import pkg_resources', + \ ' File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 35, in ', + \ ' import email.parser', + \ 'ImportError: No module named parser', + \ ]) + +Execute(The flake8 handler should handle names with spaces): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 6, + \ 'vcol': 1, + \ 'type': 'E', + \ 'text': 'indentation is not a multiple of four', + \ 'code': 'E111', + \ 'sub_type': 'style', + \ }, + \ ], + \ ale_linters#python#flake8#Handle(42, [ + \ 'C:\something\with spaces.py:6:6: E111 indentation is not a multiple of four', + \ ]) + +Execute(Warnings about trailing whitespace should be reported by default): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'W291', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'who cares', + \ }, + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'W293', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'who cares', + \ }, + \ ], + \ ale_linters#python#flake8#Handle(bufnr(''), [ + \ 'foo.py:6:1: W291 who cares', + \ 'foo.py:6:1: W293 who cares', + \ ]) + +Execute(Disabling trailing whitespace warnings should work): + let b:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [ + \ ], + \ ale_linters#python#flake8#Handle(bufnr(''), [ + \ 'foo.py:6:1: W291 who cares', + \ 'foo.py:6:1: W293 who cares', + \ ]) + +Execute(Warnings about trailing blank lines should be reported by default): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'W391', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'blank line at end of file', + \ }, + \ ], + \ ale_linters#python#flake8#Handle(bufnr(''), [ + \ 'foo.py:6:1: W391 blank line at end of file', + \ ]) + +Execute(Disabling trailing blank line warnings should work): + let b:ale_warn_about_trailing_blank_lines = 0 + + AssertEqual + \ [ + \ ], + \ ale_linters#python#flake8#Handle(bufnr(''), [ + \ 'foo.py:6:1: W391 blank line at end of file', + \ ]) + +Execute(F401 should be a warning): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'F401', + \ 'type': 'W', + \ 'text': 'module imported but unused', + \ }, + \ ], + \ ale_linters#python#flake8#Handle(bufnr(''), [ + \ 'foo.py:6:1: F401 module imported but unused', + \ ]) + +Execute(E112 should be a syntax error): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'E112', + \ 'type': 'E', + \ 'text': 'expected an indented block', + \ }, + \ ], + \ ale_linters#python#flake8#Handle(bufnr(''), [ + \ 'foo.py:6:1: E112 expected an indented block', + \ ]) + +Execute(Compatibility with hacking which uses older style flake8): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'H306', + \ 'type': 'W', + \ 'text': 'imports not in alphabetical order (smtplib, io)', + \ }, + \ ], + \ ale_linters#python#flake8#Handle(bufnr(''), [ + \ 'foo.py:6:1: H306: imports not in alphabetical order (smtplib, io)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_flakehell_handler.vader b/vim-config/plugins/ale/test/handler/test_flakehell_handler.vader new file mode 100644 index 00000000..1f77bd96 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_flakehell_handler.vader @@ -0,0 +1,276 @@ +Before: + Save g:ale_warn_about_trailing_blank_lines + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_blank_lines = 1 + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/python/flakehell.vim + +After: + Restore + + unlet! b:ale_warn_about_trailing_blank_lines + unlet! b:ale_warn_about_trailing_whitespace + + call ale#linter#Reset() + +Execute(The flakehell handler should handle basic warnings and syntax errors): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 6, + \ 'vcol': 1, + \ 'type': 'E', + \ 'text': 'indentation is not a multiple of four', + \ 'code': 'E111', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 6, + \ 'vcol': 1, + \ 'type': 'W', + \ 'text': 'some warning', + \ 'code': 'W123', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 8, + \ 'col': 3, + \ 'vcol': 1, + \ 'type': 'E', + \ 'text': 'SyntaxError: invalid syntax', + \ 'code': 'E999', + \ }, + \ ], + \ ale_linters#python#flakehell#Handle(1, [ + \ 'stdin:6:6: E111 indentation is not a multiple of four', + \ 'stdin:7:6: W123 some warning', + \ 'stdin:8:3: E999 SyntaxError: invalid syntax', + \ ]) + +Execute(The flakehell handler should set end column indexes for certain errors): + AssertEqual + \ [ + \ { + \ 'lnum': 25, + \ 'col': 1, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 3, + \ 'text': 'undefined name ''foo''', + \ 'code': 'F821', + \ }, + \ { + \ 'lnum': 28, + \ 'col': 5, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 9, + \ 'text': 'hello may be undefined, or defined from star imports: x', + \ 'code': 'F405', + \ }, + \ { + \ 'lnum': 104, + \ 'col': 5, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 12, + \ 'text': '''continue'' not properly in loop', + \ 'code': 'F999', + \ }, + \ { + \ 'lnum': 106, + \ 'col': 5, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 9, + \ 'text': '''break'' outside loop', + \ 'code': 'F999', + \ }, + \ { + \ 'lnum': 109, + \ 'col': 5, + \ 'vcol': 1, + \ 'type': 'E', + \ 'end_col': 8, + \ 'text': 'local variable ''test'' is assigned to but never used', + \ 'code': 'F841', + \ }, + \ ], + \ ale_linters#python#flakehell#Handle(1, [ + \ 'foo.py:25:1: F821 undefined name ''foo''', + \ 'foo.py:28:5: F405 hello may be undefined, or defined from star imports: x', + \ 'foo.py:104:5: F999 ''continue'' not properly in loop', + \ 'foo.py:106:5: F999 ''break'' outside loop', + \ 'foo.py:109:5: F841 local variable ''test'' is assigned to but never used', + \ ]) + +Execute(The flakehell handler should handle stack traces): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'ImportError: No module named parser (See :ALEDetail)', + \ 'detail': join([ + \ 'Traceback (most recent call last):', + \ ' File "/usr/local/bin/flakehell", line 7, in ', + \ ' from flakehell.main.cli import main', + \ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/main/cli.py", line 2, in ', + \ ' from flakehell.main import application', + \ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/main/application.py", line 17, in ', + \ ' from flakehell.plugins import manager as plugin_manager', + \ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/plugins/manager.py", line 5, in ', + \ ' import pkg_resources', + \ ' File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 35, in ', + \ ' import email.parser', + \ 'ImportError: No module named parser', + \ ], "\n"), + \ }, + \ ], + \ ale_linters#python#flakehell#Handle(42, [ + \ 'Traceback (most recent call last):', + \ ' File "/usr/local/bin/flakehell", line 7, in ', + \ ' from flakehell.main.cli import main', + \ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/main/cli.py", line 2, in ', + \ ' from flakehell.main import application', + \ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/main/application.py", line 17, in ', + \ ' from flakehell.plugins import manager as plugin_manager', + \ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/plugins/manager.py", line 5, in ', + \ ' import pkg_resources', + \ ' File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 35, in ', + \ ' import email.parser', + \ 'ImportError: No module named parser', + \ ]) + +Execute(The flakehell handler should handle names with spaces): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 6, + \ 'vcol': 1, + \ 'type': 'E', + \ 'text': 'indentation is not a multiple of four', + \ 'code': 'E111', + \ 'sub_type': 'style', + \ }, + \ ], + \ ale_linters#python#flakehell#Handle(42, [ + \ 'C:\something\with spaces.py:6:6: E111 indentation is not a multiple of four', + \ ]) + +Execute(Warnings about trailing whitespace should be reported by default): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'W291', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'who cares', + \ }, + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'W293', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'who cares', + \ }, + \ ], + \ ale_linters#python#flakehell#Handle(bufnr(''), [ + \ 'foo.py:6:1: W291 who cares', + \ 'foo.py:6:1: W293 who cares', + \ ]) + +Execute(Disabling trailing whitespace warnings should work): + let b:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [ + \ ], + \ ale_linters#python#flakehell#Handle(bufnr(''), [ + \ 'foo.py:6:1: W291 who cares', + \ 'foo.py:6:1: W293 who cares', + \ ]) + +Execute(Warnings about trailing blank lines should be reported by default): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'W391', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'blank line at end of file', + \ }, + \ ], + \ ale_linters#python#flakehell#Handle(bufnr(''), [ + \ 'foo.py:6:1: W391 blank line at end of file', + \ ]) + +Execute(Disabling trailing blank line warnings should work): + let b:ale_warn_about_trailing_blank_lines = 0 + + AssertEqual + \ [ + \ ], + \ ale_linters#python#flakehell#Handle(bufnr(''), [ + \ 'foo.py:6:1: W391 blank line at end of file', + \ ]) + +Execute(F401 should be a warning): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'F401', + \ 'type': 'W', + \ 'text': 'module imported but unused', + \ }, + \ ], + \ ale_linters#python#flakehell#Handle(bufnr(''), [ + \ 'foo.py:6:1: F401 module imported but unused', + \ ]) + +Execute(E112 should be a syntax error): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'E112', + \ 'type': 'E', + \ 'text': 'expected an indented block', + \ }, + \ ], + \ ale_linters#python#flakehell#Handle(bufnr(''), [ + \ 'foo.py:6:1: E112 expected an indented block', + \ ]) + +Execute(Compatibility with hacking which uses older style flakehell): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'vcol': 1, + \ 'code': 'H306', + \ 'type': 'W', + \ 'text': 'imports not in alphabetical order (smtplib, io)', + \ }, + \ ], + \ ale_linters#python#flakehell#Handle(bufnr(''), [ + \ 'foo.py:6:1: H306: imports not in alphabetical order (smtplib, io)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_flawfinder_handler.vader b/vim-config/plugins/ale/test/handler/test_flawfinder_handler.vader new file mode 100644 index 00000000..708bac2a --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_flawfinder_handler.vader @@ -0,0 +1,57 @@ +Before: + Save g:ale_c_flawfinder_error_severity + + unlet! g:ale_c_flawfinder_error_severity + unlet! b:ale_c_flawfinder_error_severity + + runtime ale_linters/c/flawfinder.vim + +After: + unlet! g:ale_c_flawfinder_error_severity + Restore + +Execute(The Flawfinder handler should ignore other lines of output): + AssertEqual + \ [], + \ ale#handlers#flawfinder#HandleFlawfinderFormat(347, [ + \ 'foo', + \ 'bar', + \ 'baz', + \ ]) + +Execute(The Flawfinder handler should work): + AssertEqual + \ [ + \ { + \ 'lnum': 31, + \ 'col': 4, + \ 'type': 'W', + \ 'text': "(buffer) strncpy: Easily used incorrectly", + \ }, + \ ], + \ ale#handlers#flawfinder#HandleFlawfinderFormat(347, [ + \ ":31:4: [1] (buffer) strncpy:Easily used incorrectly", + \ ]) + +Execute(The Flawfinder error severity level should be configurable): + let b:ale_c_flawfinder_error_severity = 2 + + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'col': 4, + \ 'type': 'E', + \ 'text': "(buffer) char: Statically-sized arrays can be bad", + \ }, + \ { + \ 'lnum': 31, + \ 'col': 4, + \ 'type': 'W', + \ 'text': "(buffer) strncpy: Easily used incorrectly", + \ }, + \ ], + \ ale#handlers#flawfinder#HandleFlawfinderFormat(bufnr(''), [ + \ ":12:4: [2] (buffer) char:Statically-sized arrays can be bad", + \ ":31:4: [1] (buffer) strncpy:Easily used incorrectly", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_flow_handler.vader b/vim-config/plugins/ale/test/handler/test_flow_handler.vader new file mode 100644 index 00000000..055ba026 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_flow_handler.vader @@ -0,0 +1,507 @@ +Before: + runtime ale_linters/javascript/flow.vim + +After: + unlet! g:flow_output + unlet! g:expected + unlet! g:actual + call ale#linter#Reset() + +Execute(The flow handler should throw away non-JSON lines): + AssertEqual + \ [], + \ ale_linters#javascript#flow#Handle(bufnr(''), [ + \ 'Already up-to-date.', + \ '{"flowVersion":"0.50.0","errors":[],"passed":true}', + \ ]) + AssertEqual + \ [], + \ ale_linters#javascript#flow#Handle(bufnr(''), [ + \ 'foo', + \ 'bar', + \ 'baz', + \ '{"flowVersion":"0.50.0","errors":[],"passed":true}', + \ ]) + +Execute(The flow handler should process errors correctly.): + silent! noautocmd file /home/w0rp/Downloads/graphql-js/src/language/parser.js + + let g:flow_output = { + \ "flowVersion": "0.39.0", + \ "errors": [ + \ { + \ "kind": "infer", + \ "level": "error", + \ "message": [ + \ { + \ "context": " return 1", + \ "descr": "number", + \ "type": "Blame", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile", + \ "start": { + \ "line": 417, + \ "column": 10, + \ "offset": 9503 + \ }, + \ "end": { + \ "line": 417, + \ "column": 10, + \ "offset": 9504 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 417, + \ "endline": 417, + \ "start": 10, + \ "end": 10 + \ }, + \ { + \ "context": v:null, + \ "descr": "This type is incompatible with the expected return type of", + \ "type": "Comment", + \ "path": "", + \ "line": 0, + \ "endline": 0, + \ "start": 1, + \ "end": 0 + \ }, + \ { + \ "context": "function parseArguments(lexer: Lexer<*>): Array {", + \ "descr": "array type", + \ "type": "Blame", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile", + \ "start": { + \ "line": 416, + \ "column": 43, + \ "offset": 9472 + \ }, + \ "end": { + \ "line": 416, + \ "column": 61, + \ "offset": 9491 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 416, + \ "endline": 416, + \ "start": 43, + \ "end": 61 + \ } + \ ] + \ }, + \ { + \ "kind": "infer", + \ "level": "warning", + \ "message": [ + \ { + \ "context": " return peek(lexer, TokenKind.PAREN_L) ?", + \ "descr": "unreachable code", + \ "type": "Blame", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile", + \ "start": { + \ "line": 419, + \ "column": 3, + \ "offset": 9508 + \ }, + \ "end": { + \ "line": 421, + \ "column": 7, + \ "offset": 9626 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 419, + \ "endline": 421, + \ "start": 3, + \ "end": 7 + \ } + \ ] + \ } + \ ], + \ "passed": v:false + \} + + let g:actual = ale_linters#javascript#flow#Handle(bufnr(''), [json_encode(g:flow_output)]) + let g:expected = [ + \ { + \ 'lnum': 417, + \ 'type': 'E', + \ 'col': 10, + \ 'text': 'number: This type is incompatible with the expected return type of array type', + \ }, + \ { + \ 'lnum': 419, + \ 'type': 'W', + \ 'col': 3, + \ 'text': 'unreachable code:', + \ }, + \] + + AssertEqual g:expected, g:actual + +Execute(The flow handler should fetch the correct location for the currently opened file, even when it's not in the first message.): + silent! noautocmd file /Users/rav/Projects/vim-ale-flow/index.js + + let g:flow_output = { + \ "flowVersion": "0.44.0", + \ "errors": [{ + \ "operation": { + \ "context": " , document.getElementById('foo')", + \ "descr": "React element `Foo`", + \ "type": "Blame", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile", + \ "start": { + \ "line": 6, + \ "column": 3, + \ "offset": 92 + \ }, + \ "end": { + \ "line": 6, + \ "column": 18, + \ "offset": 108 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 6, + \ "endline": 6, + \ "start": 3, + \ "end": 18 + \ }, + \ "kind": "infer", + \ "level": "error", + \ "message": [{ + \ "context": "module.exports = function(props: Props) {", + \ "descr": "property `bar`", + \ "type": "Blame", + \ "loc": { + \ "source": "/Users/rav/Projects/vim-ale-flow/foo.js", + \ "type": "SourceFile", + \ "start": { + \ "line": 9, + \ "column": 34, + \ "offset": 121 + \ }, + \ "end": { + \ "line": 9, + \ "column": 38, + \ "offset": 126 + \ } + \ }, + \ "path": "/Users/rav/Projects/vim-ale-flow/foo.js", + \ "line": 9, + \ "endline": 9, + \ "start": 34, + \ "end": 38 + \ }, { + \ "context": v:null, + \ "descr": "Property not found in", + \ "type": "Comment", + \ "path": "", + \ "line": 0, + \ "endline": 0, + \ "start": 1, + \ "end": 0 + \ }, { + \ "context": " , document.getElementById('foo')", + \ "descr": "props of React element `Foo`", + \ "type": "Blame", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile", + \ "start": { + \ "line": 6, + \ "column": 3, + \ "offset": 92 + \ }, + \ "end": { + \ "line": 6, + \ "column": 18, + \ "offset": 108 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 6, + \ "endline": 6, + \ "start": 3, + \ "end": 18 + \ }] + \ }], + \ "passed": v:false + \} + + let g:actual = ale_linters#javascript#flow#Handle(bufnr(''), [json_encode(g:flow_output)]) + let g:expected = [ + \ { + \ 'lnum': 6, + \ 'col': 3, + \ 'type': 'E', + \ 'text': 'property `bar`: Property not found in props of React element `Foo` See also: React element `Foo`', + \ } + \] + + AssertEqual g:expected, g:actual + +Execute(The flow handler should handle relative paths): + silent! noautocmd file /Users/rav/Projects/vim-ale-flow/index.js + + let g:flow_output = { + \ "flowVersion": "0.44.0", + \ "errors": [{ + \ "operation": { + \ "context": " , document.getElementById('foo')", + \ "descr": "React element `Foo`", + \ "type": "Blame", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile", + \ "start": { + \ "line": 6, + \ "column": 3, + \ "offset": 92 + \ }, + \ "end": { + \ "line": 6, + \ "column": 18, + \ "offset": 108 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 6, + \ "endline": 6, + \ "start": 3, + \ "end": 18 + \ }, + \ "kind": "infer", + \ "level": "error", + \ "message": [{ + \ "context": "module.exports = function(props: Props) {", + \ "descr": "property `bar`", + \ "type": "Blame", + \ "loc": { + \ "source": "vim-ale-flow/foo.js", + \ "type": "SourceFile", + \ "start": { + \ "line": 9, + \ "column": 34, + \ "offset": 121 + \ }, + \ "end": { + \ "line": 9, + \ "column": 38, + \ "offset": 126 + \ } + \ }, + \ "path": "vim-ale-flow/foo.js", + \ "line": 9, + \ "endline": 9, + \ "start": 34, + \ "end": 38 + \ }, { + \ "context": v:null, + \ "descr": "Property not found in", + \ "type": "Comment", + \ "path": "", + \ "line": 0, + \ "endline": 0, + \ "start": 1, + \ "end": 0 + \ }, { + \ "context": " , document.getElementById('foo')", + \ "descr": "props of React element `Foo`", + \ "type": "Blame", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile", + \ "start": { + \ "line": 6, + \ "column": 3, + \ "offset": 92 + \ }, + \ "end": { + \ "line": 6, + \ "column": 18, + \ "offset": 108 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 6, + \ "endline": 6, + \ "start": 3, + \ "end": 18 + \ }] + \ }], + \ "passed": v:false + \} + + let g:actual = ale_linters#javascript#flow#Handle(bufnr(''), [json_encode(g:flow_output)]) + let g:expected = [ + \ { + \ 'lnum': 6, + \ 'col': 3, + \ 'type': 'E', + \ 'text': 'property `bar`: Property not found in props of React element `Foo` See also: React element `Foo`', + \ } + \] + + AssertEqual g:expected, g:actual + +Execute(The flow handler should handle extra errors): + silent! noautocmd file /Users/rav/Projects/vim-ale-flow/index.js + + let g:flow_output = { + \ "flowVersion": "0.54.0", + \ "errors": [{ + \ "extra": [{ + \ "message": [{ + \ "context": v:null, + \ "descr": "Property \`setVector\` is incompatible:", + \ "type": "Blame ", + \ "path": "", + \ "line": 0, + \ "endline": 0, + \ "start": 1, + \ "end": 0 + \ }], + \ "children": [{ + \ "message": [{ + \ "context": "setVector = \{2\}", + \ "descr": "number ", + \ "type": "Blame ", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile ", + \ "start": { + \ "line": 90, + \ "column": 30, + \ "offset": 2296 + \ }, + \ "end": { + \ "line": 90, + \ "column": 30, + \ "offset": 2297 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 90, + \ "endline": 90, + \ "start": 30, + \ "end": 30 + \ }, { + \ "context": v:null, + \ "descr": "This type is incompatible with ", + \ "type": "Comment ", + \ "path": "", + \ "line": 0, + \ "endline": 0, + \ "start": 1, + \ "end": 0 + \ }, { + \ "context": "setVector: VectorType => void,", + \ "descr": "function type ", + \ "type": "Blame ", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile", + \ "start": { + \ "line": 9, + \ "column": 14, + \ "offset": 252 + \ }, + \ "end": { + \ "line": 9, + \ "column": 31, + \ "offset": 270 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 9, + \ "endline": 9, + \ "start": 14, + \ "end": 31 + \ }] + \ }] + \ }], + \ "kind": "infer", + \ "level": "error", + \ "suppressions": [], + \ "message": [{ + \ "context": " < New ", + \ "descr": "props of React element `New`", + \ "type": "Blame", + \ "loc": { + \ "source": "vim-ale-flow/foo.js", + \ "type": "SourceFile", + \ "start": { + \ "line": 89, + \ "column": 17, + \ "offset": 2262 + \ }, + \ "end": { + \ "line": 94, + \ "column": 18, + \ "offset": 2488 + \ } + \ }, + \ "path": "", + \ "line": 89, + \ "endline": 94, + \ "start": 17, + \ "end": 18 + \ }, { + \ "context": v:null, + \ "descr": "This type is incompatible with", + \ "type": "Comment", + \ "path": "", + \ "line": 0, + \ "endline": 0, + \ "start": 1, + \ "end": 0 + \ }, { + \ "context": "class New extends React.Component < NewProps,NewState > {", + \ "descr": "object type", + \ "type": "Blame", + \ "loc": { + \ "source": expand('%:p'), + \ "type": "SourceFile", + \ "start": { + \ "line": 20, + \ "column": 35, + \ "offset": 489 + \ }, + \ "end": { + \ "line": 20, + \ "column": 42, + \ "offset": 497 + \ } + \ }, + \ "path": expand('%:p'), + \ "line": 20, + \ "endline": 20, + \ "start": 35, + \ "end": 42 + \ }] + \ }], + \ "passed": v:false + \} + + let g:actual = ale_linters#javascript#flow#Handle(bufnr(''), [json_encode(g:flow_output)]) + let g:expected = [ + \ { + \ 'lnum': 20, + \ 'col': 35, + \ 'type': 'E', + \ 'text': 'props of React element `New`: This type is incompatible with object type', + \ 'detail': 'props of React element `New`: This type is incompatible with object type' + \ . "\nProperty `setVector` is incompatible: number This type is incompatible with function type ", + \ } + \] + + AssertEqual g:expected, g:actual diff --git a/vim-config/plugins/ale/test/handler/test_foodcritic_handler.vader b/vim-config/plugins/ale/test/handler/test_foodcritic_handler.vader new file mode 100644 index 00000000..67cb6cab --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_foodcritic_handler.vader @@ -0,0 +1,44 @@ +Before: + runtime ale_linters/chef/foodcritic.vim + +After: + call ale#linter#Reset() + +Execute(Basic warnings should be handled): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'code': 'CINK001', + \ 'type': 'W', + \ 'text': 'Missing CHANGELOG in markdown format', + \ 'filename': '/foo/bar/CHANGELOG.md', + \ }, + \ { + \ 'lnum': 1, + \ 'code': 'FC011', + \ 'type': 'W', + \ 'text': 'Missing README in markdown format', + \ 'filename': '/foo/bar/README.md', + \ }, + \ { + \ 'lnum': 1, + \ 'code': 'FC031', + \ 'type': 'W', + \ 'text': 'Cookbook without metadata.rb file', + \ 'filename': '/foo/bar/metadata.rb', + \ }, + \ { + \ 'lnum': 1, + \ 'code': 'FC071', + \ 'type': 'W', + \ 'text': 'Missing LICENSE file', + \ 'filename': '/foo/bar/LICENSE', + \ }, + \ ], + \ ale_linters#chef#foodcritic#Handle(bufnr(''), [ + \ 'CINK001: Missing CHANGELOG in markdown format: /foo/bar/CHANGELOG.md:1', + \ 'FC011: Missing README in markdown format: /foo/bar/README.md:1', + \ 'FC031: Cookbook without metadata.rb file: /foo/bar/metadata.rb:1', + \ 'FC071: Missing LICENSE file: /foo/bar/LICENSE:1', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_fortran_handler.vader b/vim-config/plugins/ale/test/handler/test_fortran_handler.vader new file mode 100644 index 00000000..c55a4c6f --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_fortran_handler.vader @@ -0,0 +1,95 @@ +Before: + runtime ale_linters/fortran/gcc.vim + +After: + call ale#linter#Reset() + +Execute(The fortran handler should parse lines from GCC 4.1.2 correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 357, + \ 'lnum': 4, + \ 'col': 0, + \ 'text': "Symbol ‘b’ at (1) has no IMPLICIT type", + \ 'type': 'E', + \ }, + \ { + \ 'bufnr': 357, + \ 'lnum': 3, + \ 'col': 0, + \ 'text': "Symbol ‘a’ at (1) has no IMPLICIT type", + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#fortran#gcc#Handle(357, [ + \ " In file :4", + \ "", + \ "write(*,*) b", + \ " 1", + \ "Error: Symbol ‘b’ at (1) has no IMPLICIT type", + \ " In file :3", + \ "", + \ "write(*,*) a", + \ " 1", + \ "Error: Symbol ‘a’ at (1) has no IMPLICIT type", + \ ]) + + +Execute(The fortran handler should parse lines from GCC 4.9.3 correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 357, + \ 'lnum': 3, + \ 'col': 12, + \ 'text': "Symbol ‘a’ at (1) has no IMPLICIT type", + \ 'type': 'E', + \ }, + \ { + \ 'bufnr': 357, + \ 'lnum': 4, + \ 'col': 12, + \ 'text': "Symbol ‘b’ at (1) has no IMPLICIT type", + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#fortran#gcc#Handle(357, [ + \ ":3.12:", + \ "", + \ "write(*,*) a", + \ " 1", + \ "Error: Symbol ‘a’ at (1) has no IMPLICIT type", + \ ":4.12:", + \ "", + \ "write(*,*) b", + \ " 1", + \ "Error: Symbol ‘b’ at (1) has no IMPLICIT type", + \ ]) + +Execute(The fortran handler should parse lines from GCC 6.3.1 correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 337, + \ 'lnum': 3, + \ 'col': 12, + \ 'text': "Symbol ‘a’ at (1) has no IMPLICIT type", + \ 'type': 'E', + \ }, + \ { + \ 'bufnr': 337, + \ 'lnum': 4, + \ 'col': 12, + \ 'text': "Symbol ‘b’ at (1) has no IMPLICIT type", + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#fortran#gcc#Handle(337, [ + \ ":3:12:", + \ "", + \ "Error: Symbol ‘a’ at (1) has no IMPLICIT type", + \ ":4:12:", + \ "", + \ "Error: Symbol ‘b’ at (1) has no IMPLICIT type", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_gawk_handler.vader b/vim-config/plugins/ale/test/handler/test_gawk_handler.vader new file mode 100644 index 00000000..3a7b5457 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_gawk_handler.vader @@ -0,0 +1,39 @@ +Before: + runtime ale_linters/awk/gawk.vim + +After: + call ale#linter#Reset() + +Execute(gawk syntax errors should be parsed correctly): + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 0, + \ 'text': "invalid char ''' in expression", + \ 'code': 0, + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 0, + \ 'text': 'unterminated string', + \ 'code': 0, + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 10, + \ 'col': 0, + \ 'text': "escape sequence `\u' treated as plain `u'", + \ 'code': 0, + \ 'type': 'W', + \ }, + \ ], + \ ale#handlers#gawk#HandleGawkFormat(347, [ + \ "gawk: something.awk:1: BEGIN { system('touch aaaaaaaaa') }", + \ "gawk: something.awk:1: ^ invalid char ''' in expression", + \ 'gawk: something.awk:5: { x = "aaaaaaaaaaa', + \ 'gawk: something.awk:5: ^ unterminated string', + \ "gawk: something.awk:10: warning: escape sequence `\u' treated as plain `u'", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_gcc_handler.vader b/vim-config/plugins/ale/test/handler/test_gcc_handler.vader new file mode 100644 index 00000000..a4231cab --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_gcc_handler.vader @@ -0,0 +1,316 @@ +Execute(The GCC handler should ignore other lines of output): + AssertEqual + \ [], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ 'foo', + \ 'bar', + \ 'baz', + \ ]) + +Execute(GCC errors from included files should be parsed correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'filename': 'broken.h', + \ 'type': 'E', + \ 'text': 'expected identifier or ''('' before ''{'' token', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 2, + \ 'text': 'Error found in header. See :ALEDetail', + \ 'detail': join([ + \ 'In file included from :3:2:', + \ 'broken.h:1:1: error: expected identifier or ''('' before ''{'' token', + \ ' {{{', + \ ' ^', + \ ], "\n"), + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ 'In file included from :3:2:', + \ 'broken.h:1:1: error: expected identifier or ''('' before ''{'' token', + \ ' {{{', + \ ' ^', + \ 'compilation terminated.', + \ ]) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'filename': 'b.h', + \ 'type': 'E', + \ 'text': 'expected identifier or ''('' before ''{'' token', + \ }, + \ { + \ 'lnum': 5, + \ 'text': 'Error found in header. See :ALEDetail', + \ 'detail': join([ + \ 'In file included from a.h:1:0,', + \ ' from :5:', + \ 'b.h:1:1: error: expected identifier or ''('' before ''{'' token', + \ ' {{{', + \ ' ^', + \ ], "\n"), + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ 'In file included from a.h:1:0,', + \ ' from :5:', + \ 'b.h:1:1: error: expected identifier or ''('' before ''{'' token', + \ ' {{{', + \ ' ^', + \ 'compilation terminated.', + \ ]) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'filename': 'b.h', + \ 'type': 'E', + \ 'text': 'unknown type name ''bad_type''', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'filename': 'b.h', + \ 'type': 'E', + \ 'text': 'unknown type name ''other_bad_type''', + \ }, + \ { + \ 'lnum': 3, + \ 'text': 'Error found in header. See :ALEDetail', + \ 'detail': join([ + \ 'In file included from a.h:1:0,', + \ ' from :3:', + \ 'b.h:1:1: error: unknown type name ‘bad_type’', + \ ' bad_type x;', + \ ' ^', + \ 'b.h:2:1: error: unknown type name ‘other_bad_type’', + \ ' other_bad_type y;', + \ ' ^', + \ ], "\n"), + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ 'In file included from a.h:1:0,', + \ ' from :3:', + \ 'b.h:1:1: error: unknown type name ‘bad_type’', + \ ' bad_type x;', + \ ' ^', + \ 'b.h:2:1: error: unknown type name ‘other_bad_type’', + \ ' other_bad_type y;', + \ ' ^', + \ 'compilation terminated.', + \ ]) + +Execute(The GCC handler shouldn't complain about #pragma once for headers): + silent file! test.h + + AssertEqual + \ [], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ ':1:1: warning: #pragma once in main file [enabled by default]', + \ ]) + + silent file! test.hpp + + AssertEqual + \ [], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ ':1:1: warning: #pragma once in main file [enabled by default]', + \ ]) + +Execute(The GCC handler should handle syntax errors): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 12, + \ 'type': 'E', + \ 'text': 'invalid suffix "p" on integer constant' + \ }, + \ { + \ 'lnum': 17, + \ 'col': 5, + \ 'type': 'E', + \ 'text': 'invalid suffix "n" on integer constant' + \ }, + \ { + \ 'lnum': 4, + \ 'type': 'E', + \ 'text': 'variable or field ''foo'' declared void' + \ }, + \ { + \ 'lnum': 4, + \ 'type': 'E', + \ 'text': '''cat'' was not declared in this scope' + \ }, + \ { + \ 'lnum': 12, + \ 'type': 'E', + \ 'text': 'expected '';'' before ''o''' + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ ':6:12: error: invalid suffix "p" on integer constant', + \ ':17:5: error: invalid suffix "n" on integer constant', + \ ':4: error: variable or field ''foo'' declared void', + \ ':4: error: ''cat'' was not declared in this scope', + \ ':12: error: expected `;'' before ''o''', + \ ]) + +Execute(The GCC handler should handle notes with no previous message): + AssertEqual + \ [], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ ':1:1: note: x', + \ ':1:1: note: x', + \ ]) + +Execute(The GCC handler should attach notes to previous messages): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 12, + \ 'type': 'E', + \ 'text': 'Some error', + \ 'detail': "Some error\n:1:1: note: x", + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ '-:6:12: error: Some error', + \ ':1:1: note: x', + \ ]) + +Execute(The GCC handler should interpret - as being the current file): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 12, + \ 'type': 'E', + \ 'text': 'Some error', + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ '-:6:12: error: Some error', + \ ]) + +Execute(The GCC handler should handle fatal error messages due to missing files): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'col': 12, + \ 'type': 'E', + \ 'text': 'foo.h: No such file or directory' + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ ':3:12: fatal error: foo.h: No such file or directory', + \ ]) + +Execute(The GCC handler should handle errors for inlined header functions): + AssertEqual + \ [ + \ { + \ 'lnum': 50, + \ 'col': 4, + \ 'filename': '/usr/include/bits/fcntl2.h', + \ 'type': 'E', + \ 'text': 'call to ''__open_missing_mode'' declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments', + \ }, + \ { + \ 'lnum': 44, + \ 'col': 5, + \ 'filename': '/usr/include/bits/fcntl2.h', + \ 'type': 'E', + \ 'text': 'call to ''__open_too_many_args'' declared with attribute error: open can be called either with 2 or 3 arguments, not more', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 10, + \ 'type': 'E', + \ 'text': 'call to ''__open_missing_mode'' declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments', + \ }, + \ { + \ 'lnum': 13, + \ 'col': 11, + \ 'type': 'E', + \ 'text': 'call to ''__open_too_many_args'' declared with attribute error: open can be called either with 2 or 3 arguments, not more', + \ }, + \ { + \ 'lnum': 1, + \ 'text': 'Error found in header. See :ALEDetail', + \ 'detail': join([ + \ 'In file included from /usr/include/fcntl.h:328,', + \ ' from :1:', + \ 'In function ‘open’,', + \ ' inlined from ‘main’ at :7:10:', + \ '/usr/include/bits/fcntl2.h:50:4: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments', + \ ' __open_missing_mode ();', + \ ' ^~~~~~~~~~~~~~~~~~~~~~', + \ 'In function ‘open’,', + \ ' inlined from ‘main’ at :13:11:', + \ '/usr/include/bits/fcntl2.h:44:5: error: call to ‘__open_too_many_args’ declared with attribute error: open can be called either with 2 or 3 arguments, not more', + \ ' __open_too_many_args ();', + \ ], "\n") + \ }, + \], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ 'In file included from /usr/include/fcntl.h:328,', + \ ' from :1:', + \ 'In function ‘open’,', + \ ' inlined from ‘main’ at :7:10:', + \ '/usr/include/bits/fcntl2.h:50:4: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments', + \ ' __open_missing_mode ();', + \ ' ^~~~~~~~~~~~~~~~~~~~~~', + \ 'In function ‘open’,', + \ ' inlined from ‘main’ at :13:11:', + \ '/usr/include/bits/fcntl2.h:44:5: error: call to ‘__open_too_many_args’ declared with attribute error: open can be called either with 2 or 3 arguments, not more', + \ ' __open_too_many_args ();', + \ ' ^~~~~~~~~~~~~~~~~~~~~~~', + \ ]) + +Execute(The GCC handler should handle macro expansion errors in current file): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 19, + \ 'type': 'E', + \ 'text': 'error message', + \ 'detail': "error message\n:1:19: note: in expansion of macro 'TEST'", + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ ': error: error message', + \ ':1:19: note: in expansion of macro ‘TEST’', + \ ' 1 | std::string str = TEST;', + \ ' | ^~~~', + \ ]) + +Execute(The GCC handler should handle macro expansion errors in other files): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'type': 'E', + \ 'text': 'Error found in macro expansion. See :ALEDetail', + \ 'detail': "error message\ninc.h:1:19: note: in expansion of macro 'TEST'", + \ }, + \ ], + \ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [ + \ ': error: error message', + \ 'inc.h:1:19: note: in expansion of macro ‘TEST’', + \ ' 1 | std::string str = TEST;', + \ ' | ^~~~', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_ghc_handler.vader b/vim-config/plugins/ale/test/handler/test_ghc_handler.vader new file mode 100644 index 00000000..b040a234 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ghc_handler.vader @@ -0,0 +1,132 @@ +Execute(The ghc handler should handle hdevtools output): + call ale#test#SetFilename('foo.hs') + + AssertEqual + \ [ + \ { + \ 'lnum': 147, + \ 'type': 'W', + \ 'col': 62, + \ 'text': '• Couldnt match type ‘a -> T.Text’ with ‘T.Text’ Expected type: [T.Text]', + \ 'detail': join([ + \ '• Couldnt match type ‘a -> T.Text’ with ‘T.Text’', + \ ' Expected type: [T.Text]', + \ ], "\n"), + \ }, + \ ], + \ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [ + \ 'foo.hs:147:62: warning:', + \ '• Couldnt match type ‘a -> T.Text’ with ‘T.Text’', + \ ' Expected type: [T.Text]', + \ ]) + +Execute(The ghc handler should handle ghc 8 output): + call ale#test#SetFilename('src/Appoint/Lib.hs') + + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'type': 'E', + \ 'col': 1, + \ 'text': 'Failed to load interface for ‘GitHub.Data’ Use -v to see a list of the files searched for.', + \ 'detail': join([ + \ ' Failed to load interface for ‘GitHub.Data’', + \ ' Use -v to see a list of the files searched for.', + \ ], "\n"), + \ }, + \ { + \ 'lnum': 7, + \ 'type': 'W', + \ 'col': 1, + \ 'text': 'Failed to load interface for ‘GitHub.Endpoints.PullRequests’ Use -v to see a list of the files searched for.', + \ 'detail': join([ + \ ' Failed to load interface for ‘GitHub.Endpoints.PullRequests’', + \ ' Use -v to see a list of the files searched for.', + \ ], "\n"), + \ }, + \ ], + \ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [ + \ '', + \ ale#path#Simplify('src/Appoint/Lib.hs') . ':6:1: error:', + \ ' Failed to load interface for ‘GitHub.Data’', + \ ' Use -v to see a list of the files searched for.', + \ '', + \ ale#path#Simplify('src/Appoint/Lib.hs') . ':7:1: warning:', + \ ' Failed to load interface for ‘GitHub.Endpoints.PullRequests’', + \ ' Use -v to see a list of the files searched for.', + \ ]) + +Execute(The ghc handler should handle ghc 7 output): + call ale#test#SetFilename('src/Main.hs') + + AssertEqual + \ [ + \ { + \ 'lnum': 168, + \ 'type': 'E', + \ 'col': 1, + \ 'text': 'parse error (possibly incorrect indentation or mismatched brackets)', + \ 'detail': join([ + \ ' parse error (possibly incorrect indentation or mismatched brackets)', + \ ], "\n"), + \ }, + \ { + \ 'lnum': 84, + \ 'col': 1, + \ 'type': 'W', + \ 'text': 'Top-level binding with no type signature: myLayout :: Choose Tall (Choose (Mirror Tall) Full) a', + \ 'detail': join([ + \ ' Top-level binding with no type signature:', + \ ' myLayout :: Choose Tall (Choose (Mirror Tall) Full) a', + \ ], "\n"), + \ }, + \ { + \ 'lnum': 94, + \ 'col': 5, + \ 'type': 'E', + \ 'text': 'Some other error', + \ 'detail': join([ + \ ' Some other error', + \ ], "\n"), + \ }, + \ ], + \ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [ + \ ale#path#Simplify('src/Main.hs') . ':168:1:', + \ ' parse error (possibly incorrect indentation or mismatched brackets)', + \ ale#path#Simplify('src/Main.hs') . ':84:1:Warning:', + \ ' Top-level binding with no type signature:', + \ ' myLayout :: Choose Tall (Choose (Mirror Tall) Full) a', + \ ale#path#Simplify('src/Main.hs') . ':94:5:Error:', + \ ' Some other error', + \ ]) + +Execute(The ghc handler should handle stack 1.5.1 output): + call ale#test#SetFilename('src/Main.hs') + + AssertEqual + \ [ + \ { + \ 'lnum': 160, + \ 'col': 14, + \ 'type': 'E', + \ 'text': '• Expecting one fewer arguments to ‘Exp’ Expected kind ‘k0 -> *’, but ‘Exp’ has kind ‘*’ • In the type ‘Exp a’ | 160 | pattern F :: Exp a | ^^^^^', + \ 'detail': join([ + \ ' • Expecting one fewer arguments to ‘Exp’', + \ ' Expected kind ‘k0 -> *’, but ‘Exp’ has kind ‘*’', + \ ' • In the type ‘Exp a’', + \ ' |', + \ ' 160 | pattern F :: Exp a', + \ ' | ^^^^^', + \ ], "\n"), + \ }, + \ ], + \ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [ + \ ' ' . ale#path#Simplify('src/Main.hs') . ':160:14: error:', + \ ' • Expecting one fewer arguments to ‘Exp’', + \ ' Expected kind ‘k0 -> *’, but ‘Exp’ has kind ‘*’', + \ ' • In the type ‘Exp a’', + \ ' |', + \ ' 160 | pattern F :: Exp a', + \ ' | ^^^^^', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_ghc_mod_handler.vader b/vim-config/plugins/ale/test/handler/test_ghc_mod_handler.vader new file mode 100644 index 00000000..bed5b13c --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ghc_mod_handler.vader @@ -0,0 +1,37 @@ +Execute(HandleGhcFormat should handle ghc-mod problems): + call ale#test#SetFilename('check2.hs') + + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Failed to load interface for ‘Missing’Use -v to see a list of the files searched for.', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Suggestion: Use camelCaseFound: my_variable = ...Why not: myVariable = ...', + \ }, + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'type': 'W', + \ 'text': 'Eta reduceFound: myFunc x = succ xWhy not: myFunc = succ', + \ }, + \ { + \ 'lnum': 28, + \ 'col': 28, + \ 'type': 'W', + \ 'text': 'Defaulting the following constraints to type ‘Integer’ (Num a0) arising from the literal ‘3’ at check2.hs:28:28 (Eq a0) arising from a use of ‘lookup’ at check2.hs:28:21-28 • In the first argument of ‘lookup’, namely ‘3’ In the expression: lookup 3 In the second argument of ‘fmap’, namely ‘(lookup 3 $ zip [1, 2, 3] [4, 5, 6])''’' + \ }, + \ ], + \ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [ + \ 'check2.hs:2:1:Failed to load interface for ‘Missing’Use -v to see a list of the files searched for.', + \ 'check2.hs:2:1: Suggestion: Use camelCaseFound: my_variable = ...Why not: myVariable = ...', + \ 'check2.hs:6:1: Warning: Eta reduceFound: myFunc x = succ xWhy not: myFunc = succ', + \ 'xxx.hs:6:1: Warning: Eta reduceFound: myFunc x = succ xWhy not: myFunc = succ', + \ printf("check2.hs:28:28: Warning: Defaulting the following constraints to type ‘Integer’ (Num a0) arising from the literal ‘3’ at %s/check2.hs:28:28 (Eq a0) arising from a use of ‘lookup’ at %s/check2.hs:28:21-28 • In the first argument of ‘lookup’, namely ‘3’ In the expression: lookup 3 In the second argument of ‘fmap’, namely ‘(lookup 3 $ zip [1, 2, 3] [4, 5, 6])'’", tempname(), tempname()), + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_ghdl_handler.vader b/vim-config/plugins/ale/test/handler/test_ghdl_handler.vader new file mode 100644 index 00000000..a0f5edac --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ghdl_handler.vader @@ -0,0 +1,26 @@ +Before: + runtime ale_linters/vhdl/ghdl.vim + +After: + call ale#linter#Reset() + +Execute(The ghdl handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 41, + \ 'col' : 5, + \ 'type': 'E', + \ 'text': "error: 'begin' is expected instead of 'if'" + \ }, + \ { + \ 'lnum': 12, + \ 'col' : 8, + \ 'type': 'E', + \ 'text': ' no declaration for "i0"' + \ }, + \ ], + \ ale_linters#vhdl#ghdl#Handle(bufnr(''), [ + \ "dff_en.vhd:41:5:error: 'begin' is expected instead of 'if'", + \ '/path/to/file.vhdl:12:8: no declaration for "i0"', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_gitlint_handler.vader b/vim-config/plugins/ale/test/handler/test_gitlint_handler.vader new file mode 100644 index 00000000..5c531664 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_gitlint_handler.vader @@ -0,0 +1,89 @@ +Before: + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/gitcommit/gitlint.vim + +After: + Restore + + unlet! b:ale_warn_about_trailing_whitespace + + call ale#linter#Reset() + +Execute(The gitlint handler should handle basic warnings and syntax errors): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': 'Body message is missing', + \ 'code': 'B6', + \ }, + \ { + \ 'lnum': 2, + \ 'type': 'E', + \ 'text': 'Second line is not empty: "to send to upstream"', + \ 'code': 'B4', + \ }, + \ { + \ 'lnum': 3, + \ 'type': 'E', + \ 'text': 'Body message is too short (19<20): "to send to upstream"', + \ 'code': 'B5', + \ }, + \ { + \ 'lnum': 8, + \ 'type': 'E', + \ 'text': 'Title exceeds max length (92>72): "some very long commit subject line where the author can''t wait to explain what he just fixed"', + \ 'code': 'T1', + \ }, + \ ], + \ ale_linters#gitcommit#gitlint#Handle(1, [ + \ '1: B6 Body message is missing', + \ '2: B4 Second line is not empty: "to send to upstream"', + \ '3: B5 Body message is too short (19<20): "to send to upstream"', + \ '8: T1 Title exceeds max length (92>72): "some very long commit subject line where the author can''t wait to explain what he just fixed"' + \ ]) + +Execute(Disabling trailing whitespace warnings should work): + AssertEqual + \ [ + \ { + \ 'lnum': 8, + \ 'type': 'E', + \ 'text': 'Trailing whitespace', + \ 'code': 'T2', + \ }, + \ ], + \ ale_linters#gitcommit#gitlint#Handle(bufnr(''), [ + \ '8: T2 Trailing whitespace', + \]) + + AssertEqual + \ [ + \ { + \ 'lnum': 8, + \ 'type': 'E', + \ 'text': 'Trailing whitespace', + \ 'code': 'B2', + \ }, + \ ], + \ ale_linters#gitcommit#gitlint#Handle(bufnr(''), [ + \ '8: B2 Trailing whitespace', + \]) + + let b:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [], + \ ale_linters#gitcommit#gitlint#Handle(bufnr(''), [ + \ '8: T2 Trailing whitespace', + \ ]) + + AssertEqual + \ [], + \ ale_linters#gitcommit#gitlint#Handle(bufnr(''), [ + \ '8: B2 Trailing whitespace', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_glslang_handler.vader b/vim-config/plugins/ale/test/handler/test_glslang_handler.vader new file mode 100644 index 00000000..6d3a7999 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_glslang_handler.vader @@ -0,0 +1,24 @@ +Before: + runtime ale_linters/glsl/glslang.vim + +Execute(The glsl glslang handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 0, + \ 'type': 'E', + \ 'text': '''gl_ModelViewProjectionMatrix'' : undeclared identifier', + \ }, + \ { + \ 'lnum': 121, + \ 'col': 0, + \ 'type': 'W', + \ 'text': '''switch'' : last case/default label not followed by statements', + \ }, + \ ], + \ ale_linters#glsl#glslang#Handle(bufnr(''), [ + \ 'ERROR: 0:4: ''gl_ModelViewProjectionMatrix'' : undeclared identifier', + \ 'WARNING: 0:121: ''switch'' : last case/default label not followed by statements', + \ 'ERROR: 2 compilation errors. No code generated.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_go_generic_handler.vader b/vim-config/plugins/ale/test/handler/test_go_generic_handler.vader new file mode 100644 index 00000000..2b17fdcb --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_go_generic_handler.vader @@ -0,0 +1,38 @@ +Execute(The golang handler should return the correct filenames): + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'col': 0, + \ 'text': 'some error', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'), + \ }, + \ { + \ 'lnum': 27, + \ 'col': 5, + \ 'text': 'some error with a column', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/other.go'), + \ }, + \ { + \ 'lnum': 18, + \ 'col': 0, + \ 'text': 'random error', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/go1.14.go'), + \ }, + \ { + \ 'lnum': 36, + \ 'col': 2, + \ 'text': 'another random error', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/anothergo1.14.go'), + \ }, + \ ], + \ ale#handlers#go#Handler(bufnr(''), [ + \ 'test.go:27: some error', + \ 'other.go:27:5: some error with a column', + \ 'vet: go1.14.go:18:0: random error', + \ 'vet: anothergo1.14.go:36:2: another random error', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_gobuild_handler.vader b/vim-config/plugins/ale/test/handler/test_gobuild_handler.vader new file mode 100644 index 00000000..17608c3a --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_gobuild_handler.vader @@ -0,0 +1,45 @@ +Before: + runtime ale_linters/go/gobuild.vim + +After: + call ale#linter#Reset() + +Execute (The gobuild handler should handle names with spaces): + " We can't test Windows paths with the path resovling on Linux, but we can + " test the regex. + AssertEqual + \ [ + \ [ + \ 'C:\something\file with spaces.go', + \ '27', + \ '', + \ 'missing argument for Printf("%s"): format reads arg 2, have only 1 args', + \ ], + \ [ + \ 'C:\something\file with spaces.go', + \ '5', + \ '2', + \ 'expected declaration, found ''STRING'' "log"', + \ ], + \ ], + \ map(ale_linters#go#gobuild#GetMatches([ + \ 'C:\something\file with spaces.go:27: missing argument for Printf("%s"): format reads arg 2, have only 1 args', + \ 'C:\something\file with spaces.go:5:2: expected declaration, found ''STRING'' "log"', + \ ]), 'v:val[1:4]') + +Execute (The gobuild handler should handle relative paths correctly): + call ale#test#SetFilename('app/test.go') + + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'col': 0, + \ 'text': 'missing argument for Printf("%s"): format reads arg 2, have only 1 args', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'), + \ }, + \ ], + \ ale_linters#go#gobuild#Handler(bufnr(''), [ + \ 'test.go:27: missing argument for Printf("%s"): format reads arg 2, have only 1 args', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_golangci_lint_handler.vader b/vim-config/plugins/ale/test/handler/test_golangci_lint_handler.vader new file mode 100644 index 00000000..fb6841f4 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_golangci_lint_handler.vader @@ -0,0 +1,55 @@ +Before: + runtime ale_linters/go/golangci_lint.vim + +After: + call ale#linter#Reset() + +Execute (The golangci-lint handler should handle names with spaces): + " We can't test Windows paths with the path resovling on Linux, but we can + " test the regex. + AssertEqual + \ [ + \ [ + \ 'C:\something\file with spaces.go', + \ '12', + \ '3', + \ 'expected ''package'', found ''IDENT'' gibberish (staticcheck)', + \ ], + \ [ + \ 'C:\something\file with spaces.go', + \ '37', + \ '5', + \ 'expected ''package'', found ''IDENT'' gibberish (golint)', + \ ], + \ ], + \ map(ale_linters#go#golangci_lint#GetMatches([ + \ 'C:\something\file with spaces.go:12:3: expected ''package'', found ''IDENT'' gibberish (staticcheck)', + \ 'C:\something\file with spaces.go:37:5: expected ''package'', found ''IDENT'' gibberish (golint)', + \ ]), 'v:val[1:4]') + +Execute (The golangci-lint handler should handle paths correctly): + call ale#test#SetFilename('app/test.go') + + let file = ale#path#GetAbsPath(expand('%:p:h'), 'test.go') + + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'col': 3, + \ 'text': 'expected ''package'', found ''IDENT'' gibberish (staticcheck)', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'), + \ }, + \ { + \ 'lnum': 37, + \ 'col': 5, + \ 'text': 'expected ''package'', found ''IDENT'' gibberish (golint)', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'), + \ }, + \ ], + \ ale_linters#go#golangci_lint#Handler(bufnr(''), [ + \ file . ':12:3: expected ''package'', found ''IDENT'' gibberish (staticcheck)', + \ file . ':37:5: expected ''package'', found ''IDENT'' gibberish (golint)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_gometalinter_handler.vader b/vim-config/plugins/ale/test/handler/test_gometalinter_handler.vader new file mode 100644 index 00000000..1aade8a7 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_gometalinter_handler.vader @@ -0,0 +1,57 @@ +Before: + runtime ale_linters/go/gometalinter.vim + +After: + call ale#linter#Reset() + +Execute (The gometalinter handler should handle names with spaces): + " We can't test Windows paths with the path resovling on Linux, but we can + " test the regex. + AssertEqual + \ [ + \ [ + \ 'C:\something\file with spaces.go', + \ '12', + \ '3', + \ 'warning', + \ 'expected ''package'', found ''IDENT'' gibberish (staticcheck)', + \ ], + \ [ + \ 'C:\something\file with spaces.go', + \ '37', + \ '5', + \ 'error', + \ 'expected ''package'', found ''IDENT'' gibberish (golint)', + \ ], + \ ], + \ map(ale_linters#go#gometalinter#GetMatches([ + \ 'C:\something\file with spaces.go:12:3:warning: expected ''package'', found ''IDENT'' gibberish (staticcheck)', + \ 'C:\something\file with spaces.go:37:5:error: expected ''package'', found ''IDENT'' gibberish (golint)', + \ ]), 'v:val[1:5]') + +Execute (The gometalinter handler should handle paths correctly): + call ale#test#SetFilename('app/test.go') + + let file = ale#path#GetAbsPath(expand('%:p:h'), 'test.go') + + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'col': 3, + \ 'text': 'expected ''package'', found ''IDENT'' gibberish (staticcheck)', + \ 'type': 'W', + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'), + \ }, + \ { + \ 'lnum': 37, + \ 'col': 5, + \ 'text': 'expected ''package'', found ''IDENT'' gibberish (golint)', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'), + \ }, + \ ], + \ ale_linters#go#gometalinter#Handler(bufnr(''), [ + \ file . ':12:3:warning: expected ''package'', found ''IDENT'' gibberish (staticcheck)', + \ file . ':37:5:error: expected ''package'', found ''IDENT'' gibberish (golint)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_hadolint.vader b/vim-config/plugins/ale/test/handler/test_hadolint.vader new file mode 100644 index 00000000..f84c303d --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_hadolint.vader @@ -0,0 +1,59 @@ +Before: + runtime ale_linters/dockerfile/hadolint.vim + +After: + call ale#linter#Reset() + +Execute(The hadolint handler should handle an empty string response): + AssertEqual + \ [], + \ ale_linters#dockerfile#hadolint#Handle(bufnr(''), []) + +Execute(The hadolint handler should handle a normal example): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 0, + \ 'type': 'W', + \ 'code': 'DL3006', + \ 'text': "DL3006: Always tag the version of an image explicitly", + \ 'detail': "DL3006 ( https://github.com/hadolint/hadolint/wiki/DL3006 )\n\nAlways tag the version of an image explicitly", + \ }, + \ { + \ 'lnum': 4, + \ 'col': 0, + \ 'type': 'W', + \ 'code': 'DL3033', + \ 'text': "DL3033: Specify version with `yum install -y -`.", + \ 'detail': "DL3033 ( https://github.com/hadolint/hadolint/wiki/DL3033 )\n\nSpecify version with `yum install -y -`.", + \ }, + \ { + \ 'lnum': 12, + \ 'col': 0, + \ 'type': 'W', + \ 'code': 'SC2039', + \ 'text': "SC2039: In POSIX sh, brace expansion is undefined.", + \ 'detail': "SC2039 ( https://github.com/koalaman/shellcheck/wiki/SC2039 )\n\nIn POSIX sh, brace expansion is undefined.", + \ }, + \ ], + \ ale_linters#dockerfile#hadolint#Handle(bufnr(''), [ + \ '-:1 DL3006 warning: Always tag the version of an image explicitly', + \ '-:4 DL3033 warning: Specify version with `yum install -y -`.', + \ '-:12 SC2039 warning: In POSIX sh, brace expansion is undefined.', + \ ]) + +Execute(The hadolint handler should handle parsing errors): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'E', + \ 'text': "unexpected 'b' expecting '#', ADD, ARG, CMD, COPY, ENTRYPOINT, ENV, EXPOSE, FROM, HEALTHCHECK, LABEL, MAINTAINER, ONBUILD, RUN, SHELL, STOPSIGNAL, USER, VOLUME, WORKDIR, or end of input", + \ 'detail': "hadolint could not parse the file because of a syntax error.", + \ }, + \ ], + \ ale_linters#dockerfile#hadolint#Handle(bufnr(''), [ + \ '/dev/stdin:1:1 unexpected ''b'' expecting ''#'', ADD, ARG, CMD, COPY, ENTRYPOINT, ENV, EXPOSE, FROM, HEALTHCHECK, LABEL, MAINTAINER, ONBUILD, RUN, SHELL, STOPSIGNAL, USER, VOLUME, WORKDIR, or end of input', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_haskell_stack_handler.vader b/vim-config/plugins/ale/test/handler/test_haskell_stack_handler.vader new file mode 100644 index 00000000..07e7e69c --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_haskell_stack_handler.vader @@ -0,0 +1,7 @@ +Before: + runtime ale/handlers/haskell_stack.vim + +Execute(Escape stack should correctly identify a stack exec command): + AssertEqual + \ ale#Escape('stack') . ' exec ' . ale#Escape('hlint') . ' --', + \ ale#handlers#haskell_stack#EscapeExecutable('stack', 'hlint') diff --git a/vim-config/plugins/ale/test/handler/test_hlint_handler.vader b/vim-config/plugins/ale/test/handler/test_hlint_handler.vader new file mode 100644 index 00000000..915e1748 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_hlint_handler.vader @@ -0,0 +1,80 @@ +Before: + runtime! ale_linters/haskell/hlint.vim + +After: + call ale#linter#Reset() + +Execute(The hlint handler should parse items correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 4, + \ 'end_lnum': 3, + \ 'end_col': 2, + \ 'text': 'Error: Do something. Found: [Char] Why not: String', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 4, + \ 'end_lnum': 7, + \ 'end_col': 2, + \ 'text': 'Warning: Do something. Found: [Char] Why not: String', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 73, + \ 'col': 25, + \ 'end_lnum': 73, + \ 'end_col': 31, + \ 'text': 'Suggestion: Use String. Found: [Char] Why not: String', + \ 'type': 'I', + \ }, + \ ], + \ ale_linters#haskell#hlint#Handle(bufnr(''), [json_encode([ + \ { + \ 'module': 'Main', + \ 'decl': 'foo', + \ 'severity': 'Error', + \ 'hint': 'Do something', + \ 'file': '-', + \ 'startLine': 1, + \ 'startColumn': 4, + \ 'endLine': 3, + \ 'endColumn': 2, + \ 'from': '[Char]', + \ 'to': 'String', + \ }, + \ { + \ 'module': 'Main', + \ 'decl': 'foo', + \ 'severity': 'Warning', + \ 'hint': 'Do something', + \ 'file': '-', + \ 'startLine': 2, + \ 'startColumn': 4, + \ 'endLine': 7, + \ 'endColumn': 2, + \ 'from': '[Char]', + \ 'to': 'String', + \ }, + \ { + \ 'module': 'Main', + \ 'decl': 'myFocusedBorderColor', + \ 'severity': 'Suggestion', + \ 'hint': 'Use String', + \ 'file': '-', + \ 'startLine': 73, + \ 'startColumn': 25, + \ 'endLine': 73, + \ 'endColumn': 31, + \ 'from': '[Char]', + \ 'to': 'String', + \ }, + \ ])]) + +Execute(The hlint handler should handle empty output): + AssertEqual + \ [], + \ ale_linters#haskell#hlint#Handle(bufnr(''), []) diff --git a/vim-config/plugins/ale/test/handler/test_ibm_openapi_validator_handler.vader b/vim-config/plugins/ale/test/handler/test_ibm_openapi_validator_handler.vader new file mode 100644 index 00000000..e136d5d2 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ibm_openapi_validator_handler.vader @@ -0,0 +1,49 @@ +Before: + runtime! ale_linters/openapi/ibm_validator.vim + +After: + call ale#linter#Reset() + +Execute(Problems should be parsed correctly for openapi-ibm-validator): + AssertEqual + \ [ + \ { + \ 'lnum': 54, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'Items with a description must have content in it.', + \ }, + \ { + \ 'lnum': 24, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'Operations must have a non-empty `operationId`.', + \ }, + \ { + \ 'lnum': 40, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'operationIds must follow case convention: lower_snake_case', + \ }, + \ ], + \ ale_linters#openapi#ibm_validator#Handle(bufnr(''), [ + \ '', + \ '[Warning] No .validaterc file found. The validator will run in default mode.', + \ 'To configure the validator, create a .validaterc file.', + \ '', + \ 'errors', + \ '', + \ ' Message : Items with a description must have content in it.', + \ ' Path : paths./settings.patch.description', + \ ' Line : 54', + \ '', + \ 'warnings', + \ '', + \ ' Message : Operations must have a non-empty `operationId`.', + \ ' Path : paths./stats.get.operationId', + \ ' Line : 24', + \ '', + \ ' Message : operationIds must follow case convention: lower_snake_case', + \ ' Path : paths./settings.get.operationId', + \ ' Line : 40' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_idris_handler.vader b/vim-config/plugins/ale/test/handler/test_idris_handler.vader new file mode 100644 index 00000000..6a032ea6 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_idris_handler.vader @@ -0,0 +1,66 @@ +Before: + Save $TMPDIR + + " Set TMPDIR so the temporary file checks work. + let $TMPDIR = '/tmp' + + runtime ale_linters/idris/idris.vim + +After: + Restore + + call ale#linter#Reset() + +Execute(The idris handler should parse messages that reference a single column): + if has('win32') + call ale#test#SetFilename($TEMP . '\foo.idr') + else + call ale#test#SetFilename('/tmp/foo.idr') + endif + + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 5, + \ 'type': 'E', + \ 'text': 'When checking right hand side of main with expected type IO () When checking an application of function Prelude.Monad.>>=: Type mismatch between IO () (Type of putStrLn _) and _ -> _ (Is putStrLn _ applied to too many arguments?) Specifically: Type mismatch between IO and \uv => _ -> uv' + \ } + \ ], + \ ale_linters#idris#idris#Handle(bufnr(''), [ + \ expand('%:p') . ':4:5:', + \ 'When checking right hand side of main with expected type', + \ ' IO ()', + \ '', + \ 'When checking an application of function Prelude.Monad.>>=:', + \ ' Type mismatch between', + \ ' IO () (Type of putStrLn _)', + \ ' and', + \ ' _ -> _ (Is putStrLn _ applied to too many arguments?)', + \ '', + \ ' Specifically:', + \ ' Type mismatch between', + \ ' IO', + \ ' and', + \ ' \uv => _ -> uv', + \ ]) + +Execute(The idris handler should parse messages that reference a column range): + call ale#test#SetFilename('/tmp/foo.idr') + + AssertEqual + \ [ + \ { + \ 'lnum': 11, + \ 'col': 11, + \ 'type': 'E', + \ 'text': 'When checking right hand side of Main.case block in main at /tmp/foo.idr:10:10 with expected type IO () Last statement in do block must be an expression' + \ } + \ ], + \ ale_linters#idris#idris#Handle(bufnr(''), [ + \ expand('%:p') . ':11:11-13:', + \ 'When checking right hand side of Main.case block in main at /tmp/foo.idr:10:10 with expected type', + \ ' IO ()', + \ '', + \ 'Last statement in do block must be an expression', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_inko_handler.vader b/vim-config/plugins/ale/test/handler/test_inko_handler.vader new file mode 100644 index 00000000..6621d2d6 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_inko_handler.vader @@ -0,0 +1,54 @@ +Before: + runtime ale_linters/inko/inko.vim + +After: + call ale#linter#Reset() + +Execute(The inko handler should parse errors correctly): + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Simplify('/tmp/foo.inko'), + \ 'lnum': 4, + \ 'col': 5, + \ 'text': 'this is an error', + \ 'type': 'E', + \ } + \ ], + \ ale#handlers#inko#Handle(bufnr(''), [ + \ '[', + \ ' {', + \ ' "file": "/tmp/foo.inko",', + \ ' "line": 4,', + \ ' "column": 5,', + \ ' "message": "this is an error",', + \ ' "level": "error"', + \ ' }', + \ ']' + \ ]) + +Execute(The inko handler should parse warnings correctly): + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Simplify('/tmp/foo.inko'), + \ 'lnum': 4, + \ 'col': 5, + \ 'text': 'this is a warning', + \ 'type': 'W', + \ } + \ ], + \ ale#handlers#inko#Handle(bufnr(''), [ + \ '[', + \ ' {', + \ ' "file": "/tmp/foo.inko",', + \ ' "line": 4,', + \ ' "column": 5,', + \ ' "message": "this is a warning",', + \ ' "level": "warning"', + \ ' }', + \ ']' + \ ]) + +Execute(The inko handler should handle empty output): + AssertEqual [], ale#handlers#inko#Handle(bufnr(''), []) diff --git a/vim-config/plugins/ale/test/handler/test_ispc_ispc_handler.vader b/vim-config/plugins/ale/test/handler/test_ispc_ispc_handler.vader new file mode 100644 index 00000000..619773fe --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ispc_ispc_handler.vader @@ -0,0 +1,90 @@ +Before: + runtime ale_linters/ispc/ispc.vim + +After: + call ale#linter#Reset() + +Execute(The ispc handler should parse input correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 0, + \ 'lnum': 33, + \ 'col': 14, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected ''int'', expecting '','' or '';''.', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 36, + \ 'col': 5, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected ''for''.', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 51, + \ 'col': 9, + \ 'type': 'E', + \ 'text': '''foobar.h'' file not found', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 79, + \ 'col': 52, + \ 'type': 'W', + \ 'text': 'Modulus operator with varying types is very inefficient.', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 85, + \ 'col': 13, + \ 'type': 'W', + \ 'text': 'Undefined behavior: all program instances are writing to the same location!', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 93, + \ 'col': 19, + \ 'type': 'W', + \ 'text': 'Gather required to load value.', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 93, + \ 'col': 9, + \ 'type': 'W', + \ 'text': 'Scatter required to store value.', + \ }, + \ ], + \ ale_linters#ispc#ispc#Handle(0, [ + \ 'Warning: No output file or header file name specified. Program will be compiled and warnings/errors will be issued, but no output will be generated. ', + \ 'Warning: No --target specified on command-line. Using default system target "avx2-i32x8".', + \ 'mandelbrot.ispc:33:14: Error: syntax error, unexpected ''int'', expecting '','' or '';''.', + \ 'static iline int mandel(float c_re, float c_im, int count) {', + \ ' ^^^', + \ '', + \ 'mandelbrot.ispc:36:5: Error: syntax error, unexpected ''for''.', + \ ' for (i = 0; i < count; ++i) {', + \ ' ^^^', + \ '', + \ 'mandelbrot.ispc:51:9: fatal error: ''foobar.h'' file not found', + \ '#include', + \ ' ^~~~~~~~~~', + \ 'mandelbrot.ispc:79:52: Performance Warning: Modulus operator with varying types is very inefficient.', + \ ' double x = x0 + i * (dx + epsilon*(k%2)*delta);', + \ ' ^^^', + \ '', + \ 'mandelbrot.ispc:85:13: Warning: Undefined behavior: all program instances are writing to the same location!', + \ ' output[index] = (NNN) / sample_size;', + \ ' ^^^^^^^^^^^^^', + \ '', + \ 'mandelbrot.ispc:93:19: Performance Warning: Gather required to load value.', + \ ' A[i*8] *= A[i*8];', + \ ' ^^^^^^', + \ '', + \ 'mandelbrot.ispc:93:9: Performance Warning: Scatter required to store value.', + \ ' A[i*8] *= A[i*8];', + \ ' ^^^^^^', + \ '', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_javac_handler.vader b/vim-config/plugins/ale/test/handler/test_javac_handler.vader new file mode 100644 index 00000000..3dc245af --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_javac_handler.vader @@ -0,0 +1,97 @@ +Before: + runtime ale_linters/java/javac.vim + + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('dummy.java') + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The javac handler should handle cannot find symbol errors): + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'), + \ 'lnum': 1, + \ 'text': 'error: some error', + \ 'type': 'E', + \ }, + \ { + \ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'), + \ 'lnum': 2, + \ 'col': 5, + \ 'text': 'error: cannot find symbol: BadName', + \ 'type': 'E', + \ }, + \ { + \ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'), + \ 'lnum': 34, + \ 'col': 5, + \ 'text': 'error: cannot find symbol: BadName2', + \ 'type': 'E', + \ }, + \ { + \ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'), + \ 'lnum': 37, + \ 'text': 'warning: some warning', + \ 'type': 'W', + \ }, + \ { + \ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'), + \ 'lnum': 42, + \ 'col': 11, + \ 'text': 'error: cannot find symbol: bar()', + \ 'type': 'E', + \ }, + \ { + \ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'), + \ 'lnum': 58, + \ 'col': 19, + \ 'text': 'error: incompatible types: Bar cannot be converted to Foo', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#java#javac#Handle(bufnr(''), [ + \ '/tmp/vLPr4Q5/33/foo.java:1: error: some error', + \ '/tmp/vLPr4Q5/33/foo.java:2: error: cannot find symbol', + \ ' BadName foo() {', + \ ' ^', + \ ' symbol: class BadName', + \ ' location: class Bar', + \ '/tmp/vLPr4Q5/33/foo.java:34: error: cannot find symbol', + \ ' BadName2 foo() {', + \ ' ^', + \ ' symbol: class BadName2', + \ ' location: class Bar', + \ '/tmp/vLPr4Q5/33/foo.java:37: warning: some warning', + \ '/tmp/vLPr4Q5/33/foo.java:42: error: cannot find symbol', + \ ' this.bar();', + \ ' ^', + \ ' symbol: method bar()', + \ '/tmp/vLPr4Q5/33/foo.java:58: error: incompatible types: Bar cannot be converted to Foo', + \ ' this.setFoo(bar);', + \ ' ^', + \ '6 errors', + \ ]) + +Execute(The javac handler should resolve files from different directories): + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Simplify(g:dir . '/Foo.java'), + \ 'lnum': 1, + \ 'text': 'error: some error', + \ 'type': 'E', + \ }, + \ { + \ 'filename': ale#path#Simplify(g:dir . '/Bar.java'), + \ 'lnum': 1, + \ 'text': 'error: some error', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#java#javac#Handle(bufnr(''), [ + \ './Foo.java:1: error: some error', + \ './Bar.java:1: error: some error', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_jscs_handler.vader b/vim-config/plugins/ale/test/handler/test_jscs_handler.vader new file mode 100644 index 00000000..5566116f --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_jscs_handler.vader @@ -0,0 +1,39 @@ +Before: + runtime ale_linters/javascript/jscs.vim + +After: + call ale#linter#Reset() + +Execute(jscs should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 7, + \ 'text': 'Variable declarations should use `let` or `const` not `var`', + \ 'code': 'disallowVar', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 21, + \ 'text': 'Illegal trailing whitespace', + \ 'code': 'disallowTrailingWhitespace', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 9, + \ 'text': 'Variable `hello` is not used', + \ 'code': 'disallowUnusedVariables', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'Expected indentation of 1 characters', + \ }, + \ ], + \ ale_linters#javascript#jscs#Handle(347, [ + \ 'foobar.js: line 1, col 7, disallowVar: Variable declarations should use `let` or `const` not `var`', + \ 'foobar.js: line 3, col 21, disallowTrailingWhitespace: Illegal trailing whitespace', + \ 'foobar.js: line 5, col 9, disallowUnusedVariables: Variable `hello` is not used', + \ 'foobar.js: line 2, col 1, Expected indentation of 1 characters', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_ktlint_handler.vader b/vim-config/plugins/ale/test/handler/test_ktlint_handler.vader new file mode 100644 index 00000000..f0d634e6 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ktlint_handler.vader @@ -0,0 +1,21 @@ +Before: + Save g:ale_kotlin_ktlint_rulesets + + let g:ale_kotlin_ktlint_rulesets = [] + +After: + Restore + +Execute(The ktlint handler method GetRulesets should properly parse custom rulesets): + let g:ale_kotlin_ktlint_rulesets = ['/path/to/custom/ruleset.jar', '/path/to/other/ruleset.jar'] + + AssertEqual + \ '--ruleset /path/to/custom/ruleset.jar --ruleset /path/to/other/ruleset.jar', + \ ale#handlers#ktlint#GetRulesets(bufnr('')) + +Execute(The ktlint handler method GetRulesets should return an empty string when no rulesets have been configured): + let g:ale_kotlin_ktlint_rulesets = [] + + AssertEqual + \ '', + \ ale#handlers#ktlint#GetRulesets(bufnr('')) diff --git a/vim-config/plugins/ale/test/handler/test_lacheck_handler.vader b/vim-config/plugins/ale/test/handler/test_lacheck_handler.vader new file mode 100644 index 00000000..5d1b6ace --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_lacheck_handler.vader @@ -0,0 +1,34 @@ +Before: + runtime ale_linters/tex/lacheck.vim + call ale#test#SetDirectory('/testplugin/test/handler') + +After: + call ale#linter#Reset() + call ale#test#RestoreDirectory() + +Execute(The lacheck handler should parse lines correctly): + call ale#test#SetFilename('../test-files/tex/sample1.tex') + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'type': 'W', + \ 'text': 'perhaps you should insert a `~'' before "\ref"' + \ } + \ ], + \ ale_linters#tex#lacheck#Handle(bufnr(''), [ + \ "** sample1:", + \ "\"sample1.tex\", line 1: perhaps you should insert a `~' before \"\\ref\"" + \ ]) + +Execute(The lacheck handler should ignore errors from input files): + call ale#test#SetFilename('ale_test.tex') + + AssertEqual + \ [ + \ ], + \ ale_linters#tex#lacheck#Handle(255, [ + \ "** ale_input:", + \ "\"ale_input.tex\", line 1: perhaps you should insert a `~' before \"\\ref\"" + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_languagetool_handler.vader b/vim-config/plugins/ale/test/handler/test_languagetool_handler.vader new file mode 100644 index 00000000..61d3abfd --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_languagetool_handler.vader @@ -0,0 +1,62 @@ +Before: + runtime! ale_linters/text/languagetool.vim + +After: + call ale#linter#Reset() + +Execute(languagetool handler should report 3 errors): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'col': 19, + \ 'end_col': 20, + \ 'text': 'This sentence does not start with an uppercase letter', + \ 'type': 'W', + \ 'code': 'UPPERCASE_SENTENCE_START', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 36, + \ 'end_col': 42, + \ 'text': "Did you mean 'to see'?", + \ 'type': 'W', + \ 'code': 'TOO_TO[1]', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 44, + \ 'end_col': 45, + \ 'text': "Use 'a' instead of 'an' if the following word doesn't start with a vowel sound, e.g. 'a sentence', 'a university'", + \ 'type': 'W', + \ 'code': 'EN_A_VS_AN', + \ } + \ ], + \ ale#handlers#languagetool#HandleOutput(bufnr(''), [ + \ '1.) Line 3, column 19, Rule ID: UPPERCASE_SENTENCE_START', + \ 'Message: This sentence does not start with an uppercase letter', + \ 'Suggestion: Or', + \ '...red phrases for details on potential errors. or use this text too see an few of of the probl...', + \ ' ^^ ', + \ '', + \ '2.) Line 3, column 36, Rule ID: TOO_TO[1]', + \ "Message: Did you mean 'to see'?", + \ 'Suggestion: to see', + \ '...etails on potential errors. or use this text too see an few of of the problems that LanguageTool ...', + \ ' ^^^^^^^ ', + \ '', + \ '3.) Line 3, column 44, Rule ID: EN_A_VS_AN', + \ "Message: Use 'a' instead of 'an' if the following word doesn't start with a vowel sound, e.g. 'a sentence', 'a university'", + \ 'Suggestion: a', + \ '...n potential errors. or use this text too see an few of of the problems that LanguageTool can...', + \ ' ^^ ', + \ 'Time: 2629ms for 8 sentences (3.0 sentences/sec)' + \ ]) + +Execute(languagetool handler should report no errors on empty input): + AssertEqual + \ [], + \ ale#handlers#languagetool#HandleOutput(bufnr(''), [ + \ '', + \ 'Time: 2629ms for 8 sentences (3.0 sentences/sec)' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_lessc_handler.vader b/vim-config/plugins/ale/test/handler/test_lessc_handler.vader new file mode 100644 index 00000000..31de5593 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_lessc_handler.vader @@ -0,0 +1,69 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/handler') + call ale#test#SetFilename('testfile.less') + + runtime ale_linters/less/lessc.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The lessc handler should handle errors for the current file correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Unrecognised input. Possibly missing something', + \ }, + \ ], + \ ale_linters#less#lessc#Handle(bufnr(''), [ + \ 'ParseError: Unrecognised input. Possibly missing something in - on line 2, column 1:', + \ '1 vwewww', + \ '2 ', + \]) + +Execute(The lessc handler should handle errors for other files in the same directory correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Unrecognised input. Possibly missing something', + \ 'filename': ale#path#Simplify(g:dir . '/imported.less') + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Unrecognised input. Possibly missing something', + \ 'filename': ale#path#Simplify(g:dir . '/imported.less') + \ }, + \ ], + \ ale_linters#less#lessc#Handle(bufnr(''), [ + \ 'ParseError: Unrecognised input. Possibly missing something in imported.less on line 2, column 1:', + \ '1 vwewww', + \ '2 ', + \ 'ParseError: Unrecognised input. Possibly missing something in ./imported.less on line 2, column 1:', + \ '1 vwewww', + \ '2 ', + \]) + +Execute(The lessc handler should handle errors for files in directories above correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Unrecognised input. Possibly missing something', + \ 'filename': ale#path#Simplify(g:dir . '/../imported2.less') + \ }, + \ ], + \ ale_linters#less#lessc#Handle(bufnr(''), [ + \ 'ParseError: Unrecognised input. Possibly missing something in ../imported2.less on line 2, column 1:', + \ '1 vwewww', + \ '2 ', + \]) diff --git a/vim-config/plugins/ale/test/handler/test_llc_handler.vader b/vim-config/plugins/ale/test/handler/test_llc_handler.vader new file mode 100644 index 00000000..bbe686f2 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_llc_handler.vader @@ -0,0 +1,58 @@ +Before: + runtime! ale_linters/llvm/llc.vim + +After: + call ale#linter#Reset() + +Execute(llc handler should parse errors output for STDIN): + AssertEqual + \ [ + \ { + \ 'lnum': 10, + \ 'col': 7, + \ 'text': "error: value doesn't match function result type 'i32'", + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 10, + \ 'col': 13, + \ 'text': "error: use of undefined value '@foo'", + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#llvm#llc#HandleErrors(bufnr(''), [ + \ "llc: :10:7: error: value doesn't match function result type 'i32'", + \ 'ret i64 0', + \ ' ^', + \ '', + \ "llc: :10:13: error: use of undefined value '@foo'", + \ 'call void @foo(i64 %0)', + \ ' ^', + \ ]) + +Execute(llc handler should parse errors output for some file): + call ale#test#SetFilename('test.ll') + AssertEqual + \ [ + \ { + \ 'lnum': 10, + \ 'col': 7, + \ 'text': "error: value doesn't match function result type 'i32'", + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 10, + \ 'col': 13, + \ 'text': "error: use of undefined value '@foo'", + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#llvm#llc#HandleErrors(bufnr(''), [ + \ "llc: /path/to/test.ll:10:7: error: value doesn't match function result type 'i32'", + \ 'ret i64 0', + \ ' ^', + \ '', + \ "llc: /path/to/test.ll:10:13: error: use of undefined value '@foo'", + \ 'call void @foo(i64 %0)', + \ ' ^', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_luac_handler.vader b/vim-config/plugins/ale/test/handler/test_luac_handler.vader new file mode 100644 index 00000000..3a2e769c --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_luac_handler.vader @@ -0,0 +1,36 @@ +Before: + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/lua/luac.vim + +After: + Restore + call ale#linter#Reset() + +Execute(The luac handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'line contains trailing whitespace', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 3, + \ 'text': 'unexpected symbol near ''-''', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 5, + \ 'text': '''='' expected near '')''', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#lua#luac#Handle(347, [ + \ 'luac /file/path/here.lua:1: line contains trailing whitespace', + \ 'luac /file/path/here.lua:3: unexpected symbol near ''-''', + \ 'luac /file/path/here.lua:5: ''='' expected near '')''', + \ ]) + diff --git a/vim-config/plugins/ale/test/handler/test_luacheck_handler.vader b/vim-config/plugins/ale/test/handler/test_luacheck_handler.vader new file mode 100644 index 00000000..7cebb017 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_luacheck_handler.vader @@ -0,0 +1,62 @@ +Before: + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/lua/luacheck.vim + +After: + Restore + call ale#linter#Reset() + +Execute(The luacheck handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 8, + \ 'text': 'line contains trailing whitespace', + \ 'code': 'W612', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 5, + \ 'text': 'unused loop variable ''k''', + \ 'code': 'W213', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 19, + \ 'text': 'accessing undefined variable ''x''', + \ 'code': 'W113', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#lua#luacheck#Handle(347, [ + \ ' /file/path/here.lua:1:8: (W612) line contains trailing whitespace', + \ ' /file/path/here.lua:3:5: (W213) unused loop variable ''k''', + \ ' /file/path/here.lua:3:19: (W113) accessing undefined variable ''x''', + \ ]) + +Execute(The luacheck handler should respect the warn_about_trailing_whitespace option): + let g:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 43, + \ 'text': 'unused argument ''g''', + \ 'code': 'W212', + \ 'type': 'W', + \ } + \ ], + \ ale_linters#lua#luacheck#Handle(347, [ + \ '/file/path/here.lua:15:97: (W614) trailing whitespace in a comment', + \ '/file/path/here.lua:16:60: (W612) line contains trailing whitespace', + \ '/file/path/here.lua:17:1: (W611) line contains only whitespace', + \ '/file/path/here.lua:27:57: (W613) trailing whitespace in a string', + \ '/file/path/here.lua:5:43: (W212) unused argument ''g''', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_markdownlint_handler.vader b/vim-config/plugins/ale/test/handler/test_markdownlint_handler.vader new file mode 100644 index 00000000..f2e6e328 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_markdownlint_handler.vader @@ -0,0 +1,91 @@ +Before: + runtime ale_linters/markdown/markdownlint.vim + +After: + call ale#linter#Reset() + +Execute(The Markdownlint handler should parse pre v0.19.0 output with single digit line correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'code': 'MD013/line-length', + \ 'text': 'Line length [Expected: 80; Actual: 114]', + \ 'type': 'W' + \ } + \ ], + \ ale#handlers#markdownlint#Handle(0, [ + \ 'README.md: 1: MD013/line-length Line length [Expected: 80; Actual: 114]' + \ ]) + +Execute(The Markdownlint handler should parse pre v0.19.0 output with multi digit line correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 100, + \ 'code': 'MD013/line-length', + \ 'text': 'Line length [Expected: 80; Actual: 114]', + \ 'type': 'W' + \ } + \ ], + \ ale#handlers#markdownlint#Handle(0, [ + \ 'README.md: 100: MD013/line-length Line length [Expected: 80; Actual: 114]' + \ ]) + +Execute(The Markdownlint handler should parse post v0.19.0 output with single digit line correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'code': 'MD013/line-length', + \ 'text': 'Line length [Expected: 80; Actual: 114]', + \ 'type': 'W' + \ } + \ ], + \ ale#handlers#markdownlint#Handle(0, [ + \ 'README.md:1 MD013/line-length Line length [Expected: 80; Actual: 114]' + \ ]) + +Execute(The Markdownlint handler should parse post v0.19.0 output with multi digit line correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 100, + \ 'code': 'MD013/line-length', + \ 'text': 'Line length [Expected: 80; Actual: 114]', + \ 'type': 'W' + \ } + \ ], + \ ale#handlers#markdownlint#Handle(0, [ + \ 'README.md:100 MD013/line-length Line length [Expected: 80; Actual: 114]' + \ ]) + + +Execute(The Markdownlint handler should parse post v0.22.0 output with column correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 10, + \ 'col': 20, + \ 'code': 'MD013/line-length', + \ 'text': 'Line length [Expected: 80; Actual: 114]', + \ 'type': 'W' + \ } + \ ], + \ ale#handlers#markdownlint#Handle(0, [ + \ 'README.md:10:20 MD013/line-length Line length [Expected: 80; Actual: 114]' + \ ]) + +Execute(The Markdownlint handler should parse output with multiple slashes in rule name correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 10, + \ 'code': 'MD022/blanks-around-headings/blanks-around-headers', + \ 'text': 'Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Above] [Context: "### something"]', + \ 'type': 'W' + \ } + \ ], + \ ale#handlers#markdownlint#Handle(0, [ + \ 'README.md:10 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Above] [Context: "### something"]' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_mcs_handler.vader b/vim-config/plugins/ale/test/handler/test_mcs_handler.vader new file mode 100644 index 00000000..3defc328 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_mcs_handler.vader @@ -0,0 +1,37 @@ +Before: + runtime ale_linters/cs/mcs.vim + +After: + call ale#linter#Reset() + +Execute(The mcs handler should handle cannot find symbol errors): + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'col' : 29, + \ 'text': '; expected', + \ 'code': 'CS1001', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 101, + \ 'col': 0, + \ 'text': 'Unexpected processor directive (no #if for this #endif)', + \ 'code': 'CS1028', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 10, + \ 'col': 12, + \ 'text': 'some warning', + \ 'code': 'CS0123', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#cs#mcs#Handle(347, [ + \ 'Tests.cs(12,29): error CS1001: ; expected', + \ 'Tests.cs(101,0): error CS1028: Unexpected processor directive (no #if for this #endif)', + \ 'Tests.cs(10,12): warning CS0123: some warning', + \ 'Compilation failed: 2 error(s), 1 warnings', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_mcsc_handler.vader b/vim-config/plugins/ale/test/handler/test_mcsc_handler.vader new file mode 100644 index 00000000..c04f7d27 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_mcsc_handler.vader @@ -0,0 +1,88 @@ +Before: + Save g:ale_cs_mcsc_source + + unlet! g:ale_cs_mcsc_source + + call ale#test#SetDirectory('/testplugin/test/handler') + call ale#test#SetFilename('Test.cs') + + runtime ale_linters/cs/mcsc.vim + +After: + unlet! g:ale_cs_mcsc_source + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The mcs handler should work with the default of the buffer's directory): + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'col' : 29, + \ 'text': '; expected', + \ 'code': 'CS1001', + \ 'type': 'E', + \ 'filename': ale#path#Simplify(g:dir . '/Test.cs'), + \ }, + \ ], + \ ale_linters#cs#mcsc#Handle(bufnr(''), [ + \ 'Test.cs(12,29): error CS1001: ; expected', + \ 'Compilation failed: 2 error(s), 1 warnings', + \ ]) + +Execute(The mcs handler should handle cannot find symbol errors): + let g:ale_cs_mcsc_source = '/home/foo/project/bar' + + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'col' : 29, + \ 'text': '; expected', + \ 'code': 'CS1001', + \ 'type': 'E', + \ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'), + \ }, + \ { + \ 'lnum': 101, + \ 'col': 0, + \ 'text': 'Unexpected processor directive (no #if for this #endif)', + \ 'code': 'CS1028', + \ 'type': 'E', + \ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'), + \ }, + \ { + \ 'lnum': 10, + \ 'col': 12, + \ 'text': 'some warning', + \ 'code': 'CS0123', + \ 'type': 'W', + \ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'), + \ }, + \ ], + \ ale_linters#cs#mcsc#Handle(bufnr(''), [ + \ 'Test.cs(12,29): error CS1001: ; expected', + \ 'Test.cs(101,0): error CS1028: Unexpected processor directive (no #if for this #endif)', + \ 'Test.cs(10,12): warning CS0123: some warning', + \ 'Compilation failed: 2 error(s), 1 warnings', + \ ]) + +Execute(The mcsc handler should handle non file specific compiler errors without reporting overal status report as error): + let g:ale_cs_mcsc_source = '/home/foo/project/bar' + + AssertEqual + \ [ + \ { + \ 'lnum': -1, + \ 'col' : -1, + \ 'text': 'No files to compile were specified', + \ 'code': 'CS2008', + \ 'type': 'E', + \ 'filename': '', + \ }, + \ ], + \ ale_linters#cs#mcsc#Handle(bufnr(''), [ + \ 'error CS2008: No files to compile were specified', + \ 'Compilation failed: 1 error(s), 0 warnings', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_mdl_handler.vader b/vim-config/plugins/ale/test/handler/test_mdl_handler.vader new file mode 100644 index 00000000..d01b52af --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_mdl_handler.vader @@ -0,0 +1,25 @@ +Before: + runtime ale_linters/markdown/mdl.vim + +After: + call ale#linter#Reset() + +Execute(The mdl handler should parse output correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'code': 'MD002/first-header-h1', + \ 'text': 'First header should be a top level header', + \ 'type': 'W' + \ }, + \ { + \ 'lnum': 18, + \ 'code': 'MD033/no-inline-html', + \ 'text': 'Inline HTML', + \ 'type': 'W' + \ } + \ ], + \ ale_linters#markdown#mdl#Handle(0, [ + \ '[{"filename":"README.md","line":1,"rule":"MD002","aliases":["first-header-h1"],"description":"First header should be a top level header"},{"filename":"README.md","line":18,"rule":"MD033","aliases":["no-inline-html"],"description":"Inline HTML"}]' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_mercury_mmc_handler.vader b/vim-config/plugins/ale/test/handler/test_mercury_mmc_handler.vader new file mode 100644 index 00000000..e862f287 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_mercury_mmc_handler.vader @@ -0,0 +1,58 @@ +Before: + runtime ale_linters/mercury/mmc.vim + +After: + call ale#linter#Reset() + +Execute(The mmc handler should handle syntax errors): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'type': 'E', + \ 'text': "Syntax error at token ',': operator precedence error." + \ } + \ ], + \ ale_linters#mercury#mmc#Handle(1, [ + \ "file_name.m:003: Syntax error at token ',': operator precedence error." + \ ]) + +Execute(The mmc handler should handle warnings): + AssertEqual + \ [ + \ { + \ 'lnum': 10, + \ 'type': 'W', + \ 'text': 'Warning: reference to uninitialized state variable !.X.' + \ }, + \ { + \ 'lnum': 12, + \ 'type': 'W', + \ 'text': 'warning: determinism declaration could be tighter.' + \ } + \ ], + \ ale_linters#mercury#mmc#Handle(1, [ + \ 'file_name.m:010: Warning: reference to uninitialized state variable !.X.', + \ "file_name.m:012: In `some_predicate':", + \ 'file_name.m:012: warning: determinism declaration could be tighter.' + \ ]) + +Execute(The mmc handler should handle semantic errors): + AssertEqual + \ [ + \ { + \ 'lnum': 7, + \ 'type': 'E', + \ 'text': "error: undefined type `bar'/0." + \ }, + \ { + \ 'lnum': 15, + \ 'type': 'E', + \ 'text': "Error: circular equivalence type `file_name.foo'/0." + \ } + \ ], + \ ale_linters#mercury#mmc#Handle(1, [ + \ "file_name.m:007: In clause for predicate `foldit'/4:", + \ "file_name.m:007: error: undefined type `bar'/0.", + \ "file_name.m:015: Error: circular equivalence type `file_name.foo'/0." + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_mix_handler.vader b/vim-config/plugins/ale/test/handler/test_mix_handler.vader new file mode 100644 index 00000000..a5549b5d --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_mix_handler.vader @@ -0,0 +1,21 @@ +Before: + runtime ale_linters/elixir/mix.vim + +After: + call ale#linter#Reset() + +Execute(The mix handler should parse lines correctly): + + AssertEqual + \ [ + \ { + \ 'bufnr': 347, + \ 'lnum': 87, + \ 'col': 0, + \ 'text': 'undefined function update_in/4', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#elixir#mix#Handle(347, [ + \ '** (CompileError) apps/sim/lib/sim/server.ex:87: undefined function update_in/4' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_msgfmt_hander.vader b/vim-config/plugins/ale/test/handler/test_msgfmt_hander.vader new file mode 100644 index 00000000..1a67dbc6 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_msgfmt_hander.vader @@ -0,0 +1,24 @@ +Before: + runtime ale_linters/po/msgfmt.vim + +After: + call ale#linter#Reset() + +Execute(Duplicate messages should be made easier to navigate): + AssertEqual + \ [ + \ {'lnum': 14, 'col': 0, 'type': 'W', 'text': 'some other thing'}, + \ {'lnum': 1746, 'col': 0, 'type': 'W', 'text': 'duplicate of message at line 262'}, + \ {'lnum': 262, 'col': 0, 'type': 'W', 'text': 'first location of duplicate of message at line 1746'}, + \ {'lnum': 666, 'col': 0, 'type': 'W', 'text': 'duplicate message definition...'}, + \ {'lnum': 888, 'col': 0, 'type': 'W', 'text': 'some other thing'}, + \ {'lnum': 999, 'col': 0, 'type': 'W', 'text': '...this is the location of the first definition'}, + \ ], + \ ale_linters#po#msgfmt#Handle(bufnr(''), [ + \ '/tmp/v6GMUFf/16/foo.po:14: some other thing', + \ '/tmp/v6GMUFf/16/foo.po:1746: duplicate message definition...', + \ '/tmp/v6GMUFf/16/foo.po:262: ...this is the location of the first definition', + \ '/tmp/v6GMUFf/16/foo.po:666: duplicate message definition...', + \ '/tmp/v6GMUFf/16/foo.po:888: some other thing', + \ '/tmp/v6GMUFf/16/foo.po:999: ...this is the location of the first definition', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_mypy_handler.vader b/vim-config/plugins/ale/test/handler/test_mypy_handler.vader new file mode 100644 index 00000000..039155a2 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_mypy_handler.vader @@ -0,0 +1,141 @@ +Before: + Save g:ale_python_mypy_ignore_invalid_syntax + Save g:ale_python_mypy_show_notes + + unlet! g:ale_python_mypy_show_notes + unlet! g:ale_python_mypy_ignore_invalid_syntax + + runtime ale_linters/python/mypy.vim + + call ale#test#SetDirectory('/testplugin/test/handler') + +After: + Restore + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The mypy handler should parse lines correctly): + call ale#test#SetFilename('__init__.py') + + let g:ale_python_mypy_show_notes = 0 + + AssertEqual + \ [ + \ { + \ 'lnum': 768, + \ 'col': 38, + \ 'filename': ale#path#Simplify(g:dir . '/baz.py'), + \ 'type': 'E', + \ 'text': 'Cannot determine type of ''SOME_SYMBOL''', + \ }, + \ { + \ 'lnum': 821, + \ 'col': 38, + \ 'filename': ale#path#Simplify(g:dir . '/baz.py'), + \ 'type': 'E', + \ 'text': 'Cannot determine type of ''SOME_SYMBOL''', + \ }, + \ { + \ 'lnum': 38, + \ 'col': 44, + \ 'filename': ale#path#Simplify(g:dir . '/other.py'), + \ 'type': 'E', + \ 'text': 'Cannot determine type of ''ANOTHER_SYMBOL''', + \ }, + \ { + \ 'lnum': 15, + \ 'col': 3, + \ 'filename': ale#path#Simplify(g:dir . '/__init__.py'), + \ 'type': 'E', + \ 'text': 'Argument 1 to "somefunc" has incompatible type "int"; expected "str"' + \ }, + \ { + \ 'lnum': 72, + \ 'col': 1, + \ 'filename': ale#path#Simplify(g:dir . '/__init__.py'), + \ 'type': 'W', + \ 'text': 'Some warning', + \ }, + \ ], + \ ale_linters#python#mypy#Handle(bufnr(''), [ + \ 'baz.py: note: In class "SomeClass":', + \ 'baz.py:768:38: error: Cannot determine type of ''SOME_SYMBOL''', + \ 'baz.py: note: In class "AnotherClass":', + \ 'baz.py:821:38: error: Cannot determine type of ''SOME_SYMBOL''', + \ '__init__.py:92: note: In module imported here:', + \ 'other.py: note: In class "YetAnotherClass":', + \ 'other.py:38:44: error: Cannot determine type of ''ANOTHER_SYMBOL''', + \ '__init__.py: note: At top level:', + \ '__init__.py:15:3: error: Argument 1 to "somefunc" has incompatible type "int"; expected "str"', + \ 'another_module/bar.py:14: note: In module imported here,', + \ 'another_module/__init__.py:16: note: ... from here,', + \ '__init__.py:72:1: warning: Some warning', + \ ]) + +Execute(The mypy handler should show notes if enabled): + call ale#test#SetFilename('__init__.py') + + AssertEqual + \ [ + \ { + \ 'lnum': 72, + \ 'col': 1, + \ 'filename': ale#path#Simplify(g:dir . '/__init__.py'), + \ 'type': 'I', + \ 'text': 'A note', + \ }, + \ ], + \ ale_linters#python#mypy#Handle(bufnr(''), [ + \ '__init__.py:72:1: note: A note', + \ ]) + + let g:ale_python_mypy_show_notes = 0 + + AssertEqual + \ [], + \ ale_linters#python#mypy#Handle(bufnr(''), [ + \ '__init__.py:72:1: note: A note', + \ ]) + +Execute(The mypy handler should handle Windows names with spaces): + " This test works on Unix, where this is seen as a single filename + silent file C:\\something\\with\ spaces.py + + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 0, + \ 'filename': ale#path#Simplify('C:\something\with spaces.py'), + \ 'type': 'E', + \ 'text': 'No library stub file for module ''django.db''', + \ }, + \ ], + \ ale_linters#python#mypy#Handle(bufnr(''), [ + \ 'C:\something\with spaces.py:4: error: No library stub file for module ''django.db''', + \ ]) + +Execute(The mypy syntax errors shouldn't be ignored by default): + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 0, + \ 'filename': ale#path#Simplify(g:dir . '/foo.py'), + \ 'type': 'E', + \ 'text': 'invalid syntax', + \ }, + \ ], + \ ale_linters#python#mypy#Handle(bufnr(''), [ + \ 'foo.py:4: error: invalid syntax', + \ ]) + +Execute(The mypy syntax errors should be ignored when the option is on): + let g:ale_python_mypy_ignore_invalid_syntax = 1 + + AssertEqual + \ [], + \ ale_linters#python#mypy#Handle(bufnr(''), [ + \ 'foo.py:4: error: invalid syntax', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_nagelfar_handler.vader b/vim-config/plugins/ale/test/handler/test_nagelfar_handler.vader new file mode 100644 index 00000000..ceaee19c --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_nagelfar_handler.vader @@ -0,0 +1,174 @@ +Before: + runtime ale_linters/tcl/nagelfar.vim + +After: + call ale#linter#Reset() + +Execute(The nagelfar handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'type': 'W', + \ 'text': 'Found constant "bepa" which is also a variable.' + \ }, + \ { + \ 'lnum': 7, + \ 'type': 'E', + \ 'text': 'Unknown variable "cep"' + \ }, + \ { + \ 'lnum': 7, + \ 'type': 'W', + \ 'text': 'Unknown command "se"' + \ }, + \ { + \ 'lnum': 8, + \ 'type': 'E', + \ 'text': 'Unknown variable "epa"' + \ }, + \ { + \ 'lnum': 10, + \ 'type': 'E', + \ 'text': 'Unknown variable "depa"' + \ }, + \ { + \ 'lnum': 10, + \ 'type': 'W', + \ 'text': 'Suspicious variable name "$depa"' + \ }, + \ { + \ 'lnum': 11, + \ 'type': 'W', + \ 'text': 'Suspicious variable name "$cepa"' + \ }, + \ { + \ 'lnum': 13, + \ 'type': 'E', + \ 'text': 'Wrong number of arguments (3) to "set"' + \ }, + \ { + \ 'lnum': 13, + \ 'type': 'W', + \ 'text': 'Found constant "bepa" which is also a variable.' + \ }, + \ { + \ 'lnum': 13, + \ 'type': 'W', + \ 'text': 'Found constant "cepa" which is also a variable.' + \ }, + \ { + \ 'lnum': 18, + \ 'type': 'E', + \ 'text': 'Badly formed if statement' + \ }, + \ { + \ 'lnum': 24, + \ 'type': 'E', + \ 'text': 'Unknown subcommand "gurka" to "info"' + \ }, + \ { + \ 'lnum': 31, + \ 'type': 'W', + \ 'text': 'Switch pattern starting with #. This could be a bad comment.' + \ }, + \ { + \ 'lnum': 31, + \ 'type': 'W', + \ 'text': 'Unknown command "This"' + \ }, + \ { + \ 'lnum': 31, + \ 'type': 'W', + \ 'text': 'Unknown command "bad"' + \ }, + \ { + \ 'lnum': 34, + \ 'type': 'W', + \ 'text': 'Unknown command "miffo"' + \ }, + \ { + \ 'lnum': 55, + \ 'type': 'W', + \ 'text': 'Suspicious variable name "$bepa"' + \ }, + \ { + \ 'lnum': 56, + \ 'type': 'W', + \ 'text': 'Suspicious variable name "$apa"' + \ }, + \ { + \ 'lnum': 61, + \ 'type': 'E', + \ 'text': 'Could not complete statement.' + \ }, + \ { + \ 'lnum': 67, + \ 'type': 'E', + \ 'text': 'Could not complete statement.' + \ }, + \ { + \ 'lnum': 70, + \ 'type': 'E', + \ 'text': 'Wrong number of arguments (4) to "proc"' + \ }, + \ { + \ 'lnum': 72, + \ 'type': 'E', + \ 'text': 'Wrong number of arguments (1) to "if"' + \ }, + \ { + \ 'lnum': 75, + \ 'type': 'E', + \ 'text': 'Unbalanced close brace found' + \ }, + \ { + \ 'lnum': 82, + \ 'type': 'E', + \ 'text': 'Unbalanced close brace found' + \ }, + \ { + \ 'lnum': 88, + \ 'type': 'E', + \ 'text': 'Could not complete statement.' + \ }, + \ { + \ 'lnum': 90, + \ 'type': 'E', + \ 'text': 'Wrong number of arguments (1) to "if"' + \ }, + \ { + \ 'lnum': 93, + \ 'type': 'W', + \ 'text': 'Close brace not aligned with line 90 (4 0)' + \ }, + \ ], + \ ale_linters#tcl#nagelfar#Handle(bufnr(''), [ + \ 'Line 5: W Found constant "bepa" which is also a variable.', + \ 'Line 7: E Unknown variable "cep"', + \ 'Line 7: W Unknown command "se"', + \ 'Line 8: E Unknown variable "epa"', + \ 'Line 10: E Unknown variable "depa"', + \ 'Line 10: N Suspicious variable name "$depa"', + \ 'Line 11: N Suspicious variable name "$cepa"', + \ 'Line 13: E Wrong number of arguments (3) to "set"', + \ 'Line 13: W Found constant "bepa" which is also a variable.', + \ 'Line 13: W Found constant "cepa" which is also a variable.', + \ 'Line 18: E Badly formed if statement', + \ 'Line 24: E Unknown subcommand "gurka" to "info"', + \ 'Line 31: W Switch pattern starting with #. This could be a bad comment.', + \ 'Line 31: W Unknown command "This"', + \ 'Line 31: W Unknown command "bad"', + \ 'Line 34: W Unknown command "miffo"', + \ 'Line 55: N Suspicious variable name "$bepa"', + \ 'Line 56: N Suspicious variable name "$apa"', + \ 'Line 61: E Could not complete statement.', + \ 'Line 67: E Could not complete statement.', + \ 'Line 70: E Wrong number of arguments (4) to "proc"', + \ 'Line 72: E Wrong number of arguments (1) to "if"', + \ 'Line 75: E Unbalanced close brace found', + \ 'Line 82: E Unbalanced close brace found', + \ 'Line 88: E Could not complete statement.', + \ 'Line 90: E Wrong number of arguments (1) to "if"', + \ 'Line 93: N Close brace not aligned with line 90 (4 0)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_nasm_handler.vader b/vim-config/plugins/ale/test/handler/test_nasm_handler.vader new file mode 100644 index 00000000..9c7d9650 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_nasm_handler.vader @@ -0,0 +1,30 @@ +Before: + runtime ale_linters/nasm/nasm.vim + +After: + call ale#linter#Reset() + +Execute(The nasm handler should parse GCC style output from nasm correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'text': "label alone on a line without a colon might be in error", + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'text': "invalid combination of opcode and operands", + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 7, + \ 'text': "unable to open include file `bar.asm'", + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#nasm#nasm#Handle(bufnr(''), [ + \ "tmp.asm:2: warning: label alone on a line without a colon might be in error", + \ "tmp.asm:4: error: invalid combination of opcode and operands", + \ "tmp.asm:7: fatal: unable to open include file `bar.asm'" + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_nim_handler.vader b/vim-config/plugins/ale/test/handler/test_nim_handler.vader new file mode 100644 index 00000000..b6784d84 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_nim_handler.vader @@ -0,0 +1,80 @@ +Before: + runtime ale_linters/nim/nimcheck.vim + +After: + call ale#linter#Reset() + +Execute(Parsing nim errors should work): + silent file foobar.nim + + AssertEqual + \ [ + \ { + \ 'lnum': 8, + \ 'col': 8, + \ 'text': 'use {.base.} for base methods; baseless methods are deprecated', + \ 'code': 'UseBase', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 12, + \ 'col': 2, + \ 'text': 'identifier expected, but found ''a.barfoo''', + \ 'type': 'E', + \ 'end_col': 9, + \ }, + \ { + \ 'lnum': 2, + \ 'col': 5, + \ 'text': '''NotUsed'' is declared but not used', + \ 'code': 'XDeclaredButNotUsed', + \ 'type': 'W', + \ 'end_col': 11, + \ }, + \ { + \ 'lnum': 12, + \ 'col': 2, + \ 'text': 'with : character', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 8, + \ 'text': 'imported and not used: ''strutils''', + \ 'code': 'UnusedImport', + \ 'type': 'W', + \ 'end_col': 15, + \ }, + \ { + \ 'lnum': 12, + \ 'col': 9, + \ 'text': 'undeclared identifier: ''total''', + \ 'type': 'E', + \ 'end_col': 13, + \ }, + \ { + \ 'lnum': 14, + \ 'col': 1, + \ 'text': '''sum'' cannot be assigned to', + \ 'type': 'E', + \ 'end_col': 3, + \ }, + \ { + \ 'lnum': 15, + \ 'col': 1, + \ 'text': 'redefinition of ''getName''; previous declaration here: /nested/folder/foobar.nim(14, 6)', + \ 'type': 'E', + \ 'end_col': 7, + \ }, + \ ], + \ ale_linters#nim#nimcheck#Handle(bufnr(''), [ + \ 'Line with wrong( format)', + \ 'foobar.nim(8, 8) Warning: use {.base.} for base methods; baseless methods are deprecated [UseBase]', + \ 'foobar.nim(12, 2) Error: identifier expected, but found ''a.barfoo''', + \ '/nested/folder/foobar.nim(2, 5) Hint: ''NotUsed'' is declared but not used [XDeclaredButNotUsed]', + \ 'foobar.nim(12, 2) Error: with : character', + \ 'foobar.nim(1, 8) Warning: imported and not used: ''strutils'' [UnusedImport]', + \ 'foobar.nim(12, 9) Error: undeclared identifier: ''total''', + \ 'foobar.nim(14, 1) Error: ''sum'' cannot be assigned to', + \ 'foobar.nim(15, 1) Error: redefinition of ''getName''; previous declaration here: /nested/folder/foobar.nim(14, 6)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_nix_handler.vader b/vim-config/plugins/ale/test/handler/test_nix_handler.vader new file mode 100644 index 00000000..87e8b68f --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_nix_handler.vader @@ -0,0 +1,51 @@ +Before: + runtime ale_linters/nix/nix.vim + +After: + call ale#linter#Reset() + +Execute(The nix handler should parse nix-instantiate error messages correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 3, + \ 'type': 'E', + \ 'text': "syntax error, unexpected ']', expecting ';'", + \ }, + \ { + \ 'lnum': 3, + \ 'col': 5, + \ 'type': 'E', + \ 'text': "undefined variable 'foo'", + \ }, + \ + \ ], + \ ale_linters#nix#nix#Handle(bufnr(''), [ + \ "@nix {\"line\":6,\"column\":3,\"raw_msg\":\"syntax error, unexpected ']', expecting ';'\"}", + \ "@nix {\"line\":3,\"column\":5,\"raw_msg\":\"undefined variable 'foo'\"}", + \ "@nix {\"unrelated\":\"message\"}" + \ ]) + +Execute(The nix handler should parse message from old nix-instantiate correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 23, + \ 'col': 14, + \ 'text': 'error: syntax error, unexpected IN', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 12, + \ 'text': 'error: syntax error, unexpected ''='', expecting '';''', + \ 'type': 'E', + \ }, + \ + \ ], + \ ale_linters#nix#nix#Handle(47, [ + \ 'This line should be ignored', + \ 'error: syntax error, unexpected IN, at /path/to/filename.nix:23:14', + \ 'error: syntax error, unexpected ''='', expecting '';'', at /path/to/filename.nix:3:12', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_perl6_handler.vader b/vim-config/plugins/ale/test/handler/test_perl6_handler.vader new file mode 100644 index 00000000..452a9174 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_perl6_handler.vader @@ -0,0 +1,277 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/handler') + + runtime ale_linters/perl6/perl6.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The Perl6 linter should handle empty output): + call ale#test#SetFilename('bar.pl6') + + AssertEqual [], ale_linters#perl6#perl6#Handle(bufnr(''), []) + +Execute(The Perl6 linter should complain about undeclared variables): + call ale#test#SetFilename('bar.pl6') + + AssertEqual + \ [ + \ { + \ 'lnum': '6', + \ 'text': 'Variable ''$tes'' is not declared. Did you mean any of these? $res $test ', + \ 'type': 'E', + \ 'col': '', + \ 'end_lnum': '', + \ 'code': 'X::Undeclared', + \ } + \ ], + \ ale_linters#perl6#perl6#Handle(bufnr(''), [ + \ '{ + \ "X::Undeclared" : { + \ "highexpect" : [ ], + \ "is-compile-time" : 1, + \ "modules" : [ ], + \ "column" : null, + \ "pos" : 18, + \ "symbol" : "$tes", + \ "filename" : "bar.pl6", + \ "what" : "Variable", + \ "pre" : "my $test = 0; say ", + \ "post" : "$tes", + \ "suggestions" : [ + \ "$res", + \ "$test" + \ ], + \ "line" : 6, + \ "message" : "Variable ''$tes'' is not declared. Did you mean any of these?\n $res\n $test\n" + \ } + \ }' + \ ]) + +Execute(The Perl6 linter should complain about Comp::AdHoc errors): + call ale#test#SetFilename('bar.pl6') + + AssertEqual + \ [ + \ { + \ 'lnum': '3', + \ 'type': 'E', + \ 'text': 'is repr(...) trait needs a parameter', + \ 'col': '', + \ 'end_lnum': '', + \ 'code': 'X::Comp::AdHoc', + \ } + \ ], + \ ale_linters#perl6#perl6#Handle(bufnr(''), [ + \ '{ + \ "X::Comp::AdHoc" : { + \ "pre" : "class test is repr", + \ "message" : "is repr(...) trait needs a parameter", + \ "line" : 3, + \ "post" : " {}", + \ "is-compile-time" : true, + \ "pos" : 19, + \ "highexpect" : [ ], + \ "payload" : "is repr(...) trait needs a parameter", + \ "filename" : "bar.pl6", + \ "column" : null, + \ "modules" : [ ] + \ } + \ }' + \]) + +Execute(The Perl6 linter should be able to extract a line number from an error message): + call ale#test#SetFilename('bar.pl6') + + AssertEqual + \ [ + \ { + \ 'lnum': '3', + \ 'text': 'Could not find Module::Does::not::exist at line 3 in: /usr/share/perl6/site /usr/share/perl6/vendor /usr/share/perl6 CompUnit::Repository::AbsolutePath<94023691448416> CompUnit::Repository::NQP<94023670532736> CompUnit::Repository::Perl5<94023670532776>', + \ 'col': '', + \ 'type': 'E', + \ 'end_lnum': '', + \ 'code': 'X::CompUnit::UnsatisfiedDependency', + \ } + \ ], + \ ale_linters#perl6#perl6#Handle(bufnr(''), [ + \ '{ + \ "X::CompUnit::UnsatisfiedDependency" : { + \ "message" : "Could not find Module::Does::not::exist at line 3 in:\n /usr/share/perl6/site\n /usr/share/perl6/vendor\n /usr/share/perl6\n CompUnit::Repository::AbsolutePath<94023691448416>\n CompUnit::Repository::NQP<94023670532736>\n CompUnit::Repository::Perl5<94023670532776>", + \ "specification" : "Module::Does::not::exist" + \ } + \ }' + \ ]) + +Execute(The Perl6 linter should be able to differentiate between warnings and errors): + call ale#test#SetFilename('bar.pl6') + + AssertEqual + \ [ + \ { + \ 'lnum': '1', + \ 'col': '', + \ 'code': 'X::Syntax::Regex::Unterminated', + \ 'end_lnum': '', + \ 'type': 'E', + \ 'text': 'Regex not terminated.', + \ }, + \ { + \ 'lnum': '1', + \ 'col': '', + \ 'code': 'X::Comp::AdHoc', + \ 'end_lnum': '', + \ 'type': 'W', + \ 'text': 'Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)', + \ } + \ ], + \ ale_linters#perl6#perl6#Handle(bufnr(''), [ + \ '{ + \ "X::Comp::Group" : { + \ "message" : "Regex not terminated.\nUnable to parse regex; couldn''t find final ''/''\nSpace is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)", + \ "panic" : "Unable to parse regex; couldn''t find final ''/''", + \ "sorrows" : [ + \ { + \ "X::Syntax::Regex::Unterminated" : { + \ "highexpect" : [ + \ "infix stopper" + \ ], + \ "pos" : 6, + \ "is-compile-time" : 1, + \ "modules" : [ ], + \ "post" : "", + \ "message" : "Regex not terminated.", + \ "line" : 1, + \ "filename" : "bar.pl6", + \ "column" : null, + \ "pre" : "/win 3" + \ } + \ } + \ ], + \ "worries" : [ + \ { + \ "X::Comp::AdHoc" : { + \ "filename" : "bar.pl6", + \ "line" : 1, + \ "column" : null, + \ "pre" : "/win", + \ "highexpect" : [ ], + \ "payload" : "Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)", + \ "post" : " 3", + \ "message" : "Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)", + \ "modules" : [ ], + \ "is-compile-time" : true, + \ "pos" : 4 + \ } + \ } + \ ] + \ } + \ }' + \]) + +Execute(The Perl6 linter should gracefully handle non-JSON messages): + call ale#test#SetFilename('bar.pl6') + + AssertEqual + \ [ + \ { + \ 'lnum': '1', + \ 'text': 'Received output in the default Perl6 error format. See :ALEDetail for details', + \ 'type': 'W', + \ 'detail': join([ + \ 'Potential difficulties:', + \ ' Redeclaration of symbol ''$_''', + \ ' at /home/travis/perl6-error-fail/insanity-test.pl6:1', + \ ' ------> sub foo($_) {.say}; my $_ = 1; .&foo;', + \ ' Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)', + \ ' at /home/travis/perl6-error-fail/insanity-test.pl6:4', + \ ' ------> /win 3/', + \ 'Syntax OK',], "\n") + \ } + \ ], + \ ale_linters#perl6#perl6#Handle(bufnr(''), [ + \ 'Potential difficulties:', + \ ' Redeclaration of symbol ''$_''', + \ ' at /home/travis/perl6-error-fail/insanity-test.pl6:1', + \ ' ------> sub foo($_) {.say}; my $_ = 1; .&foo;', + \ ' Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)', + \ ' at /home/travis/perl6-error-fail/insanity-test.pl6:4', + \ ' ------> /win 3/', + \ 'Syntax OK' + \ ]) + +Execute(The Perl6 linter should gracefully handle messages without a line number): + call ale#test#SetFilename('bar.pl6') + + AssertEqual + \ [ + \ { + \ 'lnum': '1', + \ 'end_lnum': '', + \ 'text': 'Cannot find method ''has_compile_time_value'' on object of type NQPMu', + \ 'type': 'E', + \ 'col' : '', + \ 'code': 'X::AdHoc', + \ } + \ ], + \ ale_linters#perl6#perl6#Handle(bufnr(''), [ + \ '{', + \ '"X::AdHoc" : {', + \ '"message" : "Cannot find method ''has_compile_time_value'' on object of type NQPMu",', + \ '"payload" : "Cannot find method ''has_compile_time_value'' on object of type NQPMu"', + \ '}', + \ '}', + \ ]) + +Execute(The Perl6 linter should not include errors from a known separate file): + call ale#test#SetFilename('bar.pl6') + + AssertEqual + \ [], + \ ale_linters#perl6#perl6#Handle(bufnr(''), [ + \ '{ + \ "X::Undeclared" : { + \ "highexpect" : [ ], + \ "is-compile-time" : 1, + \ "modules" : [ ], + \ "column" : null, + \ "pos" : 18, + \ "symbol" : "$tes", + \ "filename" : "foo.pl6", + \ "what" : "Variable", + \ "pre" : "my $test = 0; say ", + \ "post" : "$tes", + \ "suggestions" : [ + \ "$res", + \ "$test" + \ ], + \ "line" : 6, + \ "message" : "Variable ''$tes'' is not declared. Did you mean any of these?\n $res\n $test\n" + \ } + \ }' + \ ]) + +Execute(The Perl6 linter should not ignore errors without a filename): + call ale#test#SetFilename('bar.pl6') + + AssertEqual + \ [ + \ { + \ 'lnum': '3', + \ 'end_lnum': '', + \ 'text': 'Cannot find method ''has_compile_time_value'' on object of type NQPMu', + \ 'type': 'E', + \ 'col' : '', + \ 'code': 'X::AdHoc', + \ } + \ ], + \ ale_linters#perl6#perl6#Handle(bufnr(''), [ + \ '{', + \ '"X::AdHoc" : {', + \ '"line" : 3,', + \ '"message" : "Cannot find method ''has_compile_time_value'' on object of type NQPMu",', + \ '"payload" : "Cannot find method ''has_compile_time_value'' on object of type NQPMu"', + \ '}', + \ '}', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_perl_handler.vader b/vim-config/plugins/ale/test/handler/test_perl_handler.vader new file mode 100644 index 00000000..060b1ffe --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_perl_handler.vader @@ -0,0 +1,109 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/handler') + + runtime ale_linters/perl/perl.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The Perl linter should handle empty output): + call ale#test#SetFilename('bar.pl') + + AssertEqual [], ale_linters#perl#perl#Handle(bufnr(''), []) + +Execute(The Perl linter should ignore errors from other files): + call ale#test#SetFilename('bar.pl') + + AssertEqual + \ [ + \ {'lnum': '2', 'type': 'E', 'text': 'Compilation failed in require'}, + \ ], + \ ale_linters#perl#perl#Handle(bufnr(''), [ + \ 'syntax error at ' . ale#path#Simplify(g:dir . '/foo.pm') . ' line 4, near "aklsdfjmy "', + \ 'Compilation failed in require at ' . ale#path#Simplify(g:dir . '/bar.pl') . ' line 2.', + \ 'BEGIN failed--compilation aborted at ' . ale#path#Simplify(g:dir . '/bar.pl') . ' line 2.', + \ ]) + +Execute(The Perl linter should complain about failing to locate modules): + AssertEqual + \ [ + \ { + \ 'lnum': '23', + \ 'type': 'E', + \ 'text': 'Can''t locate JustOneDb.pm in @INC (you may need to install the JustOneDb module) (@INC contains: /home/local/sean/work/PostgreSQL/6616/../../../../lib /home/local/sean/work/PostgreSQL/6616/lib lib /etc/perl /usr/local/lib/perl/5.18.2 /usr/local/share/perl/5.18.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.18 /usr/share/perl/5.18 /usr/local/lib/site_perl .)', + \ }, + \ ], + \ ale_linters#perl#perl#Handle(bufnr(''), [ + \ 'Can''t locate JustOneDb.pm in @INC (you may need to install the JustOneDb module) (@INC contains: /home/local/sean/work/PostgreSQL/6616/../../../../lib /home/local/sean/work/PostgreSQL/6616/lib lib /etc/perl /usr/local/lib/perl/5.18.2 /usr/local/share/perl/5.18.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.18 /usr/share/perl/5.18 /usr/local/lib/site_perl .) at - line 23.', + \ 'BEGIN failed--compilation aborted at - line 23.', + \ ]) + + +Execute(The Perl linter should complain about failing to locate modules): + AssertEqual + \ [ + \ {'lnum': '8', 'type': 'E', 'text': 'BEGIN failed--compilation aborted'}, + \ {'lnum': '10', 'type': 'E', 'text': 'BEGIN failed--compilation aborted'} + \ ], + \ ale_linters#perl#perl#Handle(bufnr(''), [ + \ 'Unable to build `ro` accessor for slot `path` in `App::CPANFileUpdate` because the slot cannot be found. at /extlib/Method/Traits.pm line 189.', + \ 'BEGIN failed--compilation aborted at - line 8.', + \ 'Unable to build `ro` accessor for slot `path` in `App::CPANFileUpdate` because the slot cannot be found. at /extlib/Method/Traits.pm line 189.', + \ 'BEGIN failed--compilation aborted at - line 10.', + \ ]) + +Execute(The Perl linter should not report warnings as errors): + AssertEqual + \ [ + \ {'lnum': '5', 'type': 'W', 'text': '"my" variable $foo masks earlier declaration in same scope'}, + \ ], + \ ale_linters#perl#perl#Handle(bufnr(''), [ + \ '"my" variable $foo masks earlier declaration in same scope at - line 5.', + \ 't.pl syntax OK', + \ ]) + +Execute(The Perl linter does not default to reporting generic error): + AssertEqual + \ [ + \ {'lnum': '8', 'type': 'E', 'text': 'Missing right curly or square bracket'}, + \ ], + \ ale_linters#perl#perl#Handle(bufnr(''), [ + \ 'Missing right curly or square bracket at - line 8, at end of line', + \ 'syntax error at - line 8, at EOF', + \ 'Execution of t.pl aborted due to compilation errors.', + \ ]) + +" The first "error" is actually a warning, but the current implementation +" doesn't have a good way of teasing out the warnings from amongst the +" errors. If we're able to do this in future, then we'll want to switch +" the first "E" to a "W". + +Execute(The Perl linter reports errors even when mixed with warnings): + AssertEqual + \ [ + \ {'lnum': '5', 'type': 'E', 'text': '"my" variable $foo masks earlier declaration in same scope'}, + \ {'lnum': '8', 'type': 'E', 'text': 'Missing right curly or square bracket'}, + \ ], + \ ale_linters#perl#perl#Handle(bufnr(''), [ + \ '"my" variable $foo masks earlier declaration in same scope at - line 5.', + \ 'Missing right curly or square bracket at - line 8, at end of line', + \ 'syntax error at - line 8, at EOF', + \ 'Execution of t.pl aborted due to compilation errors.', + \ ]) + +Execute(The Perl linter reports errors even when an additional file location is included): + AssertEqual + \ [ + \ {'lnum': '5', 'type': 'E', 'text': '"my" variable $foo masks earlier declaration in same scope'}, + \ {'lnum': '6', 'type': 'E', 'text': '"my" variable $foo masks earlier declaration in same scope'}, + \ {'lnum': '11', 'type': 'E', 'text': 'Global symbol "$asdf" requires explicit package name (did you forget to declare "my $asdf"?)'}, + \ {'lnum': '12', 'type': 'E', 'text': 'Global symbol "$asdf" requires explicit package name (did you forget to declare "my $asdf"?)'}, + \ ], + \ ale_linters#perl#perl#Handle(bufnr(''), [ + \ '"my" variable $foo masks earlier declaration in same scope at - line 5.', + \ '"my" variable $foo masks earlier declaration in same scope at - line 6, at line 1.', + \ 'Global symbol "$asdf" requires explicit package name (did you forget to declare "my $asdf"?) at - line 11.', + \ 'Global symbol "$asdf" requires explicit package name (did you forget to declare "my $asdf"?) at - line 12, line 1.', + \ 'Execution of t.pl aborted due to compilation errors.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_perlcritic_handler.vader b/vim-config/plugins/ale/test/handler/test_perlcritic_handler.vader new file mode 100644 index 00000000..f00b07da --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_perlcritic_handler.vader @@ -0,0 +1,20 @@ +Before: + runtime ale_linters/perl/perlcritic.vim + +After: + call ale#linter#Reset() + +Execute(The Perl::Critic handler should create all issues as warnings): + AssertEqual + \ [ + \ { + \ 'lnum': '21', + \ 'col': '17', + \ 'text': 'Regular expression without "/m" flag', + \ 'type': 'W', + \ } + \ ], + \ ale_linters#perl#perlcritic#Handle(99, [ + \ '21:17 Regular expression without "/m" flag' + \ ]) + diff --git a/vim-config/plugins/ale/test/handler/test_php_handler.vader b/vim-config/plugins/ale/test/handler/test_php_handler.vader new file mode 100644 index 00000000..6fe9b323 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_php_handler.vader @@ -0,0 +1,93 @@ +Before: + runtime ale_linters/php/php.vim + +After: + call ale#linter#Reset() + +Given (Some invalid lines of PHP): + [foo;] + class Foo { / } + $foo) + ['foo' 'bar'] + function count() {} + +Execute(The php handler should calculate column numbers): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 5, + \ 'end_col': 5, + \ 'text': "syntax error, unexpected ';', expecting ']'", + \ }, + \ { + \ 'lnum': 2, + \ 'col': 13, + \ 'end_col': 13, + \ 'text': "syntax error, unexpected '/', expecting function (T_FUNCTION) or const (T_CONST)", + \ }, + \ { + \ 'lnum': 3, + \ 'col': 5, + \ 'end_col': 5, + \ 'text': "syntax error, unexpected ')'", + \ }, + \ { + \ 'lnum': 4, + \ 'col': 8, + \ 'end_col': 12, + \ 'text': "syntax error, unexpected ''bar'' (T_CONSTANT_ENCAPSED_STRING), expecting ']'", + \ }, + \ ], + \ ale_linters#php#php#Handle(347, [ + \ "This line should be ignored completely", + \ "Parse error: syntax error, unexpected ';', expecting ']' in - on line 1", + \ "Parse error: syntax error, unexpected '/', expecting function (T_FUNCTION) or const (T_CONST) in - on line 2", + \ "Parse error: syntax error, unexpected ')' in - on line 3", + \ "Parse error: syntax error, unexpected ''bar'' (T_CONSTANT_ENCAPSED_STRING), expecting ']' in - on line 4", + \ ]) + +Execute (The php handler should ignore lines starting with 'PHP Parse error'): + AssertEqual + \ [], + \ ale_linters#php#php#Handle(347, [ + \ "PHP Parse error: syntax error, This line should be ignored completely in - on line 1", + \ ]) + +Execute (The php handler should handle lines containing 'Standard input code'): + AssertEqual + \ [ + \ { + \ 'lnum': 47, + \ 'col': 0, + \ 'text': "Invalid numeric literal", + \ }, + \ ], + \ ale_linters#php#php#Handle(347, [ + \ "Parse error: Invalid numeric literal in Standard input code on line 47", + \ ]) +Execute (The php handler should parse lines without column indication): + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 0, + \ 'text': "Cannot redeclare count()", + \ }, + \ { + \ 'lnum': 21, + \ 'col': 0, + \ 'text': "syntax error, unexpected end of file", + \ }, + \ { + \ 'lnum': 47, + \ 'col': 0, + \ 'text': "Invalid numeric literal", + \ }, + \ ], + \ ale_linters#php#php#Handle(347, [ + \ "This line should be ignored completely", + \ "Fatal error: Cannot redeclare count() in - on line 5", + \ "Parse error: syntax error, unexpected end of file in - on line 21", + \ "Parse error: Invalid numeric literal in - on line 47", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_php_phan_handler.vader b/vim-config/plugins/ale/test/handler/test_php_phan_handler.vader new file mode 100644 index 00000000..bbdae5dd --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_php_phan_handler.vader @@ -0,0 +1,26 @@ +Before: + runtime ale_linters/php/phan.vim + +After: + call ale#linter#Reset() + +Execute(The php static analyzer handler should parse errors from phan): + AssertEqual + \ [ + \ { + \ 'lnum': 25, + \ 'type': 'W', + \ 'text': 'Return type of getValidator is undeclared type \Respect\Validation\Validator', + \ 'filename': 'example.php', + \ }, + \ { + \ 'lnum': 66, + \ 'type': 'W', + \ 'text': 'Call to method string from undeclared class \Respect\Validation\Validator', + \ 'filename': 'example.php', + \ }, + \ ], + \ ale_linters#php#phan#Handle(347, [ + \ "example.php:25 PhanUndeclaredTypeReturnType Return type of getValidator is undeclared type \\Respect\\Validation\\Validator", + \ "example.php:66 PhanUndeclaredClassMethod Call to method string from undeclared class \\Respect\\Validation\\Validator", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_php_phpmd_handler.vader b/vim-config/plugins/ale/test/handler/test_php_phpmd_handler.vader new file mode 100644 index 00000000..f161d731 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_php_phpmd_handler.vader @@ -0,0 +1,24 @@ +Before: + runtime ale_linters/php/phpmd.vim + +After: + call ale#linter#Reset() + +Execute(The php static analyzer handler should parse errors from phpmd): + AssertEqual + \ [ + \ { + \ 'lnum': 22, + \ 'type': 'W', + \ 'text': "Avoid unused local variables such as '$response'.", + \ }, + \ { + \ 'lnum': 14, + \ 'type': 'W', + \ 'text': "The method test uses an else expression. Else is never necessary and you can simplify the code to work without else.", + \ }, + \ ], + \ ale_linters#php#phpmd#Handle(347, [ + \ "example.php:22 Avoid unused local variables such as '$response'.", + \ "example.php:14 The method test uses an else expression. Else is never necessary and you can simplify the code to work without else.", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_phpcs_handler.vader b/vim-config/plugins/ale/test/handler/test_phpcs_handler.vader new file mode 100644 index 00000000..26d35cb8 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_phpcs_handler.vader @@ -0,0 +1,28 @@ +Before: + runtime ale_linters/php/phpcs.vim + +After: + call ale#linter#Reset() + +Execute(phpcs errors should be handled): + AssertEqual + \ [ + \ { + \ 'lnum': 18, + \ 'col': 3, + \ 'type': 'E', + \ 'sub_type': 'style', + \ 'text': 'Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact)', + \ }, + \ { + \ 'lnum': 22, + \ 'col': 3, + \ 'type': 'E', + \ 'sub_type': 'style', + \ 'text': 'All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks)', + \ }, + \ ], + \ ale_linters#php#phpcs#Handle(bufnr(''), [ + \ '/path/to/some-filename.php:18:3: error - Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact)', + \ "/path/to/some-filename.php:22:3: error - All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks), found '\"\n'.", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_phpstan_handler.vader b/vim-config/plugins/ale/test/handler/test_phpstan_handler.vader new file mode 100644 index 00000000..58cb574f --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_phpstan_handler.vader @@ -0,0 +1,51 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + + runtime ale_linters/php/phpstan.vim + +After: + Restore + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Output without errors should be parsed correctly): + call ale#test#SetFilename('phpstan-test-files/foo/test.php') + + AssertEqual + \ [], + \ ale_linters#php#phpstan#Handle(bufnr(''), [ + \ '{"totals":{"errors":0,"file_errors":0},"files":[],"errors":[]}', + \ ]) + +Execute(Output with some errors should be parsed correctly): + call ale#test#SetFilename('phpstan-test-files/foo/test.php') + + AssertEqual + \ [ + \ { + \ 'lnum': 9, + \ 'text': 'Call to method format() on an unknown class DateTimeImutable.', + \ 'type': 'E' + \ }, + \ { + \ 'lnum': 16, + \ 'text': 'Sample message.', + \ 'type': 'E' + \ }, + \ { + \ 'lnum': 192, + \ 'text': 'Invalid command testCommand.', + \ 'type': 'E' + \ } + \ ], + \ ale_linters#php#phpstan#Handle(bufnr(''), [json_encode( + \ { + \ "totals":{"errors": 0, "file_errors": 11}, + \ "files":{expand('%:p'): {"errors": 3, "messages": [ + \ {"message": "Call to method format() on an unknown class DateTimeImutable.", "line":9}, + \ {"message": "Sample message.", "line":16}, + \ {"message": "Invalid command testCommand.", "line": 192} + \ ]}} + \ }, + \)]) diff --git a/vim-config/plugins/ale/test/handler/test_pmd_handler.vader b/vim-config/plugins/ale/test/handler/test_pmd_handler.vader new file mode 100644 index 00000000..4f64c9ca --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_pmd_handler.vader @@ -0,0 +1,42 @@ +Before: + runtime ale_linters/java/pmd.vim + +After: + call ale#linter#Reset() + +Execute(The pmd handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 18, + \ 'text': 'Each class should declare at least one constructor', + \ 'code': 'Code Style - AtLeastOneConstructor', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 36, + \ 'text': 'Local variable ''node'' could be declared final', + \ 'code': 'Code Style - LocalVariableCouldBeFinal', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#java#pmd#Handle(666, [ + \ '"Problem","Package","File","Priority","Line","Description","Rule set","Rule"', + \ '"1","rsb.performance.test.ros","/home/languitar/src/rsb-performance-test-api-ros/src/main/java/rsb/performance/test/ros/NodeHolder.java","3","18","Each class should declare at least one constructor","Code Style","AtLeastOneConstructor"', + \ '"2","rsb.performance.test.ros","/home/languitar/src/rsb-performance-test-api-ros/src/main/java/rsb/performance/test/ros/NodeHolder.java","1","36","Local variable ''node'' could be declared final","Code Style","LocalVariableCouldBeFinal"' + \ ]) + +Execute(The pmd handler should parse lines correctly for java files that use unnamed packages): + AssertEqual + \ [ + \ { + \ 'lnum': 8, + \ 'text': 'Avoid unused local variables such as ''stest''.', + \ 'code': 'Best Practices - UnusedLocalVariable', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#java#pmd#Handle(666, [ + \ '"Problem","Package","File","Priority","Line","Description","Rule set","Rule"', + \ '"1","","/Users/diego/Projects/github.com/dlresende/kata-fizz-buzz/src/main/java/App.java","3","8","Avoid unused local variables such as ''stest''.","Best Practices","UnusedLocalVariable"' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_pony_handler.vader b/vim-config/plugins/ale/test/handler/test_pony_handler.vader new file mode 100644 index 00000000..25a8254b --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_pony_handler.vader @@ -0,0 +1,21 @@ +Execute(The pony handler should handle ponyc output): + call ale#test#SetFilename('foo.pony') + + AssertEqual + \ [ + \ { + \ 'filename': '/home/projects/Wombat.pony', + \ 'lnum': 22, + \ 'type': 'E', + \ 'col': 30, + \ 'text': 'can''t lookup private fields from outside the type', + \ }, + \ ], + \ ale#handlers#pony#HandlePonycFormat(bufnr(''), [ + \ 'Building builtin -> /usr/lib/pony/0.21.3/packages/builtin', + \ 'Building . -> /home/projects', + \ 'Error:', + \ '/home/projects/Wombat.pony:22:30: can''t lookup private fields from outside the type', + \ ' env.out.print(defaultWombat._hunger_level)', + \ ' ^', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_powershell_handler.vader b/vim-config/plugins/ale/test/handler/test_powershell_handler.vader new file mode 100644 index 00000000..77c3dc65 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_powershell_handler.vader @@ -0,0 +1,109 @@ +Before: + runtime ale_linters/powershell/powershell.vim + +After: + call ale#linter#Reset() + +Execute(The powershell handler should process syntax errors from parsing a powershell script): + AssertEqual + \ [ + \ { + \ 'lnum': 8, + \ 'col': 29, + \ 'type': 'E', + \ 'text': 'Missing closing ''}'' in statement block or type definition.', + \ 'code': 'ParseException', + \ }, + \ ], + \ ale_linters#powershell#powershell#Handle(bufnr(''), [ + \ "At line:8 char:29", + \ "+ Invoke-Command -ScriptBlock {", + \ "+ ~", + \ "Missing closing '}' in statement block or type definition.", + \ "At /home/harrisj/tester.ps1:5 char:5", + \ "+ [void]$ExecutionContext.InvokeCommand.NewScriptBlock($Contents);", + \ "+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + \ "+ CategoryInfo : NotSpecified: (:) [], ParseException", + \ "+ FullyQualifiedErrorId : ParseException" + \ ]) + +Execute(The powershell handler should process multiple syntax errors from parsing a powershell script): + AssertEqual + \ [ + \ { + \ 'lnum': 11, + \ 'col': 31, + \ 'type': 'E', + \ 'text': 'The string is missing the terminator: ".', + \ 'code': 'ParseException' + \ }, + \ { + \ 'lnum': 3, + \ 'col': 16, + \ 'type': 'E', + \ 'text': 'Missing closing ''}'' in statement block or type definition.', + \ 'code': 'ParseException' + \ }, + \ ], + \ ale_linters#powershell#powershell#Handle(bufnr(''), [ + \ 'At line:11 char:31', + \ '+ write-verbose ''deleted''', + \ '+ ~', + \ 'The string is missing the terminator: ".', + \ 'At line:3 char:16', + \ '+ invoke-command {', + \ '+ ~', + \ 'Missing closing ''}'' in statement block or type definition.', + \ 'At /var/folders/qv/15ybvt050v9cgwrm7c95x4r4zc4qsg/T/vwhzIc8/1/script.ps1:1 char:150', + \ '+ ... ontents); [void]$ExecutionContext.InvokeCommand.NewScriptBlock($Con ...', + \ '+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~', + \ '+ CategoryInfo : NotSpecified: (:) [], ParseException', + \ '+ FullyQualifiedErrorId : ParseException' + \ ]) +Execute(The powershell handler should process unexecpected token that contains a newline character): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 8, + \ 'type': 'E', + \ 'text': 'The string is missing the terminator: ".', + \ 'code': 'ParseException' + \ }, + \ { + \ 'lnum': 2, + \ 'col': 8, + \ 'type': 'E', + \ 'text': 'Unexpected token ''"', + \ 'code': 'ParseException' + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Missing closing ''}'' in statement block or type definition.', + \ 'code': 'ParseException' + \ } + \ ], + \ ale_linters#powershell#powershell#Handle(bufnr(''), [ + \ 'At line:2 char:8', + \ '+ "" "', + \ '+ ~', + \ 'The string is missing the terminator: ".', + \ 'At line:2 char:8', + \ '+ "" "', + \ '+ ~', + \ 'Unexpected token ''"', + \ '', + \ ' }'' in expression or statement.', + \ '', + \ 'At line:1 char:1', + \ '+ {', + \ '+ ~', + \ 'Missing closing ''}'' in statement block or type definition.', + \ 'At C:\Users\jpharris\AppData\Local\Temp\VIAA777.tmp\script.ps1:1 char:150', + \ '+ ... ontents); [void]$ExecutionContext.InvokeCommand.NewScriptBlock($Con ...', + \ '+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~', + \ ' + CategoryInfo : NotSpecified: (:) [], ParseException', + \ ' + FullyQualifiedErrorId : ParseException' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_prospector_handler.vader b/vim-config/plugins/ale/test/handler/test_prospector_handler.vader new file mode 100644 index 00000000..935c37da --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_prospector_handler.vader @@ -0,0 +1,163 @@ +Before: + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/python/prospector.vim + +After: + Restore + + call ale#linter#Reset() + + silent file something_else.py + +Execute(Basic prospector errors should be handle): + AssertEqual + \ [ + \ { + \ 'lnum': 20, + \ 'col': 1, + \ 'text': 'Trailing whitespace', + \ 'code': '(pylint) trailing-whitespace', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'Missing module docstring', + \ 'code': '(pylint) missing-docstring', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'Missing function docstring', + \ 'code': '(pylint) missing-docstring', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 5, + \ 'text': '''break'' not properly in loop', + \ 'code': '(pylint) not-in-loop', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 5, + \ 'text': 'Unreachable code', + \ 'code': '(pylint) unreachable', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 33, + \ 'text': 'No exception type(s) specified', + \ 'code': '(pylint) bare-except', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#python#prospector#Handle(bufnr(''), [ + \ '{', + \ ' "messages": [', + \ ' {', + \ ' "source": "pylint",', + \ ' "code": "trailing-whitespace",', + \ ' "message": "Trailing whitespace",', + \ ' "location": {', + \ ' "character": 0,', + \ ' "line": 20', + \ ' }', + \ ' },', + \ ' {', + \ ' "source": "pylint",', + \ ' "code": "missing-docstring",', + \ ' "message": "Missing module docstring",', + \ ' "location": {', + \ ' "character": 0,', + \ ' "line": 1', + \ ' }', + \ ' },', + \ ' {', + \ ' "source": "pylint",', + \ ' "code": "missing-docstring",', + \ ' "message": "Missing function docstring",', + \ ' "location": {', + \ ' "character": 0,', + \ ' "line": 2', + \ ' }', + \ ' },', + \ ' {', + \ ' "source": "pylint",', + \ ' "code": "not-in-loop",', + \ ' "message": "''break'' not properly in loop",', + \ ' "location": {', + \ ' "character": 4,', + \ ' "line": 3', + \ ' }', + \ ' },', + \ ' {', + \ ' "source": "pylint",', + \ ' "code": "unreachable",', + \ ' "message": "Unreachable code",', + \ ' "location": {', + \ ' "character": 4,', + \ ' "line": 4', + \ ' }', + \ ' },', + \ ' {', + \ ' "source": "pylint",', + \ ' "code": "bare-except",', + \ ' "message": "No exception type(s) specified",', + \ ' "location": {', + \ ' "character": 32,', + \ ' "line": 7', + \ ' }', + \ ' }', + \ ' ]', + \ '}', + \ ]) + +Execute(Ignoring trailing whitespace messages should work): + let g:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'Missing module docstring', + \ 'code': '(pylint) missing-docstring', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#python#prospector#Handle(bufnr(''), [ + \ '{', + \ ' "messages": [', + \ ' {', + \ ' "source": "pylint",', + \ ' "code": "trailing-whitespace",', + \ ' "message": "Trailing whitespace",', + \ ' "location": {', + \ ' "character": 0,', + \ ' "line": 4', + \ ' }', + \ ' },', + \ ' {', + \ ' "source": "pylint",', + \ ' "code": "missing-docstring",', + \ ' "message": "Missing module docstring",', + \ ' "location": {', + \ ' "character": 0,', + \ ' "line": 1', + \ ' }', + \ ' }', + \ ' ]', + \ '}', + \ ]) + +Execute(The prospector handler should handle empty output): + AssertEqual + \ [], + \ ale_linters#python#prospector#Handle(bufnr(''), []) diff --git a/vim-config/plugins/ale/test/handler/test_psscriptanalyzer_handler.vader b/vim-config/plugins/ale/test/handler/test_psscriptanalyzer_handler.vader new file mode 100644 index 00000000..060d5941 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_psscriptanalyzer_handler.vader @@ -0,0 +1,42 @@ +Before: + runtime ale_linters/powershell/psscriptanalyzer.vim + +After: + call ale#linter#Reset() + +Execute(The psscriptanalyzer handler should handle basic information or warnings): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'type': 'I', + \ 'text': 'The cmdlet ''Get-GithubRepo'' does not have a help comment.', + \ 'code': 'PSProvideCommentHelp', + \ }, + \ { + \ 'lnum': 9, + \ 'type': 'W', + \ 'text': '''%'' is an alias of ''ForEach-Object''. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content.', + \ 'code': 'PSAvoidUsingCmdletAliases', + \ }, + \ { + \ 'lnum': 23, + \ 'type': 'E', + \ 'text': 'The ComputerName parameter of a cmdlet should not be hardcoded as this will expose sensitive information about the system.', + \ 'code': 'PSAvoidUsingComputerNameHardcoded', + \ }, + \ ], + \ ale_linters#powershell#psscriptanalyzer#Handle(bufnr(''), [ + \ '1', + \ 'Information', + \ 'The cmdlet ''Get-GithubRepo'' does not have a help comment.', + \ 'PSProvideCommentHelp', + \ '9', + \ 'Warning', + \ '''%'' is an alias of ''ForEach-Object''. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content.', + \ 'PSAvoidUsingCmdletAliases', + \ '23', + \ 'Error', + \ 'The ComputerName parameter of a cmdlet should not be hardcoded as this will expose sensitive information about the system.', + \ 'PSAvoidUsingComputerNameHardcoded', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_puglint_handler.vader b/vim-config/plugins/ale/test/handler/test_puglint_handler.vader new file mode 100644 index 00000000..f37518bb --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_puglint_handler.vader @@ -0,0 +1,45 @@ +Before: + runtime ale_linters/pug/puglint.vim + +After: + call ale#linter#Reset() + +Execute(Regular errors should be handled): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 5, + \ 'type': 'E', + \ 'text': 'Static attribute "class" must be written as class literal', + \ }, + \ ], + \ ale_linters#pug#puglint#Handle(0, [ + \ '/tmp/vwYwsJA/233/test.pug:1:5 Static attribute "class" must be written as class literal', + \ ]) + +Execute(syntax errors in the configuration file should be handled): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'puglint configuration error (type :ALEDetail for more information)', + \ 'detail': join( + \ [ + \ 'undefined:2', + \ ' disallowClassAttributeWithStaticValue: true', + \ ' ^', + \ 'SyntaxError: Unexpected token d in JSON at position 4', + \ ' at JSON.parse ()', + \ ], + \ "\n" + \ ), + \ }, + \ ], + \ ale_linters#pug#puglint#Handle(0, [ + \ 'undefined:2', + \ ' disallowClassAttributeWithStaticValue: true', + \ ' ^', + \ 'SyntaxError: Unexpected token d in JSON at position 4', + \ ' at JSON.parse ()', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_puppet_handler.vader b/vim-config/plugins/ale/test/handler/test_puppet_handler.vader new file mode 100644 index 00000000..03adc9f0 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_puppet_handler.vader @@ -0,0 +1,77 @@ +Before: + runtime ale_linters/puppet/puppet.vim + +After: + call ale#linter#Reset() + +Execute(The puppet handler should parse lines correctly when no column is supplied): + " Line Error + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 0, + \ 'text': "Syntax error at '='; expected '}'" + \ }, + \ { + \ 'lnum': 3, + \ 'col': 0, + \ 'text': "Syntax error at '='; expected '}'" + \ }, + \ ], + \ ale_linters#puppet#puppet#Handle(255, [ + \ "Error: Could not parse for environment production: Syntax error at '='; expected '}' at /root/puppetcode/modules/pancakes/manifests/init.pp:5", + \ "Error: Could not parse for environment production: Syntax error at '='; expected '}' at C:/puppet/modules/pancakes/manifests/init.pp:3", + \ ]) + +Execute(The puppet handler should parse lines and column correctly): + " Line Error + AssertEqual + \ [ + \ { + \ 'lnum': 43, + \ 'col': 12, + \ 'text': "Syntax error at ':'" + \ }, + \ { + \ 'lnum': 54, + \ 'col': 9, + \ 'text': "Syntax error at ':'" + \ }, + \ { + \ 'lnum': 45, + \ 'col': 12, + \ 'text': "Syntax error at 'parameter1'" + \ }, + \ ], + \ ale_linters#puppet#puppet#Handle(255, [ + \ "Error: Could not parse for environment production: Syntax error at ':' at /root/puppetcode/modules/nginx/manifests/init.pp:43:12", + \ "Error: Could not parse for environment production: Syntax error at ':' at C:/puppet/modules/nginx/manifests/init.pp:54:9", + \ "Error: Could not parse for environment production: Syntax error at 'parameter1' (file: /tmp/modules/mariadb/manifests/slave.pp, line: 45, column: 12)", + \ ]) + +Execute(The puppet handler should correctly parse errors that are reported before even trying to parse for an environment): + " Line Error + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 11, + \ 'text': "Illegal attempt to assign to 'a Name'. Not an assignable reference" + \ }, + \ ], + \ ale_linters#puppet#puppet#Handle(255, [ + \ "Error: Illegal attempt to assign to 'a Name'. Not an assignable reference (file: /tmp/modules/waffles/manifests/syrup.pp, line: 5, column: 11)", + \ ]) +Execute(The puppet handler should parse lines when end of input is the location): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'col': 0, + \ 'text': "Syntax error at end of input" + \ }, + \ ], + \ ale_linters#puppet#puppet#Handle(255, [ + \ "Error: Could not parse for environment production: Syntax error at end of input (file: /tmp//modules/test/manifests/init.pp)", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_pycodestyle_handler.vader b/vim-config/plugins/ale/test/handler/test_pycodestyle_handler.vader new file mode 100644 index 00000000..3664455e --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_pycodestyle_handler.vader @@ -0,0 +1,154 @@ +Before: + Save g:ale_warn_about_trailing_blank_lines + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_blank_lines = 1 + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/python/pycodestyle.vim + +After: + Restore + + unlet! b:ale_warn_about_trailing_blank_lines + unlet! b:ale_warn_about_trailing_whitespace + + call ale#linter#Reset() + silent file something_else.py + +Execute(The pycodestyle handler should parse output): + AssertEqual + \ [ + \ { + \ 'lnum': 8, + \ 'col': 3, + \ 'type': 'E', + \ 'text': 'SyntaxError: invalid syntax', + \ 'code': 'E999', + \ }, + \ { + \ 'lnum': 69, + \ 'col': 11, + \ 'text': 'multiple imports on one line', + \ 'code': 'E401', + \ 'type': 'E', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 77, + \ 'col': 1, + \ 'text': 'expected 2 blank lines, found 1', + \ 'code': 'E302', + \ 'type': 'E', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 88, + \ 'col': 5, + \ 'text': 'expected 1 blank line, found 0', + \ 'code': 'E301', + \ 'type': 'E', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 222, + \ 'col': 34, + \ 'text': 'deprecated form of raising exception', + \ 'code': 'W602', + \ 'type': 'W', + \ 'sub_type': 'style', + \ }, + \ { + \ 'lnum': 544, + \ 'col': 21, + \ 'text': '.has_key() is deprecated, use ''in''', + \ 'code': 'W601', + \ 'type': 'W', + \ 'sub_type': 'style', + \ }, + \ ], + \ ale_linters#python#pycodestyle#Handle(bufnr(''), [ + \ 'stdin:8:3: E999 SyntaxError: invalid syntax', + \ 'stdin:69:11: E401 multiple imports on one line', + \ 'stdin:77:1: E302 expected 2 blank lines, found 1', + \ 'stdin:88:5: E301 expected 1 blank line, found 0', + \ 'stdin:222:34: W602 deprecated form of raising exception', + \ 'example.py:544:21: W601 .has_key() is deprecated, use ''in''', + \ ]) + +Execute(Warnings about trailing whitespace should be reported by default): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'code': 'W291', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'who cares', + \ }, + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'code': 'W293', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'who cares', + \ }, + \ ], + \ ale_linters#python#pycodestyle#Handle(bufnr(''), [ + \ 'foo.py:6:1: W291 who cares', + \ 'foo.py:6:1: W293 who cares', + \ ]) + +Execute(Disabling trailing whitespace warnings should work): + let b:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [ + \ ], + \ ale_linters#python#pycodestyle#Handle(bufnr(''), [ + \ 'foo.py:6:1: W291 who cares', + \ 'foo.py:6:1: W293 who cares', + \ ]) + +Execute(Warnings about trailing blank lines should be reported by default): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'code': 'W391', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'blank line at end of file', + \ }, + \ ], + \ ale_linters#python#pycodestyle#Handle(bufnr(''), [ + \ 'foo.py:6:1: W391 blank line at end of file', + \ ]) + +Execute(Disabling trailing blank line warnings should work): + let b:ale_warn_about_trailing_blank_lines = 0 + + AssertEqual + \ [ + \ ], + \ ale_linters#python#pycodestyle#Handle(bufnr(''), [ + \ 'foo.py:6:1: W391 blank line at end of file', + \ ]) + +Execute(E112 should be a syntax error): + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 1, + \ 'code': 'E112', + \ 'type': 'E', + \ 'text': 'expected an indented block', + \ }, + \ ], + \ ale_linters#python#pycodestyle#Handle(bufnr(''), [ + \ 'foo.py:6:1: E112 expected an indented block', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_pydocstyle_handler.vader b/vim-config/plugins/ale/test/handler/test_pydocstyle_handler.vader new file mode 100644 index 00000000..cfb75307 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_pydocstyle_handler.vader @@ -0,0 +1,116 @@ +Before: + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/python/pydocstyle.vim + +After: + Restore + + call ale#linter#Reset() + + silent file something_else.py + +" File sample.py +" # sample.py file +" +" def main(): +" """ +" This is a multi-line description that should produce multiple errors to be +" tested by the handler +" """ +" return Fales +" +" +" if __name__ == '__main__': +" main() +" +" The command to generate the handler input is: +" +" $ python -m pydocstyle --verbose --source --explain sample.py +" [...] +" $ + +Execute(Basic pydocstyle warnings should be handled): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'Missing docstring in public module', + \ 'code': 'D100', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 1, + \ 'text': '1 blank line required between summary line and description (found 0)', + \ 'code': 'D205', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 1, + \ 'text': 'First line should end with a period (not ''e'')', + \ 'code': 'D400', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 1, + \ 'text': 'First line should be in imperative mood; try rephrasing (found ''This'')', + \ 'code': 'D401', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#python#pydocstyle#Handle(bufnr(''), [ + \ 'Checking file ' . fnamemodify(bufname(bufnr('')), ':p') . '.', + \ './mydir/myfile.py:1 at module level:', + \ ' D100: Missing docstring in public module', + \ '', + \ ' All modules should normally have docstrings. [...] all functions and', + \ ' classes exported by a module should also have docstrings. Public', + \ ' methods (including the __init__ constructor) should also have', + \ ' docstrings.', + \ ' Note: Public (exported) definitions are either those with names listed', + \ ' in __all__ variable (if present), or those that do not start', + \ ' with a single underscore.', + \ '', + \ ' 1: # 2: 3: s 4: a 5: m 6: p 7: l ...', + \ '', + \ '', + \ 'C:\mydir\myfile.py:4 in public function `main`:', + \ ' D205: 1 blank line required between summary line and description (found 0)', + \ '', + \ ' Multi-line docstrings consist of a summary line just like a one-line', + \ ' docstring, followed by a blank line, followed by a more elaborate', + \ ' description. The summary line may be used by automatic indexing tools;', + \ ' it is important that it fits on one line and is separated from the', + \ ' rest of the docstring by a blank line.', + \ '', + \ ' 3: d 4: e 5: f 6: 7: m 8: a 9: i ...', + \ '', + \ '', + \ 'myfile.py:4 in public function `main`:', + \ ' D400: First line should end with a period (not ''e'')', + \ '', + \ ' The [first line of a] docstring is a phrase ending in a period.', + \ '', + \ ' 3: d 4: e 5: f 6: 7: m 8: a 9: i ...', + \ '', + \ '', + \ ale#Escape(fnamemodify(bufname(bufnr('')), ':t')) . ':4 in public function `main`:', + \ ' D401: First line should be in imperative mood; try rephrasing (found ''This'')', + \ '', + \ ' [Docstring] prescribes the function or method''s effect as a command:', + \ ' ("Do this", "Return that"), not as a description; e.g. don''t write', + \ ' "Returns the pathname ...".', + \ '', + \ ' 3: d 4: e 5: f 6: 7: m 8: a 9: i ...', + \ ]) + +Execute(Handler should handle empty output): + AssertEqual + \ [], + \ ale_linters#python#pydocstyle#Handle(bufnr(''), []) diff --git a/vim-config/plugins/ale/test/handler/test_pyflakes_handler.vader b/vim-config/plugins/ale/test/handler/test_pyflakes_handler.vader new file mode 100644 index 00000000..ab4fab49 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_pyflakes_handler.vader @@ -0,0 +1,24 @@ +Before: + runtime ale_linters/python/pyflakes.vim + +After: + call ale#linter#Reset() + +Execute(The pyflakes handler should handle basic errors): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 0, + \ 'text': 'undefined name ''foo''', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 7, + \ 'text': 'invalid syntax', + \ }, + \ ], + \ ale_linters#python#pyflakes#Handle(bufnr(''), [ + \ 'test.py:1: undefined name ''foo''', + \ 'test.py:1:7: invalid syntax', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_pylama_handler.vader b/vim-config/plugins/ale/test/handler/test_pylama_handler.vader new file mode 100644 index 00000000..d21c65d3 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_pylama_handler.vader @@ -0,0 +1,193 @@ +Before: + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/python/pylama.vim + +After: + Restore + + call ale#linter#Reset() + + silent file something_else.py + +Execute(The pylama handler should handle no messages): + AssertEqual [], ale_linters#python#pylama#Handle(bufnr(''), []) + +Execute(The pylama handler should handle basic warnings and syntax errors): + AssertEqual + \ [ + \ { + \ 'lnum': 8, + \ 'col': 1, + \ 'code': 'W0611', + \ 'type': 'W', + \ 'sub_type': '', + \ 'text': '''foo'' imported but unused [pyflakes]', + \ }, + \ { + \ 'lnum': 8, + \ 'col': 0, + \ 'code': 'E0401', + \ 'type': 'E', + \ 'sub_type': '', + \ 'text': 'Unable to import ''foo'' [pylint]', + \ }, + \ { + \ 'lnum': 10, + \ 'col': 1, + \ 'code': 'E302', + \ 'type': 'E', + \ 'sub_type': '', + \ 'text': 'expected 2 blank lines, found 1 [pycodestyle]', + \ }, + \ { + \ 'lnum': 11, + \ 'col': 1, + \ 'code': 'D401', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'First line should be in imperative mood (''Get'', not ''Gets'') [pydocstyle]', + \ }, + \ { + \ 'lnum': 15, + \ 'col': 81, + \ 'code': 'E501', + \ 'type': 'E', + \ 'sub_type': '', + \ 'text': 'line too long (96 > 80 characters) [pycodestyle]', + \ }, + \ { + \ 'lnum': 16, + \ 'col': 1, + \ 'code': 'D203', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': '1 blank line required before class docstring (found 0) [pydocstyle]', + \ }, + \ { + \ 'lnum': 18, + \ 'col': 1, + \ 'code': 'D107', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'Missing docstring in __init__ [pydocstyle]', + \ }, + \ { + \ 'lnum': 20, + \ 'col': 0, + \ 'code': 'C4001', + \ 'type': 'W', + \ 'sub_type': 'style', + \ 'text': 'Invalid string quote ", should be '' [pylint]', + \ }, + \ ], + \ ale_linters#python#pylama#Handle(bufnr(''), [ + \ 'No config file found, using default configuration', + \ 'index.py:8:1: W0611 ''foo'' imported but unused [pyflakes]', + \ 'index.py:8:0: E0401 Unable to import ''foo'' [pylint]', + \ 'index.py:10:1: E302 expected 2 blank lines, found 1 [pycodestyle]', + \ 'index.py:11:1: D401 First line should be in imperative mood (''Get'', not ''Gets'') [pydocstyle]', + \ 'index.py:15:81: E501 line too long (96 > 80 characters) [pycodestyle]', + \ 'index.py:16:1: D203 1 blank line required before class docstring (found 0) [pydocstyle]', + \ 'index.py:18:1: D107 Missing docstring in __init__ [pydocstyle]', + \ 'index.py:20:0: C4001 Invalid string quote ", should be '' [pylint]', + \ ]) + +Execute(The pylama handler should handle tracebacks with parsable messages): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'ParseError: Cannot parse file. (See :ALEDetail)', + \ 'detail': join([ + \ 'Traceback (most recent call last):', + \ ' File "/usr/local/lib/python2.7/site-packages/pylama/core.py", line 66, in run', + \ ' path, code=code, ignore=ignore, select=select, params=lparams)', + \ ' File "/usr/local/lib/python2.7/site-packages/pylama/lint/pylama_pydocstyle.py", line 37, in run', + \ ' } for e in PyDocChecker().check_source(*check_source_args)]', + \ ' File "/usr/local/lib/python2.7/site-packages/pydocstyle/checker.py", line 64, in check_source', + \ ' module = parse(StringIO(source), filename)', + \ ' File "/usr/local/lib/python2.7/site-packages/pydocstyle/parser.py", line 340, in __call__', + \ ' return self.parse(*args, **kwargs)', + \ ' File "/usr/local/lib/python2.7/site-packages/pydocstyle/parser.py", line 328, in parse', + \ ' six.raise_from(ParseError(), error)', + \ ' File "/usr/local/lib/python2.7/site-packages/six.py", line 737, in raise_from', + \ ' raise value', + \ 'ParseError: Cannot parse file.', + \ ], "\n"), + \ }, + \ { + \ 'lnum': 11, + \ 'col': 1, + \ 'code': 'E302', + \ 'type': 'E', + \ 'sub_type': '', + \ 'text': 'expected 2 blank lines, found 1 [pycodestyle]', + \ }, + \ { + \ 'lnum': 16, + \ 'col': 81, + \ 'code': 'E501', + \ 'type': 'E', + \ 'sub_type': '', + \ 'text': 'line too long (96 > 80 characters) [pycodestyle]', + \ }, + \ ], + \ ale_linters#python#pylama#Handle(bufnr(''), [ + \ 'Traceback (most recent call last):', + \ ' File "/usr/local/lib/python2.7/site-packages/pylama/core.py", line 66, in run', + \ ' path, code=code, ignore=ignore, select=select, params=lparams)', + \ ' File "/usr/local/lib/python2.7/site-packages/pylama/lint/pylama_pydocstyle.py", line 37, in run', + \ ' } for e in PyDocChecker().check_source(*check_source_args)]', + \ ' File "/usr/local/lib/python2.7/site-packages/pydocstyle/checker.py", line 64, in check_source', + \ ' module = parse(StringIO(source), filename)', + \ ' File "/usr/local/lib/python2.7/site-packages/pydocstyle/parser.py", line 340, in __call__', + \ ' return self.parse(*args, **kwargs)', + \ ' File "/usr/local/lib/python2.7/site-packages/pydocstyle/parser.py", line 328, in parse', + \ ' six.raise_from(ParseError(), error)', + \ ' File "/usr/local/lib/python2.7/site-packages/six.py", line 737, in raise_from', + \ ' raise value', + \ 'ParseError: Cannot parse file.', + \ '', + \ 'index.py:11:1: E302 expected 2 blank lines, found 1 [pycodestyle]', + \ 'index.py:16:81: E501 line too long (96 > 80 characters) [pycodestyle]', + \ ]) + +" Note: This is probably a bug, since all pylama plugins produce codes, but +" should be handled for compatibility. +" Note: The pylama isort plugin is distributed in the isort package. +Execute(The pylama handler should handle messages without codes): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'col': 0, + \ 'code': '', + \ 'type': 'W', + \ 'sub_type': '', + \ 'text': 'Incorrectly sorted imports. [isort]' + \ }, + \ ], + \ ale_linters#python#pylama#Handle(bufnr(''), [ + \ 'index.py:0:0: Incorrectly sorted imports. [isort]', + \ ]) + +" Note: This is a pylama bug, but should be handled for compatibility. +" See https://github.com/klen/pylama/pull/146 +Execute(The pylama handler should handle message codes followed by a colon): + AssertEqual + \ [ + \ { + \ 'lnum': 31, + \ 'col': 1, + \ 'code': 'E800', + \ 'type': 'E', + \ 'sub_type': '', + \ 'text': 'Found commented out code: # needs_sphinx = ''1.0'' [eradicate]', + \ }, + \ ], + \ ale_linters#python#pylama#Handle(bufnr(''), [ + \ 'index.py:31:1: E800: Found commented out code: # needs_sphinx = ''1.0'' [eradicate]', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_pylint_handler.vader b/vim-config/plugins/ale/test/handler/test_pylint_handler.vader new file mode 100644 index 00000000..ce7322f3 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_pylint_handler.vader @@ -0,0 +1,135 @@ +Before: + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/python/pylint.vim + +After: + Restore + + call ale#linter#Reset() + + silent file something_else.py + +Execute(Basic pylint errors should be handle): + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 1, + \ 'text': 'Trailing whitespace', + \ 'code': 'trailing-whitespace', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'Missing module docstring', + \ 'code': 'missing-docstring', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'Missing function docstring', + \ 'code': 'missing-docstring', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 5, + \ 'text': '''break'' not properly in loop', + \ 'code': 'not-in-loop', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 5, + \ 'text': 'Unreachable code', + \ 'code': 'unreachable', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 33, + \ 'text': 'No exception type(s) specified', + \ 'code': 'bare-except', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#python#pylint#Handle(bufnr(''), [ + \ 'No config file found, using default configuration', + \ '************* Module test', + \ 'test.py:4:0: C0303 (trailing-whitespace) Trailing whitespace', + \ 'test.py:1:0: C0111 (missing-docstring) Missing module docstring', + \ 'test.py:2:0: C0111 (missing-docstring) Missing function docstring', + \ 'test.py:3:4: E0103 (not-in-loop) ''break'' not properly in loop', + \ 'test.py:4:4: W0101 (unreachable) Unreachable code', + \ 'test.py:7:32: W0702 (bare-except) No exception type(s) specified', + \ '', + \ '------------------------------------------------------------------', + \ 'Your code has been rated at 0.00/10 (previous run: 2.50/10, -2.50)', + \ ]) + +Execute(Ignoring trailing whitespace messages should work): + let g:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'Missing module docstring', + \ 'code': 'missing-docstring', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#python#pylint#Handle(bufnr(''), [ + \ 'No config file found, using default configuration', + \ '************* Module test', + \ 'test.py:4:0: C0303 (trailing-whitespace) Trailing whitespace', + \ 'test.py:1:0: C0111 (missing-docstring) Missing module docstring', + \ '', + \ '------------------------------------------------------------------', + \ 'Your code has been rated at 0.00/10 (previous run: 2.50/10, -2.50)', + \ ]) + +Execute(The pylint handler should parse Windows filenames): + AssertEqual + \ [ + \ { + \ 'lnum': 13, + \ 'col': 6, + \ 'text': 'Undefined variable ''x''', + \ 'code': 'undefined-variable', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#python#pylint#Handle(bufnr(''), [ + \ '************* Module test', + \ 'D:\acm\github\vim\tools\test.py:13:5: E0602 (undefined-variable) Undefined variable ''x''', + \ '', + \ '------------------------------------------------------------------', + \ 'Your code has been rated at 5.83/10 (previous run: 5.83/10, +0.00)', + \ ]) + +Execute(Use msg_id): + let g:ale_python_pylint_use_msg_id = 1 + AssertEqual + \ [ + \ { + \ 'lnum': 13, + \ 'col': 6, + \ 'text': 'Undefined variable ''x''', + \ 'code': 'E0602', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#python#pylint#Handle(bufnr(''), [ + \ '************* Module test', + \ 'D:\acm\github\vim\tools\test.py:13:5: E0602 (undefined-variable) Undefined variable ''x''', + \ '', + \ '------------------------------------------------------------------', + \ 'Your code has been rated at 5.83/10 (previous run: 5.83/10, +0.00)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_pyrex_cython_handler.vader b/vim-config/plugins/ale/test/handler/test_pyrex_cython_handler.vader new file mode 100644 index 00000000..fd0f9a8b --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_pyrex_cython_handler.vader @@ -0,0 +1,26 @@ +Before: + runtime ale_linters/pyrex/cython.vim + +After: + call ale#linter#Reset() + +Execute(The cython handler should handle warnings and errors): + AssertEqual + \ [ + \ { + \ 'lnum': 42, + \ 'col': 7, + \ 'text': 'some warning', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 777, + \ 'col': 21, + \ 'text': 'some error', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#pyrex#cython#Handle(347, [ + \ 'warning: file:42:7: some warning', + \ 'file:777:21: some error', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_qmlfmt_handler.vader b/vim-config/plugins/ale/test/handler/test_qmlfmt_handler.vader new file mode 100644 index 00000000..fc8ef355 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_qmlfmt_handler.vader @@ -0,0 +1,19 @@ +Before: + runtime ale_linters/qml/qmlfmt.vim + +After: + call ale#linter#Reset() + +Execute(The qmlfmt handler should parse error messages correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 22, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'Expected token ''}''.' + \ } + \ ], + \ ale_linters#qml#qmlfmt#Handle(1, [ + \ 'Error:22:1: Expected token ''}''.' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_qmllint_handler.vader b/vim-config/plugins/ale/test/handler/test_qmllint_handler.vader new file mode 100644 index 00000000..fcc65eb5 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_qmllint_handler.vader @@ -0,0 +1,19 @@ +Before: + runtime ale_linters/qml/qmllint.vim + +After: + call ale#linter#Reset() + +Execute(The qmllint handler should parse error messages correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'Expected token ''}''' + \ } + \ ], + \ ale_linters#qml#qmllint#Handle(1, [ + \ '/tmp/ab34cd56/Test.qml:2 : Expected token ''}''' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_raco_handler.vader b/vim-config/plugins/ale/test/handler/test_raco_handler.vader new file mode 100644 index 00000000..565fd795 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_raco_handler.vader @@ -0,0 +1,27 @@ +Before: + runtime ale_linters/racket/raco.vim + +After: + call ale#linter#Reset() + +Execute(The raco handler should handle errors for the current file correctly): + AssertEqual + \ [ + \ { + \ 'filename': 'foo.rkt', + \ 'lnum': 4, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'dfine: unbound identifier in modulemessage', + \ }, + \ ], + \ ale_linters#racket#raco#Handle(bufnr(''), [ + \ 'foo.rkt:4:1: dfine: unbound identifier in modulemessage', + \ ' in: dfine', + \ ' context...:', + \ ' /usr/local/Cellar/racket/6.5/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt:34:15: loop', + \ ' /usr/local/Cellar/racket/6.5/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt:10:2: show-program', + \ ' /usr/local/Cellar/racket/6.5/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt: [running body]', + \ ' /usr/local/Cellar/minimal-racket/6.6/share/racket/collects/raco/raco.rkt: [running body]', + \ ' /usr/local/Cellar/minimal-racket/6.6/share/racket/collects/raco/main.rkt: [running body]', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_rails_best_practices_handler.vader b/vim-config/plugins/ale/test/handler/test_rails_best_practices_handler.vader new file mode 100644 index 00000000..f6d69eee --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_rails_best_practices_handler.vader @@ -0,0 +1,52 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/handler') + cd .. + + runtime ale_linters/ruby/rails_best_practices.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The rails_best_practices handler should parse JSON correctly): + call ale#test#SetFilename('test-files/ruby/valid_rails_app/app/models/thing.rb') + + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'text': 'use local variable', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 10, + \ 'text': 'other advice', + \ 'type': 'W', + \ } + \ ], + \ ale_linters#ruby#rails_best_practices#Handle(bufnr(''), [ + \ '[', + \ '{', + \ '"message": "use local variable",', + \ '"line_number": "5",', + \ printf('"filename": "%s"', substitute(expand('%:p'), '\\', '\\\\', 'g')), + \ '},{', + \ '"message": "other advice",', + \ '"line_number": "10",', + \ printf('"filename": "%s"', substitute(expand('%:p'), '\\', '\\\\', 'g')), + \ '}', + \ ']' + \ ]) + +Execute(The rails_best_practices handler should parse JSON correctly when there is no output from the tool): + AssertEqual + \ [], + \ ale_linters#ruby#rails_best_practices#Handle(347, [ + \ ]) + +Execute(The rails_best_practices handler should handle garbage output): + AssertEqual + \ [], + \ ale_linters#ruby#rails_best_practices#Handle(347, [ + \ 'No such command in 2.4.1 of ruby', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_redpen_handler.vader b/vim-config/plugins/ale/test/handler/test_redpen_handler.vader new file mode 100644 index 00000000..0b030e2d --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_redpen_handler.vader @@ -0,0 +1,98 @@ +Before: + runtime! ale_linters/markdown/redpen.vim + +After: + call ale#linter#Reset() + +Execute(redpen handler should handle errors output): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'end_lnum': 1, + \ 'end_col': 15, + \ 'text': 'Found possibly misspelled word "plugin".', + \ 'type': 'W', + \ 'code': 'Spelling', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'Found possibly misspelled word "NeoVim".', + \ 'type': 'W', + \ 'code': 'Spelling', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 35, + \ 'end_lnum': 1, + \ 'end_col': 55, + \ 'text': 'Found possibly misspelled word "コードチェック".', + \ 'type': 'W', + \ 'code': 'Spelling', + \ }, + \ ], + \ ale#handlers#redpen#HandleRedpenOutput(bufnr(''), [ + \ '[', + \ ' {', + \ ' "document": "test.md",', + \ ' "errors": [', + \ ' {', + \ ' "sentence": "ALE is a plugin for providing linting in NeoVim and Vim 8 while you edit your text files.",', + \ ' "endPosition": {', + \ ' "offset": 15,', + \ ' "lineNum": 1', + \ ' },', + \ ' "validator": "Spelling",', + \ ' "lineNum": 1,', + \ ' "sentenceStartColumnNum": 0,', + \ ' "message": "Found possibly misspelled word \"plugin\".",', + \ ' "startPosition": {', + \ ' "offset": 9,', + \ ' "lineNum": 1', + \ ' }', + \ ' },', + \ ' {', + \ ' "sentence": "ALE is a plugin for providing linting in NeoVim and Vim 8 while you edit your text files.",', + \ ' "validator": "Spelling",', + \ ' "lineNum": 1,', + \ ' "sentenceStartColumnNum": 0,', + \ ' "message": "Found possibly misspelled word \"NeoVim\"."', + \ ' },', + \ ' {', + \ ' "sentence": "ALEはNeoVimとVim8で非同期のコードチェックを実現するプラグインです。",', + \ ' "endPosition": {', + \ ' "offset": 27,', + \ ' "lineNum": 1', + \ ' },', + \ ' "validator": "Spelling",', + \ ' "lineNum": 1,', + \ ' "sentenceStartColumnNum": 0,', + \ ' "message": "Found possibly misspelled word \"コードチェック\".",', + \ ' "startPosition": {', + \ ' "offset": 20,', + \ ' "lineNum": 1', + \ ' }', + \ ' }', + \ ' ]', + \ ' }', + \ ']', + \ ]) + +Execute(The redpen handler should handle an empty error list): + AssertEqual + \ [], + \ ale#handlers#redpen#HandleRedpenOutput(bufnr(''), [ + \ '[', + \ ' {', + \ ' "document": "test.md",', + \ ' "errors": []', + \ ' }', + \ ']', + \ ]) + +Execute(The redpen handler should handle totally empty output): + AssertEqual + \ [], + \ ale#handlers#redpen#HandleRedpenOutput(bufnr(''), []) diff --git a/vim-config/plugins/ale/test/handler/test_reek_handler.vader b/vim-config/plugins/ale/test/handler/test_reek_handler.vader new file mode 100644 index 00000000..db0a1119 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_reek_handler.vader @@ -0,0 +1,81 @@ +Before: + runtime ale_linters/ruby/reek.vim + +After: + call ale#linter#Reset() + +Execute(The reek handler should parse JSON correctly, with only context enabled): + let g:ale_ruby_reek_show_context = 1 + let g:ale_ruby_reek_show_wiki_link = 0 + + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'text': 'Context#method violates rule number one', + \ 'code': 'Rule1', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 34, + \ 'text': 'Context#method violates rule number two', + \ 'code': 'Rule2', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 56, + \ 'text': 'Context#method violates rule number two', + \ 'code': 'Rule2', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#ruby#reek#Handle(347, [ + \ '[{"context":"Context#method","lines":[12],"message":"violates rule number one","smell_type":"Rule1","source":"/home/user/file.rb","parameter":"bad parameter","wiki_link":"https://example.com/Rule1.md"},{"context":"Context#method","lines":[34, 56],"message":"violates rule number two","smell_type":"Rule2","source":"/home/user/file.rb","name":"bad code","count":2,"wiki_link":"https://example.com/Rule1.md"}]' + \ ]) + +Execute(The reek handler should parse JSON correctly, with no context or wiki links): + let g:ale_ruby_reek_show_context = 0 + let g:ale_ruby_reek_show_wiki_link = 0 + + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'text': 'violates rule number one', + \ 'code': 'Rule1', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#ruby#reek#Handle(347, [ + \ '[{"context":"Context#method","lines":[12],"message":"violates rule number one","smell_type":"Rule1","source":"/home/user/file.rb","parameter":"bad parameter","wiki_link":"https://example.com/Rule1.md"}]' + \ ]) + +Execute(The reek handler should parse JSON correctly, with both context and wiki links): + let g:ale_ruby_reek_show_context = 1 + let g:ale_ruby_reek_show_wiki_link = 1 + + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'text': 'Context#method violates rule number one [https://example.com/Rule1.md]', + \ 'code': 'Rule1', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#ruby#reek#Handle(347, [ + \ '[{"context":"Context#method","lines":[12],"message":"violates rule number one","smell_type":"Rule1","source":"/home/user/file.rb","parameter":"bad parameter","wiki_link":"https://example.com/Rule1.md"}]' + \ ]) + +Execute(The reek handler should parse JSON correctly when there is no output from reek): + AssertEqual + \ [], + \ ale_linters#ruby#reek#Handle(347, [ + \ ]) + +Execute(The reek handler should handle garbage output): + AssertEqual + \ [], + \ ale_linters#ruby#reek#Handle(347, [ + \ 'No such command in 2.4.1 of ruby', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_remark_lint_handler.vader b/vim-config/plugins/ale/test/handler/test_remark_lint_handler.vader new file mode 100644 index 00000000..0794d51c --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_remark_lint_handler.vader @@ -0,0 +1,39 @@ +Before: + runtime ale_linters/markdown/remark_lint.vim + +After: + call ale#linter#Reset() + +Execute(Warning and error messages should be handled correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 4, + \ 'type': 'W', + \ 'text': 'Incorrect list-item indent: add 1 space list-item-indent remark-lint', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 5, + \ 'type': 'E', + \ 'text': 'Incorrect list-item indent: remove 1 space list-item-indent remark-lint', + \ }, + \ { + \ 'lnum': 18, + \ 'col': 71, + \ 'end_lnum': 19, + \ 'end_col': 1, + \ 'type': 'E', + \ 'text': 'Missing new line after list item list-item-spacing remark-lint', + \ }, + \ ], + \ ale_linters#markdown#remark_lint#Handle(1, [ + \ 'foo.md', + \ ' 1:4 warning Incorrect list-item indent: add 1 space list-item-indent remark-lint', + \ ' 3:5 error Incorrect list-item indent: remove 1 space list-item-indent remark-lint', + \ ' 18:71-19:1 error Missing new line after list item list-item-spacing remark-lint', + \ '', + \ '⚠ 1 warnings', + \ '✘ 2 errors', + \]) diff --git a/vim-config/plugins/ale/test/handler/test_rflint_handler.vader b/vim-config/plugins/ale/test/handler/test_rflint_handler.vader new file mode 100644 index 00000000..f2670141 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_rflint_handler.vader @@ -0,0 +1,33 @@ +Before: + runtime ale_linters/robot/rflint.vim + +After: + call ale#linter#Reset() + +Execute(Warning and error messages should be handled correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 1, + \ 'filename': 'test.robot', + \ 'type': 'W', + \ 'lnum': 1, + \ 'col': 2, + \ 'text': 'RequireSuiteDocumentation', + \ 'detail': 'No suite documentation', + \ }, + \ { + \ 'bufnr': 1, + \ 'filename': 'test.robot', + \ 'type': 'E', + \ 'lnum': 3, + \ 'col': 4, + \ 'text': 'RequireTestDocumentation', + \ 'detail': 'No testcase documentation', + \ }, + \ ], + \ ale_linters#robot#rflint#Handle(1, [ + \ 'test.robot:W:1:2:RequireSuiteDocumentation:No suite documentation', + \ 'test.robot:E:3:4:RequireTestDocumentation:No testcase documentation' + \]) + diff --git a/vim-config/plugins/ale/test/handler/test_rpmlint_handler.vader b/vim-config/plugins/ale/test/handler/test_rpmlint_handler.vader new file mode 100644 index 00000000..2ea9e5cf --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_rpmlint_handler.vader @@ -0,0 +1,33 @@ +Before: + runtime ale_linters/spec/rpmlint.vim + +After: + call ale#linter#Reset() + +Execute(The rpmlint handler should parse error messages correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 42, + \ 'lnum': 23, + \ 'text': 'macro-in-comment %version', + \ 'type': 'W', + \ }, + \ { + \ 'bufnr': 42, + \ 'lnum': 17, + \ 'text': 'hardcoded-library-path in %_prefix/lib/%name', + \ 'type': 'E', + \ }, + \ { + \ 'bufnr': 42, + \ 'lnum': 1, + \ 'text': 'specfile-error warning: bogus date in %changelog: Mon Oct 1 2005 - Foo', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#spec#rpmlint#Handle(42, [ + \ 'cyrus-imapd.spec:23: W: macro-in-comment %version', + \ 'cyrus-imapd.spec:17: E: hardcoded-library-path in %_prefix/lib/%name', + \ 'apcupsd.spec: E: specfile-error warning: bogus date in %changelog: Mon Oct 1 2005 - Foo', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_rstcheck_lint_handler.vader b/vim-config/plugins/ale/test/handler/test_rstcheck_lint_handler.vader new file mode 100644 index 00000000..c65c15eb --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_rstcheck_lint_handler.vader @@ -0,0 +1,42 @@ +Before: + runtime ale_linters/rst/rstcheck.vim + +After: + call ale#linter#Reset() + +Execute(Warning and error messages should be handled correctly): + " For some reason we can't set the directory such that the filenames are + " correct here when running the tests from the Docker image, so we have to + " just check the basenames of the files instead. + AssertEqual + \ [ + \ { + \ 'filename': 'bad_python.rst', + \ 'lnum': 7, + \ 'col': 0, + \ 'type': 'W', + \ 'text': '(python) unexpected EOF while parsing', + \ }, + \ { + \ 'filename': 'bad_cpp.rst', + \ 'lnum': 9, + \ 'col': 0, + \ 'type': 'W', + \ 'text': '(cpp) error: ''x'' was not declared in this scope', + \ }, + \ { + \ 'filename': 'bad_rst.rst', + \ 'lnum': 1, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'Title overline & underline mismatch.', + \ }, + \ ], + \ map( + \ ale_linters#rst#rstcheck#Handle(1, [ + \ 'bad_python.rst:7: (ERROR/3) (python) unexpected EOF while parsing', + \ 'bad_cpp.rst:9: (ERROR/3) (cpp) error: ''x'' was not declared in this scope', + \ 'bad_rst.rst:1: (SEVERE/4) Title overline & underline mismatch.', + \ ]), + \ 'extend(v:val, {''filename'': fnamemodify(v:val.filename, '':t'')})' + \ ) diff --git a/vim-config/plugins/ale/test/handler/test_rubocop_handler.vader b/vim-config/plugins/ale/test/handler/test_rubocop_handler.vader new file mode 100644 index 00000000..d7868f26 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_rubocop_handler.vader @@ -0,0 +1,76 @@ +Before: + runtime ale_linters/ruby/rubocop.vim + +After: + unlet! g:lines + call ale#linter#Reset() + +Execute(The rubocop handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 83, + \ 'col': 29, + \ 'end_col': 35, + \ 'text': 'Prefer single-quoted strings...', + \ 'code': 'Style/SomeCop', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 12, + \ 'col': 2, + \ 'end_col': 2, + \ 'text': 'Some error', + \ 'code': 'Style/SomeOtherCop', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 10, + \ 'col': 5, + \ 'end_col': 12, + \ 'text': 'Regular warning', + \ 'code': 'Style/WarningCop', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 11, + \ 'col': 1, + \ 'end_col': 1, + \ 'text': 'Another error', + \ 'code': 'Style/SpaceBeforeBlockBraces', + \ 'type': 'E', + \ }, + \ ], + \ ale#ruby#HandleRubocopOutput(347, [ + \ '{"metadata":{"rubocop_version":"0.47.1","ruby_engine":"ruby","ruby_version":"2.1.5","ruby_patchlevel":"273","ruby_platform":"x86_64-linux-gnu"},"files":[{"path":"my_great_file.rb","offenses":[{"severity":"convention","message":"Prefer single-quoted strings...","cop_name":"Style/SomeCop","corrected":false,"location":{"line":83,"column":29,"length":7}},{"severity":"fatal","message":"Some error","cop_name":"Style/SomeOtherCop","corrected":false,"location":{"line":12,"column":2,"length":1}},{"severity":"warning","message":"Regular warning","cop_name":"Style/WarningCop","corrected":false,"location":{"line":10,"column":5,"length":8}},{"severity":"error","message":"Another error","cop_name":"Style/SpaceBeforeBlockBraces","corrected":false,"location":{"line":11,"column":1,"length":1}}]}],"summary":{"offense_count":4,"target_file_count":1,"inspected_file_count":1}}' + \ ]) + +Execute(The rubocop handler should handle when files are checked and no offenses are found): + AssertEqual + \ [], + \ ale#ruby#HandleRubocopOutput(347, [ + \ '{"metadata":{"rubocop_version":"0.47.1","ruby_engine":"ruby","ruby_version":"2.1.5","ruby_patchlevel":"273","ruby_platform":"x86_64-linux-gnu"},"files":[{"path":"my_great_file.rb","offenses":[]}],"summary":{"offense_count":0,"target_file_count":1,"inspected_file_count":1}}' + \ ]) + +Execute(The rubocop handler should handle when no files are checked): + AssertEqual + \ [], + \ ale#ruby#HandleRubocopOutput(347, [ + \ '{"metadata":{"rubocop_version":"0.47.1","ruby_engine":"ruby","ruby_version":"2.1.5","ruby_patchlevel":"273","ruby_platform":"x86_64-linux-gnu"},"files":[],"summary":{"offense_count":0,"target_file_count":0,"inspected_file_count":0}}' + \ ]) + +Execute(The rubocop handler should handle output without any errors): + let g:lines = [ + \ '{"metadata":{"rubocop_version":"0.48.1","ruby_engine":"ruby","ruby_version":"2.4.1","ruby_patchlevel":"111","ruby_platform":"x86_64-darwin16"},"files":[]}', + \] + + AssertEqual + \ [], + \ ale#ruby#HandleRubocopOutput(347, g:lines) + \ + AssertEqual + \ [], + \ ale#ruby#HandleRubocopOutput(347, ['{}']) + AssertEqual + \ [], + \ ale#ruby#HandleRubocopOutput(347, []) diff --git a/vim-config/plugins/ale/test/handler/test_ruby_handler.vader b/vim-config/plugins/ale/test/handler/test_ruby_handler.vader new file mode 100644 index 00000000..824d8c58 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_ruby_handler.vader @@ -0,0 +1,38 @@ +Before: + runtime ale_linters/ruby/ruby.vim + +After: + call ale#linter#Reset() + +Execute(The ruby handler should parse lines correctly and add the column if it can): + " Point Error + " Warning + " Line Error + AssertEqual + \ [ + \ { + \ 'lnum': 6, + \ 'col': 13, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected '';''' + \ }, + \ { + \ 'lnum': 9, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'warning: statement not reached' + \ }, + \ { + \ 'lnum': 12, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected end-of-input, expecting keyword_end' + \ } + \ ], + \ ale#handlers#ruby#HandleSyntaxErrors(255, [ + \ "test.rb:6: syntax error, unexpected ';'", + \ " t = ;", + \ " ^", + \ "test.rb:9: warning: statement not reached", + \ "test.rb:12: syntax error, unexpected end-of-input, expecting keyword_end", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_rust_handler.vader b/vim-config/plugins/ale/test/handler/test_rust_handler.vader new file mode 100644 index 00000000..845df2b5 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_rust_handler.vader @@ -0,0 +1,483 @@ +Execute(The Rust handler should handle rustc output): + call ale#test#SetFilename('src/playpen.rs') + + AssertEqual + \ [ + \ { + \ 'lnum': 15, + \ 'end_lnum': 15, + \ 'type': 'E', + \ 'col': 5, + \ 'end_col': 7, + \ 'text': 'expected one of `.`, `;`, `?`, `}`, or an operator, found `for`', + \ }, + \ { + \ 'lnum': 13, + \ 'end_lnum': 13, + \ 'type': 'E', + \ 'col': 7, + \ 'end_col': 9, + \ 'text': 'no method named `wat` found for type `std::string::String` in the current scope', + \ }, + \ ], + \ ale#handlers#rust#HandleRustErrors(bufnr(''), [ + \ '', + \ 'ignore this', + \ json_encode({ + \ 'message': 'expected one of `.`, `;`, `?`, `}`, or an operator, found `for`', + \ 'code': v:null, + \ 'level': 'error', + \ 'spans': [ + \ { + \ 'file_name': '', + \ 'byte_start': 418, + \ 'byte_end': 421, + \ 'line_start': 15, + \ 'line_end': 15, + \ 'column_start': 5, + \ 'column_end': 8, + \ 'is_primary': v:true, + \ 'label': v:null, + \ }, + \ ], + \ }), + \ json_encode({ + \ 'message': 'main function not found', + \ 'code': v:null, + \ 'level': 'error', + \ 'spans': [], + \ }), + \ json_encode({ + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'no method named `wat` found for type `std::string::String` in the current scope', + \ 'spans': [ + \ { + \ 'byte_end': 410, + \ 'byte_start': 407, + \ 'column_end': 10, + \ 'column_start': 7, + \ 'file_name': '', + \ 'is_primary': v:true, + \ 'label': v:null, + \ 'line_end': 13, + \ 'line_start': 13, + \ } + \ ] + \ }), + \ json_encode({ + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'aborting due to previous error', + \ 'spans': [ + \ ] + \ }), + \ ]) + +Execute(The Rust handler should handle cargo output): + call ale#test#SetFilename('src/playpen.rs') + + AssertEqual + \ [ + \ { + \ 'lnum': 15, + \ 'end_lnum': 15, + \ 'type': 'E', + \ 'col': 5, + \ 'end_col': 7, + \ 'text': 'expected one of `.`, `;`, `?`, `}`, or an operator, found `for`', + \ }, + \ { + \ 'lnum': 13, + \ 'end_lnum': 13, + \ 'type': 'E', + \ 'col': 7, + \ 'end_col': 9, + \ 'text': 'no method named `wat` found for type `std::string::String` in the current scope', + \ }, + \ ], + \ ale#handlers#rust#HandleRustErrors(bufnr(''), [ + \ '', + \ 'ignore this', + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'expected one of `.`, `;`, `?`, `}`, or an operator, found `for`', + \ 'spans': [ + \ { + \ 'byte_end': 11508, + \ 'byte_start': 11505, + \ 'column_end': 8, + \ 'column_start': 5, + \ 'file_name': ale#path#Simplify('src/playpen.rs'), + \ 'is_primary': v:true, + \ 'label': v:null, + \ 'line_end': 15, + \ 'line_start': 15, + \ } + \ ] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'no method named `wat` found for type `std::string::String` in the current scope', + \ 'spans': [ + \ { + \ 'byte_end': 11497, + \ 'byte_start': 11494, + \ 'column_end': 10, + \ 'column_start': 7, + \ 'file_name': ale#path#Simplify('src/playpen.rs'), + \ 'is_primary': v:true, + \ 'label': v:null, + \ 'line_end': 13, + \ 'line_start': 13, + \ } + \ ] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'aborting due to previous error', + \ 'spans': [ + \ ] + \ }, + \ }), + \ ]) + +Execute(The Rust handler should should errors from expansion spans): + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'end_lnum': 4, + \ 'type': 'E', + \ 'col': 21, + \ 'end_col': 22, + \ 'text': 'mismatched types: expected bool, found integral variable', + \ }, + \ ], + \ ale#handlers#rust#HandleRustErrors(bufnr(''), [ + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'mismatched types', + \ 'spans': [ + \ { + \ 'byte_end': 1, + \ 'byte_start': 1, + \ 'column_end': 1, + \ 'column_start': 1, + \ 'file_name': ale#path#Simplify('src/other.rs'), + \ 'is_primary': v:true, + \ 'label': 'some other error', + \ 'line_end': 4, + \ 'line_start': 4, + \ 'expansion': { + \ 'span': { + \ 'byte_end': 54, + \ 'byte_start': 52, + \ 'column_end': 23, + \ 'column_start': 21, + \ 'file_name': ale#path#Simplify('src/playpen.rs'), + \ 'is_primary': v:true, + \ 'label': 'expected bool, found integral variable', + \ 'line_end': 4, + \ 'line_start': 4, + \ } + \ } + \ } + \ ] + \ }, + \ }), + \ ]) + +Execute(The Rust handler should show detailed errors): + call ale#test#SetFilename('src/playpen.rs') + + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'end_lnum': 4, + \ 'type': 'E', + \ 'col': 21, + \ 'end_col': 22, + \ 'text': 'mismatched types: expected bool, found integral variable', + \ }, + \ ], + \ ale#handlers#rust#HandleRustErrors(bufnr(''), [ + \ '', + \ 'ignore this', + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'mismatched types', + \ 'spans': [ + \ { + \ 'byte_end': 54, + \ 'byte_start': 52, + \ 'column_end': 23, + \ 'column_start': 21, + \ 'expansion': v:null, + \ 'file_name': ale#path#Simplify('src/playpen.rs'), + \ 'is_primary': v:true, + \ 'label': 'expected bool, found integral variable', + \ 'line_end': 4, + \ 'line_start': 4, + \ } + \ ] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'aborting due to previous error(s)', + \ 'spans': [ + \ ] + \ }, + \ }), + \ ]) + +Execute(The Rust handler should show detailed clippy errors with rendered field if it's available): + call ale#test#SetFilename('src/playpen.rs') + + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'end_lnum': 4, + \ 'type': 'E', + \ 'col': 21, + \ 'end_col': 22, + \ 'text': 'mismatched types: expected bool, found integral variable', + \ 'detail': 'this is a detailed description', + \ }, + \ ], + \ ale#handlers#rust#HandleRustErrors(bufnr(''), [ + \ '', + \ 'ignore this', + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'mismatched types', + \ 'rendered': 'this is a detailed description', + \ 'spans': [ + \ { + \ 'byte_end': 54, + \ 'byte_start': 52, + \ 'column_end': 23, + \ 'column_start': 21, + \ 'expansion': v:null, + \ 'file_name': ale#path#Simplify('src/playpen.rs'), + \ 'is_primary': v:true, + \ 'label': 'expected bool, found integral variable', + \ 'line_end': 4, + \ 'line_start': 4, + \ } + \ ] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'aborting due to previous error(s)', + \ 'spans': [ + \ ] + \ }, + \ }), + \ ]) + +Execute(The Rust handler should find correct files): + call ale#test#SetFilename('src/noerrors/mod.rs') + + AssertEqual + \ [], + \ ale#handlers#rust#HandleRustErrors(bufnr(''), [ + \ '', + \ 'ignore this', + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'unresolved import `Undefined`', + \ 'spans': [ + \ { + \ 'byte_end': 103, + \ 'byte_start': 94, + \ 'column_end': 14, + \ 'column_start': 5, + \ 'file_name': 'src/haserrors/mod.rs', + \ 'is_primary': v:true, + \ 'label': 'no `Undefined` in the root', + \ 'line_end': 1, + \ 'line_start': 1, + \ } + \ ] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'aborting due to previous error', + \ 'spans': [ + \ ] + \ }, + \ }), + \ ]) + +Execute(The Rust handler should remove secondary spans if set): + call ale#test#SetFilename('src/noerrors/mod.rs') + + let g:ale_rust_ignore_secondary_spans = 0 + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'end_lnum': 1, + \ 'type': 'E', + \ 'end_col': 20, + \ 'col': 1, + \ 'text': 'this function takes 1 parameter but 0 were supplied: defined here', + \ }, + \ { + \ 'lnum': 1, + \ 'end_lnum': 1, + \ 'type': 'E', + \ 'end_col': 45, + \ 'col': 40, + \ 'text': 'this function takes 1 parameter but 0 were supplied: expected 1 parameter', + \ }, + \ ], + \ ale#handlers#rust#HandleRustErrors(bufnr(''), [ + \ '', + \ 'fn test(x: u8) -> u8 { x } fn main() { x(); }', + \ json_encode({ + \ 'message': { + \ 'code': { + \ 'code': 'E0061', + \ 'explanation': 'Dummy explanation; not used' + \ }, + \ 'level': 'error', + \ 'message': 'this function takes 1 parameter but 0 were supplied', + \ 'spans': [ + \ { + \ 'byte_end': 20, + \ 'byte_start': 0, + \ 'column_end': 21, + \ 'column_start': 1, + \ 'file_name': 'src/noerrors/mod.rs', + \ 'is_primary': v:false, + \ 'label': 'defined here', + \ 'line_end': 1, + \ 'line_start': 1, + \ }, + \ { + \ 'byte_end': 45, + \ 'byte_start': 39, + \ 'column_end': 46, + \ 'column_start': 40, + \ 'file_name': '', + \ 'is_primary': v:true, + \ 'label': 'expected 1 parameter', + \ 'line_end': 1, + \ 'line_start': 1, + \ }, + \ ] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'aborting due to previous error', + \ 'spans': [] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'For more information about this error, try `rustc --explain E0061`.', + \ 'spans': [] + \ }, + \ }), + \ ]) + + let g:ale_rust_ignore_secondary_spans = 1 + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'end_lnum': 1, + \ 'type': 'E', + \ 'end_col': 45, + \ 'col': 40, + \ 'text': 'this function takes 1 parameter but 0 were supplied: expected 1 parameter', + \ }, + \ ], + \ ale#handlers#rust#HandleRustErrors(bufnr(''), [ + \ '', + \ 'fn test(x: u8) -> u8 { x } fn main() { x(); }', + \ json_encode({ + \ 'message': { + \ 'code': { + \ 'code': 'E0061', + \ 'explanation': 'Dummy explanation; not used' + \ }, + \ 'level': 'error', + \ 'message': 'this function takes 1 parameter but 0 were supplied', + \ 'spans': [ + \ { + \ 'byte_end': 20, + \ 'byte_start': 0, + \ 'column_end': 21, + \ 'column_start': 1, + \ 'file_name': 'src/noerrors/mod.rs', + \ 'is_primary': v:false, + \ 'label': 'defined here', + \ 'line_end': 1, + \ 'line_start': 1, + \ }, + \ { + \ 'byte_end': 45, + \ 'byte_start': 39, + \ 'column_end': 46, + \ 'column_start': 40, + \ 'file_name': '', + \ 'is_primary': v:true, + \ 'label': 'expected 1 parameter', + \ 'line_end': 1, + \ 'line_start': 1, + \ }, + \ ] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'aborting due to previous error', + \ 'spans': [] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'For more information about this error, try `rustc --explain E0061`.', + \ 'spans': [] + \ }, + \ }), + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_salt_salt_lint.vader b/vim-config/plugins/ale/test/handler/test_salt_salt_lint.vader new file mode 100644 index 00000000..7e234785 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_salt_salt_lint.vader @@ -0,0 +1,34 @@ +Before: + runtime ale_linters/salt/salt_lint.vim + +After: + call ale#linter#Reset() + +Execute(The salt handler should parse lines correctly and show error in severity HIGH): + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'code': 207, + \ 'text': 'File modes should always be encapsulated in quotation marks', + \ 'type': 'E' + \ } + \ ], + \ ale_linters#salt#salt_lint#Handle(255, [ + \ '[{"id": "207", "message": "File modes should always be encapsulated in quotation marks", "filename": "test.sls", "linenumber": 5, "line": " - mode: 0755", "severity": "HIGH"}]' + \ ]) + + +Execute(The salt handler should parse lines correctly and show error in severity not HIGH): + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'code': 204, + \ 'text': 'Lines should be no longer that 160 chars', + \ 'type': 'W' + \ } + \ ], + \ ale_linters#salt#salt_lint#Handle(255, [ + \ '[{"id": "204", "message": "Lines should be no longer that 160 chars", "filename": "test2.sls", "linenumber": 27, "line": "this line is definitely longer than 160 chars, this line is definitely longer than 160 chars, this line is definitely longer than 160 chars", "severity": "VERY_LOW"}]' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_scala_handler.vader b/vim-config/plugins/ale/test/handler/test_scala_handler.vader new file mode 100644 index 00000000..3214bdbc --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_scala_handler.vader @@ -0,0 +1,32 @@ +After: + call ale#linter#Reset() + +Execute(The handler should return an empty list with empty input): + AssertEqual [], ale#handlers#scala#HandleScalacLintFormat(bufnr(''), []) + +Execute(The handler should correctly parse error messages): + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 8, + \ 'text': ''':'' expected but identifier found.', + \ 'type': 'E' + \ }, + \ { + \ 'lnum': 6, + \ 'col': 2, + \ 'text': 'identifier expected but eof found.', + \ 'type': 'E' + \ } + \ ], + \ ale#handlers#scala#HandleScalacLintFormat(bufnr(''), + \ [ + \ "hi.scala:4: error: ':' expected but identifier found.", + \ " Some stupid scala code", + \ " ^", + \ "hi.scala:6: error: identifier expected but eof found.", + \ ")", + \ " ^", + \ "two errors found", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_scalastyle_handler.vader b/vim-config/plugins/ale/test/handler/test_scalastyle_handler.vader new file mode 100644 index 00000000..32da79c0 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_scalastyle_handler.vader @@ -0,0 +1,53 @@ +Before: + runtime! ale_linters/scala/scalastyle.vim + +After: + call ale#linter#Reset() + +Execute(The scalastyle handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 190, + \ 'text': 'Missing or badly formed ScalaDoc: Missing @param str', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 200, + \ 'col': 34, + \ 'text': 'There should be a space before the plus (+) sign', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 200, + \ 'col': 1, + \ 'text': 'There should be a space before the plus (+) sign', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#scala#scalastyle#Handle(347, [ + \ 'Starting scalastyle', + \ 'start file /home/test/Doop.scala', + \ 'warning file=/home/test/Doop.scala message=Missing or badly formed ScalaDoc: Missing @param str line=190', + \ 'error file=/home/test/Doop.scala message=There should be a space before the plus (+) sign line=200 column=33', + \ 'error file=/home/test/Doop.scala message=There should be a space before the plus (+) sign line=200 column=0', + \ 'end file /home/test/Doop.scala', + \ 'Processed 1 file(s)', + \ 'Found 0 errors', + \ 'Found 3 warnings', + \ 'Finished in 934 ms', + \ ]) + +Execute(The scalastyle linter should complain when there is no configuration file): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': '(See :help ale-scala-scalastyle) No scalastyle configuration file was found.', + \ }, + \ ], + \ ale_linters#scala#scalastyle#Handle(347, [ + \ 'scalastyle 1.0.0', + \ 'Usage: scalastyle [options] ', + \ ' -c, --config FILE configuration file (required)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_shell_handler.vader b/vim-config/plugins/ale/test/handler/test_shell_handler.vader new file mode 100644 index 00000000..c61cf37d --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_shell_handler.vader @@ -0,0 +1,177 @@ +Before: + runtime ale_linters/sh/shell.vim + +After: + call ale#linter#Reset() + +Execute(The shell handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 13, + \ 'text': 'syntax error near unexpected token d', + \ }, + \ { + \ 'lnum': 7, + \ 'text': 'line 42: line 36:', + \ }, + \ { + \ 'lnum': 11, + \ 'text': 'Syntax error: "(" unexpected', + \ }, + \ { + \ 'lnum': 95, + \ 'text': 'parse error near `out=$(( $1 / 1024. )...', + \ }, + \ { + \ 'lnum': 22, + \ 'text': ':11: :33: :44:', + \ }, + \ { + \ 'lnum': 9, + \ 'text': '`done'' unexpected', + \ }, + \ ], + \ ale_linters#sh#shell#Handle(347, [ + \ 'bash: line 13: syntax error near unexpected token d', + \ 'bash: line 7: line 42: line 36:', + \ 'sh: 11: Syntax error: "(" unexpected', + \ 'qfm:95: parse error near `out=$(( $1 / 1024. )...', + \ 'qfm:22: :11: :33: :44:', + \ 'foo.sh: syntax error at line 9: `done'' unexpected', + \ ]) + +Execute(The shell handler should parse Simplified Chinese lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'text': '未预期的符号“done”附近有语法错误', + \ }, + \ { + \ 'lnum': 90, + \ 'text': '寻找匹配的“"”时遇到了未预期的文件结束符', + \ }, + \ { + \ 'lnum': 111, + \ 'text': '语法错误: 未预期的文件结尾', + \ }, + \ { + \ 'lnum': 22, + \ 'text': ':11: :33: :44:', + \ }, + \ ], + \ ale_linters#sh#shell#Handle(347, [ + \ '/tmp/nvimWL5sOL/2/a.sh:行0: 未预期的符号“done”附近有语法错误', + \ '/tmp/nvimWL5sOL/2/a.sh:行90: 寻找匹配的“"”时遇到了未预期的文件结束符', + \ '/tmp/nvimWL5sOL/2/a.sh:行111: 语法错误: 未预期的文件结尾', + \ '/tmp/nvimWL5sOL/2/a.sh:行22: :11: :33: :44:', + \ ]) + +Execute(The shell handler should parse Traditional Chinese lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'text': '未預期的字組「(」附近有語法錯誤', + \ }, + \ { + \ 'lnum': 90, + \ 'text': '尋找匹配的「"」時遇到了未預期的檔案結束符', + \ }, + \ { + \ 'lnum': 111, + \ 'text': '語法錯誤: 未預期的檔案結尾', + \ }, + \ { + \ 'lnum': 22, + \ 'text': ':11: :33: :44:', + \ }, + \ ], + \ ale_linters#sh#shell#Handle(347, [ + \ '/tmp/nvimWL5sOL/2/a.sh: 列 0: 未預期的字組「(」附近有語法錯誤', + \ '/tmp/nvimWL5sOL/2/a.sh: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符', + \ '/tmp/nvimWL5sOL/2/a.sh: 列 111: 語法錯誤: 未預期的檔案結尾', + \ '/tmp/nvimWL5sOL/2/a.sh: 列 22: :11: :33: :44:', + \ ]) + +Execute(The shell handler should parse Japanese lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'text': "予期しないトークン `(' 周辺に構文エラーがあります", + \ }, + \ { + \ 'lnum': 90, + \ 'text': "予期しないトークン `done' 周辺に構文エラーがあります", + \ }, + \ { + \ 'lnum': 111, + \ 'text': "対応する `\"' を探索中に予期しないファイル終了 (EOF) です", + \ }, + \ { + \ 'lnum': 22, + \ 'text': ':11: :33: :44:', + \ }, + \ ], + \ ale_linters#sh#shell#Handle(347, [ + \ "/tmp/nvimWL5sOL/2/a.sh: 行 0: 予期しないトークン `(' 周辺に構文エラーがあります", + \ "/tmp/nvimWL5sOL/2/a.sh: 行 90: 予期しないトークン `done' 周辺に構文エラーがあります", + \ "/tmp/nvimWL5sOL/2/a.sh: 行 111: 対応する `\"' を探索中に予期しないファイル終了 (EOF) です", + \ "/tmp/nvimWL5sOL/2/a.sh: 行 22: :11: :33: :44:", + \ ]) + +Execute(The shell handler should parse Greek lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'text': 'συντακτικό σφάλμα κοντά στο μη αναμενόμενο σύμβολο «done»', + \ }, + \ { + \ 'lnum': 90, + \ 'text': 'syntax error: μη αναμενόμενο τέλος αρχείου', + \ }, + \ { + \ 'lnum': 111, + \ 'text': 'μη αναμενόμενο EOF κατά την αναζήτηση «"»', + \ }, + \ { + \ 'lnum': 22, + \ 'text': ':11: :33: :44:', + \ }, + \ ], + \ ale_linters#sh#shell#Handle(347, [ + \ '/tmp/nvimWL5sOL/2/a.sh: γραμμή 0: συντακτικό σφάλμα κοντά στο μη αναμενόμενο σύμβολο «done»', + \ '/tmp/nvimWL5sOL/2/a.sh: γραμμή 90: syntax error: μη αναμενόμενο τέλος αρχείου', + \ '/tmp/nvimWL5sOL/2/a.sh: γραμμή 111: μη αναμενόμενο EOF κατά την αναζήτηση «"»', + \ "/tmp/nvimWL5sOL/2/a.sh: γραμμή 22: :11: :33: :44:", + \ ]) + +Execute(The shell handler should parse Russian lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'text': 'синтаксическая ошибка рядом с неожиданным маркером «done»', + \ }, + \ { + \ 'lnum': 90, + \ 'text': 'синтаксическая ошибка: неожиданный конец файла', + \ }, + \ { + \ 'lnum': 111, + \ 'text': 'неожиданный конец файла во время поиска «"»', + \ }, + \ { + \ 'lnum': 22, + \ 'text': ':11: :33: :44:', + \ }, + \ ], + \ ale_linters#sh#shell#Handle(347, [ + \ '/tmp/nvimWL5sOL/2/a.sh: строка 0: синтаксическая ошибка рядом с неожиданным маркером «done»', + \ '/tmp/nvimWL5sOL/2/a.sh: строка 90: синтаксическая ошибка: неожиданный конец файла', + \ '/tmp/nvimWL5sOL/2/a.sh: строка 111: неожиданный конец файла во время поиска «"»', + \ '/tmp/nvimWL5sOL/2/a.sh: строка 22: :11: :33: :44:', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_shellcheck_handler.vader b/vim-config/plugins/ale/test/handler/test_shellcheck_handler.vader new file mode 100644 index 00000000..33f12989 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_shellcheck_handler.vader @@ -0,0 +1,43 @@ +Before: + runtime ale_linters/shell/shellcheck.vim + +After: + call ale#linter#Reset() + +Execute(The shellcheck handler should handle basic errors or warnings): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'W', + \ 'text': 'In POSIX sh, ''let'' is not supported.', + \ 'code': 'SC2039', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 3, + \ 'type': 'E', + \ 'text': 'Don''t put spaces around the = in assignments.', + \ 'code': 'SC1068', + \ }, + \ ], + \ ale#handlers#shellcheck#Handle(bufnr(''), [ + \ '-:2:1: warning: In POSIX sh, ''let'' is not supported. [SC2039]', + \ '-:2:3: error: Don''t put spaces around the = in assignments. [SC1068]', + \ ]) + +Execute(The shellcheck handler should handle notes): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'col': 3, + \ 'type': 'I', + \ 'text': 'Double quote to prevent globbing and word splitting.', + \ 'code': 'SC2086', + \ }, + \ ], + \ ale#handlers#shellcheck#Handle(bufnr(''), [ + \ '-:3:3: note: Double quote to prevent globbing and word splitting. [SC2086]', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_slim_handler.vader b/vim-config/plugins/ale/test/handler/test_slim_handler.vader new file mode 100644 index 00000000..bfd29f3a --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_slim_handler.vader @@ -0,0 +1,34 @@ +" Author: Markus Doits +Before: + runtime ale_linters/slim/slimlint.vim + +After: + call ale#linter#Reset() + +Execute(The slim handler should parse lines correctly): + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': '`div` is redundant when class attribute shortcut is present', + \ 'code': 'RedundantDiv', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'text': 'Line is too long. [136/80]', + \ 'code': 'LineLength', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 3, + \ 'text': 'Invalid syntax', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#slim#slimlint#Handle(347, [ + \ 'inv.slim:1 [W] RedundantDiv: `div` is redundant when class attribute shortcut is present', + \ 'inv.slim:2 [W] LineLength: Line is too long. [136/80]', + \ 'inv.slim:3 [E] Invalid syntax', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_sml_handler.vader b/vim-config/plugins/ale/test/handler/test_sml_handler.vader new file mode 100644 index 00000000..4e16e244 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_sml_handler.vader @@ -0,0 +1,87 @@ +Execute (Testing on EOF error): + AssertEqual [ + \ { + \ 'filename': 'a.sml', + \ 'lnum': 2, + \ 'col': 15, + \ 'type': 'E', + \ 'text': 'Error: syntax error found at EOF', + \ }, + \], + \ ale#handlers#sml#Handle(42, [ + \ "Standard ML of New Jersey v110.78 [built: Thu Jul 23 11:21:58 2015]", + \ "[opening a.sml]", + \ "a.sml:2.16 Error: syntax error found at EOF", + \ '/usr/lib/smlnj/bin/sml: Fatal error -- Uncaught exception Compile with "syntax error" raised at ../compiler/Parse/main/smlfile.sml:15.24-15.46', + \]) + +Execute (Testing if the handler can handle multiple errors on the same line): + AssertEqual [ + \ { + \ 'filename': 'a.sml', + \ 'lnum': 1, + \ 'col': 5, + \ 'type': 'E', + \ 'text': "Error: can't find function arguments in clause", + \ }, + \ { + \ 'filename': 'a.sml', + \ 'lnum': 1, + \ 'col': 12, + \ 'type': 'E', + \ 'text': 'Error: unbound variable or constructor: wow', + \ }, + \], + \ ale#handlers#sml#Handle(42, [ + \ "Standard ML of New Jersey v110.78 [built: Thu Jul 23 11:21:58 2015]", + \ "[opening test.sml]", + \ "a.sml:1.6-1.10 Error: can't find function arguments in clause", + \ "a.sml:1.13-1.16 Error: unbound variable or constructor: wow", + \ "/usr/lib/smlnj/bin/sml: Fatal error -- Uncaught exception Error with 0", + \ "raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27", + \]) + +Execute (Testing rarer errors): + AssertEqual [ + \ { + \ 'filename': 'a.sml', + \ 'lnum': 5, + \ 'col': 18, + \ 'type': 'E', + \ 'text': "Error: syntax error found at ID", + \ }, + \ { + \ 'filename': 'a.sml', + \ 'lnum': 7, + \ 'col': 0, + \ 'type': 'E', + \ 'text': "Error: value type in structure doesn't match signature spec", + \ }, + \], + \ ale#handlers#sml#Handle(42, [ + \ "Standard ML of New Jersey v110.78 [built: Thu Jul 23 11:21:58 2015]", + \ "[opening test.sml]", + \ "a.sml:5.19 Error: syntax error found at ID", + \ "a.sml:7.1-9.27 Error: value type in structure doesn't match signature spec", + \ "/usr/lib/smlnj/bin/sml: Fatal error -- Uncaught exception Error with 0", + \ "raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27", + \]) + +Execute (Testing a warning): + AssertEqual [ + \ { + \ 'filename': 'a.sml', + \ 'lnum': 4, + \ 'col': 4, + \ 'type': 'W', + \ 'text': "Warning: match nonexhaustive", + \ }, + \], + \ ale#handlers#sml#Handle(42, [ + \ "Standard ML of New Jersey v110.78 [built: Thu Jul 23 11:21:58 2015]", + \ "[opening a.sml]", + \ "a.sml:4.5-4.12 Warning: match nonexhaustive", + \ "0 => ...", + \ "val f = fn : int -> int", + \ "-", + \]) diff --git a/vim-config/plugins/ale/test/handler/test_solc_handler.vader b/vim-config/plugins/ale/test/handler/test_solc_handler.vader new file mode 100644 index 00000000..dcaa8b2d --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_solc_handler.vader @@ -0,0 +1,34 @@ +Before: + runtime ale_linters/solidity/solc.vim + +After: + call ale#linter#Reset() + +Execute(Check solc output parsing): + AssertEqual + \ [ + \ { + \ 'lnum': 40, + \ 'col': 48, + \ 'text': 'This declaration shadows an existing declaration.', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 23, + \ 'col': 16, + \ 'text': 'Member "getSinleSignature" not found or not visible after argument-dependent lookup in type(contract OneToN).', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#solidity#solc#Handle(bufnr(''), [ + \ 'Warning: This declaration shadows an existing declaration.', + \ ' --> /path/to/file.sol:40:48:', + \ ' |', + \ '40 | function decimals() external view returns (uint8 decimals);', + \ ' | ^------------^', + \ 'Error: Member "getSinleSignature" not found or not visible after argument-dependent lookup in type(contract OneToN).', + \ ' --> /path/to/file.sol:23:16: ', + \ ' | ', + \ '23 | return OneToN.getSinleSignature(signatures, i);', + \ ' | ^----------------------^', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_solhint_handler.vader b/vim-config/plugins/ale/test/handler/test_solhint_handler.vader new file mode 100644 index 00000000..f8fffb60 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_solhint_handler.vader @@ -0,0 +1,84 @@ +Before: + runtime ale_linters/solidity/solhint.vim + +After: + call ale#linter#Reset() + +Execute(The solhint handler should parse linter error messages correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 17, + \ 'text': 'Compiler version must be fixed', + \ 'code': 'compiler-fixed', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 8, + \ 'text': 'Use double quotes for string literals', + \ 'code': 'quotes', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 8, + \ 'text': 'Use double quotes for string literals', + \ 'code': 'quotes', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 13, + \ 'col': 3, + \ 'text': 'Expected indentation of 4 spaces but found 2', + \ 'code': 'indent', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 14, + \ 'col': 3, + \ 'text': 'Expected indentation of 4 spaces but found 2', + \ 'code': 'indent', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 47, + \ 'col': 3, + \ 'text': 'Function order is incorrect, public function can not go after internal function.', + \ 'code': 'func-order', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#solhint#Handle(bufnr(''), [ + \ 'contracts/Bounty.sol: line 1, col 17, Warning - Compiler version must be fixed (compiler-fixed)', + \ 'contracts/Bounty.sol: line 4, col 8, Error - Use double quotes for string literals (quotes)', + \ 'contracts/Bounty.sol: line 5, col 8, Error - Use double quotes for string literals (quotes)', + \ 'contracts/Bounty.sol: line 13, col 3, Error - Expected indentation of 4 spaces but found 2 (indent)', + \ 'contracts/Bounty.sol: line 14, col 3, Error - Expected indentation of 4 spaces but found 2 (indent)', + \ 'contracts/Bounty.sol: line 47, col 3, Error - Function order is incorrect, public function can not go after internal function. (func-order)', + \ ]) + + +Execute(The solhint handler should parse syntax error messages correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 30, + \ 'col': 4, + \ 'text': "missing ';' at 'uint248'", + \ 'code': 'Parse error', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 203, + \ 'col': 4, + \ 'text': "no viable alternative at input '_loserStakeMultiplier}'", + \ 'code': 'Parse error', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#solhint#Handle(bufnr(''), [ + \ "contracts/Bounty.sol: line 30, col 4, Error - Parse error: missing ';' at 'uint248'", + \ "contracts/Bounty.sol: line 203, col 4, Error - Parse error: no viable alternative at input '_loserStakeMultiplier}'", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_spectral_handler.vader b/vim-config/plugins/ale/test/handler/test_spectral_handler.vader new file mode 100644 index 00000000..89a3ff1b --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_spectral_handler.vader @@ -0,0 +1,52 @@ +Before: + runtime ale_linters/yaml/spectral.vim + +After: + call ale#linter#Reset() + +Execute(spectral handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'code': 'oas3-api-servers', + \ 'text': 'OpenAPI `servers` must be present and non-empty array.', + \ 'type': 'W' + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'code': 'oas3-schema', + \ 'text': 'Object should have required property `paths`.', + \ 'type': 'E' + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'code': 'openapi-tags', + \ 'text': 'OpenAPI object should have non-empty `tags` array.', + \ 'type': 'W' + \ }, + \ { + \ 'lnum': 3, + \ 'col': 6, + \ 'code': 'info-contact', + \ 'text': 'Info object should contain `contact` object.', + \ 'type': 'W' + \ }, + \ { + \ 'lnum': 3, + \ 'col': 6, + \ 'code': 'oas3-schema', + \ 'text': '`info` property should have required property `version`.', + \ 'type': 'E' + \ }, + \ ], + \ ale#handlers#spectral#HandleSpectralOutput(bufnr(''), [ + \ 'openapi.yml:1:1 warning oas3-api-servers "OpenAPI `servers` must be present and non-empty array."', + \ 'openapi.yml:1:1 error oas3-schema "Object should have required property `paths`."', + \ 'openapi.yml:1:1 warning openapi-tags "OpenAPI object should have non-empty `tags` array."', + \ 'openapi.yml:3:6 warning info-contact "Info object should contain `contact` object."', + \ 'openapi.yml:3:6 error oas3-schema "`info` property should have required property `version`."', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_sqlint_handler.vader b/vim-config/plugins/ale/test/handler/test_sqlint_handler.vader new file mode 100644 index 00000000..5567ca41 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_sqlint_handler.vader @@ -0,0 +1,34 @@ +Before: + runtime! ale_linters/sql/sqlint.vim + +After: + call ale#linter#Reset() + +Execute(The sqlint handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'col': 1, + \ 'text': 'syntax error at or near "WIBBLE"', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 47, + \ 'col': 11, + \ 'text': 'unterminated quoted string at or near "''', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 50, + \ 'col': 12, + \ 'text': 'some warning at end of input', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#sql#sqlint#Handle(347, [ + \ 'This line should be ignored completely', + \ 'stdin:3:1:ERROR syntax error at or near "WIBBLE"', + \ 'stdin:47:11:ERROR unterminated quoted string at or near "''', + \ 'stdin:50:12:WARNING some warning at end of input', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_sqllint_handler.vader b/vim-config/plugins/ale/test/handler/test_sqllint_handler.vader new file mode 100644 index 00000000..2f2283c8 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_sqllint_handler.vader @@ -0,0 +1,23 @@ +Before: + " Load the file which defines the linter. + runtime ale_linters/sql/sqllint.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, + \ 'col': 0, + \ 'type': '', + \ 'text': 'stdin:1 [ER_NO_DB_ERROR] No database selected' + \ }, + \ ], + \ ale_linters#sql#sqllint#Handle(bufnr(''), [ + \ 'stdin:1 [ER_NO_DB_ERROR] No database selected' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_standard_handler.vader b/vim-config/plugins/ale/test/handler/test_standard_handler.vader new file mode 100644 index 00000000..31e3a36b --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_standard_handler.vader @@ -0,0 +1,37 @@ +Before: + Save g:ale_javascript_eslint_suppress_eslintignore + + let g:ale_javascript_eslint_suppress_eslintignore = 0 + +After: + Restore + +Execute(The standard handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 47, + \ 'col': 14, + \ 'text': 'Expected indentation of 2 spaces but found 4.', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 56, + \ 'col': 41, + \ 'text': 'Strings must use singlequote.', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 13, + \ 'col': 3, + \ 'text': 'Parsing error: Unexpected token', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#eslint#Handle(347, [ + \ 'This line should be ignored completely', + \ '/path/to/some-filename.js:47:14: Expected indentation of 2 spaces but found 4.', + \ '/path/to/some-filename.js:56:41: Strings must use singlequote.', + \ 'This line should be ignored completely', + \ '/path/to/some-filename.js:13:3: Parsing error: Unexpected token', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_stylelint_handler.vader b/vim-config/plugins/ale/test/handler/test_stylelint_handler.vader new file mode 100644 index 00000000..5cb34601 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_stylelint_handler.vader @@ -0,0 +1,43 @@ +After: + unlet! g:error_lines + +Execute (stylelint errors should be handled correctly): + " Stylelint includes trailing spaces for output. This needs to be taken into + " account for parsing errors. + AssertEqual + \ [ + \ { + \ 'lnum': 108, + \ 'col': 10, + \ 'type': 'E', + \ 'text': 'Unexpected leading zero', + \ 'code': 'number-leading-zero', + \ }, + \ { + \ 'lnum': 116, + \ 'col': 20, + \ 'type': 'E', + \ 'text': 'Expected a trailing semicolon', + \ 'code': 'declaration-block-trailing-semicolon', + \ }, + \ ], + \ ale#handlers#css#HandleStyleLintFormat(42, [ + \ 'src/main.css', + \ ' 108:10 ✖ Unexpected leading zero number-leading-zero ', + \ ' 116:20 ✖ Expected a trailing semicolon declaration-block-trailing-semicolon', + \ ]) + +Execute (stylelint should complain when no configuration file is used): + let g:error_lines = [ + \ 'Error: No configuration provided for /home/w0rp/.vim/bundle/ale/test.stylus', + \ ' at module.exports (/home/w0rp/.vim/bundle/ale/node_modules/stylelint/lib/utils/configurationError.js:8:27)', + \ ' at stylelint._fullExplorer.load.then.then.config (/home/w0rp/.vim/bundle/ale/node_modules/stylelint/lib/getConfigForFile.js:39:13)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'stylelint exception thrown (type :ALEDetail for more information)', + \ 'detail': join(g:error_lines, "\n"), + \ }], + \ ale#handlers#css#HandleStyleLintFormat(347, g:error_lines[:]) diff --git a/vim-config/plugins/ale/test/handler/test_swaglint_handler.vader b/vim-config/plugins/ale/test/handler/test_swaglint_handler.vader new file mode 100644 index 00000000..7ab10439 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_swaglint_handler.vader @@ -0,0 +1,68 @@ +Before: + runtime ale_linters/yaml/swaglint.vim + +After: + call ale#linter#Reset() + +Execute(The swaglint handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'Missing required property: info', + \ 'code': 'sway_object_missing_required_property', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 6, + \ 'col': 9, + \ 'text': 'Not a valid response definition', + \ 'code': 'sway_one_of_missing', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 11, + \ 'text': 'Missing required property: description', + \ 'code': 'sway_object_missing_required_property', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 11, + \ 'text': 'Missing required property: $ref', + \ 'code': 'sway_object_missing_required_property', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'text': 'Expected type string but found type integer', + \ 'code': 'sway_invalid_type', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'text': 'No enum match for: 2', + \ 'code': 'sway_enum_mismatch', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 14, + \ 'col': 3, + \ 'text': 'Definition is not used: #/definitions/Foo', + \ 'code': 'sway_unused_definition', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#yaml#swaglint#Handle(347, [ + \ 'swagger.yaml: error @ 1:1 - Missing required property: info (sway_object_missing_required_property)', + \ 'swagger.yaml: error @ 6:9 - Not a valid response definition (sway_one_of_missing)', + \ 'swagger.yaml: error @ 7:11 - Missing required property: description (sway_object_missing_required_property)', + \ 'swagger.yaml: error @ 7:11 - Missing required property: $ref (sway_object_missing_required_property)', + \ 'swagger.yaml: error @ 1:10 - Expected type string but found type integer (sway_invalid_type)', + \ 'swagger.yaml: error @ 1:10 - No enum match for: 2 (sway_enum_mismatch)', + \ 'swagger.yaml: warning @ 14:3 - Definition is not used: #/definitions/Foo (sway_unused_definition)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_swiftlint_handler.vader b/vim-config/plugins/ale/test/handler/test_swiftlint_handler.vader new file mode 100644 index 00000000..725ff97c --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_swiftlint_handler.vader @@ -0,0 +1,30 @@ +Before: + runtime ale_linters/swift/swiftlint.vim + +After: + call ale#linter#Reset() + +Execute(The swiftint handler should parse error messages correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 7, + \ 'text': 'Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used.', + \ 'code': 'operator_usage_whitespace', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 11, + \ 'text': 'Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used.', + \ 'code': 'operator_usage_whitespace', + \ 'type': 'W', + \ }, + \ + \ ], + \ ale_linters#swift#swiftlint#Handle(bufnr(''), [ + \ 'This line should be ignored', + \ ':1:7: warning: Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used. (operator_usage_whitespace)', + \ ':1:11: warning: Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used. (operator_usage_whitespace)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_swipl_handler.vader b/vim-config/plugins/ale/test/handler/test_swipl_handler.vader new file mode 100644 index 00000000..81b8b9e5 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_swipl_handler.vader @@ -0,0 +1,155 @@ +Before: + runtime ale_linters/prolog/swipl.vim + +After: + call ale#linter#Reset() + +Execute (The swipl handler should handle oneline warning / error): + call ale#test#SetFilename('test.pl') + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 1, + \ 'text': 'Syntax error: Operator expected', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#prolog#swipl#Handle(bufnr(''), [ + \ 'ERROR: /path/to/test.pl:5:1: Syntax error: Operator expected', + \ ]) + +Execute (The swipl handler should handle a warning / error of two lines): + call ale#test#SetFilename('test.pl') + AssertEqual + \ [ + \ { + \ 'lnum': 9, + \ 'col': 0, + \ 'text': 'Singleton variables: [M]', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#prolog#swipl#Handle(bufnr(''), [ + \ 'Warning: /path/to/test.pl:9:', + \ ' Singleton variables: [M]', + \ ]) + +Execute (The swipl handler should handle a warning / error of two lines in the new format): + call ale#test#SetFilename('test.pl') + AssertEqual + \ [ + \ { + \ 'lnum': 9, + \ 'col': 0, + \ 'text': 'Singleton variables: [M]', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#prolog#swipl#Handle(bufnr(''), [ + \ 'Warning: /path/to/test.pl:9:', + \ 'Warning: Singleton variables: [M]', + \ ]) + +Execute (The swipl handler should join three or more lines with '. '): + call ale#test#SetFilename('test.pl') + AssertEqual + \ [ + \ { + \ 'lnum': 10, + \ 'col': 0, + \ 'text': 'Clauses of fib/2 are not together in the source-file. Earlier definition at /path/to/test.pl:7. Current predicate: f/0. Use :- discontiguous fib/2. to suppress this message', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#prolog#swipl#Handle(bufnr(''), [ + \ 'Warning: /path/to/test.pl:10:', + \ ' Clauses of fib/2 are not together in the source-file', + \ ' Earlier definition at /path/to/test.pl:7', + \ ' Current predicate: f/0', + \ ' Use :- discontiguous fib/2. to suppress this message', + \ ]) + +Execute (The swipl handler should ignore warnings / errors 'No permission to call sandboxed ...'): + call ale#test#SetFilename('test.pl') + AssertEqual + \ [], + \ ale_linters#prolog#swipl#Handle(bufnr(''), [ + \ 'ERROR: /path/to/test.pl:11:', + \ ' No permission to call sandboxed `''$set_predicate_attribute''(_G3416:_G3417,_G3413,_G3414)''', + \ ' Reachable from:', + \ ' system:''$set_pattr''(A,B,C,D)', + \ ' system:''$set_pattr''(vimscript:A,B,C)', + \ ' vimscript: (multifile A)', + \ 'ERROR: /path/to/test.pl:12:', + \ ' No permission to call sandboxed `''$set_predicate_attribute''(_G205:_G206,_G202,_G203)''', + \ ' Reachable from:', + \ ' system:''$set_pattr''(A,B,C,D)', + \ ' system:''$set_pattr''(vimscript:A,B,C)', + \ ' vimscript: (multifile A)', + \ 'ERROR: /path/to/test.pl:13:', + \ ' No permission to call sandboxed `''$set_predicate_attribute''(_G1808:_G1809,_G1805,_G1806)''', + \ ' Reachable from:', + \ ' system:''$set_pattr''(A,B,C,D)', + \ ' system:''$set_pattr''(vimscript:A,B,C)', + \ ' vimscript: (multifile A)', + \ ]) + +Execute (The swipl handler should join three or more lines with '. ' on latest swipl): + call ale#test#SetFilename('test.pl') + AssertEqual + \ [ + \ { + \ 'lnum': 10, + \ 'col': 0, + \ 'text': 'Clauses of fib/2 are not together in the source-file. Earlier definition at /path/to/test.pl:7. Current predicate: f/0. Use :- discontiguous fib/2. to suppress this message', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#prolog#swipl#Handle(bufnr(''), [ + \ 'Warning: /path/to/test.pl:10:', + \ 'Warning: Clauses of fib/2 are not together in the source-file', + \ 'Warning: Earlier definition at /path/to/test.pl:7', + \ 'Warning: Current predicate: f/0', + \ 'Warning: Use :- discontiguous fib/2. to suppress this message', + \ ]) + +Execute (The swipl handler should ignore warnings / errors 'No permission to call sandboxed with latest swpl...'): + call ale#test#SetFilename('test.pl') + AssertEqual + \ [], + \ ale_linters#prolog#swipl#Handle(bufnr(''), [ + \ 'ERROR: /path/to/test.pl:11:', + \ 'ERROR: No permission to call sandboxed `''$set_predicate_attribute''(_G3416:_G3417,_G3413,_G3414)''', + \ 'ERROR: Reachable from:', + \ 'ERROR: system:''$set_pattr''(A,B,C,D)', + \ 'ERROR: system:''$set_pattr''(vimscript:A,B,C)', + \ 'ERROR: vimscript: (multifile A)', + \ 'ERROR: /path/to/test.pl:12:', + \ 'ERROR: No permission to call sandboxed `''$set_predicate_attribute''(_G205:_G206,_G202,_G203)''', + \ 'ERROR: Reachable from:', + \ 'ERROR: system:''$set_pattr''(A,B,C,D)', + \ 'ERROR: system:''$set_pattr''(vimscript:A,B,C)', + \ 'ERROR: vimscript: (multifile A)', + \ 'ERROR: /path/to/test.pl:13:', + \ 'ERROR: No permission to call sandboxed `''$set_predicate_attribute''(_G1808:_G1809,_G1805,_G1806)''', + \ 'ERROR: Reachable from:', + \ 'ERROR: system:''$set_pattr''(A,B,C,D)', + \ 'ERROR: system:''$set_pattr''(vimscript:A,B,C)', + \ 'ERROR: vimscript: (multifile A)', + \ ]) + +Execute (The swipl handler should handle a warning / error with no line number): + call ale#test#SetFilename('test.pl') + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 0, + \ 'text': 'Exported procedure module_name:pred/0 is not defined', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#prolog#swipl#Handle(bufnr(''), [ + \ 'ERROR: Exported procedure module_name:pred/0 is not defined', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_syntaxerl_handler.vader b/vim-config/plugins/ale/test/handler/test_syntaxerl_handler.vader new file mode 100644 index 00000000..95f2bfef --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_syntaxerl_handler.vader @@ -0,0 +1,24 @@ +Before: + runtime ale_linters/erlang/syntaxerl.vim + +After: + call ale#linter#Reset() + +Execute (Handle SyntaxErl output): + AssertEqual + \ [ + \ { + \ 'lnum': 42, + \ 'text': "syntax error before: ','", + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 42, + \ 'text': 'function foo/0 is unused', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#erlang#syntaxerl#Handle(bufnr(''), [ + \ "/tmp/v2wDixk/1/module.erl:42: syntax error before: ','", + \ '/tmp/v2wDixk/2/module.erl:42: warning: function foo/0 is unused', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_systemd_analyze_handler.vader b/vim-config/plugins/ale/test/handler/test_systemd_analyze_handler.vader new file mode 100644 index 00000000..c7d668e0 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_systemd_analyze_handler.vader @@ -0,0 +1,19 @@ +Before: + runtime ale_linters/systemd/systemd_analyze.vim + +After: + call ale#linter#Reset() + +Execute(The systemd-analyze handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 9, + \ 'col': 1, + \ 'type': 'W', + \ 'text': 'Unknown key name ''Wat'' in section ''Service'', ignoring.', + \ }, + \ ], + \ ale_linters#systemd#systemd_analyze#Handle(bufnr(''), [ + \ '/home/user/.config/systemd/user/foo.service:9: Unknown key name ''Wat'' in section ''Service'', ignoring.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_terraform_handler.vader b/vim-config/plugins/ale/test/handler/test_terraform_handler.vader new file mode 100644 index 00000000..d054cb3b --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_terraform_handler.vader @@ -0,0 +1,99 @@ +Before: + " Load the file which defines the linter. + runtime ale_linters/terraform/terraform.vim + call ale#test#SetDirectory('/testplugin/test/test-files/terraform') + call ale#test#SetFilename('providers.tf') + +After: + " Unload all linters again. + call ale#linter#Reset() + call ale#test#RestoreDirectory() + +Execute(The output should be correct): + AssertEqual + \ [ + \ { + \ 'lnum': 17, + \ 'col': 13, + \ 'filename': ale#path#Simplify(g:dir . '/providers.tf'), + \ 'type': 'W', + \ 'text': 'Terraform 0.13 and earlier allowed provider version', + \ }, + \ { + \ 'lnum': 0, + \ 'col': 0, + \ 'filename': ale#path#Simplify(g:dir . '/providers.tf'), + \ 'type': 'E', + \ 'text': 'Plugin reinitialization required. Please run "terraform"', + \ } + \ ], + \ ale_linters#terraform#terraform#Handle(bufnr(''), [ + \ '{', + \ '"valid": false,', + \ '"error_count": 1,', + \ '"warning_count": 1,', + \ '"diagnostics": [', + \ ' {', + \ ' "severity": "warning",', + \ ' "summary": "Version constraints inside provider configuration blocks are deprecated",', + \ ' "detail": "Terraform 0.13 and earlier allowed provider version",', + \ ' "range": {', + \ ' "filename": "providers.tf",', + \ ' "start": {', + \ ' "line": 17,', + \ ' "column": 13,', + \ ' "byte": 669', + \ ' },', + \ ' "end": {', + \ ' "line": 17,', + \ ' "column": 24,', + \ ' "byte": 680', + \ ' }', + \ ' }', + \ ' },', + \ ' {', + \ ' "severity": "error",', + \ ' "summary": "Could not load plugin",', + \ ' "detail": "Plugin reinitialization required. Please run \"terraform\""', + \ ' }', + \ ' ]', + \ '}', + \ ]) + +Execute(Should use summary if detail not available): + AssertEqual + \ [ + \ { + \ 'lnum': 91, + \ 'col': 41, + \ 'filename': ale#path#Simplify(g:dir . '/main.tf'), + \ 'type': 'E', + \ 'text': 'storage_os_disk: required field is not set', + \ } + \ ], + \ ale_linters#terraform#terraform#Handle(bufnr(''), [ + \ '{', + \ ' "valid": false,', + \ ' "error_count": 1,', + \ ' "warning_count": 0,', + \ ' "diagnostics": [', + \ ' {', + \ ' "severity": "error",', + \ ' "summary": "storage_os_disk: required field is not set",', + \ ' "range": {', + \ ' "filename": "main.tf",', + \ ' "start": {', + \ ' "line": 91,', + \ ' "column": 41,', + \ ' "byte": 2381', + \ ' },', + \ ' "end": {', + \ ' "line": 91,', + \ ' "column": 41,', + \ ' "byte": 2381', + \ ' }', + \ ' }', + \ ' }', + \ ' ]', + \ '}' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_textlint_handler.vader b/vim-config/plugins/ale/test/handler/test_textlint_handler.vader new file mode 100644 index 00000000..c00d54de --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_textlint_handler.vader @@ -0,0 +1,41 @@ +Before: + runtime! ale_linters/markdown/textlint.vim + +After: + call ale#linter#Reset() + +Execute(textlint handler should handle errors output): + AssertEqual + \ [ + \ { + \ 'lnum': 16, + \ 'col': 50, + \ 'text': 'Found possibly misspelled word "NeoVim".', + \ 'type': 'W', + \ 'code': 'preset-japanese/no-doubled-joshi', + \ }, + \ ], + \ ale#handlers#textlint#HandleTextlintOutput(bufnr(''), [ + \ '[', + \ ' {', + \ ' "filePath": "test.md",', + \ ' "messages": [', + \ ' {', + \ ' "type": "lint",', + \ ' "ruleId": "preset-japanese/no-doubled-joshi",', + \ ' "index": 1332,', + \ ' "line": 16,', + \ ' "column": 50,', + \ ' "severity": 2,', + \ ' "message": "Found possibly misspelled word \"NeoVim\"."', + \ ' }', + \ ' ]', + \ ' }', + \ ']', + \ ]) + +Execute(textlint handler should no error output): + AssertEqual + \ [], + \ ale#handlers#textlint#HandleTextlintOutput(bufnr(''), [ + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_tflint_handler.vader b/vim-config/plugins/ale/test/handler/test_tflint_handler.vader new file mode 100644 index 00000000..6b8173af --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_tflint_handler.vader @@ -0,0 +1,99 @@ +Before: + runtime! ale_linters/terraform/tflint.vim + +After: + call ale#linter#Reset() + +Execute(The tflint handler should parse items correctly for pre 0.11): + AssertEqual + \ [ + \ { + \ 'lnum': 12, + \ 'text': 'be warned, traveller', + \ 'code': 'aws_db_instance_readable_password', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 9, + \ 'text': 'error message', + \ 'code': 'aws_elasticache_cluster_invalid_type', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 5, + \ 'text': 'just so ya know', + \ 'code': 'aws_instance_not_specified_iam_profile', + \ 'type': 'I', + \ }, + \ ], + \ ale_linters#terraform#tflint#Handle(123, [ + \ '[ { "detector": "aws_db_instance_readable_password", "type": "WARNING", "message": "be warned, traveller", "line": 12, "file": "github.com/wata727/example-module/aws_db_instance.tf", "link": "https://github.com/wata727/tflint/blob/master/docs/aws_db_instance_readable_password.md" }, { "detector": "aws_elasticache_cluster_invalid_type", "type": "ERROR", "message": "error message", "line": 9, "file": "github.com/wata727/example-module/aws_elasticache_cluster.tf", "link": "https://github.com/wata727/tflint/blob/master/docs/aws_elasticache_cluster_invalid_type.md" }, { "detector": "aws_instance_not_specified_iam_profile", "type": "NOTICE", "message": "just so ya know", "line": 5, "file": "github.com/wata727/example-module/aws_instance.tf", "link": "https://github.com/wata727/tflint/blob/master/docs/aws_instance_not_specified_iam_profile.md" } ]' + \ ]) + +Execute(The tflint handler should parse items correctly): + AssertEqual + \ [ + \ { + \ 'filename': 'github.com/wata727/example-module/aws_instance.tf', + \ 'lnum': 1, + \ 'col': 30, + \ 'end_lnum': 2, + \ 'end_col': 1, + \ 'text': 'A block definition must have block content delimited by "{" and "}", starting on the same line as the block header.', + \ 'code': 'Invalid block definition', + \ 'type': 'E', + \ }, + \ { + \ 'filename': 'github.com/wata727/example-module/aws_instance.tf', + \ 'lnum': 2, + \ 'col': 3, + \ 'end_lnum': 2, + \ 'end_col': 6, + \ 'text': 'An argument named "ami" is not expected here.', + \ 'code': 'Unsupported argument', + \ 'type': 'E', + \ }, + \ { + \ 'filename': 'github.com/wata727/example-module/aws_instance.tf', + \ 'lnum': 3, + \ 'col': 3, + \ 'end_lnum': 1, + \ 'end_col': 6, + \ 'text': 'An argument named "instance_type" is not expected here.', + \ 'code': 'Unsupported argument', + \ 'type': 'E', + \ }, + \ { + \ 'filename': 'github.com/wata727/example-module/aws_db_instance.tf', + \ 'lnum': 12, + \ 'col': 11, + \ 'end_lnum': 12, + \ 'end_col': 21, + \ 'text': 'be warned, traveller', + \ 'code': 'aws_db_instance_readable_password', + \ 'type': 'W', + \ }, + \ { + \ 'filename': 'github.com/wata727/example-module/aws_elasticache_cluster.tf', + \ 'lnum': 9, + \ 'col': 29, + \ 'end_lnum': 9, + \ 'end_col': 29, + \ 'text': 'error message', + \ 'code': 'aws_elasticache_cluster_invalid_type', + \ 'type': 'E', + \ }, + \ { + \ 'filename': 'github.com/wata727/example-module/aws_instance.tf', + \ 'lnum': 5, + \ 'col': 15, + \ 'end_lnum': 5, + \ 'end_col': 25, + \ 'text': 'just so ya know', + \ 'code': 'aws_instance_not_specified_iam_profile', + \ 'type': 'I', + \ }, + \ ], + \ ale_linters#terraform#tflint#Handle(123, [ + \ '{"issues":[{"rule":{"name":"aws_db_instance_readable_password","severity":"WARNING","link":"https://github.com/wata727/tflint/blob/master/docs/aws_db_instance_readable_password.md"},"message":"be warned, traveller","range":{"filename":"github.com/wata727/example-module/aws_db_instance.tf","start":{"line":12,"column":11},"end":{"line":12,"column":21},"callers":[]}},{"rule":{"name":"aws_elasticache_cluster_invalid_type","severity":"ERROR","link":"https://github.com/wata727/tflint/blob/master/docs/aws_elasticache_cluster_invalid_type.md"},"message":"error message","range":{"filename":"github.com/wata727/example-module/aws_elasticache_cluster.tf","start":{"line":9,"column":29},"end":{"line":9,"column":29},"callers":[]}},{"rule":{"name":"aws_instance_not_specified_iam_profile","severity":"NOTICE","link":"https://github.com/wata727/tflint/blob/master/docs/aws_instance_not_specified_iam_profile.md"},"message":"just so ya know","range":{"filename":"github.com/wata727/example-module/aws_instance.tf","start":{"line":5,"column":15},"end":{"line":5,"column":25},"callers":[]}}],"errors":[{"message":"github.com/wata727/example-module/aws_instance.tf:1,30-2,1: Invalid block definition; A block definition must have block content delimited by \"{\" and \"}\", starting on the same line as the block header."},{"message":"github.com/wata727/example-module/aws_instance.tf:2,3-6: Unsupported argument; An argument named \"ami\" is not expected here."},{"message":"github.com/wata727/example-module/aws_instance.tf:3,3-16: Unsupported argument; An argument named \"instance_type\" is not expected here."}]}' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_thrift_handler.vader b/vim-config/plugins/ale/test/handler/test_thrift_handler.vader new file mode 100644 index 00000000..9bdb9378 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_thrift_handler.vader @@ -0,0 +1,63 @@ +Before: + runtime ale_linters/thrift/thrift.vim + +After: + call ale#linter#Reset() + +Execute(The thrift handler should handle basic warnings and errors): + AssertEqual + \ [ + \ { + \ 'lnum': 17, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'The "byte" type is a compatibility alias for "i8". Use i8" to emphasize the signedness of this type.', + \ }, + \ { + \ 'lnum': 20, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'Could not find include file include.thrift', + \ }, + \ { + \ 'lnum': 83, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'Enum FOO is already defined!', + \ }, + \ ], + \ ale_linters#thrift#thrift#Handle(1, [ + \ '[WARNING:/path/filename.thrift:17] The "byte" type is a compatibility alias for "i8". Use i8" to emphasize the signedness of this type.', + \ '[WARNING:/path/filename.thrift:20] Could not find include file include.thrift', + \ '[FAILURE:/path/filename.thrift:83] Enum FOO is already defined!', + \ ]) + +Execute(The thrift handler should handle multiline errors): + AssertEqual + \ [ + \ { + \ 'lnum': 75, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'This integer is too big: "11111111114213213453243"', + \ }, + \ { + \ 'lnum': 76, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'Implicit field keys are deprecated and not allowed with -strict', + \ }, + \ { + \ 'lnum': 77, + \ 'col': 0, + \ 'type': 'E', + \ 'text': "Unknown error (last token was ';')", + \ }, + \ ], + \ ale_linters#thrift#thrift#Handle(1, [ + \ "[ERROR:/path/filename.thrift:75] (last token was '11111111114213213453243')", + \ 'This integer is too big: "11111111114213213453243"', + \ "[ERROR:/path/filename.thrift:76] (last token was ';')", + \ 'Implicit field keys are deprecated and not allowed with -strict', + \ "[ERROR:/path/filename.thrift:77] (last token was ';')", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_thriftcheck_handler.vader b/vim-config/plugins/ale/test/handler/test_thriftcheck_handler.vader new file mode 100644 index 00000000..e80e5050 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_thriftcheck_handler.vader @@ -0,0 +1,28 @@ +Before: + runtime ale_linters/thrift/thriftcheck.vim + +After: + call ale#linter#Reset() + +Execute(The thriftcheck handler should handle basic warnings and errors): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'E', + \ 'text': '"py" namespace must match "^idl\\."', + \ 'code': 'namespace.pattern', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 5, + \ 'type': 'W', + \ 'text': '64-bit integer constant -2147483649 may not work in all languages', + \ 'code': 'int.64bit', + \ }, + \ ], + \ ale_linters#thrift#thriftcheck#Handle(1, [ + \ 'file.thrift:1:1: error: "py" namespace must match "^idl\\." (namespace.pattern)', + \ 'file.thrift:3:5: warning: 64-bit integer constant -2147483649 may not work in all languages (int.64bit)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_tlint_handler.vader b/vim-config/plugins/ale/test/handler/test_tlint_handler.vader new file mode 100644 index 00000000..e146346c --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_tlint_handler.vader @@ -0,0 +1,34 @@ +Before: + runtime ale_linters/php/tlint.vim + +After: + call ale#linter#Reset() + +Execute(The tlint handler should calculate line numbers): + AssertEqual + \ [ + \ { + \ 'lnum': '5', + \ 'col': 0, + \ 'sub_type': + \ 'style', + \ 'type': 'W', + \ 'text': ['! There should be no unused imports.', 'There should be no unused imports.', '', '', '', '', '', '', '', ''] + \ }, + \ { + \ 'lnum': '15', + \ 'col': 0, + \ 'sub_type': + \ 'style', + \ 'type': 'W', + \ 'text': ['! There should be no method visibility in test methods.', 'There should be no method visibility in test methods.', '', '', '', '', '', '', '', ''] + \ }, + \ ], + \ ale_linters#php#tlint#Handle(347, [ + \ "Lints for /Users/jose/Code/Tighten/tester/tests/Unit/ExampleTest.php", + \ "============", + \ "! There should be no unused imports.", + \ "5 : `use Illuminate\Foundation\Testing\RefreshDatabase;`", + \ "! There should be no method visibility in test methods.", + \ "15 : ` public function testBasicTest()`", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_tslint_handler.vader b/vim-config/plugins/ale/test/handler/test_tslint_handler.vader new file mode 100644 index 00000000..32036edf --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_tslint_handler.vader @@ -0,0 +1,315 @@ +Before: + Save g:ale_typescript_tslint_ignore_empty_files + + unlet! g:ale_typescript_tslint_ignore_empty_files + unlet! b:ale_typescript_tslint_ignore_empty_files + + runtime ale_linters/typescript/tslint.vim + + call ale#test#SetDirectory('/testplugin/test/handler') + +After: + Restore + + unlet! b:ale_typescript_tslint_ignore_empty_files + unlet! b:relative_to_root + unlet! b:tempname_suffix + unlet! b:relative_tempname + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The tslint handler should parse lines correctly): + call ale#test#SetFilename('app/test.ts') + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 15, + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'), + \ 'end_lnum': 1, + \ 'type': 'E', + \ 'end_col': 15, + \ 'text': 'Missing semicolon', + \ 'code': 'semicolon', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 8, + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'), + \ 'end_lnum': 3, + \ 'type': 'W', + \ 'end_col': 12, + \ 'text': 'Something else', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 8, + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/something-else.ts'), + \ 'end_lnum': 3, + \ 'type': 'W', + \ 'end_col': 12, + \ 'text': 'Something else', + \ 'code': 'something', + \ }, + \ { + \ 'lnum': 31, + \ 'col': 9, + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'), + \ 'end_lnum': 31, + \ 'type': 'E', + \ 'end_col': 20, + \ 'text': 'Calls to console.log are not allowed.', + \ 'code': 'no-console', + \ }, + \ ] , + \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([ + \ { + \ 'endPosition': { + \ 'character': 14, + \ 'line': 0, + \ 'position': 1000 + \ }, + \ 'failure': 'Missing semicolon', + \ 'fix': { + \ 'innerLength': 0, + \ 'innerStart': 14, + \ 'innerText': ';' + \ }, + \ 'name': 'test.ts', + \ 'ruleName': 'semicolon', + \ 'ruleSeverity': 'ERROR', + \ 'startPosition': { + \ 'character': 14, + \ 'line': 0, + \ 'position': 1000 + \ } + \ }, + \ { + \ 'endPosition': { + \ 'character': 11, + \ 'line': 2, + \ 'position': 1000 + \ }, + \ 'failure': 'Something else', + \ 'fix': { + \ 'innerLength': 0, + \ 'innerStart': 14, + \ 'innerText': ';' + \ }, + \ 'name': 'test.ts', + \ 'ruleSeverity': 'WARNING', + \ 'startPosition': { + \ 'character': 7, + \ 'line': 1, + \ 'position': 1000 + \ } + \ }, + \ { + \ 'endPosition': { + \ 'character': 11, + \ 'line': 2, + \ 'position': 22 + \ }, + \ 'failure': 'Something else', + \ 'fix': { + \ 'innerLength': 0, + \ 'innerStart': 14, + \ 'innerText': ';' + \ }, + \ 'name': 'something-else.ts', + \ 'ruleName': 'something', + \ 'ruleSeverity': 'WARNING', + \ 'startPosition': { + \ 'character': 7, + \ 'line': 1, + \ 'position': 14 + \ } + \ }, + \ { + \ "endPosition": { + \ "character": 19, + \ "line": 30, + \ "position": 14590 + \ }, + \ "failure": "Calls to console.log are not allowed.", + \ 'name': 'test.ts', + \ "ruleName": "no-console", + \ "startPosition": { + \ "character": 8, + \ "line": 30, + \ "position": 14579 + \ } + \ }, + \])]) + +Execute(The tslint handler should handle empty output): + AssertEqual + \ [], + \ ale_linters#typescript#tslint#Handle(bufnr(''), []) + +Execute(The tslint handler report errors for empty files by default): + call ale#test#SetFilename('app/test.ts') + + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'), + \ 'end_lnum': 2, + \ 'type': 'E', + \ 'end_col': 1, + \ 'text': 'Consecutive blank lines are forbidden', + \ 'code': 'no-consecutive-blank-lines', + \ }, + \ ], + \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([{ + \ 'endPosition': { + \ 'character': 0, + \ 'line': 1, + \ 'position': 1 + \ }, + \ 'failure': 'Consecutive blank lines are forbidden', + \ 'fix': [{ + \ 'innerStart': 0, + \ 'innerLength': 1, + \ 'innerText': '' + \ }], + \ 'name': 'test.ts', + \ 'ruleName': 'no-consecutive-blank-lines', + \ 'ruleSeverity': 'ERROR', + \ 'startPosition': { + \ 'character': 0, + \ 'line': 1, + \ 'position': 1 + \ } + \ }])]) + +Execute(The tslint handler should not report errors for empty files when the ignore option is on): + let b:ale_typescript_tslint_ignore_empty_files = 1 + call ale#test#SetFilename('app/test.ts') + + AssertEqual + \ [ + \ ], + \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([{ + \ 'endPosition': { + \ 'character': 0, + \ 'line': 1, + \ 'position': 1 + \ }, + \ 'failure': 'Consecutive blank lines are forbidden', + \ 'fix': [{ + \ 'innerStart': 0, + \ 'innerLength': 1, + \ 'innerText': '' + \ }], + \ 'name': 'test.ts', + \ 'ruleName': 'no-consecutive-blank-lines', + \ 'ruleSeverity': 'ERROR', + \ 'startPosition': { + \ 'character': 0, + \ 'line': 1, + \ 'position': 1 + \ } + \ }])]) + +Given typescript(A file with extra blank lines): + const x = 3 + + + const y = 4 + +Execute(The tslint handler should report errors when the ignore option is on, but the file is not empty): + let b:ale_typescript_tslint_ignore_empty_files = 1 + call ale#test#SetFilename('app/test.ts') + + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'), + \ 'end_lnum': 2, + \ 'type': 'E', + \ 'end_col': 1, + \ 'text': 'Consecutive blank lines are forbidden', + \ 'code': 'no-consecutive-blank-lines', + \ }, + \ ], + \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([{ + \ 'endPosition': { + \ 'character': 0, + \ 'line': 1, + \ 'position': 1 + \ }, + \ 'failure': 'Consecutive blank lines are forbidden', + \ 'fix': [{ + \ 'innerStart': 0, + \ 'innerLength': 1, + \ 'innerText': '' + \ }], + \ 'name': 'test.ts', + \ 'ruleName': 'no-consecutive-blank-lines', + \ 'ruleSeverity': 'ERROR', + \ 'startPosition': { + \ 'character': 0, + \ 'line': 1, + \ 'position': 1 + \ } + \ }])]) + +Execute(The tslint handler should not report no-implicit-dependencies errors): + call ale#test#SetFilename('app/test.ts') + + AssertEqual + \ [ + \ ], + \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([{ + \ 'endPosition': { + \ 'character': 0, + \ 'line': 1, + \ 'position': 1 + \ }, + \ 'failure': 'this is ignored', + \ 'name': 'test.ts', + \ 'ruleName': 'no-implicit-dependencies', + \ 'ruleSeverity': 'ERROR', + \ 'startPosition': { + \ 'character': 0, + \ 'line': 1, + \ 'position': 1 + \ }, + \ }])]) + +Execute(The tslint handler should set filename keys for temporary files): + " The temporay filename below is hacked into being a relative path so we can + " test that we resolve the temporary filename first. + let b:relative_to_root = substitute(expand('%:p'), '\v[^/\\]*([/\\])[^/\\]*', '../', 'g') + let b:tempname_suffix = substitute(tempname(), '^\v([A-Z]:)?[/\\]', '', '') + let b:relative_tempname = substitute(b:relative_to_root . b:tempname_suffix, '\\', '/', 'g') + + AssertEqual + \ [ + \ {'lnum': 47, 'col': 1, 'code': 'curly', 'end_lnum': 47, 'type': 'E', 'end_col': 26, 'text': 'if statements must be braced'}, + \ ], + \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([ + \ { + \ 'endPosition': { + \ 'character':25, + \ 'line':46, + \ 'position':1383, + \ }, + \ 'failure': 'if statements must be braced', + \ 'name': b:relative_tempname, + \ 'ruleName': 'curly', + \ 'ruleSeverity':'ERROR', + \ 'startPosition': { + \ 'character':0, + \ 'line':46, + \ 'position':1358, + \ } + \ }, + \ ])]) diff --git a/vim-config/plugins/ale/test/handler/test_typecheck_handler.vader b/vim-config/plugins/ale/test/handler/test_typecheck_handler.vader new file mode 100644 index 00000000..fda55d68 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_typecheck_handler.vader @@ -0,0 +1,24 @@ +Before: + runtime ale_linters/typescript/typecheck.vim + +After: + call ale#linter#Reset() + +Execute(The typecheck handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 16, + \ 'col': 7, + \ 'text': "Type 'A' is not assignable to type 'B'", + \ }, + \ { + \ 'lnum': 7, + \ 'col': 41, + \ 'text': "Property 'a' does not exist on type 'A'", + \ }, + \ ], + \ ale_linters#typescript#typecheck#Handle(347, [ + \ "somets.ts[16, 7]: Type 'A' is not assignable to type 'B'", + \ "somets.ts[7, 41]: Property 'a' does not exist on type 'A'", + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_v_handler.vader b/vim-config/plugins/ale/test/handler/test_v_handler.vader new file mode 100644 index 00000000..4d6e3d9b --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_v_handler.vader @@ -0,0 +1,54 @@ +Before: + runtime ale_linters/v/v.vim + +After: + call ale#linter#Reset() + +Execute (The v handler should correctly parse error messages): + AssertEqual + \ [{ + \ 'lnum': 4, + \ 'col': 3, + \ 'filename': ale#path#GetAbsPath(expand('%:p:h'), 'const ants.v'), + \ 'type': 'W', + \ 'end_col': 14, + \ 'text': 'const names cannot contain uppercase letters, use snake_case instead' + \ }, + \ { + \ 'lnum': 4, + \ 'col': 8, + \ 'filename': ale#path#GetAbsPath(expand('%:p:h'), 'main.v'), + \ 'type': 'W', + \ 'end_col': 10, + \ 'text': 'module "os" is imported but never used' + \ }, + \ { + \ 'lnum': 20, + \ 'col': 10, + \ 'filename': ale#path#GetAbsPath(expand('%:p:h'), 'main.v'), + \ 'type': 'E', + \ 'end_col': 18, + \ 'text': 'undefined ident: `win_widt`' + \ }], + \ ale_linters#v#v#Handler('', [ + \ './const ants.v:4:3: warning: const names cannot contain uppercase letters, use snake_case instead', + \ ' 2 |', + \ ' 3 | const (', + \ ' 4 | BUTTON_TEXT = "OK"', + \ ' | ~~~~~~~~~~~', + \ ' 5 | )', + \ './main.v:4:8: warning: module "os" is imported but never used', + \ ' 2 |', + \ ' 3 | import ui', + \ ' 4 | import os', + \ ' | ~~', + \ ' 5 |', + \ ' 6 | const (', + \ './main.v:20:10: error: undefined ident: `win_widt`', + \ ' 18 | mut app := &App{}', + \ ' 19 | app.window = ui.window({', + \ ' 20 | width: win_widt', + \ ' | ~~~~~~~~', + \ ' 21 | height: win_height', + \ ' 22 | title: "Counter"', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_vala_lint_handler.vader b/vim-config/plugins/ale/test/handler/test_vala_lint_handler.vader new file mode 100644 index 00000000..b8a4fbfa --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_vala_lint_handler.vader @@ -0,0 +1,54 @@ +Before: + runtime ale_linters/vala/vala_lint.vim + +After: + call ale#linter#Reset() + +Execute(The Vala-Lint handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 18, + \ 'col': 18, + \ 'text': 'Expected space before paren', + \ 'code': 'space-before-paren', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 64, + \ 'col': 37, + \ 'text': 'Expected space before paren', + \ 'code': 'space-before-paren', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 73, + \ 'col': 37, + \ 'text': 'Expected space before paren', + \ 'code': 'space-before-paren', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#vala#vala_lint#Handle(bufnr(''), [ + \ 'Application.vala', + \ ' 18.18 error Expected space before paren space-before-paren', + \ ' 64.37 warn Expected space before paren space-before-paren', + \ ' 73.37 error Expected space before paren space-before-paren', + \ ]) + +Execute(The Vala-Lint handler should ignore unknown error types): + AssertEqual + \ [ + \ { + \ 'lnum': 73, + \ 'col': 37, + \ 'text': 'Expected space before paren', + \ 'code': 'space-before-paren', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#vala#vala_lint#Handle(bufnr(''), [ + \ 'Application.vala', + \ ' 18.18 test Expected space before paren space-before-paren', + \ ' 73.37 error Expected space before paren space-before-paren', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_vale_handler.vader b/vim-config/plugins/ale/test/handler/test_vale_handler.vader new file mode 100644 index 00000000..37badb47 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_vale_handler.vader @@ -0,0 +1,88 @@ +Execute(The vale handler should handle broken JSON): + AssertEqual + \ [], + \ ale#handlers#vale#Handle(bufnr(''), ["{asdf"]) + +Execute(The vale handler should handle am empty string response): + AssertEqual + \ [], + \ ale#handlers#vale#Handle(bufnr(''), []) + +Execute(The vale handler should handle an empty result): + AssertEqual + \ [], + \ ale#handlers#vale#Handle(bufnr(''), ["{}"]) + +Execute(The vale handler should handle a normal example): + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 195, + \ 'end_col': 201, + \ 'type': 'W', + \ 'text': "Consider removing 'usually'", + \ 'code': 'vale.Hedging', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 1, + \ 'end_col': 27, + \ 'type': 'E', + \ 'text': "'Documentation' is repeated!", + \ 'code': 'vale.Repetition', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 1, + \ 'end_col': 27, + \ 'type': 'I', + \ 'text': "'Documentation' is repeated!", + \ 'code': 'vale.Repetition', + \ }, + \ ], + \ ale#handlers#vale#Handle(bufnr(''), [ + \ '{', + \ ' "/home/languitar/src/autosuspend/README.md": [', + \ ' {', + \ ' "Check": "vale.Hedging",', + \ ' "Description": "",', + \ ' "Line": 5,', + \ ' "Link": "",', + \ " \"Message\": \"Consider removing 'usually'\",", + \ ' "Severity": "warning",', + \ ' "Span": [', + \ ' 195,', + \ ' 201', + \ ' ],', + \ ' "Hide": false', + \ ' },', + \ ' {', + \ ' "Check": "vale.Repetition",', + \ ' "Description": "",', + \ ' "Line": 7,', + \ ' "Link": "",', + \ " \"Message\": \"'Documentation' is repeated!\",", + \ ' "Severity": "error",', + \ ' "Span": [', + \ ' 1,', + \ ' 27', + \ ' ],', + \ ' "Hide": false', + \ ' },', + \ ' {', + \ ' "Check": "vale.Repetition",', + \ ' "Description": "",', + \ ' "Line": 7,', + \ ' "Link": "",', + \ " \"Message\": \"'Documentation' is repeated!\",", + \ ' "Severity": "suggestion",', + \ ' "Span": [', + \ ' 1,', + \ ' 27', + \ ' ],', + \ ' "Hide": false', + \ ' }', + \ ' ]', + \ '}', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_vcom_handler.vader b/vim-config/plugins/ale/test/handler/test_vcom_handler.vader new file mode 100644 index 00000000..943b525a --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_vcom_handler.vader @@ -0,0 +1,36 @@ +Before: + runtime ale_linters/vhdl/vcom.vim + +After: + call ale#linter#Reset() + +Execute(The vcom handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 218, + \ 'type': 'W', + \ 'text': '(vcom-1236) Shared variables must be of a protected type.' + \ }, + \ { + \ 'lnum': 73, + \ 'type': 'E', + \ 'text': '(vcom-1136) Unknown identifier "aresetn".' + \ }, + \ { + \ 'lnum': 73, + \ 'type': 'E', + \ 'text': 'Bad resolution function (STD_LOGIC) for type (error).' + \ }, + \ { + \ 'lnum': 73, + \ 'type': 'E', + \ 'text': 'near ":": (vcom-1576) expecting ";" or ")".' + \ }, + \ ], + \ ale_linters#vhdl#vcom#Handle(bufnr(''), [ + \ '** 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 ")".', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_verilator_handler.vader b/vim-config/plugins/ale/test/handler/test_verilator_handler.vader new file mode 100644 index 00000000..59ec1361 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_verilator_handler.vader @@ -0,0 +1,52 @@ +Before: + runtime ale_linters/verilog/verilator.vim + +After: + call ale#linter#Reset() + + +Execute (The verilator handler should parse legacy messages with only line numbers): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected IDENTIFIER', + \ 'filename': 'foo.v' + \ }, + \ { + \ 'lnum': 10, + \ 'type': 'W', + \ 'text': 'Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).', + \ 'filename': 'bar.v' + \ }, + \ ], + \ ale_linters#verilog#verilator#Handle(bufnr(''), [ + \ '%Error: foo.v:3: syntax error, unexpected IDENTIFIER', + \ '%Warning-BLKSEQ: bar.v:10: Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).', + \ ]) + + +Execute (The verilator handler should parse new format messages with line and column numbers): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'col' : 1, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected endmodule, expecting ;', + \ 'filename': 'bar.v' + \ }, + \ { + \ 'lnum': 4, + \ 'col' : 6, + \ 'type': 'W', + \ 'text': 'Signal is not used: r', + \ 'filename': 'foo.v' + \ }, + \ ], + \ ale_linters#verilog#verilator#Handle(bufnr(''), [ + \ '%Error: bar.v:3:1: syntax error, unexpected endmodule, expecting ;', + \ '%Warning-UNUSED: foo.v:4:6: Signal is not used: r', + \ ]) + diff --git a/vim-config/plugins/ale/test/handler/test_vint_handler.vader b/vim-config/plugins/ale/test/handler/test_vint_handler.vader new file mode 100644 index 00000000..c542b4ea --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_vint_handler.vader @@ -0,0 +1,65 @@ +Before: + runtime ale_linters/vim/vint.vim + +After: + call ale#linter#Reset() + +Execute(The vint handler should parse error messages correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'filename': 'gcc.vim', + \ 'text': 'Use scriptencoding when multibyte char exists (see :help :script encoding)', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 17, + \ 'filename': 'gcc.vim', + \ 'end_col': 18, + \ 'text': 'Use robust operators ''==#'' or ''==?'' instead of ''=='' (see Google VimScript Style Guide (Matching))', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 8, + \ 'filename': 'gcc.vim', + \ 'end_col': 15, + \ 'text': 'Make the scope explicit like ''l:filename'' (see Anti-pattern of vimrc (Scope of identifier))', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 7, + \ 'col': 8, + \ 'filename': 'gcc.vim', + \ 'end_col': 15, + \ 'text': 'Undefined variable: filename (see :help E738)', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 8, + \ 'col': 11, + \ 'filename': 'gcc.vim', + \ 'end_col': 16, + \ 'text': 'E128: Function name must start with a capital or contain a colon: foobar (see ynkdir/vim-vimlparser)', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 9, + \ 'col': 12, + \ 'filename': 'gcc.vim', + \ 'end_col': 13, + \ 'text': 'Use robust operators ''=~#'' or ''=~?'' instead of ''=~'' (see Google VimScript Style Guide (Matching))', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#vim#vint#Handle(bufnr(''), [ + \ 'gcc.vim:1:1: warning: Use scriptencoding when multibyte char exists (see :help :script encoding)', + \ 'gcc.vim:3:17: warning: Use robust operators `==#` or `==?` instead of `==` (see Google VimScript Style Guide (Matching))', + \ 'gcc.vim:3:8: style_problem: Make the scope explicit like `l:filename` (see Anti-pattern of vimrc (Scope of identifier))', + \ 'gcc.vim:7:8: warning: Undefined variable: filename (see :help E738)', + \ 'gcc.vim:8:11: error: E128: Function name must start with a capital or contain a colon: foobar (see ynkdir/vim-vimlparser)', + \ 'gcc.vim:9:12: warning: Use robust operators `=~#` or `=~?` instead of `=~` (see Google VimScript Style Guide (Matching))', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_vlog_handler.vader b/vim-config/plugins/ale/test/handler/test_vlog_handler.vader new file mode 100644 index 00000000..7262f63d --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_vlog_handler.vader @@ -0,0 +1,47 @@ +Before: + runtime ale_linters/verilog/vlog.vim + +After: + call ale#linter#Reset() + +Execute(The vlog handler should parse old-style lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 7, + \ 'type': 'W', + \ 'text': '(vlog-2623) Undefined variable: C.', + \ 'filename': 'add.v' + \ }, + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.', + \ 'filename': 'file.v' + \ }, + \ ], + \ ale_linters#verilog#vlog#Handle(bufnr(''), [ + \ '** Warning: add.v(7): (vlog-2623) Undefined variable: C.', + \ '** Error: file.v(1): (vlog-13294) Identifier must be declared with a port mode: C.', + \ ]) + +Execute(The vlog handler should parse new-style lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 7, + \ 'type': 'W', + \ 'text': '(vlog-2623) Undefined variable: C.', + \ 'filename': 'add.v' + \ }, + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.', + \ 'filename': 'file.v' + \ }, + \ ], + \ ale_linters#verilog#vlog#Handle(bufnr(''), [ + \ '** Warning: (vlog-2623) add.v(7): Undefined variable: C.', + \ '** Error: (vlog-13294) file.v(1): Identifier must be declared with a port mode: C.', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_vulture_handler.vader b/vim-config/plugins/ale/test/handler/test_vulture_handler.vader new file mode 100644 index 00000000..b28055db --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_vulture_handler.vader @@ -0,0 +1,92 @@ +Before: + runtime ale_linters/python/vulture.vim + + call ale#test#SetDirectory('/testplugin/test/handler') + +After: + Restore + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + silent file something_else.py + +Execute(Basic vulture check with relative path in result should be handled): + call ale#test#SetFilename('something_else.py') + AssertEqual + \ [ + \ { + \ 'lnum': 34, + \ 'text': 'unused variable ''foo'' (60% confidence)', + \ 'type': 'W', + \ 'filename': ale#path#Simplify(g:dir . '/something_else.py'), + \ }, + \ ], + \ ale_linters#python#vulture#Handle(bufnr(''), [ + \ './something_else.py:34: unused variable ''foo'' (60% confidence)', + \ ]) + +Execute(Basic vulture check with absolute path in result should be handled): + call ale#test#SetFilename('something_else.py') + AssertEqual + \ [ + \ { + \ 'lnum': 34, + \ 'text': 'unused variable ''foo'' (60% confidence)', + \ 'type': 'W', + \ 'filename': ale#path#Simplify(g:dir . '/something_else.py'), + \ }, + \ ], + \ ale_linters#python#vulture#Handle(bufnr(''), [ + \ ale#path#Simplify(g:dir . '/something_else.py') . ':34: unused variable ''foo'' (60% confidence)', + \ ]) + +Execute(Vulture check for two files should be handled): + call ale#test#SetFilename('something_else.py') + AssertEqual + \ [ + \ { + \ 'lnum': 34, + \ 'text': 'unused variable ''foo'' (60% confidence)', + \ 'type': 'W', + \ 'filename': ale#path#Simplify(g:dir . '/something_else.py'), + \ }, + \ { + \ 'lnum': 12, + \ 'text': 'unused variable ''bar'' (60% confidence)', + \ 'type': 'W', + \ 'filename': ale#path#Simplify(g:dir . '/second_one.py'), + \ }, + \ ], + \ ale_linters#python#vulture#Handle(bufnr(''), [ + \ './something_else.py:34: unused variable ''foo'' (60% confidence)', + \ './second_one.py:12: unused variable ''bar'' (60% confidence)', + \ ]) + + +Execute(Vulture exception should be handled): + call ale#test#SetFilename('something_else.py') + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'BaddestException: Everything gone wrong (See :ALEDetail)', + \ 'detail': join([ + \ 'Traceback (most recent call last):', + \ ' File "/usr/lib/python3.6/site-packages/vulture/__init__.py", line 13, in ', + \ ' from .core import stuff', + \ 'BaddestException: Everything gone wrong', + \ ], "\n"), + \ } + \ ], + \ ale_linters#python#vulture#Handle(bufnr(''), [ + \ 'Traceback (most recent call last):', + \ ' File "/usr/lib/python3.6/site-packages/vulture/__init__.py", line 13, in ', + \ ' from .core import stuff', + \ 'BaddestException: Everything gone wrong', + \ ]) + +Execute(The vulture handler should handle empty output): + AssertEqual + \ [], + \ ale_linters#python#vulture#Handle(bufnr(''), []) diff --git a/vim-config/plugins/ale/test/handler/test_write_good_handler.vader b/vim-config/plugins/ale/test/handler/test_write_good_handler.vader new file mode 100644 index 00000000..8bf4b223 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_write_good_handler.vader @@ -0,0 +1,37 @@ +Execute(The write-good handler should handle the example from the write-good README): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'end_col': 2, + \ 'type': 'W', + \ 'text': '"So" adds no meaning', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 12, + \ 'end_col': 21, + \ 'type': 'W', + \ 'text': '"was stolen" may be passive voice', + \ }, + \ { + \ 'lnum': 6, + \ 'col': 2, + \ 'end_col': 2, + \ 'type': 'W', + \ 'text': '"foo bar" bla', + \ }, + \ ], + \ ale#handlers#writegood#Handle(bufnr(''), [ + \ 'In /tmp/vBYivbZ/6/test.md', + \ '=============', + \ 'So the cat was stolen.', + \ '^^', + \ '"So" adds no meaning on line 1 at column 0', + \ '-------------', + \ 'So the cat was stolen.', + \ ' ^^^^^^^^^^', + \ '"was stolen" may be passive voice on line 1 at column 11', + \ '"foo bar" bla on line 6 at column 1', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_xmllint_handler.vader b/vim-config/plugins/ale/test/handler/test_xmllint_handler.vader new file mode 100644 index 00000000..a17d74a9 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_xmllint_handler.vader @@ -0,0 +1,30 @@ +Before: + runtime ale_linters/xml/xmllint.vim + +After: + call ale#linter#Reset() + +Execute(The xmllint handler should parse error messages correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 22, + \ 'type': 'W', + \ 'text': 'warning: Unsupported version ''dummy''' + \ }, + \ { + \ 'lnum': 34, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'parser error : Start tag expected, ''<'' not found' + \ } + \ ], + \ ale_linters#xml#xmllint#Handle(1, [ + \ 'path/to/file.xml:1: warning: Unsupported version ''dummy''', + \ '', + \ ' ^', + \ '-:34: parser error : Start tag expected, ''<'' not found', + \ 'blahblah>', + \ '^' + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_xvhdl_handler.vader b/vim-config/plugins/ale/test/handler/test_xvhdl_handler.vader new file mode 100644 index 00000000..b90539b8 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_xvhdl_handler.vader @@ -0,0 +1,24 @@ +Before: + runtime ale_linters/vhdl/xvhdl.vim + +After: + call ale#linter#Reset() + +Execute(The xvhdl handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 17, + \ 'type': 'E', + \ 'text': '[VRFC 10-91] aresetn is not declared ' + \ }, + \ { + \ 'lnum': 128, + \ 'type': 'E', + \ 'text': '[VRFC 10-91] m_axis_tx_tdata is not declared ' + \ }, + \ ], + \ ale_linters#vhdl#xvhdl#Handle(bufnr(''), [ + \ '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]', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_xvlog_handler.vader b/vim-config/plugins/ale/test/handler/test_xvlog_handler.vader new file mode 100644 index 00000000..2e1f83fc --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_xvlog_handler.vader @@ -0,0 +1,18 @@ +Before: + runtime ale_linters/verilog/xvlog.vim + +After: + call ale#linter#Reset() + +Execute(The xvlog handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'type': 'E', + \ 'text': '[VRFC 10-1412] syntax error near output ' + \ }, + \ ], + \ ale_linters#verilog#xvlog#Handle(bufnr(''), [ + \ 'ERROR: [VRFC 10-1412] syntax error near output [/path/to/file.v:5]', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_yamllint_handler.vader b/vim-config/plugins/ale/test/handler/test_yamllint_handler.vader new file mode 100644 index 00000000..dd51119c --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_yamllint_handler.vader @@ -0,0 +1,59 @@ +Before: + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_whitespace = 1 + + runtime! ale/handlers/yamllint.vim + +After: + Restore + + unlet! b:ale_warn_about_trailing_whitespace + + call ale#linter#Reset() + +Execute(Problems should be parsed correctly for yamllint): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'W', + \ 'text': 'missing document start "---"', + \ 'code': 'document-start', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'syntax error: expected the node content, but found ''''', + \ }, + \ ], + \ ale#handlers#yamllint#Handle(bufnr(''), [ + \ 'something.yaml:1:1: [warning] missing document start "---" (document-start)', + \ 'something.yml:2:1: [error] syntax error: expected the node content, but found ''''', + \ ]) + +Execute(The yamllint handler should respect ale_warn_about_trailing_whitespace): + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 18, + \ 'type': 'E', + \ 'text': 'trailing spaces', + \ 'code': 'trailing-spaces', + \ }, + \ ], + \ ale#handlers#yamllint#Handle(bufnr(''), [ + \ 'something.yml:5:18: [error] trailing spaces (trailing-spaces)', + \ ]) + + let b:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [ + \ ], + \ ale#handlers#yamllint#Handle(bufnr(''), [ + \ 'something.yml:5:18: [error] trailing spaces (trailing-spaces)', + \ ]) diff --git a/vim-config/plugins/ale/test/handler/test_yosys_handler.vader b/vim-config/plugins/ale/test/handler/test_yosys_handler.vader new file mode 100644 index 00000000..a55d0b5b --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_yosys_handler.vader @@ -0,0 +1,27 @@ +Before: + runtime ale_linters/verilog/yosys.vim + +After: + call ale#linter#Reset() + +Execute(The yosys handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected TOK_ID', + \ 'filename': 'file.v' + \ }, + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': 'internal error', + \ }, + \ ], + \ ale_linters#verilog#yosys#Handle(bufnr(''), [ + \ '1. Executing Verilog-2005 frontend: file.v', + \ 'ERROR: internal error', + \ 'file.v:3: ERROR: syntax error, unexpected TOK_ID', + \ ]) + diff --git a/vim-config/plugins/ale/test/handler/test_zeek_handler.vader b/vim-config/plugins/ale/test/handler/test_zeek_handler.vader new file mode 100644 index 00000000..07a80d86 --- /dev/null +++ b/vim-config/plugins/ale/test/handler/test_zeek_handler.vader @@ -0,0 +1,17 @@ +Before: + runtime ale_linters/zeek/zeek.vim + +After: + call ale#linter#Reset() + +Execute(The zeek handler should parse input correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'text': 'unknown identifier bar, at or near "bar"' + \ }, + \ ], + \ ale_linters#zeek#zeek#HandleErrors(bufnr(''), [ + \ 'error in /tmp/foo.zeek, line 2: unknown identifier bar, at or near "bar"' + \ ]) diff --git a/vim-config/plugins/ale/test/jsonnet_files/testfile.jsonnet b/vim-config/plugins/ale/test/jsonnet_files/testfile.jsonnet new file mode 100644 index 00000000..fc8fb78a --- /dev/null +++ b/vim-config/plugins/ale/test/jsonnet_files/testfile.jsonnet @@ -0,0 +1 @@ +{ foo: bar } diff --git a/vim-config/plugins/ale/test/linter/test_ada_gcc.vader b/vim-config/plugins/ale/test/linter/test_ada_gcc.vader new file mode 100644 index 00000000..906b31a4 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ada_gcc.vader @@ -0,0 +1,42 @@ +Before: + call ale#assert#SetUpLinterTest('ada', 'gcc') + call ale#test#SetFilename('dummy.adb') + + function! GetOutputDir(command) abort + let l:split_command = split(a:command) + let l:index = index(l:split_command, '-o') + return l:split_command[l:index + 1] + endfunction + + let b:out_file = GetOutputDir(ale_linters#ada#gcc#GetCommand(bufnr(''))) + +After: + delfunction GetOutputDir + + unlet! b:out_file + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'gcc', + \ ale#Escape('gcc') . ' -x ada -c -gnatc' + \ . ' -o ' . b:out_file + \ . ' -I %s:h' + \ . ' -gnatwa -gnatq %t' + + let b:ale_ada_gcc_executable = 'foo' + + AssertLinter 'foo', + \ ale#Escape('foo') . ' -x ada -c -gnatc' + \ . ' -o ' . b:out_file + \ . ' -I %s:h' + \ . ' -gnatwa -gnatq %t' + +Execute(The options should be configurable): + let g:ale_ada_gcc_options = '--foo --bar' + + AssertLinter 'gcc', + \ ale#Escape('gcc') . ' -x ada -c -gnatc' + \ . ' -o ' . b:out_file + \ . ' -I %s:h' + \ . ' --foo --bar %t' diff --git a/vim-config/plugins/ale/test/linter/test_adals.vader b/vim-config/plugins/ale/test/linter/test_adals.vader new file mode 100644 index 00000000..5a04594e --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_adals.vader @@ -0,0 +1,17 @@ +Before: + call ale#assert#SetUpLinterTest('ada', 'adals') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Sets adals executable): + let g:ale_ada_adals_executable = '/path/to /Ada' + AssertLinter '/path/to /Ada', ale#Escape('/path/to /Ada') + +Execute(Sets adals encoding): + let b:ale_ada_adals_encoding = 'iso-8859-1' + AssertLSPConfig {'ada.defaultCharset': 'iso-8859-1', 'ada.projectFile': 'default.gpr'} + +Execute(Sets adals project): + let g:ale_ada_adals_project = 'myproject.gpr' + AssertLSPConfig {'ada.defaultCharset': 'utf-8', 'ada.projectFile': 'myproject.gpr'} diff --git a/vim-config/plugins/ale/test/linter/test_alex.vader b/vim-config/plugins/ale/test/linter/test_alex.vader new file mode 100644 index 00000000..20e20301 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_alex.vader @@ -0,0 +1,34 @@ +Before: + call ale#assert#SetUpLinterTest('tex', 'alex') + call ale#test#SetFilename('test_file.tex') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The global executable should be used when the local one cannot be found): + AssertLinter 'alex', + \ ale#Escape('alex') . ' %s --text', + +Execute(Should use the node_modules/.bin executable, if available): + call ale#test#SetFilename('../test-files/alex/node-modules/test_file.tex') + + AssertLinter ale#path#Simplify(g:dir . '/../test-files/alex/node-modules/node_modules/.bin/alex'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/alex/node-modules/node_modules/.bin/alex')) + \ . ' %s --text', + +Execute(Should use the node_modules/alex executable, if available): + call ale#test#SetFilename('../test-files/alex/node-modules-2/test_file.tex') + + AssertLinter ale#path#Simplify(g:dir . '/../test-files/alex/node-modules-2/node_modules/alex/cli.js'), + \ (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/alex/node-modules-2/node_modules/alex/cli.js')) + \ . ' %s --text', + +Execute(Should let users configure a global executable and override local paths): + call ale#test#SetFilename('../test-files/write-good/node-modules-2/test_file.tex') + + let g:ale_alex_executable = '/path/to/custom/alex' + let g:ale_alex_use_global = 1 + + AssertLinter '/path/to/custom/alex', + \ ale#Escape('/path/to/custom/alex') . ' %s --text' diff --git a/vim-config/plugins/ale/test/linter/test_ameba.vader b/vim-config/plugins/ale/test/linter/test_ameba.vader new file mode 100644 index 00000000..7746b44f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ameba.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('crystal', 'ameba') + call ale#test#SetFilename('dummy.cr') + + let g:ale_crystal_ameba_executable = 'bin/ameba' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to bin/ameba): + AssertLinter 'bin/ameba', ale#Escape('bin/ameba') + \ . ' --format json ' + \ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.cr')) + +Execute(Should be able to set a custom executable): + let g:ale_crystal_ameba_executable = 'ameba' + + AssertLinter 'ameba' , ale#Escape('ameba') + \ . ' --format json ' + \ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.cr')) diff --git a/vim-config/plugins/ale/test/linter/test_angular.vader b/vim-config/plugins/ale/test/linter/test_angular.vader new file mode 100644 index 00000000..fe0749a1 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_angular.vader @@ -0,0 +1,44 @@ +Before: + call ale#assert#SetUpLinterTest('html', 'angular') + let g:paths = {} + +After: + call ale#assert#TearDownLinterTest() + unlet g:paths + +Execute(The Angular LSP connection shouldn't be created outside of Angular projects): + AssertLSPLanguage 'html' + AssertLSPConfig {} + AssertLSPProject '' + AssertLinterNotExecuted + +Execute(The default command for Angular should be correct): + call ale#test#SetFilename('../test-files/angular/test.html') + let g:paths = { + \ 'ngserver': ale#test#GetFilename('../test-files/angular/node_modules/@angular/language-server/bin/ngserver'), + \ 'service': ale#test#GetFilename('../test-files/angular/node_modules/@angular/language-service'), + \ 'typescript': ale#test#GetFilename('../test-files/angular/node_modules/typescript'), + \} + + AssertLSPLanguage 'html' + AssertLSPProject ale#test#GetFilename('../test-files/angular') + AssertLinter g:paths.ngserver, ale#Escape(g:paths.ngserver) + \ . ' --ngProbeLocations ' . ale#Escape(g:paths.service) + \ . ' --tsProbeLocations ' . ale#Escape(g:paths.typescript) + \ . ' --stdio' + +Execute(It should be possible to use the global ngserver): + let b:ale_html_angular_use_global = 1 + + call ale#test#SetFilename('../test-files/angular/test.html') + let g:paths = { + \ 'service': ale#test#GetFilename('../test-files/angular/node_modules/@angular/language-service'), + \ 'typescript': ale#test#GetFilename('../test-files/angular/node_modules/typescript'), + \} + + AssertLSPLanguage 'html' + AssertLSPProject ale#test#GetFilename('../test-files/angular') + AssertLinter 'ngserver', ale#Escape('ngserver') + \ . ' --ngProbeLocations ' . ale#Escape(g:paths.service) + \ . ' --tsProbeLocations ' . ale#Escape(g:paths.typescript) + \ . ' --stdio' diff --git a/vim-config/plugins/ale/test/linter/test_ansible_lint.vader b/vim-config/plugins/ale/test/linter/test_ansible_lint.vader new file mode 100644 index 00000000..6fb8acb5 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ansible_lint.vader @@ -0,0 +1,22 @@ +Before: + call ale#assert#SetUpLinterTest('ansible', 'ansible_lint') + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + unlet! b:bin_dir + unlet! b:executable + call ale#assert#TearDownLinterTest() + +Execute(The ansible_lint version <5.0.0 command callback should return default string): + GivenCommandOutput ['v4.1.2'] + AssertLinter 'ansible-lint', ale#Escape('ansible-lint') . ' --nocolor -p %t' + +Execute(The ansible_lint version >=5.0.0 command callback should return default string): + GivenCommandOutput ['v5.1.2'] + AssertLinter 'ansible-lint', ale#Escape('ansible-lint') . ' --nocolor --parseable-severity -x yaml %s' + +Execute(The ansible_lint executable should be configurable): + let g:ale_ansible_ansible_lint_executable = '~/.local/bin/ansible-lint' + GivenCommandOutput ['v4.1.2'] + AssertLinter '~/.local/bin/ansible-lint', + \ ale#Escape('~/.local/bin/ansible-lint') . ' --nocolor -p %t' diff --git a/vim-config/plugins/ale/test/linter/test_asciidoc_textlint.vader b/vim-config/plugins/ale/test/linter/test_asciidoc_textlint.vader new file mode 100644 index 00000000..a79a0ae3 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_asciidoc_textlint.vader @@ -0,0 +1,65 @@ +" Author: januswel, w0rp + +Before: + " This is just one language for the linter. + call ale#assert#SetUpLinterTest('asciidoc', 'textlint') + + " The configuration is shared between many languages. + Save g:ale_textlint_executable + Save g:ale_textlint_use_global + Save g:ale_textlint_options + + let g:ale_textlint_executable = 'textlint' + let g:ale_textlint_use_global = 0 + let g:ale_textlint_options = '' + + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + +After: + unlet! b:command_tail + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' -f json --stdin --stdin-filename %s' + +Execute(The executable should be configurable): + let b:ale_textlint_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -f json --stdin --stdin-filename %s' + +Execute(The options should be configurable): + let b:ale_textlint_options = '--something' + + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' --something -f json --stdin --stdin-filename %s' + +Execute(The local executable from .bin should be used if available): + call ale#test#SetFilename('../test-files/textlint/with_bin_path/foo.txt') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_bin_path/node_modules/.bin/textlint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_bin_path/node_modules/.bin/textlint')) + \ . ' -f json --stdin --stdin-filename %s' + +Execute(The local executable from textlint/bin should be used if available): + call ale#test#SetFilename('../test-files/textlint/with_textlint_bin_path/foo.txt') + + if has('win32') + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape('node.exe') . ' ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + else + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + endif diff --git a/vim-config/plugins/ale/test/linter/test_asm_gcc.vader b/vim-config/plugins/ale/test/linter/test_asm_gcc.vader new file mode 100644 index 00000000..5976b5f2 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_asm_gcc.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('asm', 'gcc') + call ale#test#SetFilename('test.cpp') + let b:command_tail = ' -x assembler' + \ . ' -o ' . (has('win32') ? 'nul': '/dev/null') + \ . '-iquote %s:h' + \ . ' -Wall -' + +After: + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail + + let b:ale_asm_gcc_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail diff --git a/vim-config/plugins/ale/test/linter/test_bandit.vader b/vim-config/plugins/ale/test/linter/test_bandit.vader new file mode 100644 index 00000000..e9488c00 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_bandit.vader @@ -0,0 +1,90 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'bandit') + let b:bandit_flags = ' --format custom ' + \ . '--msg-template "{line}:{test_id}:{severity}:{msg}" ' + +After: + call ale#assert#TearDownLinterTest() + unlet! b:bandit_flags + +Execute(The bandit command callback should return default string): + AssertLinter 'bandit', + \ ale#Escape('bandit') + \ . b:bandit_flags + \ . ' -' + +Execute(The bandit command callback should allow options): + let g:ale_python_bandit_options = '--configfile bandit.yaml' + + AssertLinter 'bandit', + \ ale#Escape('bandit') + \ . b:bandit_flags + \ . ' --configfile bandit.yaml -' + +Execute(The bandit executable should be configurable): + let g:ale_python_bandit_executable = '~/.local/bin/bandit' + + AssertLinter '~/.local/bin/bandit', + \ ale#Escape('~/.local/bin/bandit') + \ . b:bandit_flags + \ . ' -' + +Execute(Setting executable to 'pipenv' appends 'run bandit'): + let g:ale_python_bandit_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') + \ . ' run bandit' + \ . b:bandit_flags + \ . ' -' + +Execute(Pipenv is detected when python_bandit_auto_pipenv is set): + let g:ale_python_bandit_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinter 'pipenv', + \ ale#Escape('pipenv') + \ . ' run bandit' + \ . b:bandit_flags + \ . ' -' + +Execute(Setting executable to 'poetry' appends 'run bandit'): + let g:ale_python_bandit_executable = 'path/to/poetry' + + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') + \ . ' run bandit' + \ . b:bandit_flags + \ . ' -' + +Execute(Poetry is detected when python_bandit_auto_poetry is set): + let g:ale_python_bandit_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinter 'poetry', + \ ale#Escape('poetry') + \ . ' run bandit' + \ . b:bandit_flags + \ . ' -' + +Execute(The bandit command callback should add .bandit by default): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_bandit/namespace/foo/bar.py') + + let b:config_path = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_bandit/.bandit' + \) + + AssertLinter 'bandit', + \ ale#Escape('bandit') + \ . ' --ini ' . ale#Escape(b:config_path) + \ . b:bandit_flags + \ . ' -' + +Execute(The bandit command callback should support not using .bandit): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_bandit/subdir/foo/bar.py') + let g:ale_python_bandit_use_config = 0 + + AssertLinter 'bandit', + \ ale#Escape('bandit') + \ . b:bandit_flags + \ . ' -' diff --git a/vim-config/plugins/ale/test/linter/test_bashate.vader b/vim-config/plugins/ale/test/linter/test_bashate.vader new file mode 100644 index 00000000..714cf690 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_bashate.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('sh', 'bashate') + call ale#test#SetFilename('test.sh') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default bashate command should be correct): + AssertLinter 'bashate', ale#Escape('bashate') . ' %t' + +Execute(The bashate command should accept options): + let b:ale_sh_bashate_options = '-i E310 --max-line-length 100' + + AssertLinter 'bashate', + \ ale#Escape('bashate') . ' -i E310 --max-line-length 100 %t' diff --git a/vim-config/plugins/ale/test/linter/test_bib_bibclean.vader b/vim-config/plugins/ale/test/linter/test_bib_bibclean.vader new file mode 100644 index 00000000..fa6f7d33 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_bib_bibclean.vader @@ -0,0 +1,24 @@ +Before: + call ale#assert#SetUpLinterTest('bib', 'bibclean') + + let g:ale_ruby_rubocop_executable = 'bibclean' + let g:ale_ruby_rubocop_options = '' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to bibclean): + AssertLinter 'bibclean', ale#Escape('bibclean') + \ . ' -file-position ' + +Execute(Should be able to set a custom executable): + let g:ale_bib_bibclean_executable = 'bin/bibclean' + + AssertLinter 'bin/bibclean' , ale#Escape('bin/bibclean') + \ . ' -file-position ' + +Execute(Should not include custom options): + let g:ale_bib_bibclean_options = '-no-prettryprint' + + AssertLinter 'bibclean' , ale#Escape('bibclean') + \ . ' -file-position ' diff --git a/vim-config/plugins/ale/test/linter/test_bingo.vader b/vim-config/plugins/ale/test/linter/test_bingo.vader new file mode 100644 index 00000000..d8328414 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_bingo.vader @@ -0,0 +1,74 @@ +Before: + Save g:ale_go_go111module + + call ale#assert#SetUpLinterTest('go', 'bingo') + +After: + Restore + + if isdirectory(g:dir . '/.git') + call delete(g:dir . '/.git', 'd') + endif + + unlet! b:ale_completion_enabled + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(should set correct defaults): + AssertLinter 'bingo', ale#Escape('bingo') . ' --mode stdio' + +Execute(should configure bingo callback executable): + let b:ale_go_bingo_executable = 'boo' + let b:ale_go_bingo_options = '' + + AssertLinter 'boo', ale#Escape('boo') + +Execute(should set bingo options): + call ale#test#SetFilename('../test-files/go/go1/prj1/file.go') + " let b:ale_completion_enabled = 1 + let b:ale_go_bingo_options = '' + + AssertLinter 'bingo', + \ ale#Escape('bingo') . '' + + let b:ale_go_bingo_options = '--mode stdio --trace' + + AssertLinter 'bingo', + \ ale#Escape('bingo') . ' --mode stdio --trace' + +Execute(should support Go environment variables): + call ale#test#SetFilename('../test-files/go/go1/prj1/file.go') + let b:ale_go_go111module = 'on' + + AssertLinter 'bingo', + \ ale#Env('GO111MODULE', 'on') . ale#Escape('bingo') . ' --mode stdio' + + +Execute(Should return directory for 'go.mod' if found in parent directory): + call ale#test#SetFilename('../test-files/go/test.go') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/go') + +Execute(Should return nearest directory with '.git' if found in parent directory): + call ale#test#SetFilename('test.go') + call mkdir(g:dir . '/.git') + + AssertLSPProject g:dir + +Execute(Should ignore 'go.mod' and return '.git' dir if modules off): + call ale#test#SetFilename('../test-files/go/test.go') + + let b:ale_go_go111module = 'off' + let b:parent_dir = ale#path#Simplify(g:dir . '/..') + let b:git_dir = b:parent_dir . '/.git' + + if !isdirectory(b:git_dir) + call mkdir(b:git_dir) + endif + + AssertLSPProject b:parent_dir + + call delete(b:git_dir, 'd') + unlet! b:parent_dir + unlet! b:git_dir diff --git a/vim-config/plugins/ale/test/linter/test_brakeman.vader b/vim-config/plugins/ale/test/linter/test_brakeman.vader new file mode 100644 index 00000000..d3bf1920 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_brakeman.vader @@ -0,0 +1,37 @@ +Before: + call ale#assert#SetUpLinterTest('ruby', 'brakeman') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The brakeman command callback should detect absence of a valid Rails app): + call ale#test#SetFilename('../test-files/ruby/not_a_rails_app/test.rb') + + AssertLinter 'brakeman', '' + +Execute(The brakeman command callback should find a valid Rails app root): + call ale#test#SetFilename('../test-files/ruby/valid_rails_app/db/test.rb') + + AssertLinter 'brakeman', ale#Escape('brakeman') + \ . ' -f json -q -p ' + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/ruby/valid_rails_app')) + +Execute(The brakeman command callback should include configured options): + call ale#test#SetFilename('../test-files/ruby/valid_rails_app/db/test.rb') + + let g:ale_ruby_brakeman_options = '--combobulate' + + AssertLinter 'brakeman', ale#Escape('brakeman') + \ . ' -f json -q --combobulate -p ' + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/ruby/valid_rails_app')) + +Execute(Setting bundle appends 'exec brakeman'): + call ale#test#SetFilename('../test-files/ruby/valid_rails_app/db/test.rb') + + let g:ale_ruby_brakeman_executable = 'bundle' + let g:ale_ruby_brakeman_options = '--combobulate' + + AssertLinter 'bundle', ale#Escape('bundle') + \ . ' exec brakeman' + \ . ' -f json -q --combobulate -p ' + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/ruby/valid_rails_app')) diff --git a/vim-config/plugins/ale/test/linter/test_c_cc.vader b/vim-config/plugins/ale/test/linter/test_c_cc.vader new file mode 100644 index 00000000..c8c2de7d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_c_cc.vader @@ -0,0 +1,55 @@ +Before: + Save g:ale_c_parse_makefile + Save g:ale_history_enabled + + let g:ale_c_parse_makefile = 0 + let g:ale_history_enabled = 0 + + let g:get_cflags_return_value = '' + let g:executable_map = {} + + runtime autoload/ale/c.vim + runtime autoload/ale/engine.vim + + function! ale#engine#IsExecutable(buffer, executable) abort + return has_key(g:executable_map, a:executable) + endfunction + + function! ale#c#GetCFlags(buffer, output) abort + return g:get_cflags_return_value + endfunction + + call ale#assert#SetUpLinterTest('c', 'cc') + + let b:command_tail = ' -S -x c' + \ . ' -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -std=c11 -Wall -' + +After: + unlet! g:get_cflags_return_value + unlet! g:executable_map + unlet! b:command_tail + + runtime autoload/ale/c.vim + runtime autoload/ale/engine.vim + + call ale#assert#TearDownLinterTest() + +Execute(clang should be used instead of gcc, if available): + let g:executable_map = {'clang': 1} + + AssertLinter 'clang', [ale#Escape('clang') . b:command_tail] + +Execute(The executable should be configurable): + AssertLinter 'gcc', [ale#Escape('gcc') . b:command_tail] + + let b:ale_c_cc_executable = 'foobar' + + AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail] + +Execute(The -std flag should be replaced by parsed C flags): + let b:command_tail = substitute(b:command_tail, 'c11', 'c99 ', '') + let g:get_cflags_return_value = '-std=c99' + + AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail diff --git a/vim-config/plugins/ale/test/linter/test_c_ccls.vader b/vim-config/plugins/ale/test/linter/test_c_ccls.vader new file mode 100644 index 00000000..a4f575c6 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_c_ccls.vader @@ -0,0 +1,69 @@ +" Author: Ye Jingchen , Ben Falconer +" Description: A language server for C + +Before: + call ale#assert#SetUpLinterTest('c', 'ccls') + + Save b:ale_c_build_dir_names + Save b:ale_c_ccls_executable + Save b:ale_c_ccls_init_options + +After: + call ale#assert#TearDownLinterTest() + +Execute(The project root should be detected correctly using compile_commands.json file): + call ale#test#SetFilename(tempname() . '/dummy.c') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ccls/with_compile_commands_json/dummy.c') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ccls/with_compile_commands_json') + +Execute(The project root should be detected correctly using .ccls file): + call ale#test#SetFilename(tempname() . '/dummy.c') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ccls/with_ccls/dummy.c') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ccls/with_ccls') + +Execute(The project root should be detected correctly using .ccls-root file): + call ale#test#SetFilename(tempname() . '/dummy.c') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ccls/with_ccls-root/dummy.c') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ccls/with_ccls-root') + +Execute(The executable should be configurable): + AssertLinter 'ccls', ale#Escape('ccls') + + let b:ale_c_ccls_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + +Execute(The initialization options should be configurable): + AssertLSPOptions {} + + let b:ale_c_ccls_init_options = { 'cacheDirectory': '/tmp/ccls' } + + AssertLSPOptions { 'cacheDirectory': '/tmp/ccls' } + +Execute(The compile command database should be detected correctly): + call ale#test#SetFilename('../test-files/ccls/with_ccls/dummy.c') + + AssertLSPOptions {} + + call ale#test#SetFilename('../test-files/ccls/with_compile_commands_json/dummy.c') + + AssertLSPOptions { 'compilationDatabaseDirectory': + \ ale#path#Simplify(g:dir . '/../test-files/ccls/with_compile_commands_json') } + + call ale#test#SetFilename('../test-files/ccls/with_build_dir/dummy.c') + let b:ale_c_build_dir_names = ['unusual_build_dir_name'] + + AssertLSPOptions { 'compilationDatabaseDirectory': + \ ale#path#Simplify(g:dir . '/../test-files/ccls/with_build_dir/unusual_build_dir_name') } diff --git a/vim-config/plugins/ale/test/linter/test_c_clang_tidy.vader b/vim-config/plugins/ale/test/linter/test_c_clang_tidy.vader new file mode 100644 index 00000000..c4433550 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_c_clang_tidy.vader @@ -0,0 +1,77 @@ +Before: + Save g:ale_c_parse_makefile + let g:ale_c_parse_makefile = 0 + + call ale#assert#SetUpLinterTest('c', 'clangtidy') + call ale#test#SetFilename('test.c') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The clangtidy command default should be correct): + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' %s' + +Execute(You should be able to remove the -checks option for clang-tidy): + let b:ale_c_clangtidy_checks = [] + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' %s' + +Execute(You should be able to set other checks for clang-tidy): + let b:ale_c_clangtidy_checks = ['-*', 'clang-analyzer-*'] + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' -checks=' . ale#Escape('-*,clang-analyzer-*') . ' %s' + +Execute(You should be able to manually set compiler flags for clang-tidy): + let b:ale_c_clangtidy_checks = ['*'] + let b:ale_c_clangtidy_options = '-Wall' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' -checks=' . ale#Escape('*') . ' %s -- -Wall' + +Execute(You should be able to manually set flags for clang-tidy): + let b:ale_c_clangtidy_extra_options = '-config=' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' ' . ale#Escape('-config=') . ' %s' + +Execute(The build directory should be configurable): + let b:ale_c_clangtidy_checks = ['*'] + let b:ale_c_build_dir = '/foo/bar' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' -checks=' . ale#Escape('*') . ' %s' + \ . ' -p ' . ale#Escape('/foo/bar') + +Execute(The build directory setting should override the options): + let b:ale_c_clangtidy_checks = ['*'] + let b:ale_c_build_dir = '/foo/bar' + let b:ale_c_clangtidy_options = '-Wall' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' -checks=' . ale#Escape('*') . ' %s' + \ . ' -p ' . ale#Escape('/foo/bar') + +Execute(The build directory should be used for header files): + call ale#test#SetFilename('test.h') + + let b:ale_c_clangtidy_checks = ['*'] + let b:ale_c_build_dir = '/foo/bar' + let b:ale_c_clangtidy_options = '-Wall' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' -checks=' . ale#Escape('*') . ' %s' + \ . ' -p ' . ale#Escape('/foo/bar') + +Execute(The executable should be configurable): + let b:ale_c_clangtidy_checks = ['*'] + let b:ale_c_clangtidy_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -checks=' . ale#Escape('*') . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_c_clangd.vader b/vim-config/plugins/ale/test/linter/test_c_clangd.vader new file mode 100644 index 00000000..b7a4e029 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_c_clangd.vader @@ -0,0 +1,47 @@ +Before: + call ale#assert#SetUpLinterTest('c', 'clangd') + + Save b:ale_c_clangd_options + Save b:ale_c_build_dir + Save b:ale_c_build_dir_names + Save b:ale_c_parse_compile_commands + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'c' + +Execute(The default executable should be correct): + AssertLinter 'clangd', ale#Escape('clangd') + +Execute(The project root should be detected correctly): + call ale#test#SetFilename(tempname() . '/dummy.c') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/clangd/with_compile_commands/dummy.c') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/clangd/with_compile_commands') + +Execute(The executable should be configurable): + let g:ale_c_clangd_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + +Execute(The options should be configurable): + let b:ale_c_clangd_options = '-compile-commands-dir=foo' + + AssertLinter 'clangd', ale#Escape('clangd') . ' ' . b:ale_c_clangd_options + +Execute(The compile command database should be detected correctly): + call ale#test#SetFilename('../test-files/clangd/with_build_dir/dummy_src/dummy.c') + + let b:ale_c_clangd_options = '' + let b:ale_c_build_dir = '' + let b:ale_c_build_dir_names = ['unusual_build_dir_name'] + let b:ale_c_parse_compile_commands = 1 + + AssertLinter 'clangd', ale#Escape('clangd') + \ . ' -compile-commands-dir=' + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/clangd/with_build_dir/unusual_build_dir_name')) diff --git a/vim-config/plugins/ale/test/linter/test_c_cppcheck.vader b/vim-config/plugins/ale/test/linter/test_c_cppcheck.vader new file mode 100644 index 00000000..c84053f8 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_c_cppcheck.vader @@ -0,0 +1,46 @@ +Before: + call ale#assert#SetUpLinterTest('c', 'cppcheck') + let b:command_tail = ' -q --language=c --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') . ' --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t' + +After: + unlet! b:command_tail + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'cppcheck', ale#Escape('cppcheck') . b:command_tail + + let b:ale_c_cppcheck_executable = 'foobar' + + AssertLinterCwd '' + AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail + +Execute(cppcheck for C should detect compile_commands.json files): + call ale#test#SetFilename('../test-files/cppcheck/one/foo.c') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/cppcheck/one') + AssertLinter 'cppcheck', ale#Escape('cppcheck') + \ . ' -q --language=c' + \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') + \ . ' --project=' . ale#Escape('compile_commands.json') + \ . ' --enable=style %t' + +Execute(cppcheck for C should detect compile_commands.json files in build directories): + call ale#test#SetFilename('../test-files/cppcheck/with_build_dir/foo.cpp') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/cppcheck/with_build_dir') + AssertLinter 'cppcheck', ale#Escape('cppcheck') + \ . ' -q --language=c' + \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') + \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) + \ . ' --enable=style %t' + +Execute(cppcheck for C should include file dir if compile_commands.json file is not found): + call ale#test#SetFilename('../test-files/cppcheck/foo.cpp') + + AssertLinter 'cppcheck', + \ ale#Escape('cppcheck') + \ . ' -q --language=c' + \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') + \ . ' --enable=style' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/cppcheck')) + \ . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_c_cquery.vader b/vim-config/plugins/ale/test/linter/test_c_cquery.vader new file mode 100644 index 00000000..bca0dbbc --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_c_cquery.vader @@ -0,0 +1,37 @@ +Before: + call ale#assert#SetUpLinterTest('c', 'cquery') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The project root should be detected correctly using compile_commands.json file): + call ale#test#SetFilename(tempname() . '/dummy.c') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/cquery/dummy.c') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/cquery') + +Execute(The project root should be detected correctly using .cquery file): + call ale#test#SetFilename(tempname() . '/dummy.c') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/cquery/with_cquery/dummy.c') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/cquery/with_cquery') + +Execute(The executable should be configurable): + AssertLinter 'cquery', ale#Escape('cquery') + + let b:ale_c_cquery_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + +Execute(The cache directory should be configurable): + AssertLSPOptions {'cacheDirectory': expand('$HOME/.cache/cquery')} + + let b:ale_c_cquery_cache_directory = '/foo/bar' + + AssertLSPOptions {'cacheDirectory': '/foo/bar'} diff --git a/vim-config/plugins/ale/test/linter/test_c_flawfinder.vader b/vim-config/plugins/ale/test/linter/test_c_flawfinder.vader new file mode 100644 index 00000000..38385e2b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_c_flawfinder.vader @@ -0,0 +1,24 @@ +Before: + call ale#assert#SetUpLinterTest('c', 'flawfinder') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The flawfinder command should be correct): + AssertLinter 'flawfinder', ale#Escape('flawfinder') . ' -CDQS --minlevel=1 %t' + +Execute(The minlevel of flawfinder should be configurable): + let b:ale_c_flawfinder_minlevel = 8 + + AssertLinter 'flawfinder', ale#Escape('flawfinder') . ' -CDQS --minlevel=8 %t' + +Execute(Additional flawfinder options should be configurable): + let b:ale_c_flawfinder_options = '--foobar' + + AssertLinter 'flawfinder', + \ ale#Escape('flawfinder') . ' -CDQS --foobar --minlevel=1 %t' + +Execute(The flawfinder exectable should be configurable): + let b:ale_c_flawfinder_executable = 'foo/bar' + + AssertLinter 'foo/bar', ale#Escape('foo/bar') . ' -CDQS --minlevel=1 %t' diff --git a/vim-config/plugins/ale/test/linter/test_c_import_paths.vader b/vim-config/plugins/ale/test/linter/test_c_import_paths.vader new file mode 100644 index 00000000..19e39915 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_c_import_paths.vader @@ -0,0 +1,162 @@ +Before: + " Make sure the c.vim file is loaded first. + call ale#c#FindProjectRoot(bufnr('')) + + Save g:ale_c_parse_compile_commands + Save g:ale_c_parse_makefile + Save g:__ale_c_project_filenames + + let g:original_project_filenames = g:__ale_c_project_filenames + let g:executable_map = {} + + " Remove the .git/HEAD dir for C import paths for these tests. + " The tests run inside of a git repo. + let g:__ale_c_project_filenames = filter( + \ copy(g:__ale_c_project_filenames), + \ 'v:val isnot# ''.git/HEAD''' + \) + + let g:ale_c_parse_compile_commands = 0 + let g:ale_c_parse_makefile = 0 + + runtime autoload/ale/engine.vim + + function! ale#engine#IsExecutable(buffer, executable) abort + return has_key(g:executable_map, a:executable) + endfunction + +After: + Restore + + unlet! g:original_project_filenames + unlet! g:executable_map + + runtime autoload/ale/engine.vim + + call ale#assert#TearDownLinterTest() + +Execute(The C cc linter should include 'include' directories for projects with a Makefile): + call ale#assert#SetUpLinterTest('c', 'cc') + call ale#test#SetFilename('../test-files/c/makefile_project/subdir/file.c') + let g:ale_c_cc_options = '' + + AssertLinter 'gcc', + \ ale#Escape('gcc') + \ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/makefile_project/include')) + \ . ' -' + +Execute(The C cc linter should include 'include' directories for projects with a configure file): + call ale#assert#SetUpLinterTest('c', 'cc') + call ale#test#SetFilename('../test-files/c/configure_project/subdir/file.c') + let g:ale_c_cc_options = '' + + AssertLinter 'gcc', + \ ale#Escape('gcc') + \ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/configure_project/include')) + \ . ' -' + +Execute(The C cc linter should include root directories for projects with .h files in them): + call ale#assert#SetUpLinterTest('c', 'cc') + call ale#test#SetFilename('../test-files/c/h_file_project/subdir/file.c') + let g:ale_c_cc_options = '' + + AssertLinter 'gcc', + \ ale#Escape('gcc') + \ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/h_file_project')) + \ . ' -' + +Execute(The C cc linter should include root directories for projects with .hpp files in them): + call ale#assert#SetUpLinterTest('c', 'cc') + call ale#test#SetFilename('../test-files/c/hpp_file_project/subdir/file.c') + let g:ale_c_cc_options = '' + + AssertLinter 'gcc', + \ ale#Escape('gcc') + \ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/hpp_file_project')) + \ . ' -' + +Execute(The C ClangTidy handler should include 'include' directories for projects with a Makefile): + call ale#assert#SetUpLinterTest('c', 'clangtidy') + call ale#test#SetFilename('../test-files/c/makefile_project/subdir/file.cpp') + let g:ale_c_clangtidy_options = '' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' %s ' + \ . '-- -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/makefile_project/include')) + +Execute(The C++ cc linter should include 'include' directories for projects with a Makefile): + call ale#assert#SetUpLinterTest('cpp', 'cc') + call ale#test#SetFilename('../test-files/c/makefile_project/subdir/file.cpp') + let g:ale_cpp_cc_options = '' + + AssertLinter 'gcc', + \ ale#Escape('gcc') + \ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/makefile_project/include')) + \ . ' -' + +Execute(The C++ cc linter should include 'include' directories for projects with a configure file): + call ale#assert#SetUpLinterTest('cpp', 'cc') + call ale#test#SetFilename('../test-files/c/configure_project/subdir/file.cpp') + let g:ale_cpp_cc_options = '' + + AssertLinter 'gcc', + \ ale#Escape('gcc') + \ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/configure_project/include')) + \ . ' -' + +Execute(The C++ cc linter should include root directories for projects with .h files in them): + call ale#assert#SetUpLinterTest('cpp', 'cc') + call ale#test#SetFilename('../test-files/c/h_file_project/subdir/file.cpp') + let g:ale_cpp_cc_options = '' + + AssertLinter 'gcc', + \ ale#Escape('gcc') + \ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/h_file_project')) + \ . ' -' + +Execute(The C++ cc linter should include root directories for projects with .hpp files in them): + call ale#assert#SetUpLinterTest('cpp', 'cc') + call ale#test#SetFilename('../test-files/c/hpp_file_project/subdir/file.cpp') + let g:ale_cpp_cc_options = '' + + AssertLinter 'gcc', + \ ale#Escape('gcc') + \ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/hpp_file_project')) + \ . ' -' + +Execute(The C++ ClangTidy handler should include json folders for projects with suitable build directory in them): + call ale#assert#SetUpLinterTest('cpp', 'clangtidy') + call ale#test#SetFilename('../test-files/c/json_project/subdir/file.cpp') + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' %s ' + \ . '-p ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/json_project/build')) + +Execute(The C++ ClangTidy handler should include 'include' directories for projects with a Makefile): + call ale#assert#SetUpLinterTest('cpp', 'clangtidy') + call ale#test#SetFilename('../test-files/c/makefile_project/subdir/file.cpp') + let g:ale_cpp_clangtidy_options = '' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' %s ' + \ . '-- -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/c/makefile_project/include')) + diff --git a/vim-config/plugins/ale/test/linter/test_cargo.vader b/vim-config/plugins/ale/test/linter/test_cargo.vader new file mode 100644 index 00000000..25dd0253 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cargo.vader @@ -0,0 +1,222 @@ +Before: + call ale#assert#SetUpLinterTest('rust', 'cargo') + call ale#test#SetFilename('../test-files/cargo/test.rs') + + let g:cd = 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/cargo')) . ' && ' + let g:suffix = ' --frozen --message-format=json -q' + let g:ale_rust_cargo_avoid_whole_workspace = 0 + + " Test with version 0.22.0 by default. + GivenCommandOutput ['cargo 0.22.0 (3423351a5 2017-10-06)'] + +After: + call ale#assert#TearDownLinterTest() + + unlet! g:cd + unlet! g:suffix + +Execute(The linter should not be executed when there's no Cargo.toml file): + call ale#test#SetFilename('../foo.rs') + AssertLinterNotExecuted + +Execute(The linter should be executed when there is a Cargo.toml file): + GivenCommandOutput [] + AssertLinter 'cargo', 'cargo build --frozen --message-format=json -q' + +Execute(`cargo check` should be used when the version is new enough): + GivenCommandOutput ['cargo 0.17.0 (3423351a5 2017-10-06)'] + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo check' . g:suffix, + \] + + " We should cache the version check + GivenCommandOutput [] + AssertLinter 'cargo', ['cargo check' . g:suffix] + +Execute(`cargo build` should be used when cargo is too old): + GivenCommandOutput ['cargo 0.16.0 (3423351a5 2017-10-06)'] + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo build' . g:suffix, + \] + + GivenCommandOutput [] + AssertLinter 'cargo', ['cargo build' . g:suffix] + +Execute(`cargo build` should be used when g:ale_rust_cargo_use_check is set to 0): + let g:ale_rust_cargo_use_check = 0 + + GivenCommandOutput ['cargo 0.24.0 (3423351a5 2017-10-06)'] + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo build' . g:suffix, + \] + + " We should cache the version check + GivenCommandOutput [] + AssertLinter 'cargo', ['cargo build' . g:suffix] + +Execute(`cargo check` should be used when the version is new enough): + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo check' . g:suffix, + \] + + " We should cache the version check + GivenCommandOutput [] + AssertLinter 'cargo', ['cargo check' . g:suffix] + +Execute(--all-targets should be used when g:ale_rust_cargo_check_all_targets is set to 1): + let g:ale_rust_cargo_check_all_targets = 1 + + AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --all-targets' . g:suffix] + " We should cache the version check + AssertLinter 'cargo', ['cargo check --all-targets' . g:suffix] + +Execute(--tests should be used when g:ale_rust_cargo_check_tests is set to 1): + let g:ale_rust_cargo_check_tests = 1 + + AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --tests' . g:suffix] + + " We should cache the version check + GivenCommandOutput [] + AssertLinter 'cargo', ['cargo check --tests' . g:suffix] + +Execute(--examples should be used when g:ale_rust_cargo_check_examples is set to 1): + let g:ale_rust_cargo_check_examples = 1 + + AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --examples' . g:suffix] + + " We should cache the version check + GivenCommandOutput [] + AssertLinter 'cargo', ['cargo check --examples' . g:suffix] + +Execute(--no-default-features should be used when g:ale_rust_cargo_default_feature_behavior is none): + let b:ale_rust_cargo_default_feature_behavior = 'none' + + AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --no-default-features'] + +Execute(g:ale_rust_cargo_include_features added when g:ale_rust_cargo_default_feature_behavior is none): + let b:ale_rust_cargo_default_feature_behavior = 'none' + let b:ale_rust_cargo_include_features = 'foo bar' + + AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --no-default-features --features ' . ale#Escape('foo bar')] + +Execute(g:ale_rust_cargo_include_features added and escaped): + let b:ale_rust_cargo_default_feature_behavior = 'default' + let b:ale_rust_cargo_include_features = "foo bar baz" + + AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --features ' . ale#Escape('foo bar baz')] + +Execute(--all-features should be used when g:ale_rust_cargo_default_feature_behavior is all): + let b:ale_rust_cargo_default_feature_behavior = 'all' + " When all features are enabled we should ignore extra features to add + " since it won't do anything + let b:ale_rust_cargo_include_features = 'foo bar' + + GivenCommandOutput ['cargo 0.22.0 (3423351a5 2017-10-06)'] + AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --all-features'] + +Execute(Cargo should run from the crate directory when set to avoid the workspace): + let g:ale_rust_cargo_avoid_whole_workspace = 1 + call ale#test#SetFilename('../test-files/cargo/workspace_paths/subpath/test.rs') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/cargo/workspace_paths/subpath') + call ale#semver#ResetVersionCache() + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo check --frozen --message-format=json -q', + \] + +Execute(Cargo should not run from the crate directory when not set to avoid the workspace): + let g:ale_rust_cargo_avoid_whole_workspace = 0 + call ale#test#SetFilename('../test-files/cargo/workspace_paths/subpath/test.rs') + + AssertLinterCwd '' + call ale#semver#ResetVersionCache() + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo check --frozen --message-format=json -q', + \] + +Execute(When ale_rust_cargo_use_clippy is set, cargo-clippy is used as linter): + let b:ale_rust_cargo_use_clippy = 1 + + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo clippy --frozen --message-format=json -q', + \] + +Execute(When ale_rust_cargo_clippy_options is set, cargo-clippy appends it to commandline): + let b:ale_rust_cargo_use_clippy = 1 + let b:ale_rust_cargo_clippy_options = '-- -D warnings' + + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo clippy --frozen --message-format=json -q -- -D warnings', + \] + +Execute(Clippy options work without prepending --): + let b:ale_rust_cargo_use_clippy = 1 + let b:ale_rust_cargo_clippy_options = '-D warnings' + + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo clippy --frozen --message-format=json -q -- -D warnings', + \] + +Execute(Build supports all cargo flags): + let g:ale_rust_cargo_use_check = 0 + let g:ale_rust_cargo_check_all_targets = 1 + let g:ale_rust_cargo_check_tests = 1 + let g:ale_rust_cargo_check_examples = 1 + let b:ale_rust_cargo_default_feature_behavior = 'all' + let b:ale_rust_cargo_target_dir = 'target/ale' + + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo build --all-targets --examples --tests --target-dir ' . ale#Escape('target/ale') . ' --frozen --message-format=json -q --all-features', + \] + +Execute(Clippy supports all cargo flags): + let b:ale_rust_cargo_use_clippy = 1 + let g:ale_rust_cargo_check_all_targets = 1 + let g:ale_rust_cargo_check_tests = 1 + let g:ale_rust_cargo_check_examples = 1 + let b:ale_rust_cargo_default_feature_behavior = 'all' + let b:ale_rust_cargo_clippy_options = '-D warnings' + let b:ale_rust_cargo_target_dir = 'target/ale' + + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo clippy --all-targets --examples --tests --target-dir ' . ale#Escape('target/ale') . ' --frozen --message-format=json -q --all-features -- -D warnings', + \] + +Execute(cargo-check does not refer ale_rust_cargo_clippy_options): + let b:ale_rust_cargo_use_clippy = 0 + let b:ale_rust_cargo_use_check = 1 + let b:ale_rust_cargo_clippy_options = '-- -D warnings' + + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo check --frozen --message-format=json -q', + \] + +Execute(`cargo --target-dir` should be used when the version is new enough and it is set): + let b:ale_rust_cargo_target_dir = 'target/ale' + + GivenCommandOutput ['cargo 0.17.0 (3423351a5 2017-10-06)'] + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo check --target-dir ' . ale#Escape('target/ale') . g:suffix, + \] + +Execute(`cargo --target-dir` should not be used when the version is not new enough and it is set): + let b:ale_rust_cargo_target_dir = 'target/ale' + + GivenCommandOutput ['cargo 0.16.0 (3423351a5 2017-10-06)'] + AssertLinter 'cargo', [ + \ ale#Escape('cargo') . ' --version', + \ 'cargo build' . g:suffix, + \] diff --git a/vim-config/plugins/ale/test/linter/test_checkstyle.vader b/vim-config/plugins/ale/test/linter/test_checkstyle.vader new file mode 100644 index 00000000..8197e6b5 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_checkstyle.vader @@ -0,0 +1,72 @@ +Before: + call ale#assert#SetUpLinterTest('java', 'checkstyle') + call ale#test#SetFilename('dummy.java') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The checkstyle callback should return the correct default value): + AssertLinter 'checkstyle', + \ ale#Escape('checkstyle') + \ . ' -c ' . ale#Escape('/google_checks.xml') + \ . ' %s' + +Execute(The checkstyle executable should be configurable): + let b:ale_java_checkstyle_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') + \ . ' -c ' . ale#Escape('/google_checks.xml') + \ . ' %s' + +Execute(Custom options should be supported): + let b:ale_java_checkstyle_options = '--foobar -cp -classpath /path/to/checkstyle-8.7-all.jar' + + AssertLinter 'checkstyle', + \ ale#Escape('checkstyle') + \ . ' --foobar -cp -classpath /path/to/checkstyle-8.7-all.jar' + \ . ' -c ' . ale#Escape('/google_checks.xml') + \ . ' %s' + +Execute(configuration files set in _config should be supported): + let b:ale_java_checkstyle_config = ale#path#Simplify(g:dir . '/../test-files/checkstyle/other_config.xml') + + AssertLinter 'checkstyle', + \ ale#Escape('checkstyle') + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/checkstyle/other_config.xml')) + \ . ' %s' + +Execute(configuration files set in _options should be preferred over _config): + let b:ale_java_checkstyle_config = '/foo.xml' + let b:ale_java_checkstyle_options = '-c /bar.xml' + + AssertLinter 'checkstyle', ale#Escape('checkstyle') . ' -c /bar.xml %s' + + let b:ale_java_checkstyle_options = '-x -c /bar.xml' + + AssertLinter 'checkstyle', ale#Escape('checkstyle') . ' -x -c /bar.xml %s' + +Execute(google_checks.xml should be used by default): + call ale#test#SetFilename('../test-files/checkstyle/test.java') + + AssertLinter 'checkstyle', + \ ale#Escape('checkstyle') + \ . ' -c ' . ale#Escape('/google_checks.xml') + \ . ' %s' + +Execute(Other relative paths should be supported): + let b:ale_java_checkstyle_config = '../test-files/checkstyle/other_config.xml' + + AssertLinter 'checkstyle', + \ ale#Escape('checkstyle') + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/checkstyle/other_config.xml')) + \ . ' %s' + + call ale#test#SetFilename('../test-files/checkstyle/test.java') + + let b:ale_java_checkstyle_config = 'other_config.xml' + + AssertLinter 'checkstyle', + \ ale#Escape('checkstyle') + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/checkstyle/other_config.xml')) + \ . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_circleci.vader b/vim-config/plugins/ale/test/linter/test_circleci.vader new file mode 100644 index 00000000..000a77ec --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_circleci.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('yaml', 'circleci') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The linter should not run for every YAML file): + AssertLinterNotExecuted + +Execute(The linter should for YAML files in a .circleci directory): + call ale#test#SetFilename('../test-files/.circleci/config.yml') + + AssertLinter 'circleci', 'circleci --skip-update-check config validate - < %s' diff --git a/vim-config/plugins/ale/test/linter/test_clang_tidy.vader b/vim-config/plugins/ale/test/linter/test_clang_tidy.vader new file mode 100644 index 00000000..eb1220be --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_clang_tidy.vader @@ -0,0 +1,84 @@ +Before: + Save g:ale_c_parse_makefile + let g:ale_c_parse_makefile = 0 + + call ale#assert#SetUpLinterTest('cpp', 'clangtidy') + call ale#test#SetFilename('test.cpp') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The clangtidy command default should be correct): + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' %s' + +Execute(You should be able to remove the -checks option for clang-tidy): + let b:ale_cpp_clangtidy_checks = [] + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' %s' + +Execute(You should be able to set other checks for clang-tidy): + let b:ale_cpp_clangtidy_checks = ['-*', 'clang-analyzer-*'] + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' -checks=' . ale#Escape('-*,clang-analyzer-*') . ' %s' + +Execute(You should be able to manually set compiler flags for clang-tidy): + let b:ale_cpp_clangtidy_checks = ['*'] + let b:ale_cpp_clangtidy_options = '-Wall' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' -checks=' . ale#Escape('*') . ' %s -- -Wall' + +Execute(You should be able to manually set flags for clang-tidy): + let b:ale_cpp_clangtidy_extra_options = '-config=' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' ' . ale#Escape('-config=') . ' %s' + +Execute(The build directory should be configurable): + let b:ale_cpp_clangtidy_checks = ['*'] + let b:ale_c_build_dir = '/foo/bar' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' -checks=' . ale#Escape('*') . ' %s' + \ . ' -p ' . ale#Escape('/foo/bar') + +Execute(The build directory setting should override the options): + let b:ale_cpp_clangtidy_checks = ['*'] + let b:ale_c_build_dir = '/foo/bar' + let b:ale_cpp_clangtidy_options = '-Wall' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' -checks=' . ale#Escape('*') . ' %s' + \ . ' -p ' . ale#Escape('/foo/bar') + +Execute(The build directory should be used for header files): + call ale#test#SetFilename('test.h') + + let b:ale_cpp_clangtidy_checks = ['*'] + let b:ale_c_build_dir = '/foo/bar' + let b:ale_cpp_clangtidy_options = '-Wall' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' -checks=' . ale#Escape('*') . ' %s' + \ . ' -p ' . ale#Escape('/foo/bar') + + call ale#test#SetFilename('test.hpp') + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') + \ . ' -checks=' . ale#Escape('*') . ' %s' + \ . ' -p ' . ale#Escape('/foo/bar') + +Execute(The executable should be configurable): + let b:ale_cpp_clangtidy_checks = ['*'] + let b:ale_cpp_clangtidy_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -checks=' . ale#Escape('*') . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_clj_kondo.vader b/vim-config/plugins/ale/test/linter/test_clj_kondo.vader new file mode 100644 index 00000000..869f9f2a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_clj_kondo.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('clojure', 'clj_kondo') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'clj-kondo', 'clj-kondo' + \ . ' --cache --lint %t' + +Execute(Extra options should be supported): + let g:ale_clojure_clj_kondo_options = '--config ./clj-kondo/config.edn' + + AssertLinter 'clj-kondo', 'clj-kondo' + \ . ' --config ./clj-kondo/config.edn --lint %t' diff --git a/vim-config/plugins/ale/test/linter/test_cookstyle.vader b/vim-config/plugins/ale/test/linter/test_cookstyle.vader new file mode 100644 index 00000000..ad7391cc --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cookstyle.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('chef', 'cookstyle') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'cookstyle', ale#Escape('cookstyle') . ' --force-exclusion --format json --stdin %s' + +Execute(The executable path should be configurable): + let b:ale_chef_cookstyle_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --force-exclusion --format json --stdin %s' + +Execute(The linter options should be configurable): + let b:ale_chef_cookstyle_options = '--parallel' + + AssertLinter 'cookstyle', ale#Escape('cookstyle') . ' --parallel --force-exclusion --format json --stdin %s' + diff --git a/vim-config/plugins/ale/test/linter/test_cpp_cc.vader b/vim-config/plugins/ale/test/linter/test_cpp_cc.vader new file mode 100644 index 00000000..dec3a07c --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cpp_cc.vader @@ -0,0 +1,55 @@ +Before: + Save g:ale_c_parse_makefile + Save g:ale_history_enabled + + let g:ale_c_parse_makefile = 0 + let g:ale_history_enabled = 0 + + let g:get_cflags_return_value = '' + let g:executable_map = {} + + runtime autoload/ale/c.vim + runtime autoload/ale/engine.vim + + function! ale#engine#IsExecutable(buffer, executable) abort + return has_key(g:executable_map, a:executable) + endfunction + + function! ale#c#GetCFlags(buffer, output) abort + return g:get_cflags_return_value + endfunction + + call ale#assert#SetUpLinterTest('cpp', 'cc') + + let b:command_tail = ' -S -x c++' + \ . ' -o ' . (has('win32') ? 'nul': '/dev/null') + \ . ' -iquote %s:h' + \ . ' -std=c++14 -Wall -' + +After: + unlet! g:get_cflags_return_value + unlet! g:executable_map + unlet! b:command_tail + + runtime autoload/ale/c.vim + runtime autoload/ale/engine.vim + + call ale#assert#TearDownLinterTest() + +Execute(clang++ should be used instead of gcc, if available): + let g:executable_map = {'clang++': 1} + + AssertLinter 'clang++', [ale#Escape('clang++') . b:command_tail] + +Execute(The executable should be configurable): + AssertLinter 'gcc', [ale#Escape('gcc') . b:command_tail] + + let b:ale_cpp_cc_executable = 'foobar' + + AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail] + +Execute(The -std flag should be replaced by parsed C flags): + let b:command_tail = substitute(b:command_tail, 'c++14', 'c++11 ', '') + let g:get_cflags_return_value = '-std=c++11' + + AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail diff --git a/vim-config/plugins/ale/test/linter/test_cpp_ccls.vader b/vim-config/plugins/ale/test/linter/test_cpp_ccls.vader new file mode 100644 index 00000000..12aa30e3 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cpp_ccls.vader @@ -0,0 +1,69 @@ +" Author: Ye Jingchen , Ben Falconer +" Description: A language server for C++ + +Before: + call ale#assert#SetUpLinterTest('cpp', 'ccls') + + Save b:ale_c_build_dir_names + Save b:ale_cpp_ccls_executable + Save b:ale_cpp_ccls_init_options + +After: + call ale#assert#TearDownLinterTest() + +Execute(The project root should be detected correctly using compile_commands.json file): + call ale#test#SetFilename(tempname() . '/dummy.cpp') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ccls/with_compile_commands_json/dummy.cpp') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ccls/with_compile_commands_json') + +Execute(The project root should be detected correctly using .ccls file): + call ale#test#SetFilename(tempname() . '/dummy.cpp') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ccls/with_ccls/dummy.cpp') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ccls/with_ccls') + +Execute(The project root should be detected correctly using .ccls-root file): + call ale#test#SetFilename(tempname() . '/dummy.cpp') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ccls/with_ccls-root/dummy.cpp') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ccls/with_ccls-root') + +Execute(The executable should be configurable): + AssertLinter 'ccls', ale#Escape('ccls') + + let b:ale_cpp_ccls_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + +Execute(The initialization options should be configurable): + AssertLSPOptions {} + + let b:ale_cpp_ccls_init_options = { 'cacheDirectory': '/tmp/ccls' } + + AssertLSPOptions { 'cacheDirectory': '/tmp/ccls' } + +Execute(The compile command database should be detected correctly): + call ale#test#SetFilename('../test-files/ccls/with_ccls/dummy.c') + + AssertLSPOptions {} + + call ale#test#SetFilename('../test-files/ccls/with_compile_commands_json/dummy.c') + + AssertLSPOptions { 'compilationDatabaseDirectory': + \ ale#path#Simplify(g:dir . '/../test-files/ccls/with_compile_commands_json') } + + call ale#test#SetFilename('../test-files/ccls/with_build_dir/dummy.c') + let b:ale_c_build_dir_names = ['unusual_build_dir_name'] + + AssertLSPOptions { 'compilationDatabaseDirectory': + \ ale#path#Simplify(g:dir . '/../test-files/ccls/with_build_dir/unusual_build_dir_name') } diff --git a/vim-config/plugins/ale/test/linter/test_cpp_clangcheck.vader b/vim-config/plugins/ale/test/linter/test_cpp_clangcheck.vader new file mode 100644 index 00000000..188141d5 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cpp_clangcheck.vader @@ -0,0 +1,35 @@ +Before: + call ale#assert#SetUpLinterTest('cpp', 'clangcheck') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'clang-check', + \ ale#Escape('clang-check') + \ . ' -analyze %s --extra-arg=-Xclang --extra-arg=-analyzer-output=text --extra-arg=-fno-color-diagnostics' + + let b:ale_cpp_clangcheck_executable = 'foobar' + + " The extra arguments in the command are used to prevent .plist files from + " being generated. + AssertLinter 'foobar', + \ ale#Escape('foobar') + \ . ' -analyze %s --extra-arg=-Xclang --extra-arg=-analyzer-output=text --extra-arg=-fno-color-diagnostics' + +Execute(The options should be configurable): + let b:ale_cpp_clangcheck_options = '--something' + + AssertLinter 'clang-check', + \ ale#Escape('clang-check') + \ . ' -analyze %s' + \ . ' --extra-arg=-Xclang --extra-arg=-analyzer-output=text --extra-arg=-fno-color-diagnostics' + \ . ' --something' + +Execute(The build directory should be used when set): + let b:ale_cpp_clangcheck_options = '--something' + let b:ale_c_build_dir = '/foo/bar' + + AssertLinter 'clang-check', + \ ale#Escape('clang-check') + \ . ' -analyze %s --something -p ' . ale#Escape('/foo/bar') diff --git a/vim-config/plugins/ale/test/linter/test_cpp_clazy.vader b/vim-config/plugins/ale/test/linter/test_cpp_clazy.vader new file mode 100644 index 00000000..e5a81b8f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cpp_clazy.vader @@ -0,0 +1,56 @@ +Before: + call ale#assert#SetUpLinterTest('cpp', 'clazy') + call ale#test#SetFilename('test.cpp') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The clazy command default should be correct): + AssertLinter 'clazy-standalone', + \ ale#Escape('clazy-standalone') . ' -checks=' . ale#Escape('level1') . ' %s' + +Execute(You should be able to remove the -checks option for clazy-standalone): + let b:ale_cpp_clazy_checks = [] + + AssertLinter 'clazy-standalone', ale#Escape('clazy-standalone') . ' %s' + +Execute(You should be able to set other checks for clazy-standalone): + let b:ale_cpp_clazy_checks = ['level2', 'level3'] + + AssertLinter 'clazy-standalone', + \ ale#Escape('clazy-standalone') + \ . ' -checks=' . ale#Escape('level2,level3') . ' %s' + +Execute(You should be able to manually set compiler flags for clazy-standalone): + let b:ale_cpp_clazy_options = '-qt4-compat' + + AssertLinter 'clazy-standalone', + \ ale#Escape('clazy-standalone') . ' -checks=' . ale#Escape('level1') . ' -qt4-compat' . ' %s' + \ +Execute(The build directory should be configurable): + let b:ale_c_build_dir = '/foo/bar' + + AssertLinter 'clazy-standalone', + \ ale#Escape('clazy-standalone') + \ . ' -checks=' . ale#Escape('level1') . ' -p ' . ale#Escape('/foo/bar') . ' %s' + +Execute(The build directory should be used for header files): + call ale#test#SetFilename('test.h') + + let b:ale_c_build_dir = '/foo/bar' + + AssertLinter 'clazy-standalone', + \ ale#Escape('clazy-standalone') + \ . ' -checks=' . ale#Escape('level1') . ' -p ' . ale#Escape('/foo/bar') . ' %s' + + call ale#test#SetFilename('test.hpp') + + AssertLinter 'clazy-standalone', + \ ale#Escape('clazy-standalone') + \ . ' -checks=' . ale#Escape('level1') . ' -p ' . ale#Escape('/foo/bar') . ' %s' + +Execute(The executable should be configurable): + let b:ale_cpp_clazy_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -checks=' . ale#Escape('level1') . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_cpp_cppcheck.vader b/vim-config/plugins/ale/test/linter/test_cpp_cppcheck.vader new file mode 100644 index 00000000..62195803 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cpp_cppcheck.vader @@ -0,0 +1,66 @@ +Before: + call ale#assert#SetUpLinterTest('cpp', 'cppcheck') + let b:command_tail = ' -q --language=c++ --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') . ' --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t' + +After: + " Remove a test file we might open for some tests. + if &buftype != 'nofile' + :q! + set buftype=nofile + endif + + unlet! b:command_tail + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'cppcheck', ale#Escape('cppcheck') . b:command_tail + + let b:ale_cpp_cppcheck_executable = 'foobar' + + AssertLinterCwd '' + AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail + +Execute(cppcheck for C++ should detect compile_commands.json files): + call ale#test#SetFilename('../test-files/cppcheck/one/foo.cpp') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/cppcheck/one') + AssertLinter 'cppcheck', ale#Escape('cppcheck') + \ . ' -q --language=c++' + \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') + \ . ' --project=' . ale#Escape('compile_commands.json') + \ . ' --enable=style %t' + +Execute(cppcheck for C++ should detect compile_commands.json files in build directories): + call ale#test#SetFilename('../test-files/cppcheck/with_build_dir/foo.cpp') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/cppcheck/with_build_dir') + AssertLinter 'cppcheck', ale#Escape('cppcheck') + \ . ' -q --language=c++' + \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') + \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) + \ . ' --enable=style %t' + +Execute(cppcheck for C++ should include file dir if compile_commands.json file is not found): + call ale#test#SetFilename('../test-files/cppcheck/foo.cpp') + + AssertLinter 'cppcheck', + \ ale#Escape('cppcheck') + \ . ' -q --language=c++' + \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') + \ . ' --enable=style' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/cppcheck')) + \ . ' %t' + +Execute(cppcheck for C++ should ignore compile_commands.json file if buffer is modified): + call ale#test#SetFilename('../test-files/cppcheck/one/foo.cpp') + + set buftype= + set modified + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/cppcheck/one') + AssertLinter 'cppcheck', ale#Escape('cppcheck') + \ . ' -q --language=c++' + \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') + \ . ' --enable=style' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/cppcheck/one')) + \ . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_cpp_cquery.vader b/vim-config/plugins/ale/test/linter/test_cpp_cquery.vader new file mode 100644 index 00000000..f638e401 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cpp_cquery.vader @@ -0,0 +1,40 @@ +" Author: Ben Falconer +" Description: A language server for C++ + +Before: + call ale#assert#SetUpLinterTest('cpp', 'cquery') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The project root should be detected correctly using compile_commands.json file): + call ale#test#SetFilename(tempname() . '/dummy.cpp') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/cquery/dummy.cpp') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/cquery') + +Execute(The project root should be detected correctly using .cquery file): + call ale#test#SetFilename(tempname() . '/dummy.cpp') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/cquery/with_cquery/dummy.cpp') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/cquery/with_cquery') + +Execute(The executable should be configurable): + AssertLinter 'cquery', ale#Escape('cquery') + + let b:ale_cpp_cquery_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + +Execute(The cache directory should be configurable): + AssertLSPOptions {'cacheDirectory': expand('$HOME/.cache/cquery')} + + let b:ale_cpp_cquery_cache_directory = '/foo/bar' + + AssertLSPOptions {'cacheDirectory': '/foo/bar'} diff --git a/vim-config/plugins/ale/test/linter/test_cpp_flawfinder.vader b/vim-config/plugins/ale/test/linter/test_cpp_flawfinder.vader new file mode 100644 index 00000000..3f4067ea --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cpp_flawfinder.vader @@ -0,0 +1,26 @@ +Before: + call ale#assert#SetUpLinterTest('cpp', 'flawfinder') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The flawfinder command should be correct): + AssertLinter 'flawfinder', + \ ale#Escape('flawfinder') . ' -CDQS --minlevel=1 %t' + +Execute(The minlevel of flawfinder should be configurable): + let b:ale_cpp_flawfinder_minlevel = 8 + + AssertLinter 'flawfinder', + \ ale#Escape('flawfinder') . ' -CDQS --minlevel=8 %t' + +Execute(Additional flawfinder options should be configurable): + let b:ale_cpp_flawfinder_options = ' --foobar' + + AssertLinter 'flawfinder', + \ ale#Escape('flawfinder') . ' -CDQS --foobar --minlevel=1 %t' + +Execute(The flawfinder exectable should be configurable): + let b:ale_cpp_flawfinder_executable = 'foo/bar' + + AssertLinter 'foo/bar', ale#Escape('foo/bar') . ' -CDQS --minlevel=1 %t' diff --git a/vim-config/plugins/ale/test/linter/test_cpplint.vader b/vim-config/plugins/ale/test/linter/test_cpplint.vader new file mode 100644 index 00000000..d5fd457b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cpplint.vader @@ -0,0 +1,17 @@ +Before: + call ale#assert#SetUpLinterTest('cpp', 'cpplint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'cpplint', ale#Escape('cpplint') . ' %s' + + let b:ale_cpp_cpplint_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' %s' + +Execute(The options should be configurable): + let b:ale_cpp_cpplint_options = '--something' + + AssertLinter 'cpplint', ale#Escape('cpplint') . ' --something %s' diff --git a/vim-config/plugins/ale/test/linter/test_cs_csc.vader b/vim-config/plugins/ale/test/linter/test_cs_csc.vader new file mode 100644 index 00000000..28d0304a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cs_csc.vader @@ -0,0 +1,42 @@ +Before: + call ale#assert#SetUpLinterTest('cs', 'csc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The csc linter should return the correct default command): + AssertLinterCwd expand('%:p:h') + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + +Execute(The options should be be used in the command): + let g:ale_cs_csc_options = '' + + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + +Execute(The souce path should be be used in the command): + let g:ale_cs_csc_source = '../foo/bar' + + AssertLinterCwd '../foo/bar' + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + +Execute(The list of search pathes for assemblies should be be used in the command if not empty): + let g:ale_cs_csc_assembly_path = ['/usr/lib/mono', '../foo/bar'] + + AssertLinter 'csc', 'csc /unsafe' + \ . ' /lib:' . ale#Escape('/usr/lib/mono') . ',' . ale#Escape('../foo/bar') + \ . ' /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + + let g:ale_cs_csc_assembly_path = [] + + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + +Execute(The list of assemblies should be be used in the command if not empty): + let g:ale_cs_csc_assemblies = ['foo.dll', 'bar.dll'] + + AssertLinter 'csc', 'csc /unsafe' + \ . ' /r:' . ale#Escape('foo.dll') . ',' . ale#Escape('bar.dll') + \ . ' /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + + let g:ale_cs_csc_assemblies = [] + + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') diff --git a/vim-config/plugins/ale/test/linter/test_cs_mcs.vader b/vim-config/plugins/ale/test/linter/test_cs_mcs.vader new file mode 100644 index 00000000..dbebd106 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cs_mcs.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('cs', 'mcs') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'mcs', 'mcs -unsafe --parse %t' + +Execute(The options should be be used in the command): + let b:ale_cs_mcs_options = '-pkg:dotnet' + + AssertLinter 'mcs', 'mcs -unsafe --parse -pkg:dotnet %t' diff --git a/vim-config/plugins/ale/test/linter/test_cs_mcsc.vader b/vim-config/plugins/ale/test/linter/test_cs_mcsc.vader new file mode 100644 index 00000000..e784cf15 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cs_mcsc.vader @@ -0,0 +1,42 @@ +Before: + call ale#assert#SetUpLinterTest('cs', 'mcsc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The mcsc linter should return the correct default command): + AssertLinterCwd expand('%:p:h') + AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + +Execute(The options should be be used in the command): + let g:ale_cs_mcsc_options = '-pkg:dotnet' + + AssertLinter 'mcs', 'mcs -unsafe -pkg:dotnet -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + +Execute(The souce path should be be used in the command): + let g:ale_cs_mcsc_source = '../foo/bar' + + AssertLinterCwd '../foo/bar' + AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + +Execute(The list of search pathes for assemblies should be be used in the command if not empty): + let g:ale_cs_mcsc_assembly_path = ['/usr/lib/mono', '../foo/bar'] + + AssertLinter 'mcs', 'mcs -unsafe' + \ . ' -lib:' . ale#Escape('/usr/lib/mono') . ',' . ale#Escape('../foo/bar') + \ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + + let g:ale_cs_mcsc_assembly_path = [] + + AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + +Execute(The list of assemblies should be be used in the command if not empty): + let g:ale_cs_mcsc_assemblies = ['foo.dll', 'bar.dll'] + + AssertLinter 'mcs', 'mcs -unsafe' + \ . ' -r:' . ale#Escape('foo.dll') . ',' . ale#Escape('bar.dll') + \ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + + let g:ale_cs_mcsc_assemblies = [] + + AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') diff --git a/vim-config/plugins/ale/test/linter/test_cucumber.vader b/vim-config/plugins/ale/test/linter/test_cucumber.vader new file mode 100644 index 00000000..6a7851ef --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cucumber.vader @@ -0,0 +1,18 @@ +Before: + call ale#assert#SetUpLinterTest('cucumber', 'cucumber') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Should require the nearest features dir, if one is found): + call ale#test#SetFilename('../test-files/cucumber/features/cuke.feature') + + AssertLinter 'cucumber', + \ 'cucumber --dry-run --quiet --strict --format=json ' + \ . '-r ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/cucumber/features/')) . ' %t' + +Execute(Should require nothing if no features dir is found): + call ale#test#SetFilename('something/without/a/features/dir') + + AssertLinter 'cucumber', + \ 'cucumber --dry-run --quiet --strict --format=json %t' diff --git a/vim-config/plugins/ale/test/linter/test_cuda_nvcc.vader b/vim-config/plugins/ale/test/linter/test_cuda_nvcc.vader new file mode 100644 index 00000000..4578d052 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cuda_nvcc.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('cuda', 'nvcc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'nvcc', + \ ale#Escape('nvcc') . ' -cuda -std=c++11 %s -o ' . g:ale#util#nul_file + + let b:ale_cuda_nvcc_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -cuda -std=c++11 %s -o ' . g:ale#util#nul_file + +Execute(The options should be configurable): + let g:ale_cuda_nvcc_options = '--foobar' + + AssertLinter 'nvcc', + \ ale#Escape('nvcc') . ' -cuda --foobar %s -o ' . g:ale#util#nul_file diff --git a/vim-config/plugins/ale/test/linter/test_cypher_cypher_lint.vader b/vim-config/plugins/ale/test/linter/test_cypher_cypher_lint.vader new file mode 100644 index 00000000..6b64dc1f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_cypher_cypher_lint.vader @@ -0,0 +1,8 @@ +Before: + call ale#assert#SetUpLinterTest('cypher', 'cypher_lint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command and executable should be correct): + AssertLinter 'cypher-lint', 'cypher-lint' diff --git a/vim-config/plugins/ale/test/linter/test_d_dls.vader b/vim-config/plugins/ale/test/linter/test_d_dls.vader new file mode 100644 index 00000000..156ebf66 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_d_dls.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('d', 'dls') + + Save &filetype + let &filetype = 'd' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'd' + +Execute(The default executable should be correct): + AssertLinter 'dls', 'dls' + +Execute(The executable should be configurable): + let g:ale_d_dls_executable = 'foobar' + + AssertLinter 'foobar', 'foobar' diff --git a/vim-config/plugins/ale/test/linter/test_dart_analysis_server.vader b/vim-config/plugins/ale/test/linter/test_dart_analysis_server.vader new file mode 100644 index 00000000..1754109a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_dart_analysis_server.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('dart', 'analysis_server') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'dart', ale#Escape('dart') + \ . ' ./snapshots/analysis_server.dart.snapshot --lsp' + +Execute(The executable should be configurable): + let g:ale_dart_analysis_server_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + \ . ' ./snapshots/analysis_server.dart.snapshot --lsp' diff --git a/vim-config/plugins/ale/test/linter/test_dart_language_server.vader b/vim-config/plugins/ale/test/linter/test_dart_language_server.vader new file mode 100644 index 00000000..5567f271 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_dart_language_server.vader @@ -0,0 +1,8 @@ +Before: + call ale#assert#SetUpLinterTest('dart', 'language_server') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'dart_language_server', ale#Escape('dart_language_server') diff --git a/vim-config/plugins/ale/test/linter/test_dartanalyzer.vader b/vim-config/plugins/ale/test/linter/test_dartanalyzer.vader new file mode 100644 index 00000000..7275b187 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_dartanalyzer.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('dart', 'dartanalyzer') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command and executable should be correct): + AssertLinter 'dartanalyzer', ale#Escape('dartanalyzer') . ' %s' + +Execute(The executable should be configurable): + let g:ale_dart_dartanalyzer_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' %s' + +Execute(The .packages file should be set if detected): + call ale#test#SetFilename('../test-files/dart/foo') + + AssertLinter 'dartanalyzer', ale#Escape('dartanalyzer') + \ . ' --packages ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/dart/.packages')) + \ . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_desktop_file_validate.vader b/vim-config/plugins/ale/test/linter/test_desktop_file_validate.vader new file mode 100644 index 00000000..4a49057b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_desktop_file_validate.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('desktop', 'desktop_file_validate') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'desktop-file-validate', + \ ale#Escape('desktop-file-validate') . ' %t' + +Execute(Extra options should work): + let b:ale_desktop_desktop_file_validate_options = '--warn-kde' + + AssertLinter 'desktop-file-validate', + \ ale#Escape('desktop-file-validate') . ' --warn-kde %t' diff --git a/vim-config/plugins/ale/test/linter/test_dialyxir.vader b/vim-config/plugins/ale/test/linter/test_dialyxir.vader new file mode 100644 index 00000000..250ffefd --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_dialyxir.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpLinterTest('elixir', 'dialyxir') + call ale#test#SetFilename('../test-files/elixir/mix_project/lib/app.ex') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Builds dialyxir command with a normal project): + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elixir/mix_project') + AssertLinter 'mix', 'mix help dialyzer && mix dialyzer' + +Execute(Builds dialyxir command with an umbrella project): + call ale#test#SetFilename('../test-files/elixir/umbrella_project/apps/mix_project/lib/app.ex') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elixir/umbrella_project') + AssertLinter 'mix', 'mix help dialyzer && mix dialyzer' diff --git a/vim-config/plugins/ale/test/linter/test_dmd_commandline.vader b/vim-config/plugins/ale/test/linter/test_dmd_commandline.vader new file mode 100644 index 00000000..609fc073 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_dmd_commandline.vader @@ -0,0 +1,96 @@ +Before: + runtime ale_linters/d/dmd.vim + +After: + call ale#linter#Reset() + +Execute(DMD command line should be correct with imports): + AssertEqual + \ 'dmd ' . + \ '-I' . ale#Escape('source') . ' ' . + \ '-I' . ale#Escape('/prefix/include/d') . ' ' . + \ '-I' . ale#Escape('/home/user/.dub/packages/pkg-0.0.1/pkg/src') . ' ' . + \ ' ' . + \ ' ' . + \ ' ' . + \ '-o- -wi -vcolumns -c %t', + \ ale_linters#d#dmd#DMDCommand(bufnr(''), [ + \ 'source', + \ '/prefix/include/d', + \ '/home/user/.dub/packages/pkg-0.0.1/pkg/src', + \ '', + \ '', + \ '', + \ '', + \ '', + \ '', + \ ], {}) + +Execute(DMD command line should be correct with imports and version): + AssertEqual + \ 'dmd ' . + \ '-I' . ale#Escape('source') . ' ' . + \ '-I' . ale#Escape('/prefix/include/d') . ' ' . + \ '-I' . ale#Escape('/home/user/.dub/packages/pkg-0.0.1/pkg/src') . ' ' . + \ ' ' . + \ '-version=' . ale#Escape('SOME_VERSION') . ' ' . + \ ' ' . + \ '-o- -wi -vcolumns -c %t', + \ ale_linters#d#dmd#DMDCommand(bufnr(''), [ + \ 'source', + \ '/prefix/include/d', + \ '/home/user/.dub/packages/pkg-0.0.1/pkg/src', + \ '', + \ '', + \ '', + \ 'SOME_VERSION', + \ '', + \ '', + \ ], {}) + +Execute(DMD command line should be correct): + AssertEqual + \ 'dmd ' . + \ '-I' . ale#Escape('source') . ' ' . + \ '-I' . ale#Escape('/prefix/include/d') . ' ' . + \ '-I' . ale#Escape('/home/user/.dub/packages/pkg-0.0.1/pkg/src') . ' ' . + \ '-J' . ale#Escape('views') . ' ' . + \ '-version=' . ale#Escape('SOME_VERSION') . ' ' . + \ '-version=' . ale#Escape('SOME_OTHER_VERSION') . ' ' . + \ '-debug=' . ale#Escape('SomeFeature') . ' ' . + \ '-o- -wi -vcolumns -c %t', + \ ale_linters#d#dmd#DMDCommand(bufnr(''), [ + \ 'source', + \ '/prefix/include/d', + \ '/home/user/.dub/packages/pkg-0.0.1/pkg/src', + \ '', + \ 'views', + \ '', + \ 'SOME_VERSION', + \ 'SOME_OTHER_VERSION', + \ '', + \ 'SomeFeature', + \ ], {}) + +Execute(DMD command line should be correct with CR): + " on windows, the function is called with carriage return + AssertEqual + \ 'dmd ' . + \ '-I' . ale#Escape('source') . ' ' . + \ '-I' . ale#Escape('C:\prefix\include\d') . ' ' . + \ '-I' . ale#Escape('C:\Users\user\AppData\Local\Dub\packages\pkg-0.0.1\pkg\src') . ' ' . + \ ' ' . + \ ' ' . + \ ' ' . + \ '-o- -wi -vcolumns -c %t', + \ ale_linters#d#dmd#DMDCommand(bufnr(''), [ + \ "source\r", + \ "C:\\prefix\\include\\d\r", + \ "C:\\Users\\user\\AppData\\Local\\Dub\\packages\\pkg-0.0.1\\pkg\\src\r", + \ "\r", + \ "\r", + \ "\r", + \ "\r", + \ "\r", + \ "\r", + \ ], {}) diff --git a/vim-config/plugins/ale/test/linter/test_dockerfile_lint.vader b/vim-config/plugins/ale/test/linter/test_dockerfile_lint.vader new file mode 100644 index 00000000..abc32e0d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_dockerfile_lint.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('dockerfile', 'dockerfile_lint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'dockerfile_lint', ale#Escape('dockerfile_lint') . ' -p -j -f %t' + +Execute(The executable should be configurable): + let b:ale_dockerfile_dockerfile_lint_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' -p -j -f %t' + +Execute(The options should be configurable): + let b:ale_dockerfile_dockerfile_lint_options = '-r additional.yaml' + + AssertLinter 'dockerfile_lint', ale#Escape('dockerfile_lint') . ' -r additional.yaml -p -j -f %t' + diff --git a/vim-config/plugins/ale/test/linter/test_dogma.vader b/vim-config/plugins/ale/test/linter/test_dogma.vader new file mode 100644 index 00000000..c8b599af --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_dogma.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpLinterTest('elixir', 'dogma') + call ale#test#SetFilename('../test-files/elixir/mix_project/lib/app.ex') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Builds dogma command with a normal project): + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elixir/mix_project') + AssertLinter 'mix', 'mix help dogma && mix dogma %s --format=flycheck' + +Execute(Builds dogma command with an umbrella project): + call ale#test#SetFilename('../test-files/elixir/umbrella_project/apps/mix_project/lib/app.ex') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elixir/umbrella_project') + AssertLinter 'mix', 'mix help dogma && mix dogma %s --format=flycheck' diff --git a/vim-config/plugins/ale/test/linter/test_eclipselsp.vader b/vim-config/plugins/ale/test/linter/test_eclipselsp.vader new file mode 100644 index 00000000..6bbc4053 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_eclipselsp.vader @@ -0,0 +1,111 @@ +Before: + call ale#assert#SetUpLinterTest('java', 'eclipselsp') + call ale#test#SetFilename('dummy.java') + + let b:ale_java_eclipselsp_path = '/home/user/eclipse.dst.ls' + + let b:cfg = ale#path#Simplify(g:dir . '/../config_linux') + + if has('win32') + let b:cfg = ale#path#Simplify(g:dir . '/../config_win') + elseif has('macunix') + let b:cfg = ale#path#Simplify(g:dir . '/../config_mac') + endif + +After: + unlet! b:ale_java_eclipselsp_path + unlet! b:cfg + + call ale#assert#TearDownLinterTest() + +Execute(VersionCheck should return correct version): + + " OpenJDK Java 1.8 + AssertEqual [1, 8, 0], ale_linters#java#eclipselsp#VersionCheck([ + \ 'openjdk version "1.8.0_191"', + \ 'OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-0ubuntu0.18.04.1-b12)', + \ 'OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)' + \]) + + " OpenJDK Java 10 + AssertEqual [10, 0, 2], ale_linters#java#eclipselsp#VersionCheck([ + \ 'openjdk version "10.0.2" 2018-07-17', + \ 'OpenJDK Runtime Environment (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4)', + \ 'OpenJDK 64-Bit Server VM (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4, mixed mode)' + \]) + + " Oracle Java 1.8 + AssertEqual [1, 8, 0], ale_linters#java#eclipselsp#VersionCheck([ + \ 'java version "1.8.0_161"', + \ 'Java(TM) SE Runtime Environment (build 1.8.0_161-b12)', + \ 'Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)' + \]) + + " Oracle Java 10 + AssertEqual [10, 0, 1], ale_linters#java#eclipselsp#VersionCheck([ + \ 'java version "10.0.1" 2018-04-17', + \ 'Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)', + \ 'Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)' + \]) + + AssertEqual [], ale_linters#java#eclipselsp#VersionCheck(['x']) + + AssertEqual [], ale_linters#java#eclipselsp#VersionCheck([]) + +Execute(The eclipselsp callback should return the correct default value): + let cmd = [ ale#Escape('java'), + \ '', + \ '-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(''), + \ '-configuration', + \ ale#Escape(b:cfg), + \ '-data', + \ ale#Escape(ale#path#Simplify('')) + \] + AssertLinter 'java', join(cmd, ' ') + +Execute(The eclipselsp callback should allow custom executable): + let b:ale_java_eclipselsp_executable='/bin/foobar' + let cmd = [ ale#Escape('/bin/foobar'), + \ '', + \ '-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(''), + \ '-configuration', + \ ale#Escape(b:cfg), + \ '-data', + \ ale#Escape(ale#path#Simplify('')) + \] + AssertLinter '/bin/foobar', join(cmd, ' ') + +Execute(The eclipselsp callback should allow custom configuration path and javaagent): + let b:ale_java_eclipselsp_config_path = '/home/config' + let b:ale_java_eclipselsp_javaagent = '/home/lombok.jar /home/lombok2.jar' + let cmd = [ ale#Escape('java'), + \ ale#Escape('-javaagent:/home/lombok.jar'), + \ ale#Escape('-javaagent:/home/lombok2.jar'), + \ '-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(''), + \ '-configuration', + \ ale#Escape(ale#path#Simplify('/home/config')), + \ '-data', + \ ale#Escape(ale#path#Simplify('')) + \] + AssertLinter 'java', join(cmd, ' ') diff --git a/vim-config/plugins/ale/test/linter/test_elixir_credo.vader b/vim-config/plugins/ale/test/linter/test_elixir_credo.vader new file mode 100644 index 00000000..9c639c57 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_elixir_credo.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('elixir', 'credo') + call ale#test#SetFilename('../test-files/elixir/mix_project/lib/app.ex') + + +After: + unlet! g:ale_elixir_credo_strict + + call ale#assert#TearDownLinterTest() + +Execute(Builds credo command with normal project): + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elixir/mix_project') + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with umbrella project): + call ale#test#SetFilename('../test-files/elixir/umbrella_project/apps/mix_project/lib/app.ex') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elixir/umbrella_project') + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with --strict mode when set to 1): + let g:ale_elixir_credo_strict = 1 + + AssertLinter 'mix', + \ 'mix help credo && mix credo --strict --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with suggest mode by default): + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with suggest mode when set to 0): + let g:ale_elixir_credo_strict = 0 + + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with a custom config file): + let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs' + + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s' diff --git a/vim-config/plugins/ale/test/linter/test_elixir_ls.vader b/vim-config/plugins/ale/test/linter/test_elixir_ls.vader new file mode 100644 index 00000000..84e805ba --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_elixir_ls.vader @@ -0,0 +1,34 @@ +Before: + call ale#assert#SetUpLinterTest('elixir', 'elixir_ls') + +After: + call ale#assert#TearDownLinterTest() + +Execute(should set correct defaults): + if has('win32') + AssertLinter 'elixir-ls\language_server.bat', 'elixir-ls\language_server.bat' + else + AssertLinter 'elixir-ls/language_server.sh', 'elixir-ls/language_server.sh' + endif + +Execute(should configure elixir-ls release location): + let b:ale_elixir_elixir_ls_release = 'boo' + + if has('win32') + AssertLinter 'boo\language_server.bat', 'boo\language_server.bat' + else + AssertLinter 'boo/language_server.sh', 'boo/language_server.sh' + endif + +Execute(should set correct LSP values): + call ale#test#SetFilename('../test-files/elixir/umbrella_project/apps/app1/lib/app.ex') + + AssertLSPLanguage 'elixir' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/elixir/umbrella_project') + +Execute(should accept configuration settings): + AssertLSPConfig {} + let b:ale_elixir_elixir_ls_config = {'elixirLS': {'dialyzerEnabled': v:false}} + AssertLSPConfig {'elixirLS': {'dialyzerEnabled': v:false}} diff --git a/vim-config/plugins/ale/test/linter/test_elixir_mix.vader b/vim-config/plugins/ale/test/linter/test_elixir_mix.vader new file mode 100644 index 00000000..a04bee55 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_elixir_mix.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('elixir', 'mix') + call ale#test#SetFilename('../test-files/elixir/mix_project/lib/app.ex') + let g:env_prefix = ale#Env('MIX_BUILD_PATH', 'TEMP_DIR') + +After: + unlet! g:env_prefix + + call ale#assert#TearDownLinterTest() + +Execute(The default mix command should be correct): + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elixir/mix_project') + AssertLinter 'mix', g:env_prefix . 'mix compile %s' + +Execute(Build mix commands with an umbrella root): + call ale#test#SetFilename('../test-files/elixir/umbrella_project/apps/mix_project/lib/app.ex') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elixir/umbrella_project') + AssertLinter 'mix', g:env_prefix . 'mix compile %s' diff --git a/vim-config/plugins/ale/test/linter/test_elm_ls.vader b/vim-config/plugins/ale/test/linter/test_elm_ls.vader new file mode 100644 index 00000000..98b01c96 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_elm_ls.vader @@ -0,0 +1,29 @@ +Before: + call ale#assert#SetUpLinterTest('elm', 'elm_ls') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + call ale#test#SetFilename('../test-files/elm/newapp/src/Main.elm') + + AssertLinter 'elm-language-server', ale#Escape('elm-language-server') . ' --stdio' + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/elm/newapp/src/Main.elm') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/elm/newapp') + +Execute(Should let users configure a global executable and override local paths): + call ale#test#SetFilename('../test-files/elm/newapp/src/Main.elm') + + let g:ale_elm_ls_executable = '/path/to/custom/elm-language-server' + let g:ale_elm_ls_use_global = 1 + + AssertLinter '/path/to/custom/elm-language-server', + \ ale#Escape('/path/to/custom/elm-language-server') . ' --stdio' + +Execute(The language should be correct): + AssertLSPLanguage 'elm' diff --git a/vim-config/plugins/ale/test/linter/test_elm_make.vader b/vim-config/plugins/ale/test/linter/test_elm_make.vader new file mode 100644 index 00000000..90e0c920 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_elm_make.vader @@ -0,0 +1,63 @@ +Before: + call ale#assert#SetUpLinterTest('elm', 'make') + +After: + unlet! g:executable + + call ale#assert#TearDownLinterTest() + +Execute(should get valid executable with default params): + call ale#test#SetFilename('../test-files/elm/newapp/src/Main.elm') + + let g:executable = ale#path#Simplify(g:dir . '/../test-files/elm/newapp/node_modules/.bin/elm') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elm/newapp') + AssertLinter g:executable, + \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t' + +Execute(should get elm-test executable for test code with elm >= 0.19): + call ale#test#SetFilename('../test-files/elm/newapp/tests/TestSuite.elm') + + let g:executable = ale#path#Simplify(g:dir . '/../test-files/elm/newapp/node_modules/.bin/elm-test') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elm/newapp') + AssertLinter g:executable, + \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null --compiler ' + \ . ale#path#Simplify(g:dir . '/../test-files/elm/newapp/node_modules/.bin/elm') . ' %t' + +Execute(should fallback to elm executable with elm >= 0.19): + call ale#test#SetFilename('../test-files/elm/newapp-notests/tests/TestMain.elm') + + let g:executable = ale#path#Simplify(g:dir . '/../test-files/elm/newapp-notests/node_modules/.bin/elm') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elm/newapp-notests') + AssertLinter g:executable, + \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t' + +Execute(should get plain elm executable for test code with elm < 0.19): + call ale#test#SetFilename('../test-files/elm/oldapp/tests/TestSuite.elm') + + let g:executable = ale#path#Simplify(g:dir . '/../test-files/elm/oldapp/node_modules/.bin/elm') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elm/oldapp') + AssertLinter g:executable, + \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t' + +Execute(should get valid executable with 'use_global' params): + let g:ale_elm_make_use_global = 1 + + call ale#test#SetFilename('../test-files/elm/newapp/src/Main.elm') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elm/newapp') + AssertLinter 'elm', + \ ale#Escape('elm') . ' make --report=json --output=/dev/null %t' + +Execute(should get valid executable with 'use_global' and 'executable' params): + let g:ale_elm_make_executable = 'other-elm' + let g:ale_elm_make_use_global = 1 + + call ale#test#SetFilename('../test-files/elm/newapp/src/Main.elm') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/elm/newapp') + AssertLinter 'other-elm', + \ ale#Escape('other-elm') . ' make --report=json --output=/dev/null %t' diff --git a/vim-config/plugins/ale/test/linter/test_embertemplatelint.vader b/vim-config/plugins/ale/test/linter/test_embertemplatelint.vader new file mode 100644 index 00000000..97687d29 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_embertemplatelint.vader @@ -0,0 +1,17 @@ +Before: + call ale#assert#SetUpLinterTest('handlebars', 'embertemplatelint') + + GivenCommandOutput ['1.6.0'] + +After: + call ale#assert#TearDownLinterTest() + +Execute(ember-template-lint executables runs the right command): + AssertLinter 'ember-template-lint', + \ ale#Escape('ember-template-lint') . ' --json --filename %s' + +Execute(old ember-template-lint executables runs the right command): + GivenCommandOutput [] + + AssertLinter 'ember-template-lint', + \ ale#Escape('ember-template-lint') . ' --json %t' diff --git a/vim-config/plugins/ale/test/linter/test_erb.vader b/vim-config/plugins/ale/test/linter/test_erb.vader new file mode 100644 index 00000000..c64c7ba5 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_erb.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpLinterTest('eruby', 'erb') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should not contain any filter code by default): + call ale#test#SetFilename('../test-files/ruby/not_a_rails_app/file.rb') + + AssertLinter 'erb', 'erb -P -T - -x %t | ruby -c' + +Execute(Executable should filter invalid eRuby when inside a Rails project): + call ale#test#SetFilename('../test-files/ruby/valid_rails_app/app/views/my_great_view.html.erb') + + AssertLinter 'erb', + \ 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src') . '< %t | ruby -c' diff --git a/vim-config/plugins/ale/test/linter/test_erblint.vader b/vim-config/plugins/ale/test/linter/test_erblint.vader new file mode 100644 index 00000000..147b5965 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_erblint.vader @@ -0,0 +1,26 @@ +Before: + call ale#assert#SetUpLinterTest('eruby', 'erblint') + call ale#test#SetFilename('dummy.html.erb') + + let g:ale_eruby_erblint_executable = 'erblint' + let g:ale_eruby_erblint_options = '' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to erblint): + AssertLinter 'erblint', ale#Escape('erblint') + \ . ' --format json --stdin %s' + +Execute(Should be able to set a custom executable): + let g:ale_eruby_erblint_executable = 'bin/erblint' + + AssertLinter 'bin/erblint' , ale#Escape('bin/erblint') + \ . ' --format json --stdin %s' + +Execute(Setting bundle appends 'exec erblint'): + let g:ale_eruby_erblint_executable = 'path to/bundle' + + AssertLinter 'path to/bundle', ale#Escape('path to/bundle') + \ . ' exec erblint' + \ . ' --format json --stdin %s' diff --git a/vim-config/plugins/ale/test/linter/test_erlang_dialyzer.vader b/vim-config/plugins/ale/test/linter/test_erlang_dialyzer.vader new file mode 100644 index 00000000..5e818d7f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_erlang_dialyzer.vader @@ -0,0 +1,45 @@ +Before: + call ale#assert#SetUpLinterTest('erlang', 'dialyzer') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct.): + AssertLinter 'dialyzer', + \ ale#Escape('dialyzer') + \ . ' -n --plt ' . ale#Escape(expand('$HOME/.dialyzer_plt')) + \ . ' -Wunmatched_returns' + \ . ' -Werror_handling' + \ . ' -Wrace_conditions' + \ . ' -Wunderspecs' + \ . ' %s' + +Execute(The command should accept configured executable.): + let b:ale_erlang_dialyzer_executable = '/usr/bin/dialyzer' + AssertLinter '/usr/bin/dialyzer', + \ ale#Escape('/usr/bin/dialyzer') + \ . ' -n --plt ' . ale#Escape(expand('$HOME/.dialyzer_plt')) + \ . ' -Wunmatched_returns' + \ . ' -Werror_handling' + \ . ' -Wrace_conditions' + \ . ' -Wunderspecs' + \ . ' %s' + +Execute(The command should accept configured options.): + let b:ale_erlang_dialyzer_options = '-r ' . expand('$HOME') + AssertLinter 'dialyzer', + \ ale#Escape('dialyzer') + \ . ' -n --plt ' . ale#Escape(expand('$HOME/.dialyzer_plt')) + \ . ' -r ' . expand('$HOME') + \ . ' %s' + +Execute(The command should accept configured PLT file.): + let b:ale_erlang_dialyzer_plt_file = 'custom-plt' + AssertLinter 'dialyzer', + \ ale#Escape('dialyzer') + \ . ' -n --plt ' . ale#Escape(expand('custom-plt')) + \ . ' -Wunmatched_returns' + \ . ' -Werror_handling' + \ . ' -Wrace_conditions' + \ . ' -Wunderspecs' + \ . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_erlang_elvis.vader b/vim-config/plugins/ale/test/linter/test_erlang_elvis.vader new file mode 100644 index 00000000..4aab49d6 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_erlang_elvis.vader @@ -0,0 +1,16 @@ +Before: + let b:file = fnamemodify(bufname(''), ':.') + call ale#assert#SetUpLinterTest('erlang', 'elvis') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Default command should be correct): + AssertLinter 'elvis', + \ ale#Escape('elvis') . ' rock --output-format=parsable ' . ale#Escape(b:file) + +Execute(Executable should be configurable): + let b:ale_erlang_elvis_executable = '/path/to/elvis' + + AssertLinter '/path/to/elvis', + \ ale#Escape('/path/to/elvis') . ' rock --output-format=parsable ' . ale#Escape(b:file) diff --git a/vim-config/plugins/ale/test/linter/test_erlang_erlc.vader b/vim-config/plugins/ale/test/linter/test_erlang_erlc.vader new file mode 100644 index 00000000..0651b512 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_erlang_erlc.vader @@ -0,0 +1,62 @@ +Before: + call ale#assert#SetUpLinterTest('erlang', 'erlc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct.): + let g:cmd = ale_linters#erlang#erlc#GetCommand(bufnr('')) + let g:regex = 'erlc.\+-o.\+%t' + let g:matched = match(g:cmd, g:regex) + + " match returns -1 if not found + AssertNotEqual + \ g:matched, + \ -1, + \ 'Command error: expected [' . g:cmd . '] to match [' . g:regex . ']' + +Execute(The command should accept configured executable.): + let b:ale_erlang_erlc_executable = '/usr/bin/erlc' + let g:cmd = ale_linters#erlang#erlc#GetCommand(bufnr('')) + let g:regex = '/usr/bin/erlc.\+-o.\+%t' + let g:matched = match(g:cmd, g:regex) + + " match returns -1 if not found + AssertNotEqual + \ g:matched, + \ -1, + \ 'Command error: expected [' . g:cmd . '] to match [' . g:regex . ']' + +Execute(The command should accept configured options.): + let b:ale_erlang_erlc_options = '-I include' + let g:cmd = ale_linters#erlang#erlc#GetCommand(bufnr('')) + let g:regex = 'erlc.\+-o.\+-I include.\+%t' + let g:matched = match(g:cmd, g:regex) + + " match returns -1 if not found + AssertNotEqual + \ g:matched, + \ -1, + \ 'Command error: expected [' . g:cmd . '] to match [' . g:regex . ']' + +Execute(Linter should recognize OTP23 format.): + let g:lines = ["t.erl:6: only association operators '=>' are allowed in map construction"] + let g:output_text = ale_linters#erlang#erlc#Handle(bufnr(''), g:lines)[0].text + + let g:expected = "only association operators '=>' are allowed in map construction" + AssertEqual + \ g:output_text, + \ g:expected, + \ 'Command error: expected [' . g:output_text . '] to match [' . g:expected . ']' + +Execute(Linter should recognize OTP24 format.): + let g:lines = ["t.erl:6:16: only association operators '=>' are allowed in map construction", + \ "% 6| #{ a => A, b := B }.", + \ "% | ^"] + let g:output_text = ale_linters#erlang#erlc#Handle(bufnr(''), g:lines)[0].text + + let g:expected = "only association operators '=>' are allowed in map construction" + AssertEqual + \ g:output_text, + \ g:expected, + \ 'Command error: expected [' . g:output_text . '] to match [' . g:expected . ']' diff --git a/vim-config/plugins/ale/test/linter/test_erlang_syntaxerl.vader b/vim-config/plugins/ale/test/linter/test_erlang_syntaxerl.vader new file mode 100644 index 00000000..e7cc26ea --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_erlang_syntaxerl.vader @@ -0,0 +1,45 @@ +Before: + call ale#assert#SetUpLinterTest('erlang', 'syntaxerl') + +After: + call ale#assert#TearDownLinterTest() + +Execute (The default commands should be correct): + AssertLinter 'syntaxerl', [ + \ ale#Escape('syntaxerl') . ' -h', + \ ale#Escape('syntaxerl') . ' %t', + \] + +Execute (The executable should be configurable): + let b:ale_erlang_syntaxerl_executable = 'foobar' + + AssertLinter 'foobar', [ + \ ale#Escape('foobar') . ' -h', + \ ale#Escape('foobar') . ' %t', + \] + +Execute (The -b option should be used when available): + GivenCommandOutput [ + \ 'Syntax checker for Erlang (0.14.0)', + \ 'Usage: syntaxerl [-d | --debug] ', + \ ' syntaxerl <-h | --help>', + \ ' -d, --debug Enable debug output', + \ ' -h, --help Show this message', + \] + AssertLinter 'syntaxerl', [ + \ ale#Escape('syntaxerl') . ' -h', + \ ale#Escape('syntaxerl') . ' %t', + \] + + GivenCommandOutput [ + \ 'Syntax checker for Erlang (0.14.0)', + \ 'Usage: syntaxerl [-b | --base ] [-d | --debug] ', + \ ' syntaxerl <-h | --help>', + \ ' -b, --base Set original filename', + \ ' -d, --debug Enable debug output', + \ ' -h, --help Show this message', + \] + AssertLinter 'syntaxerl', [ + \ ale#Escape('syntaxerl') . ' -h', + \ ale#Escape('syntaxerl') . ' -b %s %t', + \] diff --git a/vim-config/plugins/ale/test/linter/test_erubi.vader b/vim-config/plugins/ale/test/linter/test_erubi.vader new file mode 100644 index 00000000..cd4a0b68 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_erubi.vader @@ -0,0 +1,32 @@ +Before: + call ale#assert#SetUpLinterTest('eruby', 'erubi') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should not contain any filter code by default): + call ale#test#SetFilename('../test-files/ruby/not_a_rails_app/file.rb') + + AssertLinter 'ruby', [ + \ 'ruby -r erubi/capture_end -e ' . ale#Escape('""'), + \ 'ruby -r erubi/capture_end -e ' . ale#Escape('puts Erubi::CaptureEndEngine.new($stdin.read).src') . '< %t | ruby -c', + \] + +Execute(Executable should filter invalid eRuby when inside a Rails project): + call ale#test#SetFilename('../test-files/ruby/valid_rails_app/app/views/my_great_view.html.erb') + + AssertLinter 'ruby', [ + \ 'ruby -r erubi/capture_end -e ' . ale#Escape('""'), + \ 'ruby -r erubi/capture_end -e ' . ale#Escape('puts Erubi::CaptureEndEngine.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src') . '< %t | ruby -c', + \] + +Execute(Command should be blank if the first command in the chain returns output): + GivenCommandOutput [ + \ "/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- erubi/capture_end (LoadError)", + \ " from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'", + \] + + AssertLinter 'ruby', [ + \ 'ruby -r erubi/capture_end -e ' . ale#Escape('""'), + \ '', + \] diff --git a/vim-config/plugins/ale/test/linter/test_erubis.vader b/vim-config/plugins/ale/test/linter/test_erubis.vader new file mode 100644 index 00000000..cfca54a2 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_erubis.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpLinterTest('eruby', 'erubis') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should not contain any filter code by default): + call ale#test#SetFilename('../test-files/ruby/not_a_rails_app/file.rb') + + AssertLinter 'erubis', 'erubis -x %t | ruby -c' + +Execute(Executable should filter invalid eRuby when inside a Rails project): + call ale#test#SetFilename('../test-files/ruby/valid_rails_app/app/views/my_great_view.html.erb') + + AssertLinter 'erubis', + \ 'ruby -r erubis -e ' . ale#Escape('puts Erubis::Eruby.new($stdin.read.gsub(%{<%=},%{<%})).src') . '< %t | ruby -c' diff --git a/vim-config/plugins/ale/test/linter/test_eslint.vader b/vim-config/plugins/ale/test/linter/test_eslint.vader new file mode 100644 index 00000000..4dde5639 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_eslint.vader @@ -0,0 +1,85 @@ +Before: + call ale#assert#SetUpLinterTest('javascript', 'eslint') + runtime autoload/ale/handlers/eslint.vim + + let b:args = ' -f json --stdin --stdin-filename %s' + +After: + unlet! b:args + unlet! b:executable + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinterCwd '' + AssertLinter 'eslint', ale#Escape('eslint') . b:args + +Execute(create-react-app directories should be detected correctly): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js') + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/eslint/react-app') + AssertLinter b:executable, + \ (has('win32') ? ale#Escape('node.exe') . ' ' : '') + \ . ale#Escape(b:executable) . b:args + +Execute(use-global should override create-react-app detection): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir/testfile.js') + + let g:ale_javascript_eslint_use_global = 1 + let g:ale_javascript_eslint_executable = 'eslint_d' + + let b:executable = 'eslint_d' + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/eslint/react-app') + AssertLinter b:executable, ale#Escape(b:executable) . b:args + +Execute(other app directories should be detected correctly): + call ale#test#SetFilename('../test-files/eslint/other-app/subdir/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../test-files/eslint/node_modules/.bin/eslint') + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/eslint') + AssertLinter b:executable, ale#Escape(b:executable) . b:args + +Execute(use-global should override other app directories): + call ale#test#SetFilename('../test-files/eslint/other-app/subdir/testfile.js') + + let g:ale_javascript_eslint_use_global = 1 + let g:ale_javascript_eslint_executable = 'eslint_d' + + let b:executable = 'eslint_d' + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/eslint') + AssertLinter b:executable, ale#Escape(b:executable) . b:args + +Execute(eslint_d should be detected correctly): + call ale#test#SetFilename('../test-files/eslint/app-with-eslint-d/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../test-files/eslint/app-with-eslint-d/node_modules/.bin/eslint_d') + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/eslint/app-with-eslint-d') + AssertLinter b:executable, ale#Escape(b:executable) . b:args + +Execute(eslint.js executables should be run with node on Windows): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js') + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/eslint/react-app') + AssertLinter b:executable, + \ (has('win32') ? ale#Escape('node.exe') . ' ' : '') + \ . ale#Escape(b:executable) . b:args + +Execute(eslint.js should be run from a containing project with node_modules): + call ale#test#SetFilename('../test-files/eslint/react-app/subdir-with-package-json/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../test-files/eslint/react-app/node_modules/eslint/bin/eslint.js') + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/eslint/react-app') + AssertLinter b:executable, + \ (has('win32') ? ale#Escape('node.exe') . ' ' : '') + \ . ale#Escape(b:executable) . b:args + +Execute(eslint.js should be run from a containing project with .yarn/sdks): + call ale#test#SetFilename('../test-files/eslint/yarn2-app/subdir/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../test-files/eslint/yarn2-app/.yarn/sdks/eslint/bin/eslint.js') + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/eslint/yarn2-app') + AssertLinter b:executable, + \ (has('win32') ? ale#Escape('node.exe') . ' ' : '') + \ . ale#Escape(b:executable) . b:args diff --git a/vim-config/plugins/ale/test/linter/test_fecs.vader b/vim-config/plugins/ale/test/linter/test_fecs.vader new file mode 100644 index 00000000..4287d324 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_fecs.vader @@ -0,0 +1,9 @@ +Before: + call ale#assert#SetUpLinterTest('javascript', 'fecs') + runtime autoload/ale/handlers/fecs.vim + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'fecs', ale#Escape('fecs') . ' check --colors=false --rule=true %t' diff --git a/vim-config/plugins/ale/test/linter/test_flake8.vader b/vim-config/plugins/ale/test/linter/test_flake8.vader new file mode 100644 index 00000000..0b87c27b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_flake8.vader @@ -0,0 +1,217 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'flake8') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + + GivenCommandOutput ['3.0.0'] + +After: + unlet! b:executable + unlet! b:bin_dir + call ale#assert#TearDownLinterTest() + +Execute(The flake8 callbacks should return the correct default values): + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --version', + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \] + + " The version check should be cached. + GivenCommandOutput [] + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \] + + " Try with older versions. + call ale#semver#ResetVersionCache() + GivenCommandOutput ['2.9.9'] + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --version', + \ ale#Escape('flake8') . ' --format=default -', + \] + +Execute(The option for disabling changing directories should work): + let g:ale_python_flake8_change_directory = 'off' + + AssertLinterCwd ['', ''] + call ale#semver#ResetVersionCache() + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --version', + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \] + + let g:ale_python_flake8_change_directory = 0 + + AssertLinterCwd [''] + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \] + + " Invalid options should be considered the same as turning the setting off. + let g:ale_python_flake8_change_directory = 'xxx' + + AssertLinterCwd [''] + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \] + +Execute(The option for changing directory to project root should work): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_tox/namespace/foo/bar.py') + + AssertLinterCwd ale#python#FindProjectRootIni(bufnr('')) + call ale#semver#ResetVersionCache() + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --version', + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \] + +Execute(The option for changing directory to file dir should work): + let g:ale_python_flake8_change_directory = 'file' + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_tox/namespace/foo/bar.py') + + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --version', + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \] + + let g:ale_python_flake8_change_directory = 1 + + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \] + +Execute(The flake8 command callback should let you set options): + let g:ale_python_flake8_options = '--some-option' + + GivenCommandOutput ['3.0.4'] + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --version', + \ ale#Escape('flake8') . ' --some-option' + \ . ' --format=default --stdin-display-name %s -', + \] + + call ale#semver#ResetVersionCache() + GivenCommandOutput ['2.9.9'] + AssertLinter 'flake8', [ + \ ale#Escape('flake8') . ' --version', + \ ale#Escape('flake8') . ' --some-option --format=default -', + \] + +Execute(You should be able to set a custom executable and it should be escaped): + let g:ale_python_flake8_executable = 'executable with spaces' + + AssertLinterCwd ['%s:h', '%s:h'] + call ale#semver#ResetVersionCache() + AssertLinter 'executable with spaces', [ + \ ale#Escape('executable with spaces') . ' --version', + \ ale#Escape('executable with spaces') + \ . ' --format=default' + \ . ' --stdin-display-name %s -', + \] + +Execute(The flake8 callbacks should detect virtualenv directories): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let b:executable = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/flake8' + \) + + AssertLinter b:executable, [ + \ ale#Escape(b:executable) . ' --version', + \ ale#Escape(b:executable) + \ . ' --format=default' + \ . ' --stdin-display-name %s -', + \] + +Execute(The FindProjectRoot should detect the project root directory for namespace package via Manifest.in): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_manifest/namespace/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/namespace_package_manifest'), + \ ale#python#FindProjectRoot(bufnr('')) + +Execute(The FindProjectRoot should detect the project root directory for namespace package via setup.cf): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_setup/namespace/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/namespace_package_setup'), + \ ale#python#FindProjectRoot(bufnr('')) + +Execute(The FindProjectRoot should detect the project root directory for namespace package via pytest.ini): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_pytest/namespace/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/namespace_package_pytest'), + \ ale#python#FindProjectRoot(bufnr('')) + +Execute(The FindProjectRoot should detect the project root directory for namespace package via tox.ini): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_tox/namespace/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/namespace_package_tox'), + \ ale#python#FindProjectRoot(bufnr('')) + +Execute(The FindProjectRoot should detect the project root directory for non-namespace package): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/no_virtualenv/subdir/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/no_virtualenv/subdir'), + \ ale#python#FindProjectRoot(bufnr('')) + +" Some users currently run flake8 this way, so we should support it. +Execute(Using `python -m flake8` should be supported for running flake8): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let g:ale_python_flake8_executable = 'python' + let g:ale_python_flake8_options = '-m flake8 --some-option' + + GivenCommandOutput ['2.9.9'] + AssertLinter 'python', [ + \ ale#Escape('python') . ' -m flake8 --version', + \ ale#Escape('python') + \ . ' -m flake8 --some-option --format=default -' + \] + + call ale#semver#ResetVersionCache() + + " Leading spaces shouldn't matter + let g:ale_python_flake8_options = ' -m flake8 --some-option' + + GivenCommandOutput ['2.9.9'] + AssertLinter 'python', [ + \ ale#Escape('python') . ' -m flake8 --version', + \ ale#Escape('python') + \ . ' -m flake8 --some-option --format=default -' + \] + +Execute(Setting executable to 'pipenv' should append 'run flake8'): + let g:ale_python_flake8_executable = 'path/to/pipenv' + + " FIXME: pipenv should check the version with flake8. + GivenCommandOutput [] + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') . ' run flake8 --format=default -' + +Execute(Pipenv is detected when python_flake8_auto_pipenv is set): + let g:ale_python_flake8_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinterCwd ale#python#FindProjectRootIni(bufnr('')) + AssertLinter 'pipenv', + \ ale#Escape('pipenv') . ' run flake8 --format=default --stdin-display-name %s -' + +Execute(Setting executable to 'poetry' should append 'run flake8'): + let g:ale_python_flake8_executable = 'path/to/poetry' + + " FIXME: poetry should check the version with flake8. + GivenCommandOutput [] + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') . ' run flake8 --format=default -' + +Execute(poetry is detected when python_flake8_auto_poetry is set): + let g:ale_python_flake8_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinterCwd ale#python#FindProjectRootIni(bufnr('')) + AssertLinter 'poetry', + \ ale#Escape('poetry') . ' run flake8 --format=default --stdin-display-name %s -' diff --git a/vim-config/plugins/ale/test/linter/test_flakehell.vader b/vim-config/plugins/ale/test/linter/test_flakehell.vader new file mode 100644 index 00000000..fa7cb9e3 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_flakehell.vader @@ -0,0 +1,202 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'flakehell') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + + GivenCommandOutput ['0.8.0'] + +After: + unlet! b:executable + unlet! b:bin_dir + call ale#assert#TearDownLinterTest() + +Execute(The flakehell callbacks should return the correct default values): + AssertLinter 'flakehell', [ + \ ale#Escape('flakehell') . ' --version', + \ ale#Escape('flakehell') . ' lint --format=default --stdin-display-name %s -', + \] + + " The version check should be cached. + GivenCommandOutput [] + AssertLinter 'flakehell', [ + \ ale#Escape('flakehell') . ' lint --format=default --stdin-display-name %s -', + \] + +Execute(The option for disabling changing directories should work): + let g:ale_python_flakehell_change_directory = 'off' + + AssertLinterCwd ['', ''] + call ale#semver#ResetVersionCache() + AssertLinter 'flakehell', [ + \ ale#Escape('flakehell') . ' --version', + \ ale#Escape('flakehell') . ' lint --format=default --stdin-display-name %s -', + \] + + let g:ale_python_flakehell_change_directory = 0 + + AssertLinterCwd [''] + AssertLinter 'flakehell', [ + \ ale#Escape('flakehell') . ' lint --format=default --stdin-display-name %s -', + \] + + " Invalid options should be considered the same as turning the setting off. + let g:ale_python_flakehell_change_directory = 'xxx' + + AssertLinterCwd [''] + AssertLinter 'flakehell', [ + \ ale#Escape('flakehell') . ' lint --format=default --stdin-display-name %s -', + \] + +Execute(The option for changing directory to project root should work): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_tox/namespace/foo/bar.py') + + AssertLinterCwd ale#python#FindProjectRootIni(bufnr('')) + call ale#semver#ResetVersionCache() + AssertLinter 'flakehell', [ + \ ale#Escape('flakehell') . ' --version', + \ ale#Escape('flakehell') . ' lint --format=default --stdin-display-name %s -', + \] + +Execute(The option for changing directory to file dir should work): + let g:ale_python_flakehell_change_directory = 'file' + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_tox/namespace/foo/bar.py') + + AssertLinter 'flakehell', [ + \ ale#Escape('flakehell') . ' --version', + \ ale#Escape('flakehell') . ' lint --format=default --stdin-display-name %s -', + \] + + let g:ale_python_flakehell_change_directory = 1 + + AssertLinter 'flakehell', [ + \ ale#Escape('flakehell') . ' lint --format=default --stdin-display-name %s -', + \] + +Execute(The flakehell command callback should let you set options): + let g:ale_python_flakehell_options = '--some-option' + + GivenCommandOutput ['0.8.0'] + AssertLinter 'flakehell', [ + \ ale#Escape('flakehell') . ' --version', + \ ale#Escape('flakehell') . ' lint --some-option' + \ . ' --format=default --stdin-display-name %s -', + \] + +Execute(You should be able to set a custom executable and it should be escaped): + let g:ale_python_flakehell_executable = 'executable with spaces' + + AssertLinterCwd ['%s:h', '%s:h'] + call ale#semver#ResetVersionCache() + AssertLinter 'executable with spaces', [ + \ ale#Escape('executable with spaces') . ' --version', + \ ale#Escape('executable with spaces') + \ . ' lint' + \ . ' --format=default' + \ . ' --stdin-display-name %s -', + \] + +Execute(The flakehell callbacks should detect virtualenv directories): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let b:executable = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/flakehell' + \) + + AssertLinter b:executable, [ + \ ale#Escape(b:executable) . ' --version', + \ ale#Escape(b:executable) + \ . ' lint' + \ . ' --format=default' + \ . ' --stdin-display-name %s -', + \] + +Execute(The FindProjectRoot should detect the project root directory for namespace package via Manifest.in): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_manifest/namespace/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/namespace_package_manifest'), + \ ale#python#FindProjectRoot(bufnr('')) + +Execute(The FindProjectRoot should detect the project root directory for namespace package via setup.cf): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_setup/namespace/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/namespace_package_setup'), + \ ale#python#FindProjectRoot(bufnr('')) + +Execute(The FindProjectRoot should detect the project root directory for namespace package via pytest.ini): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_pytest/namespace/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/namespace_package_pytest'), + \ ale#python#FindProjectRoot(bufnr('')) + +Execute(The FindProjectRoot should detect the project root directory for namespace package via tox.ini): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/namespace_package_tox/namespace/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/namespace_package_tox'), + \ ale#python#FindProjectRoot(bufnr('')) + +Execute(The FindProjectRoot should detect the project root directory for non-namespace package): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/no_virtualenv/subdir/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/no_virtualenv/subdir'), + \ ale#python#FindProjectRoot(bufnr('')) + +" Some users currently run flakehell this way, so we should support it. +Execute(Using `python -m flakehell` should be supported for running flakehell): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let g:ale_python_flakehell_executable = 'python' + let g:ale_python_flakehell_options = '--some-option' + + AssertLinter 'python', [ + \ ale#Escape('python') . ' -m flakehell --version', + \ ale#Escape('python') + \ . ' -m flakehell lint --some-option --format=default --stdin-display-name %s -' + \] + + call ale#semver#ResetVersionCache() + + " Leading spaces shouldn't matter + let g:ale_python_flakehell_options = ' --some-option' + + AssertLinter 'python', [ + \ ale#Escape('python') . ' -m flakehell --version', + \ ale#Escape('python') + \ . ' -m flakehell lint --some-option --format=default --stdin-display-name %s -' + \] + +Execute(Setting executable to 'pipenv' should append 'run flakehell'): + let g:ale_python_flakehell_executable = 'path/to/pipenv' + + " FIXME: pipenv should check the version with flakehell. + GivenCommandOutput [] + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') . ' run flakehell lint --format=default -' + +Execute(Pipenv is detected when python_flakehell_auto_pipenv is set): + let g:ale_python_flakehell_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinterCwd ale#python#FindProjectRootIni(bufnr('')) + AssertLinter 'pipenv', + \ ale#Escape('pipenv') . ' run flakehell lint --format=default --stdin-display-name %s -' + +Execute(Setting executable to 'poetry' should append 'run flakehell'): + let g:ale_python_flakehell_executable = 'path/to/poetry' + + " FIXME: poetry should check the version with flakehell. + GivenCommandOutput [] + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') . ' run flakehell lint --format=default -' + +Execute(poetry is detected when python_flakehell_auto_poetry is set): + let g:ale_python_flakehell_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinterCwd ale#python#FindProjectRootIni(bufnr('')) + AssertLinter 'poetry', + \ ale#Escape('poetry') . ' run flakehell lint --format=default --stdin-display-name %s -' diff --git a/vim-config/plugins/ale/test/linter/test_flow.vader b/vim-config/plugins/ale/test/linter/test_flow.vader new file mode 100644 index 00000000..8488a2e9 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_flow.vader @@ -0,0 +1,42 @@ +Before: + call ale#assert#SetUpLinterTest('javascript', 'flow') + +After: + call ale#assert#TearDownLinterTest() + +Execute(flow should return a command to run if a .flowconfig file exists): + call ale#test#SetFilename('../test-files/flow/a/sub/dummy') + + AssertLinter 'flow', + \ ale#Escape('flow') + \ . ' check-contents --respect-pragma --json --from ale %s < %t' + \ . (!has('win32') ? '; echo' : '') + +Execute(flow should not use the respect pragma argument if the option is off): + call ale#test#SetFilename('../test-files/flow/a/sub/dummy') + + let b:ale_javascript_flow_use_respect_pragma = 0 + + AssertLinter 'flow', + \ ale#Escape('flow') + \ . ' check-contents --json --from ale %s < %t' + \ . (!has('win32') ? '; echo' : '') + +Execute(flow should should not use --respect-pragma for old versions): + call ale#test#SetFilename('../test-files/flow/a/sub/dummy') + + GivenCommandOutput [ + \ 'Warning: `flow --version` is deprecated in favor of `flow version`', + \ 'Flow, a static type checker for JavaScript, version 0.27.0', + \] + AssertLinter 'flow', [ + \ ale#Escape('flow') . ' --version', + \ ale#Escape('flow') + \ . ' check-contents --json --from ale %s < %t' + \ . (!has('win32') ? '; echo' : ''), + \] + +Execute(flow should not return a command to run if no .flowconfig file exists): + call ale#test#SetFilename('../test-files/flow/b/sub/dummy') + + AssertLinterNotExecuted diff --git a/vim-config/plugins/ale/test/linter/test_foodcritic.vader b/vim-config/plugins/ale/test/linter/test_foodcritic.vader new file mode 100644 index 00000000..c5564cb1 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_foodcritic.vader @@ -0,0 +1,18 @@ +Before: + call ale#assert#SetUpLinterTest('chef', 'foodcritic') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'foodcritic', ale#Escape('foodcritic') . ' %s' + +Execute(Extra options should be included with escapeed tildes (~)): + let b:ale_chef_foodcritic_options = '-t ~F011' + + AssertLinter 'foodcritic', ale#Escape('foodcritic') . ' -t \~F011 %s' + +Execute(The executable should be configurable): + let b:ale_chef_foodcritic_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_fortran_fortls.vader b/vim-config/plugins/ale/test/linter/test_fortran_fortls.vader new file mode 100644 index 00000000..581f94ba --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_fortran_fortls.vader @@ -0,0 +1,18 @@ +Before: + call ale#assert#SetUpLinterTest('fortran', 'language_server') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'fortls', ale#Escape('fortls') + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/fortls-project/test.F90') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/fortls-project') + +Execute(The language should be correct): + AssertLSPLanguage 'fortran' diff --git a/vim-config/plugins/ale/test/linter/test_fsc.vader b/vim-config/plugins/ale/test/linter/test_fsc.vader new file mode 100644 index 00000000..278e7c16 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_fsc.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('scala', 'fsc') + +After: + call ale#assert#TearDownLinterTest() + +Given scala(An empty Scala file): +Execute(The default executable and command should be correct): + AssertLinter 'fsc', ale#Escape('fsc') . ' -Ystop-after:parser %t' + +Given scala.sbt(An empty SBT file): +Execute(fsc should not be run for sbt files): + AssertLinterNotExecuted diff --git a/vim-config/plugins/ale/test/linter/test_fusionlint.vader b/vim-config/plugins/ale/test/linter/test_fusionlint.vader new file mode 100644 index 00000000..1c63b811 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_fusionlint.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('fuse', 'fusionlint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The fuse fusionlint command callback should return the correct default string): + AssertLinter 'fusion-lint', ale#Escape('fusion-lint') . ' --filename %s -i' + +Execute(The fuse fusionlint command callback should let you set options): + let g:ale_fuse_fusionlint_options = '--example-option argument' + + AssertLinter 'fusion-lint', + \ ale#Escape('fusion-lint') . ' --example-option argument --filename %s -i' + +Execute(The fusionlint executable should be configurable): + let g:ale_fuse_fusionlint_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --filename %s -i' diff --git a/vim-config/plugins/ale/test/linter/test_gawk.vader b/vim-config/plugins/ale/test/linter/test_gawk.vader new file mode 100644 index 00000000..ba9f59ab --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_gawk.vader @@ -0,0 +1,25 @@ +Before: + call ale#assert#SetUpLinterTest('awk', 'gawk') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'gawk', + \ ale#Escape('gawk') . ' --source ' . ale#Escape('BEGIN { exit } END { exit 1 }') + \ . ' -f %t --lint /dev/null' + +Execute(The executable should be configurable): + let b:ale_awk_gawk_executable = '/other/gawk' + + AssertLinter '/other/gawk', + \ ale#Escape('/other/gawk') . ' --source ' . ale#Escape('BEGIN { exit } END { exit 1 }') + \ . ' -f %t --lint /dev/null' + +Execute(The options should be configurable): + let b:ale_awk_gawk_executable = 'gawk' + let b:ale_awk_gawk_options = '--something' + + AssertLinter 'gawk', + \ ale#Escape('gawk') . ' --source ' . ale#Escape('BEGIN { exit } END { exit 1 }') + \ . ' --something -f %t --lint /dev/null' diff --git a/vim-config/plugins/ale/test/linter/test_gfortran.vader b/vim-config/plugins/ale/test/linter/test_gfortran.vader new file mode 100644 index 00000000..3e6ef951 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_gfortran.vader @@ -0,0 +1,24 @@ +Before: + call ale#assert#SetUpLinterTest('fortran', 'gcc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The fortran gcc command callback should return the correct default string): + AssertLinter 'gcc', ale#Escape('gcc') . ' -S -x f95 -fsyntax-only -ffree-form -Wall -' + +Execute(The fortran gcc command callback should let you set options): + let g:ale_fortran_gcc_options = '-Wotherthings' + + AssertLinter 'gcc', ale#Escape('gcc') . ' -S -x f95 -fsyntax-only -ffree-form -Wotherthings -' + +Execute(The fortran gcc command callback should let you use -ffixed-form): + let g:ale_fortran_gcc_use_free_form = 0 + + AssertLinter 'gcc', ale#Escape('gcc') . ' -S -x f95 -fsyntax-only -ffixed-form -Wall -' + +Execute(The fortran executable should be configurable): + let g:ale_fortran_gcc_executable = 'gfortran' + + AssertLinter 'gfortran', + \ ale#Escape('gfortran') . ' -S -x f95 -fsyntax-only -ffree-form -Wall -' diff --git a/vim-config/plugins/ale/test/linter/test_ghdl.vader b/vim-config/plugins/ale/test/linter/test_ghdl.vader new file mode 100644 index 00000000..f254e11f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ghdl.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('vhdl', 'ghdl') + +After: + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'ghdl', ale#Escape('ghdl') . ' -s --std=08 %t' + + let b:ale_vhdl_ghdl_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' -s --std=08 %t' + +Execute(The options should be configurable): + let b:ale_vhdl_ghdl_options = '--something' + + AssertLinter 'ghdl', ale#Escape('ghdl') . ' -s --something %t' diff --git a/vim-config/plugins/ale/test/linter/test_gitlint.vader b/vim-config/plugins/ale/test/linter/test_gitlint.vader new file mode 100644 index 00000000..4df675f3 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_gitlint.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('gitcommit', 'gitlint') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + unlet! b:bin_dir + unlet! b:executable + + call ale#assert#TearDownLinterTest() + +Execute(The gitlint callbacks should return the correct default values): + AssertLinter 'gitlint', ale#Escape('gitlint') . ' lint' + +Execute(The gitlint executable should be configurable, and escaped properly): + let g:ale_gitcommit_gitlint_executable = 'executable with spaces' + + AssertLinter 'executable with spaces', + \ ale#Escape('executable with spaces') . ' lint' + +Execute(The gitlint command callback should let you set options): + let g:ale_gitcommit_gitlint_options = '--some-option' + + AssertLinter 'gitlint', ale#Escape('gitlint') . ' --some-option lint' + +Execute(The gitlint callbacks shouldn't detect virtualenv directories where they don't exist): + call ale#test#SetFilename('../test-files/python/no_virtualenv/subdir/foo/COMMIT_EDITMSG') + + AssertLinter 'gitlint', ale#Escape('gitlint') . ' lint' + +Execute(The gitlint callbacks should detect virtualenv directories): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/COMMIT_EDITMSG') + let b:executable = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/gitlint' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' lint' + +Execute(You should able able to use the global gitlint instead): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/COMMIT_EDITMSG') + let g:ale_gitcommit_gitlint_use_global = 1 + + AssertLinter 'gitlint', ale#Escape('gitlint') . ' lint' diff --git a/vim-config/plugins/ale/test/linter/test_glslang.vader b/vim-config/plugins/ale/test/linter/test_glslang.vader new file mode 100644 index 00000000..980406af --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_glslang.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('glsl', 'glslang') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'glslangValidator', ale#Escape('glslangValidator') . ' -C %t' + +Execute(The executable should be configurable): + let b:ale_glsl_glslang_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' -C %t' + +Execute(Options should work): + let g:ale_glsl_glslang_options = '--test' + + AssertLinter 'glslangValidator', + \ ale#Escape('glslangValidator') . ' --test -C %t' diff --git a/vim-config/plugins/ale/test/linter/test_glslls.vader b/vim-config/plugins/ale/test/linter/test_glslls.vader new file mode 100644 index 00000000..133c2a2f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_glslls.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('glsl', 'glslls') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'glslls', ale#Escape('glslls') . ' --stdin' + +Execute(Executable should be configurable): + let b:ale_glsl_glslls_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --stdin' + +Execute(Setting logfile should work): + let b:ale_glsl_glslls_logfile = '/tmp/test.log' + + AssertLinter 'glslls', + \ ale#Escape('glslls') . ' --verbose -l /tmp/test.log --stdin' diff --git a/vim-config/plugins/ale/test/linter/test_gobuild.vader b/vim-config/plugins/ale/test/linter/test_gobuild.vader new file mode 100644 index 00000000..bac4d74e --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_gobuild.vader @@ -0,0 +1,33 @@ +Before: + Save g:ale_go_go_executable + + call ale#assert#SetUpLinterTest('go', 'gobuild') + + GivenCommandOutput ['/foo/bar', '/foo/baz'] + +After: + Restore + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinterCwd '%s:h' + AssertLinter 'go', 'go test -c -o /dev/null ./' + +Execute(Go environment variables should be supported): + let b:ale_go_go111module = 'on' + + AssertLinter 'go', ale#Env('GO111MODULE', 'on') . 'go test -c -o /dev/null ./' + + unlet! b:ale_go_go111module + +Execute(Extra options should be supported): + let g:ale_go_gobuild_options = '--foo-bar' + + AssertLinter 'go', 'go test --foo-bar -c -o /dev/null ./' + + let g:ale_go_gobuild_options = '' + +Execute(The executable should be configurable): + let g:ale_go_go_executable = 'foobar' + + AssertLinter 'foobar', 'foobar test -c -o /dev/null ./' diff --git a/vim-config/plugins/ale/test/linter/test_gofmt.vader b/vim-config/plugins/ale/test/linter/test_gofmt.vader new file mode 100644 index 00000000..b056a659 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_gofmt.vader @@ -0,0 +1,26 @@ +Before: + Save g:ale_go_go111module + Save b:ale_go_go111module + + let b:ale_go_go111module = '' + + call ale#assert#SetUpLinterTest('go', 'gofmt') + call ale#test#SetFilename('../test-files/go/testfile2.go') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The default gofmt command should be correct): + AssertLinter 'gofmt', + \ ale#Escape('gofmt') . ' -e %t' + +Execute(The gofmt command should support Go environment variables): + let b:ale_go_go111module = 'on' + + AssertLinter 'gofmt', + \ ale#Env('GO111MODULE', 'on') + \ . ale#Escape('gofmt') . ' -e %t' diff --git a/vim-config/plugins/ale/test/linter/test_golangci_lint.vader b/vim-config/plugins/ale/test/linter/test_golangci_lint.vader new file mode 100644 index 00000000..ee754bba --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_golangci_lint.vader @@ -0,0 +1,50 @@ +Before: + Save g:ale_go_go111module + + call ale#assert#SetUpLinterTest('go', 'golangci_lint') + call ale#test#SetFilename('test.go') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The golangci-lint defaults should be correct): + AssertLinterCwd '%s:h', + AssertLinter 'golangci-lint', + \ ale#Escape('golangci-lint') + \ . ' run ' . ale#Escape(expand('%' . ':t')) + \ . ' --enable-all' + +Execute(The golangci-lint callback should use a configured executable): + let b:ale_go_golangci_lint_executable = 'something else' + + AssertLinter 'something else', + \ ale#Escape('something else') + \ . ' run ' . ale#Escape(expand('%' . ':t')) + \ . ' --enable-all' + +Execute(The golangci-lint callback should use configured options): + let b:ale_go_golangci_lint_options = '--foobar' + + AssertLinter 'golangci-lint', + \ ale#Escape('golangci-lint') + \ . ' run ' . ale#Escape(expand('%' . ':t')) + \ . ' --foobar' + +Execute(The golangci-lint callback should support environment variables): + let b:ale_go_go111module = 'on' + + AssertLinter 'golangci-lint', + \ ale#Env('GO111MODULE', 'on') + \ . ale#Escape('golangci-lint') + \ . ' run ' . ale#Escape(expand('%' . ':t')) + \ . ' --enable-all' + +Execute(The golangci-lint `lint_package` option should use the correct command): + let b:ale_go_golangci_lint_package = 1 + + AssertLinter 'golangci-lint', + \ ale#Escape('golangci-lint') . ' run --enable-all' diff --git a/vim-config/plugins/ale/test/linter/test_golangserver.vader b/vim-config/plugins/ale/test/linter/test_golangserver.vader new file mode 100644 index 00000000..b31d8dc8 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_golangserver.vader @@ -0,0 +1,76 @@ +Before: + Save $GOPATH + Save g:ale_completion_enabled + Save g:ale_go_go111module + + let g:ale_completion_enabled = 0 + let g:sep = has('win32') ? ';' : ':' + + call ale#assert#SetUpLinterTest('go', 'langserver') + let $GOPATH = ale#path#Simplify(g:dir . '/../test-files/go/go1') + \ . g:sep + \ . ale#path#Simplify(g:dir . '/../test-files/go/go2') + +After: + Restore + + unlet! b:ale_completion_enabled + unlet! b:ale_go_go111module + unlet! g:sep + + call ale#assert#TearDownLinterTest() + +Execute(should set correct defaults): + AssertLinter 'go-langserver', ale#Escape('go-langserver') + +Execute(should configure go-langserver callback executable): + let b:ale_go_langserver_executable = 'boo' + + AssertLinter 'boo', ale#Escape('boo') + +Execute(should set go-langserver options): + call ale#test#SetFilename('../test-files/go/go1/prj1/file.go') + let b:ale_completion_enabled = 1 + let b:ale_go_langserver_options = '' + + AssertLinter 'go-langserver', + \ ale#Escape('go-langserver') . ' -gocodecompletion' + + let b:ale_go_langserver_options = '-trace' + + AssertLinter 'go-langserver', + \ ale#Escape('go-langserver') . ' -gocodecompletion -trace' + +Execute(should ignore go-langserver -gocodecompletion option): + call ale#test#SetFilename('../test-files/go/go1/prj1/file.go') + + let b:ale_go_langserver_options = '-trace -gocodecompletion' + let b:ale_completion_enabled = 1 + + AssertLinter 'go-langserver', + \ ale#Escape('go-langserver') . ' -gocodecompletion -trace' + + let b:ale_completion_enabled = 0 + + AssertLinter 'go-langserver', ale#Escape('go-langserver') . ' -trace' + +Execute(should support Go environment variables): + let b:ale_go_go111module = 'on' + + AssertLinter 'go-langserver', + \ ale#Env('GO111MODULE', 'on') . ale#Escape('go-langserver') + +Execute(should set go-langserver for go app1): + call ale#test#SetFilename('../test-files/go/go1/prj1/file.go') + + AssertLSPLanguage 'go' + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/go/go1') + +Execute(should set go-langserver for go app2): + call ale#test#SetFilename('../test-files/go/go2/prj1/file.go') + + AssertLSPLanguage 'go' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/go/go2') diff --git a/vim-config/plugins/ale/test/linter/test_golint.vader b/vim-config/plugins/ale/test/linter/test_golint.vader new file mode 100644 index 00000000..64916707 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_golint.vader @@ -0,0 +1,30 @@ +Before: + Save g:ale_go_go111module + + call ale#assert#SetUpLinterTest('go', 'golint') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The default golint command should be correct): + AssertLinter 'golint', ale#Escape('golint') . ' %t' + +Execute(The golint executable should be configurable): + let b:ale_go_golint_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' %t' + +Execute(The golint options should be configurable): + let b:ale_go_golint_options = '--foo' + + AssertLinter 'golint', ale#Escape('golint') . ' --foo %t' + +Execute(The golint command should support Go environment variables): + let b:ale_go_go111module = 'on' + + AssertLinter 'golint', + \ ale#Env('GO111MODULE', 'on') . ale#Escape('golint') . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_gometalinter.vader b/vim-config/plugins/ale/test/linter/test_gometalinter.vader new file mode 100644 index 00000000..5ff744f5 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_gometalinter.vader @@ -0,0 +1,49 @@ +Before: + Save g:ale_go_go111module + + call ale#assert#SetUpLinterTest('go', 'gometalinter') + call ale#test#SetFilename('test.go') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The gometalinter defaults should be correct): + AssertLinterCwd '%s:h', + AssertLinter 'gometalinter', + \ ale#Escape('gometalinter') + \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) + \ . ' .' + +Execute(The gometalinter callback should use a configured executable): + let b:ale_go_gometalinter_executable = 'something else' + + AssertLinter 'something else', + \ ale#Escape('something else') + \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) + \ . ' .' + +Execute(The gometalinter callback should use configured options): + let b:ale_go_gometalinter_options = '--foobar' + + AssertLinter 'gometalinter', + \ ale#Escape('gometalinter') + \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) + \ . ' --foobar' . ' .' + +Execute(The gometalinter should use configured environment variables): + let b:ale_go_go111module = 'off' + + AssertLinter 'gometalinter', + \ ale#Env('GO111MODULE', 'off') + \ . ale#Escape('gometalinter') + \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) + \ . ' .' + +Execute(The gometalinter `lint_package` option should use the correct command): + let b:ale_go_gometalinter_lint_package = 1 + + AssertLinter 'gometalinter', ale#Escape('gometalinter') . ' .' diff --git a/vim-config/plugins/ale/test/linter/test_gopls.vader b/vim-config/plugins/ale/test/linter/test_gopls.vader new file mode 100644 index 00000000..1c91fa10 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_gopls.vader @@ -0,0 +1,96 @@ +Before: + Save g:ale_go_go111module + Save $GOPATH + + let $GOPATH = '/non/existent/directory' + + call ale#assert#SetUpLinterTest('go', 'gopls') + +After: + if isdirectory(g:dir . '/.git') + call delete(g:dir . '/.git', 'd') + endif + + unlet! b:ale_go_go111module + unlet! b:ale_go_go111module + unlet! b:ale_completion_enabled + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'gopls', ale#Escape('gopls') . ' --mode stdio' + +Execute(The executable should be configurable): + let b:ale_go_gopls_executable = 'boo' + + AssertLinter 'boo', ale#Escape('boo') . ' --mode stdio' + +Execute(gopls should be found in GOPATH): + " This is a directory with a fake executable + let $GOPATH = ale#test#GetFilename('../test-files/go/gopath') + + AssertLinter + \ ale#test#GetFilename('../test-files/go/gopath/bin/gopls'), + \ ale#Escape(ale#test#GetFilename('../test-files/go/gopath/bin/gopls')) + \ . ' --mode stdio' + +Execute(Global settings should be preferre for gopls if use_global = 1): + " This is a directory with a fake executable + let $GOPATH = ale#test#GetFilename('../test-files/go/gopath') + let b:ale_go_gopls_executable = 'boo' + let b:ale_go_gopls_use_global = 1 + + AssertLinter 'boo', ale#Escape('boo') . ' --mode stdio' + +Execute(Settings options should work): + call ale#test#SetFilename('../test-files/go/go1/prj1/file.go') + " let b:ale_completion_enabled = 1 + let b:ale_go_gopls_options = '' + + AssertLinter 'gopls', + \ ale#Escape('gopls') . '' + + let b:ale_go_gopls_options = '--mode stdio --trace' + + AssertLinter 'gopls', + \ ale#Escape('gopls') . ' --mode stdio --trace' + + let b:ale_go_gopls_init_options = {'ui.diagnostic.analyses': {'composites': v:false}} + AssertLSPOptions {'ui.diagnostic.analyses': {'composites': v:false}} + +Execute(Go environment variables should be passed on): + let b:ale_go_go111module = 'off' + + AssertLinter 'gopls', + \ ale#Env('GO111MODULE', 'off') . ale#Escape('gopls') . ' --mode stdio' + +Execute(Project directories should be detected based on 'go.mod' being present): + call ale#test#SetFilename('../test-files/go/test.go') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/go') + +Execute(Project directories with .git should be detected): + call ale#test#SetFilename('test.go') + + if !isdirectory(g:dir . '/.git') + call mkdir(g:dir . '/.git') + endif + + AssertLSPProject g:dir + +Execute('go.mod' should be ignored if modules are off): + call ale#test#SetFilename('../test-files/go/test.go') + + let b:ale_go_go111module = 'off' + let b:parent_dir = ale#path#Simplify(g:dir . '/..') + let b:git_dir = b:parent_dir . '/.git' + + if !isdirectory(b:git_dir) + call mkdir(b:git_dir) + endif + + AssertLSPProject b:parent_dir + + call delete(b:git_dir, 'd') + unlet! b:parent_dir + unlet! b:git_dir diff --git a/vim-config/plugins/ale/test/linter/test_gosimple.vader b/vim-config/plugins/ale/test/linter/test_gosimple.vader new file mode 100644 index 00000000..960f8ee9 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_gosimple.vader @@ -0,0 +1,19 @@ +Before: + Save g:ale_go_go111module + + call ale#assert#SetUpLinterTest('go', 'gosimple') + call ale#test#SetFilename('../test-files/go/testfile2.go') + +After: + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The default gosimple command should be correct): + AssertLinterCwd '%s:h' + AssertLinter 'gosimple', 'gosimple .' + +Execute(The gosimple command should support Go environment variables): + let b:ale_go_go111module = 'on' + + AssertLinter 'gosimple', ale#Env('GO111MODULE', 'on') . 'gosimple .' diff --git a/vim-config/plugins/ale/test/linter/test_gotype.vader b/vim-config/plugins/ale/test/linter/test_gotype.vader new file mode 100644 index 00000000..22829a17 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_gotype.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_go_go111module + + call ale#assert#SetUpLinterTest('go', 'gotype') + call ale#test#SetFilename('../test-files/go/testfile2.go') + +After: + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The default gotype command should be correct): + AssertLinterCwd '%s:h' + AssertLinter 'gotype', 'gotype -e .' + +Execute(The gotype callback should ignore test files): + call ale#test#SetFilename('bla_test.go') + + AssertLinterNotExecuted + +Execute(The gotype callback should support Go environment variables): + let b:ale_go_go111module = 'on' + + AssertLinter 'gotype', ale#Env('GO111MODULE', 'on') . 'gotype -e .' diff --git a/vim-config/plugins/ale/test/linter/test_govet.vader b/vim-config/plugins/ale/test/linter/test_govet.vader new file mode 100644 index 00000000..12ec168a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_govet.vader @@ -0,0 +1,32 @@ +Before: + Save g:ale_go_go_executable + Save g:ale_go_govet_options + Save g:ale_go_go111module + + call ale#assert#SetUpLinterTest('go', 'govet') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'go', 'go vet .' + +Execute(Extra options should be supported): + let g:ale_go_govet_options = '--foo-bar' + + AssertLinterCwd '%s:h' + AssertLinter 'go', 'go vet --foo-bar .' + +Execute(The executable should be configurable): + let g:ale_go_go_executable = 'foobar' + + AssertLinter 'foobar', 'foobar vet .' + +Execute(Go environment variables should be supported): + let b:ale_go_go111module = 'on' + + AssertLinter 'go', ale#Env('GO111MODULE', 'on') . 'go vet .' diff --git a/vim-config/plugins/ale/test/linter/test_graphql_gqlint.vader b/vim-config/plugins/ale/test/linter/test_graphql_gqlint.vader new file mode 100644 index 00000000..22c05a6a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_graphql_gqlint.vader @@ -0,0 +1,9 @@ +Before: + call ale#assert#SetUpLinterTest('graphql', 'gqlint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The linter should run from the directory of the file in the buffer): + AssertLinterCwd '%s:h' + AssertLinter 'gqlint', 'gqlint --reporter=simple %t' diff --git a/vim-config/plugins/ale/test/linter/test_haml_hamllint.vader b/vim-config/plugins/ale/test/linter/test_haml_hamllint.vader new file mode 100644 index 00000000..9d81179b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haml_hamllint.vader @@ -0,0 +1,41 @@ +Before: + call ale#assert#SetUpLinterTest('haml', 'hamllint') + + let g:default_command = 'haml-lint %t' + +After: + unlet! b:conf + unlet! b:conf_hamllint + unlet! b:conf_rubocop + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'haml-lint', 'haml-lint %t' + +Execute(The command should have the .rubocop.yml prepended as an env var if one exists): + call ale#test#SetFilename('../test-files/hamllint/rubocop-yml/subdir/file.haml') + let b:conf = ale#path#Simplify(g:dir . '/../test-files/hamllint/rubocop-yml/.rubocop.yml') + + AssertLinter 'haml-lint', + \ ale#Env('HAML_LINT_RUBOCOP_CONF', b:conf) . 'haml-lint %t' + +Execute(The command should have the nearest .haml-lint.yml set as --config if it exists): + call ale#test#SetFilename('../test-files/hamllint/haml-lint-yml/subdir/file.haml') + let b:conf = ale#path#Simplify(g:dir . '/../test-files/hamllint/haml-lint-yml/.haml-lint.yml') + + AssertLinter 'haml-lint', + \ 'haml-lint --config ' . ale#Escape(b:conf) . ' %t', + +Execute(The command should include a .rubocop.yml and a .haml-lint if both are found): + call ale#test#SetFilename('../test-files/hamllint/haml-lint-and-rubocop/subdir/file.haml') + let b:conf_hamllint = ale#path#Simplify(g:dir . '/../test-files/hamllint/haml-lint-and-rubocop/.haml-lint.yml') + let b:conf_rubocop = ale#path#Simplify(g:dir . '/../test-files/hamllint/haml-lint-and-rubocop/.rubocop.yml') + + AssertLinter 'haml-lint', + \ ale#Env('HAML_LINT_RUBOCOP_CONF', b:conf_rubocop) + \ . 'haml-lint --config ' . ale#Escape(b:conf_hamllint) . ' %t' + +Execute(The executable can be overridden): + let b:ale_haml_hamllint_executable = 'bin/haml-lint' + AssertLinter 'bin/haml-lint', 'bin/haml-lint %t' diff --git a/vim-config/plugins/ale/test/linter/test_haskell_cabal_ghc.vader b/vim-config/plugins/ale/test/linter/test_haskell_cabal_ghc.vader new file mode 100644 index 00000000..b4976b34 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haskell_cabal_ghc.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('haskell', 'cabal_ghc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The options should be used in the command): + AssertLinterCwd '%s:h' + AssertLinter 'cabal', 'cabal exec -- ghc -fno-code -v0 %t' + + let b:ale_haskell_cabal_ghc_options = 'foobar' + + AssertLinter 'cabal', 'cabal exec -- ghc foobar %t' diff --git a/vim-config/plugins/ale/test/linter/test_haskell_ghc.vader b/vim-config/plugins/ale/test/linter/test_haskell_ghc.vader new file mode 100644 index 00000000..2f33477d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haskell_ghc.vader @@ -0,0 +1,12 @@ +Before: + call ale#assert#SetUpLinterTest('haskell', 'ghc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The options should be used in the command): + AssertLinter 'ghc', 'ghc -fno-code -v0 %t' + + let b:ale_haskell_ghc_options = 'foobar' + + AssertLinter 'ghc', 'ghc foobar %t' diff --git a/vim-config/plugins/ale/test/linter/test_haskell_ghc_mod.vader b/vim-config/plugins/ale/test/linter/test_haskell_ghc_mod.vader new file mode 100644 index 00000000..c1cc8597 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haskell_ghc_mod.vader @@ -0,0 +1,10 @@ +Before: + call ale#assert#SetUpLinterTest('haskell', 'ghc_mod') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Default should use ghc-mod): + AssertLinter + \ 'ghc-mod', + \ ale#Escape('ghc-mod') . ' --map-file %s=%t check %s' diff --git a/vim-config/plugins/ale/test/linter/test_haskell_hdevtools.vader b/vim-config/plugins/ale/test/linter/test_haskell_hdevtools.vader new file mode 100644 index 00000000..0ef2f0e3 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haskell_hdevtools.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpLinterTest('haskell', 'hdevtools') + + let b:command_tail = ' check -g -Wall -p %s %t' + +After: + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'hdevtools', ale#Escape('hdevtools') . b:command_tail + + let b:ale_haskell_hdevtools_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail diff --git a/vim-config/plugins/ale/test/linter/test_haskell_hie.vader b/vim-config/plugins/ale/test/linter/test_haskell_hie.vader new file mode 100644 index 00000000..5bd2794c --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haskell_hie.vader @@ -0,0 +1,27 @@ +Before: + call ale#assert#SetUpLinterTest('haskell', 'hie') + + Save &filetype + let &filetype = 'haskell' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'haskell' + +Execute(The default executable should be correct): + AssertLinter 'hie', + \ ale#Escape('hie') . ' --lsp' + +Execute(The project root should be detected correctly): + AssertLSPProject g:dir + + call ale#test#SetFilename('hie_paths/file.hs') + + AssertLSPProject ale#path#Simplify(g:dir . '/hie_paths') + +Execute(The executable should be configurable): + let g:ale_haskell_hie_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --lsp' diff --git a/vim-config/plugins/ale/test/linter/test_haskell_hlint.vader b/vim-config/plugins/ale/test/linter/test_haskell_hlint.vader new file mode 100644 index 00000000..6d227c9d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haskell_hlint.vader @@ -0,0 +1,17 @@ +Before: + call ale#assert#SetUpLinterTest('haskell', 'hlint') + + let b:base_opts = '--color=never --json -' + +After: + unlet! b:base_opts + call ale#assert#TearDownLinterTest() + +Execute(executable should be configurable): + AssertLinter 'hlint', ale#Escape('hlint') . ' ' . b:base_opts + let b:ale_haskell_hlint_executable = 'myHlint' + AssertLinter 'myHlint', ale#Escape('myHlint') . ' ' . b:base_opts + +Execute(should accept options): + let b:ale_haskell_hlint_options= '-h myhlintfile.yaml' + AssertLinter 'hlint', ale#Escape('hlint') . ' -h myhlintfile.yaml ' . b:base_opts diff --git a/vim-config/plugins/ale/test/linter/test_haskell_hls.vader b/vim-config/plugins/ale/test/linter/test_haskell_hls.vader new file mode 100644 index 00000000..e64aab6f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haskell_hls.vader @@ -0,0 +1,27 @@ +Before: + call ale#assert#SetUpLinterTest('haskell', 'hls') + + Save &filetype + let &filetype = 'haskell' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'haskell' + +Execute(The default executable should be correct): + AssertLinter 'haskell-language-server-wrapper', + \ ale#Escape('haskell-language-server-wrapper') . ' --lsp' + +Execute(The project root should be detected correctly): + AssertLSPProject g:dir + + call ale#test#SetFilename('hls_paths/file.hs') + + AssertLSPProject ale#path#Simplify(g:dir . '/hls_paths') + +Execute(The executable should be configurable): + let g:ale_haskell_hls_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --lsp' diff --git a/vim-config/plugins/ale/test/linter/test_haskell_stack_build.vader b/vim-config/plugins/ale/test/linter/test_haskell_stack_build.vader new file mode 100644 index 00000000..8b5b0971 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haskell_stack_build.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('haskell', 'stack_build') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The linter should not be executed when there's no stack.yaml file): + AssertLinterNotExecuted + +Execute(The linter should be executed when there is a stack.yaml file): + call ale#test#SetFilename('../test-files/stack/test.hs') + + AssertLinter 'stack', 'stack build --fast' diff --git a/vim-config/plugins/ale/test/linter/test_haskell_stack_ghc.vader b/vim-config/plugins/ale/test/linter/test_haskell_stack_ghc.vader new file mode 100644 index 00000000..04bd23f5 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_haskell_stack_ghc.vader @@ -0,0 +1,18 @@ +Before: + call ale#assert#SetUpLinterTest('haskell', 'stack_ghc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The linter should not be executed when there's no stack.yaml file): + AssertLinterNotExecuted + +Execute(The linter should be executed when there is a stack.yaml file): + call ale#test#SetFilename('../test-files/stack/test.hs') + + AssertLinterCwd '%s:h' + AssertLinter 'stack', 'stack ghc -- -fno-code -v0 %t' + + let b:ale_haskell_stack_ghc_options = 'foobar' + + AssertLinter 'stack', 'stack ghc -- foobar %t' diff --git a/vim-config/plugins/ale/test/linter/test_hdl_checker_options.vader b/vim-config/plugins/ale/test/linter/test_hdl_checker_options.vader new file mode 100644 index 00000000..6e7eef46 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_hdl_checker_options.vader @@ -0,0 +1,86 @@ +Before: + call ale#assert#SetUpLinterTest('vhdl', 'hdl_checker') + + Save g:ale_hdl_checker_executable + Save g:ale_hdl_checker_config_file + Save g:ale_hdl_checker_options + + let g:default_config_file = has('unix') ? '.hdl_checker.config' : '_hdl_checker.config' + + runtime autoload/ale/handlers/hdl_checker.vim + +After: + Restore + + call ale#assert#TearDownLinterTest() + + unlet! g:default_config_file + unlet! g:call_count + + runtime autoload/ale/handlers/hdl_checker.vim + +Execute(Get default initialization dict): + AssertEqual + \ {'project_file': g:default_config_file}, + \ ale#handlers#hdl_checker#GetInitOptions(bufnr('')) + +Execute(Get custom initialization dict): + let g:ale_hdl_checker_config_file = 'some_file_name' + + AssertEqual + \ {'project_file': 'some_file_name'}, + \ ale#handlers#hdl_checker#GetInitOptions(bufnr('')) + +Execute(Get the checker command without extra user parameters): + AssertEqual + \ ale#Escape('hdl_checker') . ' --lsp', + \ ale#handlers#hdl_checker#GetCommand(bufnr('')) + +Execute(Get the checker command with user configured parameters): + let g:ale_hdl_checker_options = '--log-level DEBUG' + + AssertEqual + \ ale#Escape('hdl_checker') . ' --lsp --log-level DEBUG', + \ ale#handlers#hdl_checker#GetCommand(bufnr('')) + +Execute(Customize executable): + let g:ale_hdl_checker_executable = '/some/other/path' + AssertEqual + \ ale#Escape('/some/other/path') . ' --lsp', + \ ale#handlers#hdl_checker#GetCommand(bufnr('')) + +Execute(Get project root based on .git): + call ale#test#SetFilename('../test-files/hdl_server/with_git/files/foo.vhd') + " Create .git file + silent! call mkdir(g:dir . '/../test-files/hdl_server/with_git/.git') + AssertNotEqual '', glob(g:dir . '/../test-files/hdl_server/with_git/.git') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/hdl_server/with_git'), + \ ale#handlers#hdl_checker#GetProjectRoot(bufnr('')) + +Execute(Get project root based on config file): + call ale#test#SetFilename('../test-files/hdl_server/with_config_file/foo.vhd') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/hdl_server/with_config_file'), + \ ale#handlers#hdl_checker#GetProjectRoot(bufnr('')) + +Execute(Return no project root if neither .git or config file are found): + let g:call_count = 0 + + " Mock this command to avoid the test to find ale's own .git folder + function! ale#handlers#hdl_checker#IsDotGit(path) abort + let g:call_count += 1 + return 0 + endfunction + + call ale#test#SetFilename('../test-files/hdl_server/foo.vhd') + + AssertEqual + \ '', + \ ale#handlers#hdl_checker#GetProjectRoot(bufnr('')) + + AssertEqual g:call_count, 1 + + unlet! g:call_count diff --git a/vim-config/plugins/ale/test/linter/test_html_stylelint.vader b/vim-config/plugins/ale/test/linter/test_html_stylelint.vader new file mode 100644 index 00000000..c5ac1b98 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_html_stylelint.vader @@ -0,0 +1,60 @@ +Before: + Save g:ale_html_stylelint_executable + Save g:ale_html_stylelint_use_global + Save g:ale_html_stylelint_options + + unlet! b:executable + + unlet! g:ale_html_stylelint_executable + unlet! g:ale_html_stylelint_use_global + unlet! g:ale_html_stylelint_options + + call ale#test#SetDirectory('/testplugin/test/linter') + call ale#test#SetFilename('testfile.html') + + runtime ale_linters/html/stylelint.vim + +After: + Restore + + unlet! b:executable + unlet! b:ale_html_stylelint_executable + unlet! b:ale_html_stylelint_use_global + unlet! b:ale_html_stylelint_options + + call ale#test#SetFilename('test.txt') + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(node_modules directories should be discovered): + call ale#test#SetFilename('../test-files/stylelint/nested/testfile.html') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/stylelint/node_modules/.bin/stylelint' + \) + + AssertEqual b:executable, ale_linters#html#stylelint#GetExecutable(bufnr('')) + AssertEqual + \ ale#Escape(b:executable) . ' --stdin-filename %s', + \ ale_linters#html#stylelint#GetCommand(bufnr('')) + +Execute(The global override should work): + let b:ale_html_stylelint_executable = 'foobar' + let b:ale_html_stylelint_use_global = 1 + + call ale#test#SetFilename('../test-files/stylelint/nested/testfile.html') + + AssertEqual 'foobar', ale_linters#html#stylelint#GetExecutable(bufnr('')) + AssertEqual + \ ale#Escape('foobar') . ' --stdin-filename %s', + \ ale_linters#html#stylelint#GetCommand(bufnr('')) + +Execute(Extra options should be configurable): + let b:ale_html_stylelint_options = '--whatever' + + AssertEqual 'stylelint', ale_linters#html#stylelint#GetExecutable(bufnr('')) + AssertEqual + \ ale#Escape('stylelint') . ' --whatever --stdin-filename %s', + \ ale_linters#html#stylelint#GetCommand(bufnr('')) diff --git a/vim-config/plugins/ale/test/linter/test_htmlhint.vader b/vim-config/plugins/ale/test/linter/test_htmlhint.vader new file mode 100644 index 00000000..df5797af --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_htmlhint.vader @@ -0,0 +1,51 @@ +Before: + call ale#assert#SetUpLinterTest('html', 'htmlhint') + call ale#test#SetFilename('../test-files/htmlhint/test.html') + + let g:node_executable = ale#path#Simplify( + \ g:dir . '/../test-files/htmlhint/node_modules/.bin/htmlhint' + \) + let g:config_path = ale#path#Simplify( + \ g:dir . '/../test-files/htmlhint/with_config/.htmlhintrc' + \) + +After: + unlet! g:node_executable + unlet! g:config_path + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter g:node_executable, + \ ale#Escape(g:node_executable) . ' --format=unix %t' + +Execute(The global executable should be uesd if the option is set): + let g:ale_html_htmlhint_executable = 'foo' + let g:ale_html_htmlhint_use_global = 1 + + AssertLinter 'foo', ale#Escape('foo') . ' --format=unix %t', + +" This is so old configurations which might include this still work. +Execute(--format=unix should be removed from the options if added): + let g:ale_html_htmlhint_options = '--format=unix' + + AssertLinter g:node_executable, + \ ale#Escape(g:node_executable) . ' --format=unix %t' + +Execute(The configuration file should be automatically detected): + call ale#test#SetFilename('../test-files/htmlhint/with_config/test.html') + + AssertLinter g:node_executable, + \ ale#Escape(g:node_executable) + \ . ' --config ' . ale#Escape(g:config_path) + \ . ' --format=unix %t' + +" This is so old configurations which might include the config will work. +Execute(The configuration file should be configurable through the options variable): + call ale#test#SetFilename('../test-files/htmlhint/with_config/test.html') + let g:ale_html_htmlhint_options = '--config=/foo/bar/.htmlhintrc' + + AssertLinter g:node_executable, + \ ale#Escape(g:node_executable) + \ . ' --config=/foo/bar/.htmlhintrc' + \ . ' --format=unix %t' diff --git a/vim-config/plugins/ale/test/linter/test_ibm_openapi_validator.vader b/vim-config/plugins/ale/test/linter/test_ibm_openapi_validator.vader new file mode 100644 index 00000000..3484cc09 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ibm_openapi_validator.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('openapi', 'ibm_validator') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The yaml ibm-openapi-validator command callback should return the correct default string): + AssertLinter 'lint-openapi', ale#Escape('lint-openapi') . ' %t' + +Execute(The yaml ibm-openapi-validator command callback should be configurable): + let g:ale_openapi_ibm_validator_executable = '~/.local/bin/lint-openapi' + let g:ale_openapi_ibm_validator_options = '-c ~/.config' + + AssertLinter '~/.local/bin/lint-openapi', ale#Escape('~/.local/bin/lint-openapi') + \ . ' -c ~/.config %t' diff --git a/vim-config/plugins/ale/test/linter/test_idris.vader b/vim-config/plugins/ale/test/linter/test_idris.vader new file mode 100644 index 00000000..ce7cd270 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_idris.vader @@ -0,0 +1,21 @@ +Before: + call ale#assert#SetUpLinterTest('idris', 'idris') + +After: + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be used in the command): + AssertLinter 'idris', + \ ale#Escape('idris') . ' --total --warnpartial --warnreach --warnipkg --check %s' + + let b:ale_idris_idris_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' --total --warnpartial --warnreach --warnipkg --check %s' + +Execute(The options should be configurable): + let b:ale_idris_idris_options = '--something' + + AssertLinter 'idris', ale#Escape('idris') . ' --something --check %s' diff --git a/vim-config/plugins/ale/test/linter/test_ink_ls.vader b/vim-config/plugins/ale/test/linter/test_ink_ls.vader new file mode 100644 index 00000000..a832a250 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ink_ls.vader @@ -0,0 +1,22 @@ +Before: + call ale#assert#SetUpLinterTest('ink', 'ls') + set ft=ink + +After: + call ale#assert#TearDownLinterTest() + +Execute(should set correct defaults): + AssertLinter 'ink-language-server', ale#Escape('ink-language-server') . ' --stdio' + +Execute(should set correct LSP values): + call ale#test#SetFilename('../test-files/ink/story/main.ink') + + AssertLSPLanguage 'ink' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ink/story') + +Execute(should accept configuration settings): + AssertLSPConfig {} + let b:ale_ink_ls_initialization_options = {'ink': {'runThroughMono': v:true}} + AssertLSPOptions {'ink': {'runThroughMono': v:true}} diff --git a/vim-config/plugins/ale/test/linter/test_inko_inko.vader b/vim-config/plugins/ale/test/linter/test_inko_inko.vader new file mode 100644 index 00000000..c08cbed4 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_inko_inko.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('inko', 'inko') + call ale#test#SetFilename('../test-files/inko/test.inko') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'inko', ale#Escape('inko') . ' build --check --format=json %s' + +Execute(The inko callback should include tests/ for test paths): + call ale#engine#Cleanup(bufnr('')) + noautocmd e! ../test-files/inko/tests/test/test_foo.inko + call ale#engine#InitBufferInfo(bufnr('')) + + AssertLinter 'inko', + \ ale#Escape('inko') + \ . ' build --check --format=json --include ' + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/inko/tests/')) + \ . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_ispc_ispc.vader b/vim-config/plugins/ale/test/linter/test_ispc_ispc.vader new file mode 100644 index 00000000..f1aeb2f8 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ispc_ispc.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('ispc', 'ispc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'ispc', + \ ale#Escape('ispc') . ' --nowrap %s' + + let b:ale_ispc_ispc_executable = 'foo' + + AssertLinter 'foo', + \ ale#Escape('foo') . ' --nowrap %s' + +Execute(The options should be configurable): + let g:ale_ispc_ispc_options = '--foo' + + AssertLinter 'ispc', + \ ale#Escape('ispc') . ' --nowrap --foo' . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_iverilog.vader b/vim-config/plugins/ale/test/linter/test_iverilog.vader new file mode 100644 index 00000000..d7a29f05 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_iverilog.vader @@ -0,0 +1,14 @@ +Before: + call ale#assert#SetUpLinterTest('verilog', 'iverilog') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default iverilog command should be correct): + AssertLinter 'iverilog', 'iverilog -t null -Wall %t' + +Execute(iverilog options should be configurable): + " Additional args for the linter + let g:ale_verilog_iverilog_options = '-y.' + + AssertLinter 'iverilog', 'iverilog -t null -Wall -y. %t' diff --git a/vim-config/plugins/ale/test/linter/test_javac.vader b/vim-config/plugins/ale/test/linter/test_javac.vader new file mode 100644 index 00000000..85a76e6a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_javac.vader @@ -0,0 +1,326 @@ +Before: + call ale#assert#SetUpLinterTest('java', 'javac') + call ale#test#SetFilename('dummy.java') + + let g:cp_sep = has('unix') ? ':' : ';' + let g:prefix = ale#Escape('javac') . ' -Xlint' + + function! GetCommand(previous_output) abort + let l:command = ale_linters#java#javac#GetCommand( + \ bufnr(''), + \ a:previous_output + \) + + let l:split_command = split(l:command) + let l:index = index(l:split_command, '-d') + + let l:split_command[l:index + 1] = 'TEMP' + + return join(l:split_command) + endfunction + +After: + unlet! g:cp_sep + unlet! g:prefix + + delfunction GetCommand + + call ale#assert#TearDownLinterTest() + +Execute(The javac callback should return the correct default value): + AssertLinterCwd '%s:h' + AssertLinter 'javac', g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should use string type g:ale_java_javac_classpath correctly): + let g:ale_java_javac_classpath = 'foo.jar' + + AssertLinter 'javac', + \ g:prefix + \ . ' -cp ' . ale#Escape('foo.jar') + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should use list type g:ale_java_javac_classpath correctly): + let g:ale_java_javac_classpath = ['foo.jar'] + + AssertLinter 'javac', + \ g:prefix + \ . ' -cp ' . ale#Escape('foo.jar') + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The executable should be configurable): + let g:ale_java_javac_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -Xlint' + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should include discovered classpaths): + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [ + \ '[DEBUG] Ignore this.', + \ '[INFO] Something we should ignore.', + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \], {}) + + AssertEqual + \ g:prefix + \ . ' -cp ' + \ . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + +Execute(The javac callback should combine discovered classpaths and manual ones): + let g:ale_java_javac_classpath = 'configured.jar' + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [ + \ '[DEBUG] Ignore this.', + \ '[INFO] Something we should ignore.', + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \], {}) + + AssertEqual + \ g:prefix + \ . ' -cp ' + \ . ale#Escape(join( + \ [ + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \ 'configured.jar', + \ ], + \ g:cp_sep + \ )) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_classpath = 'configured.jar' . g:cp_sep . 'configured2.jar' + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [ + \ '[DEBUG] Ignore this.', + \ '[INFO] Something we should ignore.', + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \], {}) + + AssertEqual + \ g:prefix + \ . ' -cp ' + \ . ale#Escape(join( + \ [ + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \ 'configured.jar', + \ 'configured2.jar', + \ ], + \ g:cp_sep + \ )) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_classpath = ['configured.jar'] + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [ + \ '[DEBUG] Ignore this.', + \ '[INFO] Something we should ignore.', + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \], {}) + + AssertEqual + \ g:prefix + \ . ' -cp ' + \ . ale#Escape(join( + \ [ + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \ 'configured.jar', + \ ], + \ g:cp_sep + \ )) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_classpath = ['configured.jar', 'configured2.jar'] + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [ + \ '[DEBUG] Ignore this.', + \ '[INFO] Something we should ignore.', + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \], {}) + + AssertEqual + \ g:prefix + \ . ' -cp ' + \ . ale#Escape(join( + \ [ + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \ 'configured.jar', + \ 'configured2.jar', + \ ], + \ g:cp_sep + \ )) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + +Execute(The javac callback should use string type g:ale_java_javac_sourcepath correctly): + let g:ale_java_javac_sourcepath = '../test-files/java/with_main/build/gen/main' + + AssertLinter 'javac', + \ g:prefix + \ . ' -sourcepath ' . ale#Escape( + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/build/gen/main/') + \ ) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should use list type g:ale_java_javac_sourcepath correctly): + let g:ale_java_javac_sourcepath = ['../test-files/java/with_main/build/gen/main'] + + AssertLinter 'javac', + \ g:prefix + \ . ' -sourcepath ' . ale#Escape( + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/build/gen/main/') + \ ) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback shouldn't add -sourcepath when g:ale_java_javac_sourcepath variable path doesn't exist): + let g:ale_java_javac_sourcepath = '../test-files/java/with_main/build/gen3/main' + + AssertLinter 'javac', + \ g:prefix + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should combine discovered sourcepath and manual ones): + call ale#engine#Cleanup(bufnr('')) + call ale#test#SetFilename('../test-files/java/with_main/src/main/java/com/something/dummy.java') + call ale#engine#InitBufferInfo(bufnr('')) + + let g:ale_java_javac_sourcepath = '../test-files/java/with_main/build/gen/main' + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) + + AssertEqual + \ ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/src/main/java/'), + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/build/gen/main/'), + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_sourcepath = '../test-files/java/with_main/build/gen/main' + \ . g:cp_sep . '../test-files/java/with_main/build/gen2/main' + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) + + AssertEqual + \ ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/src/main/java/'), + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/build/gen/main/'), + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/build/gen2/main/') + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_sourcepath = ['../test-files/java/with_main/build/gen/main'] + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) + + AssertEqual + \ ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/src/main/java/'), + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/build/gen/main/') + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_sourcepath = [ + \ '../test-files/java/with_main/build/gen/main', + \ '../test-files/java/with_main/build/gen2/main' + \ ] + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) + + AssertEqual + \ ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/src/main/java/'), + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/build/gen/main/'), + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/build/gen2/main/') + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + +Execute(The javac callback should detect source directories): + call ale#engine#Cleanup(bufnr('')) + noautocmd e! ../test-files/java/with_main/src/main/java/com/something/dummy + call ale#engine#InitBufferInfo(bufnr('')) + + AssertLinter 'javac', + \ ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape( + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/src/main/java/') + \ ) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should combine detected source directories and classpaths): + call ale#engine#Cleanup(bufnr('')) + call ale#test#SetFilename('../test-files/java/with_main/src/main/java/com/something/dummy.java') + call ale#engine#InitBufferInfo(bufnr('')) + + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [ + \ '[DEBUG] Ignore this.', + \ '[INFO] Something we should ignore.', + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \], {}) + + AssertEqual + \ ale#Escape('javac') . ' -Xlint' + \ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep)) + \ . ' -sourcepath ' . ale#Escape( + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/src/main/java/') + \ ) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + +Execute(The javac callback should use g:ale_java_javac_options correctly): + let g:ale_java_javac_options = '--anything --else' + + AssertLinter 'javac', + \ g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' --anything --else %t' + +Execute(The javac callback should include src/test/java for test paths): + call ale#engine#Cleanup(bufnr('')) + " The test path is only included for test files. + " Regular Java files shouldn't import from tests. + noautocmd e! ../test-files/java/with_main/src/test/java/com/something/dummy + call ale#engine#InitBufferInfo(bufnr('')) + + AssertLinter 'javac', + \ ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/src/main/java/'), + \ ale#path#Simplify(g:dir . '/../test-files/java/with_main/src/test/java/'), + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should include src/main/jaxb when available): + call ale#engine#Cleanup(bufnr('')) + noautocmd e! ../test-files/java/with_jaxb/src/main/java/com/something/dummy + call ale#engine#InitBufferInfo(bufnr('')) + + AssertLinter 'javac', + \ ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/../test-files/java/with_jaxb/src/main/java/'), + \ ale#path#Simplify(g:dir . '/../test-files/java/with_jaxb/src/main/jaxb/'), + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should add -sourcepath even if src/java/main doesn't exist): + call ale#engine#Cleanup(bufnr('')) + call ale#test#SetFilename('../test-files/java/no_main/src/test/java/com/something/dummy.java') + call ale#engine#InitBufferInfo(bufnr('')) + + AssertLinter 'javac', + \ ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/../test-files/java/no_main/src/test/java/'), + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_javalsp.vader b/vim-config/plugins/ale/test/linter/test_javalsp.vader new file mode 100644 index 00000000..122f409b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_javalsp.vader @@ -0,0 +1,80 @@ + +Before: + call ale#assert#SetUpLinterTest('java', 'javalsp') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The javalsp callback should return the correct default value): + AssertLinter '', ale#Escape('') + +Execute(The javalsp java executable should be configurable): + let b:ale_java_javalsp_executable = '/bin/foobar' + + AssertLinter '/bin/foobar', ale#Escape('/bin/foobar') + +Execute(The javalsp callback should return backward compatible value): + let b:ale_java_javalsp_executable = '/bin/java' + let cmd = [ + \ ale#Escape('/bin/java'), + \ '--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', + \] + AssertLinter '/bin/java', join(cmd, ' ') + +Execute(The javalsp should have default config): + AssertEqual + \ { + \ 'java': { + \ 'classPath': [], + \ 'externalDependencies': [] + \ } + \ }, + \ ale_linters#java#javalsp#Config(bufnr('')) + +Execute(The javalsp should have default config if user sets empty hash): + let b:ale_java_javalsp_config = {} + + AssertEqual + \ { + \ 'java': { + \ 'classPath': [], + \ 'externalDependencies': [] + \ } + \ }, + \ ale_linters#java#javalsp#Config(bufnr('')) + +Execute(The javalsp should have add missing config): + let b:ale_java_javalsp_config = { 'java': { 'classPath': ['aaa.jar'] } } + + AssertEqual + \ { + \ 'java': { + \ 'classPath': ['aaa.jar'], + \ 'externalDependencies': [] + \ } + \ }, + \ ale_linters#java#javalsp#Config(bufnr('')) + + let b:ale_java_javalsp_config = + \ { + \ 'java': { + \ 'externalDependencies': ['unit-test:2.0.0'] + \ } + \ } + + AssertEqual + \ { + \ 'java': { + \ 'classPath': [], + \ 'externalDependencies': ['unit-test:2.0.0'] + \ } + \ }, + \ ale_linters#java#javalsp#Config(bufnr('')) diff --git a/vim-config/plugins/ale/test/linter/test_javascript_deno_lsp.vader b/vim-config/plugins/ale/test/linter/test_javascript_deno_lsp.vader new file mode 100644 index 00000000..965ce600 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_javascript_deno_lsp.vader @@ -0,0 +1,79 @@ +Before: + let g:ale_deno_importMap = 'import_map.json' + let g:ale_deno_unstable = 0 + let g:ale_deno_executable = 'deno' + let g:ale_deno_lsp_project_root = '' + + runtime autoload/ale/handlers/deno.vim + call ale#assert#SetUpLinterTest('javascript', 'deno') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Should set deno lsp for JavaScript projects using stable Deno API): + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false, + \ 'importMap': '' + \} + +Execute(Should set deno lsp using unstable Deno API if enabled by user): + let g:ale_deno_unstable = 1 + + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:true, + \ 'importMap': '' + \} + +Execute(Should set the default importMap filepath): + call ale#test#SetFilename('../test-files/javascript_deno/main.js') + + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false, + \ 'importMap': ale#path#Simplify(g:dir . '/../test-files/javascript_deno/import_map.json') + \} + +Execute(Should set the importMap filepath from user defined importMap): + let g:ale_deno_importMap = 'custom_import_map.json' + call ale#test#SetFilename('../test-files/javascript_deno/main.js') + + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false, + \ 'importMap': ale#path#Simplify(g:dir . '/../test-files/javascript_deno/custom_import_map.json') + \} + +Execute(Should set the importMap filepath from user defined importMap with unstable API): + let g:ale_deno_importMap = 'custom_import_map.json' + let g:ale_deno_unstable = 1 + call ale#test#SetFilename('../test-files/javascript_deno/main.js') + + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:true, + \ 'importMap': ale#path#Simplify(g:dir . '/../test-files/javascript_deno/custom_import_map.json') + \} + +Execute(Should find project root containing tsconfig.json): + call ale#test#SetFilename('../test-files/javascript_deno/main.js') + + AssertLSPLanguage 'javascript' + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/javascript_deno') + +Execute(Should use user-specified project root): + let g:ale_deno_lsp_project_root = '/' + + call ale#test#SetFilename('../test-files/javascript_deno/main.js') + + AssertLSPLanguage 'javascript' + AssertLSPProject '/' + +Execute(Check Deno LSP command): + AssertLinter 'deno', ale#Escape('deno') . ' lsp' diff --git a/vim-config/plugins/ale/test/linter/test_javascript_tsserver.vader b/vim-config/plugins/ale/test/linter/test_javascript_tsserver.vader new file mode 100644 index 00000000..1c29c8fd --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_javascript_tsserver.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpLinterTest('javascript', 'tsserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'tsserver', ale#Escape('tsserver') + +Execute(should resolve correct path when nested 1): + call ale#test#SetFilename('../test-files/tsserver/src/level-1/level-2/file3.ts') + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/tsserver/src/level-1') + +Execute(should resolve correct path when nested 2): + call ale#test#SetFilename('../test-files/tsserver/src/file1.ts') + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/tsserver') diff --git a/vim-config/plugins/ale/test/linter/test_jq.vader b/vim-config/plugins/ale/test/linter/test_jq.vader new file mode 100644 index 00000000..20c3db5b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_jq.vader @@ -0,0 +1,8 @@ +Before: + call ale#assert#SetUpLinterTest('json', 'jq') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'jq', ale#Escape('jq') diff --git a/vim-config/plugins/ale/test/linter/test_jscs.vader b/vim-config/plugins/ale/test/linter/test_jscs.vader new file mode 100644 index 00000000..7cdf5467 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_jscs.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('javascript', 'jscs') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Should return the correct default values): + AssertLinter 'jscs', + \ ale#Escape('jscs') . ' --reporter inline --no-colors -' + +Execute(Should allow using a custom executable): + let g:ale_javascript_jscs_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' --reporter inline --no-colors -' diff --git a/vim-config/plugins/ale/test/linter/test_jshint.vader b/vim-config/plugins/ale/test/linter/test_jshint.vader new file mode 100644 index 00000000..517c957c --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_jshint.vader @@ -0,0 +1,17 @@ +Before: + Save g:ale_jshint_config_loc + + unlet! g:ale_jshint_config_loc + + call ale#assert#SetUpLinterTest('javascript', 'jshint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'jshint', ale#Escape('jshint') . ' --reporter unix --extract auto --filename %s -' + +Execute(Setting a config location should add the config parameter): + let g:ale_jshint_config_loc = '/some/file' + + AssertLinter 'jshint', ale#Escape('jshint') . ' --reporter unix --extract auto --config ' . ale#Escape('/some/file') . ' --filename %s -' diff --git a/vim-config/plugins/ale/test/linter/test_jsonnet_lint.vader b/vim-config/plugins/ale/test/linter/test_jsonnet_lint.vader new file mode 100644 index 00000000..529ae008 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_jsonnet_lint.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('jsonnet', 'jsonnet_lint') + call ale#test#SetFilename('../jsonnet_files/testfile.jsonnet') + +After: + Restore + + call ale#assert#TearDownLinterTest() + +Execute(The default jsonnet-lint command should be correct): + AssertLinter 'jsonnet-lint', + \ ale#Escape('jsonnet-lint') . ' %t' + +Execute(jsonnet-lint command and options should be customizable): + let g:ale_jsonnet_jsonnet_lint_executable = 'jsonnet' + let g:ale_jsonnet_jsonnet_lint_options = 'fmt' + + AssertLinter 'jsonnet', + \ ale#Escape('jsonnet') . ' fmt %t' diff --git a/vim-config/plugins/ale/test/linter/test_jsonnetfmt.vader b/vim-config/plugins/ale/test/linter/test_jsonnetfmt.vader new file mode 100644 index 00000000..d070cd9f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_jsonnetfmt.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('jsonnet', 'jsonnetfmt') + call ale#test#SetFilename('../jsonnet_files/testfile.jsonnet') + +After: + Restore + + call ale#assert#TearDownLinterTest() + +Execute(The default jsonnetfmt command should be correct): + AssertLinter 'jsonnetfmt', + \ ale#Escape('jsonnetfmt') . ' %t' + +Execute(jsonnetfmt command and options should be customizable): + let g:ale_jsonnet_jsonnetfmt_executable = 'jsonnet' + let g:ale_jsonnet_jsonnetfmt_options = 'fmt' + + AssertLinter 'jsonnet', + \ ale#Escape('jsonnet') . ' fmt %t' diff --git a/vim-config/plugins/ale/test/linter/test_julia_languageserver.vader b/vim-config/plugins/ale/test/linter/test_julia_languageserver.vader new file mode 100644 index 00000000..d75665a0 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_julia_languageserver.vader @@ -0,0 +1,30 @@ +Before: + Save g:ale_julia_executable + + call ale#assert#SetUpLinterTest('julia', 'languageserver') + +After: + Restore + + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'julia', + \ ale#Escape('julia') . + \' --project=@. --startup-file=no --history-file=no -e ' . + \ ale#Escape('using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);') + +Execute(The executable should be configurable): + let g:ale_julia_executable = 'julia-new' + + AssertLinter 'julia-new', + \ ale#Escape('julia-new') . + \' --project=@. --startup-file=no --history-file=no -e ' . + \ ale#Escape('using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);') + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/julia/test.jl') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/julia') diff --git a/vim-config/plugins/ale/test/linter/test_kotlin_languageserver.vader b/vim-config/plugins/ale/test/linter/test_kotlin_languageserver.vader new file mode 100644 index 00000000..97b867ab --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_kotlin_languageserver.vader @@ -0,0 +1,23 @@ +Before: + call ale#assert#SetUpLinterTest('kotlin', 'languageserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'kotlin-language-server', ale#Escape('kotlin-language-server') + +Execute(Gradle project roots with build.gradle should be detected correctly): + call ale#test#SetFilename('../test-files/gradle/build-gradle-project/src/main/kotlin/dummy.kt') + + AssertLSPProject ale#test#GetFilename('../test-files/gradle/build-gradle-project') + +Execute(Maven project roots with pom.xml should be detected correctly): + call ale#test#SetFilename('../test-files/maven/maven-kotlin-project/src/main/kotlin/dummy.kt') + + AssertLSPProject ale#test#GetFilename('../test-files/maven/maven-kotlin-project') + +Execute(No root should be detected if configuration files can't be found): + call ale#test#SetFilename('../test-files/gradle/non-gradle-project/src/main/kotlin/dummy.kt') + + AssertLSPProject '' diff --git a/vim-config/plugins/ale/test/linter/test_kotlinc.vader b/vim-config/plugins/ale/test/linter/test_kotlinc.vader new file mode 100644 index 00000000..fe94bffa --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_kotlinc.vader @@ -0,0 +1,9 @@ +Before: + call ale#assert#SetUpLinterTest('kotlin', 'kotlinc') + call ale#test#SetFilename('test.kt') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'kotlinc', 'kotlinc ' . ale#Escape(expand('%:p')) diff --git a/vim-config/plugins/ale/test/linter/test_languagetool.vader b/vim-config/plugins/ale/test/linter/test_languagetool.vader new file mode 100644 index 00000000..ff6b2064 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_languagetool.vader @@ -0,0 +1,22 @@ +Before: + call ale#assert#SetUpLinterTest('text', 'languagetool') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'languagetool', ale#Escape('languagetool') + \ . ' --autoDetect %s' + +Execute(Should be able to set a custom executable): + let g:ale_languagetool_executable = 'foobar' + + AssertLinter 'foobar' , ale#Escape('foobar') + \ . ' --autoDetect %s' + +Execute(Should be able to include custom languagetool options): + let g:ale_languagetool_options = '--language en' + + " is now 'foobar' based on above global + AssertLinter 'foobar', ale#Escape('foobar') + \ . ' --language en %s' diff --git a/vim-config/plugins/ale/test/linter/test_less_stylelint.vader b/vim-config/plugins/ale/test/linter/test_less_stylelint.vader new file mode 100644 index 00000000..cbe7d23c --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_less_stylelint.vader @@ -0,0 +1,31 @@ +Before: + call ale#assert#SetUpLinterTest('less', 'stylelint') + unlet! b:executable + +After: + unlet! b:executable + call ale#assert#TearDownLinterTest() + +Execute(node_modules directories should be discovered): + call ale#test#SetFilename('../test-files/stylelint/nested/testfile.less') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/stylelint/node_modules/.bin/stylelint' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' --stdin-filename %s' + +Execute(The global override should work): + let b:ale_less_stylelint_executable = 'foobar' + let b:ale_less_stylelint_use_global = 1 + + call ale#test#SetFilename('../test-files/stylelint/nested/testfile.less') + + AssertLinter 'foobar', ale#Escape('foobar') . ' --stdin-filename %s' + +Execute(Extra options should be configurable): + let b:ale_less_stylelint_options = '--whatever' + + AssertLinter 'stylelint', + \ ale#Escape('stylelint') . ' --whatever --stdin-filename %s' diff --git a/vim-config/plugins/ale/test/linter/test_lessc.vader b/vim-config/plugins/ale/test/linter/test_lessc.vader new file mode 100644 index 00000000..b7d664c6 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_lessc.vader @@ -0,0 +1,46 @@ +Before: + call ale#assert#SetUpLinterTest('less', 'lessc') + call ale#test#SetFilename('testfile.less') + + unlet! b:executable + +After: + unlet! b:executable + + call ale#assert#TearDownLinterTest() + +Execute(node_modules directories should be discovered): + call ale#test#SetFilename('../test-files/lessc/nested/testfile.less') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/lessc/node_modules/.bin/lessc' + \) + + AssertLinter b:executable, ale#Escape(b:executable) + \ . ' --no-color --lint' + \ . ' --include-path=' + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/lessc/nested')) + \ . ' -' + +Execute(The global override should work): + let b:ale_less_lessc_executable = 'foobar' + let b:ale_less_lessc_use_global = 1 + + call ale#test#SetFilename('../test-files/lessc/nested/testfile.less') + + AssertLinter 'foobar', ale#Escape('foobar') + \ . ' --no-color --lint' + \ . ' --include-path=' + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/lessc/nested')) + \ . ' -' + +Execute(Extra options should be configurable): + let b:ale_less_lessc_options = '--whatever' + + AssertLinter 'lessc', ale#Escape('lessc') + \ . ' --no-color --lint' + \ . ' --include-path=' + \ . ale#Escape(ale#path#Simplify(g:dir)) + \ . ' --whatever' + \ . ' -' diff --git a/vim-config/plugins/ale/test/linter/test_lintr.vader b/vim-config/plugins/ale/test/linter/test_lintr.vader new file mode 100644 index 00000000..8f6fb88f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_lintr.vader @@ -0,0 +1,34 @@ +Before: + call ale#assert#SetUpLinterTest('r', 'lintr') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default lintr command should be correct): + AssertLinterCwd '%s:h' + AssertLinter 'Rscript', + \ 'Rscript --no-save --no-restore --no-site-file --no-init-file -e ' + \ . ale#Escape('suppressPackageStartupMessages(library(lintr));' + \ . 'lint(cache = FALSE, commandArgs(TRUE), ' + \ . 'with_defaults())') + \ . ' %t' + +Execute(The lintr options should be configurable): + let b:ale_r_lintr_options = 'with_defaults(object_usage_linter = NULL)' + + AssertLinter 'Rscript', + \ 'Rscript --no-save --no-restore --no-site-file --no-init-file -e ' + \ . ale#Escape('suppressPackageStartupMessages(library(lintr));' + \ . 'lint(cache = FALSE, commandArgs(TRUE), ' + \ . 'with_defaults(object_usage_linter = NULL))') + \ . ' %t' + +Execute(If the lint_package flag is set, lintr::lint_package should be called): + let b:ale_r_lintr_lint_package = 1 + + AssertLinter 'Rscript', + \ 'Rscript --no-save --no-restore --no-site-file --no-init-file -e ' + \ . ale#Escape('suppressPackageStartupMessages(library(lintr));' + \ . 'lint_package(cache = FALSE, ' + \ . 'linters = with_defaults())') + \ . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_llc.vader b/vim-config/plugins/ale/test/linter/test_llc.vader new file mode 100644 index 00000000..a0caaa48 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_llc.vader @@ -0,0 +1,21 @@ +Before: + call ale#assert#SetUpLinterTest('llvm', 'llc') + + function! AssertHasPrefix(str, prefix) abort + let msg = printf("'%s' is expected to be prefixed with '%s'", a:str, a:prefix) + AssertEqual stridx(a:str, a:prefix), 0, msg + endfunction + +After: + delfunction AssertHasPrefix + + call ale#assert#TearDownLinterTest() + +Execute(The llc command should be customizable): + AssertLinter 'llc', + \ ale#Escape('llc') . ' -filetype=null -o=' . g:ale#util#nul_file + + let g:ale_llvm_llc_executable = 'llc-5.0' + + AssertLinter 'llc-5.0', + \ ale#Escape('llc-5.0') . ' -filetype=null -o=' . g:ale#util#nul_file diff --git a/vim-config/plugins/ale/test/linter/test_luac.vader b/vim-config/plugins/ale/test/linter/test_luac.vader new file mode 100644 index 00000000..55f39cba --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_luac.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('lua', 'luac') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'luac', ale#Escape('luac') . ' -p -' + +Execute(The luac executable should be configurable): + let g:ale_lua_luac_executable = 'luac.sh' + + AssertLinter 'luac.sh', ale#Escape('luac.sh') . ' -p -' diff --git a/vim-config/plugins/ale/test/linter/test_luacheck.vader b/vim-config/plugins/ale/test/linter/test_luacheck.vader new file mode 100644 index 00000000..f0ef221c --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_luacheck.vader @@ -0,0 +1,23 @@ +Before: + call ale#assert#SetUpLinterTest('lua', 'luacheck') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The lua luacheck command callback should return the correct default string): + AssertLinter 'luacheck', + \ ale#Escape('luacheck') . ' --formatter plain --codes --filename %s -' + +Execute(The lua luacheck command callback should let you set options): + let g:ale_lua_luacheck_options = '--config filename' + + AssertLinter 'luacheck', + \ ale#Escape('luacheck') + \ . ' --config filename' + \ . ' --formatter plain --codes --filename %s -' + +Execute(The luacheck executable should be configurable): + let g:ale_lua_luacheck_executable = 'luacheck.sh' + + AssertLinter 'luacheck.sh', + \ ale#Escape('luacheck.sh') . ' --formatter plain --codes --filename %s -' diff --git a/vim-config/plugins/ale/test/linter/test_markdown_markdownlint.vader b/vim-config/plugins/ale/test/linter/test_markdown_markdownlint.vader new file mode 100644 index 00000000..12766cfd --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_markdown_markdownlint.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('markdown', 'markdownlint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'markdownlint', ale#Escape('markdownlint') . ' %s' + +Execute(The options should be configurable): + let g:ale_markdown_markdownlint_options = '--config ~/custom/.markdownlintrc' + + AssertLinter 'markdownlint', ale#Escape('markdownlint') . ' --config ~/custom/.markdownlintrc %s' diff --git a/vim-config/plugins/ale/test/linter/test_markdown_mdl.vader b/vim-config/plugins/ale/test/linter/test_markdown_mdl.vader new file mode 100644 index 00000000..1ce4db1a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_markdown_mdl.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('markdown', 'mdl') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'mdl', ale#Escape('mdl') . ' -j' + +Execute(The executable and options should be configurable): + let g:ale_markdown_mdl_executable = 'foo bar' + let g:ale_markdown_mdl_options = '--wat' + + AssertLinter 'foo bar', ale#Escape('foo bar') . ' -j --wat' + +Execute(Setting bundle appends 'exec mdl'): + let g:ale_markdown_mdl_executable = 'path to/bundle' + + AssertLinter 'path to/bundle', ale#Escape('path to/bundle') . ' exec mdl -j' diff --git a/vim-config/plugins/ale/test/linter/test_markdown_vale.vader b/vim-config/plugins/ale/test/linter/test_markdown_vale.vader new file mode 100644 index 00000000..5300805b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_markdown_vale.vader @@ -0,0 +1,32 @@ +Before: + call ale#assert#SetUpLinterTest('markdown', 'vale') + call ale#test#SetFilename('dummy.md') + + let g:ale_markdown_vale_executable = 'vale' + let g:ale_markdown_vale_input_file = '%t' + let g:ale_markdown_vale_options = '' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to vale): + AssertLinter 'vale', ale#Escape('vale') + \ . ' --output=JSON %t' + +Execute(Should be able to set a custom executable): + let g:ale_markdown_vale_executable = 'bin/vale' + + AssertLinter 'bin/vale' , ale#Escape('bin/vale') + \ . ' --output=JSON %t' + +Execute(Should be able to set custom options): + let g:ale_markdown_vale_options = '--foo --bar' + + AssertLinter 'vale', ale#Escape('vale') + \ . ' --output=JSON --foo --bar %t' + +Execute(Should be able to set a custom input file): + let g:ale_markdown_vale_input_file = '%s' + + AssertLinter 'vale', ale#Escape('vale') + \ . ' --output=JSON %s' diff --git a/vim-config/plugins/ale/test/linter/test_mercury_mmc.vader b/vim-config/plugins/ale/test/linter/test_mercury_mmc.vader new file mode 100644 index 00000000..5ab5e74f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_mercury_mmc.vader @@ -0,0 +1,22 @@ +Before: + call ale#assert#SetUpLinterTest('mercury', 'mmc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinterCwd '%s:h' + AssertLinter 'mmc', + \ ale#Escape('mmc') . ' --errorcheck-only --make --output-compile-error-lines 100 %s:t:r' + +Execute(The executable should be configurable): + let b:ale_mercury_mmc_executable = 'foo' + + AssertLinter 'foo', + \ ale#Escape('foo') . ' --errorcheck-only --make --output-compile-error-lines 100 %s:t:r' + +Execute(The options should be configurable): + let b:ale_mercury_mmc_options = '--bar' + + AssertLinter 'mmc', + \ ale#Escape('mmc') . ' --errorcheck-only --bar %s:t:r' diff --git a/vim-config/plugins/ale/test/linter/test_mypy.vader b/vim-config/plugins/ale/test/linter/test_mypy.vader new file mode 100644 index 00000000..bac59d92 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_mypy.vader @@ -0,0 +1,106 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'mypy') + call ale#test#SetFilename('test.py') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + unlet! b:bin_dir + unlet! b:executable + + call ale#assert#TearDownLinterTest() + +Execute(The mypy callbacks should return the correct default values): + AssertLinterCwd g:dir + AssertLinter 'mypy', + \ ale#Escape('mypy') + \ . ' --show-column-numbers' + \ . ' --shadow-file %s %t %s' + +Execute(The mypy executable should be configurable, and escaped properly): + let g:ale_python_mypy_executable = 'executable with spaces' + + AssertLinter 'executable with spaces', + \ ale#Escape('executable with spaces') + \ . ' --show-column-numbers' + \ . ' --shadow-file %s %t %s' + +Execute(The mypy command callback should let you set options): + let g:ale_python_mypy_options = '--some-option' + + AssertLinter 'mypy', + \ ale#Escape('mypy') + \ . ' --some-option' + \ . ' --show-column-numbers' + \ . ' --shadow-file %s %t %s' + +Execute(The mypy command should switch directories to the detected project root): + call ale#test#SetFilename('../test-files/python/no_virtualenv/subdir/foo/bar.py') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/no_virtualenv/subdir') + AssertLinter 'mypy', + \ ale#Escape('mypy') + \ . ' --show-column-numbers' + \ . ' --shadow-file %s %t %s' + +Execute(The mypy callbacks should detect virtualenv directories and switch to the project root): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let b:executable = ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/mypy') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/subdir') + AssertLinter b:executable, + \ ale#Escape(b:executable) + \ . ' --show-column-numbers' + \ . ' --shadow-file %s %t %s' + +Execute(The mypy callbacks should cd to directory containing mypy.ini if found): + call ale#test#SetFilename('../test-files/python/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/with_mypy_ini_and_pytest_ini') + AssertLinter 'mypy', + \ ale#Escape('mypy') + \ . ' --show-column-numbers' + \ . ' --shadow-file %s %t %s' + +Execute(You should able able to use the global mypy instead): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + let g:ale_python_mypy_use_global = 1 + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/subdir') + AssertLinter 'mypy', + \ ale#Escape('mypy') + \ . ' --show-column-numbers' + \ . ' --shadow-file %s %t %s' + +Execute(Setting executable to 'pipenv' appends 'run mypy'): + let g:ale_python_mypy_executable = 'path/to/pipenv' + + AssertLinterCwd expand('#' . bufnr('') . ':p:h') + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') . ' run mypy' + \ . ' --show-column-numbers --shadow-file %s %t %s' + +Execute(Pipenv is detected when python_mypy_auto_pipenv is set): + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + let g:ale_python_mypy_auto_pipenv = 1 + + AssertLinterCwd expand('#' . bufnr('') . ':p:h') + AssertLinter 'pipenv', + \ ale#Escape('pipenv') . ' run mypy --show-column-numbers --shadow-file %s %t %s' + +Execute(Setting executable to 'poetry' appends 'run mypy'): + let g:ale_python_mypy_executable = 'path/to/poetry' + + AssertLinterCwd expand('#' . bufnr('') . ':p:h') + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') . ' run mypy' + \ . ' --show-column-numbers --shadow-file %s %t %s' + +Execute(Poetry is detected when python_mypy_auto_poetry is set): + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + let g:ale_python_mypy_auto_poetry = 1 + + AssertLinterCwd expand('#' . bufnr('') . ':p:h') + AssertLinter 'poetry', + \ ale#Escape('poetry') . ' run mypy --show-column-numbers --shadow-file %s %t %s' diff --git a/vim-config/plugins/ale/test/linter/test_nagelfar.vader b/vim-config/plugins/ale/test/linter/test_nagelfar.vader new file mode 100644 index 00000000..94bb1d53 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_nagelfar.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('tcl', 'nagelfar') + +After: + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'nagelfar.tcl', ale#Escape('nagelfar.tcl') . ' %s' + + let b:ale_tcl_nagelfar_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' %s' + +Execute(The options should be configurable): + let b:ale_tcl_nagelfar_options = '--something' + + AssertLinter 'nagelfar.tcl', ale#Escape('nagelfar.tcl') . ' --something %s' diff --git a/vim-config/plugins/ale/test/linter/test_nasm_nasm.vader b/vim-config/plugins/ale/test/linter/test_nasm_nasm.vader new file mode 100644 index 00000000..2bfe2b0d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_nasm_nasm.vader @@ -0,0 +1,32 @@ +Before: + call ale#assert#SetUpLinterTest('nasm', 'nasm') + + let b:command_tail = + \ ' -X gnu -I %s:h' . (has('win32') ? '\' : '/') . ' %s -o ' . (has('win32') ? 'NUL' : '/dev/null') + let b:command_tail_opt = + \ ' -X gnu -I %s:h' . (has('win32') ? '\' : '/') . ' -w+orphan-labels %s -o ' . (has('win32') ? 'NUL' : '/dev/null') + +After: + unlet! b:command_tail + unlet! b:command_tail_opt + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'nasm', ale#Escape('nasm') . b:command_tail, + + let b:ale_nasm_nasm_executable = '~/nasm' + + AssertLinter '~/nasm', ale#Escape('~/nasm') . b:command_tail + +Execute(The options should be configurable): + let b:ale_nasm_nasm_options = '-w-macro-params' + + AssertLinter 'nasm', ale#Escape('nasm') + \ . ' -X gnu -I %s:h' . (has('win32') ? '\' : '/') + \ . ' -w-macro-params %s -o ' . (has('win32') ? 'NUL' : '/dev/null') + +Execute(The options should be used in command): + let b:ale_nasm_nasm_options = '-w+orphan-labels' + + AssertLinter 'nasm', ale#Escape('nasm') . b:command_tail_opt diff --git a/vim-config/plugins/ale/test/linter/test_nimlsp.vader b/vim-config/plugins/ale/test/linter/test_nimlsp.vader new file mode 100644 index 00000000..c109deef --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_nimlsp.vader @@ -0,0 +1,12 @@ +Before: + call ale#assert#SetUpLinterTest('nim', 'nimlsp') + +After: + call ale#assert#TearDownLinterTest() + +Execute(It does not set nim sources by default): + AssertLinter 'nimlsp', ale#Escape('nimlsp') + +Execute(Sets nimlsp and escapes sources from g:ale_nim_nimlsp_nim_sources): + let g:ale_nim_nimlsp_nim_sources = '/path/to /Nim' + AssertLinter 'nimlsp', ale#Escape('nimlsp') . ' ' . ale#Escape('/path/to /Nim') diff --git a/vim-config/plugins/ale/test/linter/test_objc_ccls.vader b/vim-config/plugins/ale/test/linter/test_objc_ccls.vader new file mode 100644 index 00000000..58d824c5 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_objc_ccls.vader @@ -0,0 +1,66 @@ +Before: + call ale#assert#SetUpLinterTest('objc', 'ccls') + + Save b:ale_c_build_dir_names + Save b:ale_objc_ccls_executable + Save b:ale_objc_ccls_init_options + +After: + call ale#assert#TearDownLinterTest() + +Execute(The project root should be detected correctly using compile_commands.json file): + call ale#test#SetFilename(tempname() . '/dummy.m') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ccls/with_compile_commands_json/dummy.m') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ccls/with_compile_commands_json') + +Execute(The project root should be detected correctly using .ccls file): + call ale#test#SetFilename(tempname() . '/dummy.m') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ccls/with_ccls/dummy.m') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ccls/with_ccls') + +Execute(The project root should be detected correctly using .ccls-root file): + call ale#test#SetFilename(tempname() . '/dummy.m') + + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ccls/with_ccls-root/dummy.m') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ccls/with_ccls-root') + +Execute(The executable should be configurable): + AssertLinter 'ccls', ale#Escape('ccls') + + let b:ale_objc_ccls_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + +Execute(The initialization options should be configurable): + AssertLSPOptions {} + + let b:ale_objc_ccls_init_options = { 'cacheDirectory': '/tmp/ccls' } + + AssertLSPOptions { 'cacheDirectory': '/tmp/ccls' } + +Execute(The compile command database should be detected correctly): + call ale#test#SetFilename('../test-files/ccls/with_ccls/dummy.c') + + AssertLSPOptions {} + + call ale#test#SetFilename('../test-files/ccls/with_compile_commands_json/dummy.c') + + AssertLSPOptions { 'compilationDatabaseDirectory': + \ ale#path#Simplify(g:dir . '/../test-files/ccls/with_compile_commands_json') } + + call ale#test#SetFilename('../test-files/ccls/with_build_dir/dummy.c') + let b:ale_c_build_dir_names = ['unusual_build_dir_name'] + + AssertLSPOptions { 'compilationDatabaseDirectory': + \ ale#path#Simplify(g:dir . '/../test-files/ccls/with_build_dir/unusual_build_dir_name') } diff --git a/vim-config/plugins/ale/test/linter/test_ocaml_ocamllsp.vader b/vim-config/plugins/ale/test/linter/test_ocaml_ocamllsp.vader new file mode 100644 index 00000000..4f33af18 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ocaml_ocamllsp.vader @@ -0,0 +1,29 @@ +Before: + call ale#assert#SetUpLinterTest('ocaml', 'ocamllsp') + + Save &filetype + let &filetype = 'ocaml' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'ocaml' + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ocamllsp/file.ml') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ocamllsp') + +Execute(The executable should be run using opam exec by default): + call ale#test#SetFilename('../test-files/ocamllsp/file.ml') + + AssertLinter 'ocamllsp', 'opam config exec -- ocamllsp' + +Execute(The executable should be run directly if use_opam flag is disabled): + let g:ale_ocaml_ocamllsp_use_opam = 0 + call ale#test#SetFilename('../test-files/ocamllsp/file.ml') + + AssertLinter 'ocamllsp', 'ocamllsp' diff --git a/vim-config/plugins/ale/test/linter/test_ocaml_ols.vader b/vim-config/plugins/ale/test/linter/test_ocaml_ols.vader new file mode 100644 index 00000000..bf9ae65b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ocaml_ols.vader @@ -0,0 +1,40 @@ +Before: + call ale#assert#SetUpLinterTest('ocaml', 'ols') + + Save &filetype + let &filetype = 'ocaml' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'ocaml' + +Execute(The default executable should be correct): + AssertLinter 'ocaml-language-server', + \ ale#Escape('ocaml-language-server') . ' --stdio' + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ols/file.ml') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ols') + +Execute(The local executable should be used when available): + call ale#test#SetFilename('../test-files/ols/file.ml') + + AssertLinter ale#path#Simplify(g:dir . '/../test-files/ols/node_modules/.bin/ocaml-language-server'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/ols/node_modules/.bin/ocaml-language-server')) . ' --stdio' + +Execute(The gloabl executable should always be used when use_global is set): + let g:ale_ocaml_ols_use_global = 1 + call ale#test#SetFilename('../test-files/ols/file.ml') + + AssertLinter 'ocaml-language-server', + \ ale#Escape('ocaml-language-server') . ' --stdio' + +Execute(The executable should be configurable): + let g:ale_ocaml_ols_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --stdio' diff --git a/vim-config/plugins/ale/test/linter/test_ocamlinterface_ocamllsp.vader b/vim-config/plugins/ale/test/linter/test_ocamlinterface_ocamllsp.vader new file mode 100644 index 00000000..aa0b2100 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ocamlinterface_ocamllsp.vader @@ -0,0 +1,29 @@ +Before: + call ale#assert#SetUpLinterTest('ocamlinterface', 'ocamllsp') + + Save &filetype + let &filetype = 'ocamlinterface' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'ocaml.interface' + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ocamllsp/file.ml') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ocamllsp') + +Execute(The executable should be run using opam exec by default): + call ale#test#SetFilename('../test-files/ocamllsp/file.ml') + + AssertLinter 'ocamllsp', 'opam config exec -- ocamllsp' + +Execute(The executable should be run directly if use_opam flag is disabled): + let g:ale_ocaml_ocamllsp_use_opam = 0 + call ale#test#SetFilename('../test-files/ocamllsp/file.ml') + + AssertLinter 'ocamllsp', 'ocamllsp' diff --git a/vim-config/plugins/ale/test/linter/test_perl.vader b/vim-config/plugins/ale/test/linter/test_perl.vader new file mode 100644 index 00000000..3c4b661c --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_perl.vader @@ -0,0 +1,14 @@ +Before: + call ale#assert#SetUpLinterTest('perl', 'perl') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default Perl command callback should be correct): + AssertLinter 'perl', ale#Escape('perl') . ' -c -Mwarnings -Ilib %t' + +Execute(Overriding the executable and command should work): + let b:ale_perl_perl_executable = 'foobar' + let b:ale_perl_perl_options = '-w' + + AssertLinter 'foobar', ale#Escape('foobar') . ' -w %t' diff --git a/vim-config/plugins/ale/test/linter/test_perl6.vader b/vim-config/plugins/ale/test/linter/test_perl6.vader new file mode 100644 index 00000000..d3ec6e17 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_perl6.vader @@ -0,0 +1,14 @@ +Before: + call ale#assert#SetUpLinterTest('perl6', 'perl6') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default Perl6 command callback should be correct): + AssertLinter 'perl6', 'perl6' . ' -c -Ilib %t' + +Execute(Overriding the executable and command should work): + let b:ale_perl6_perl6_executable = 'foobar' + let b:ale_perl6_perl6_options = '-w' + + AssertLinter 'foobar', 'foobar' . ' -w %t' diff --git a/vim-config/plugins/ale/test/linter/test_perlcritic.vader b/vim-config/plugins/ale/test/linter/test_perlcritic.vader new file mode 100644 index 00000000..0f1e2856 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_perlcritic.vader @@ -0,0 +1,36 @@ +Before: + call ale#assert#SetUpLinterTest('perl', 'perlcritic') + call ale#test#SetFilename('test.pl') + let g:ale_perl_perlcritic_profile = '' + +After: + unlet! b:readme_path + call ale#assert#TearDownLinterTest() + +Execute(The command should be correct with g:ale_perl_perlcritic_showrules off): + let b:ale_perl_perlcritic_showrules = 0 + + AssertLinter 'perlcritic', ale#Escape('perlcritic') + \ . ' --verbose ' . ale#Escape('%l:%c %m\n') . ' --nocolor' + +Execute(The command should be correct with g:ale_perl_perlcritic_showrules on): + let b:ale_perl_perlcritic_showrules = 1 + + AssertLinter 'perlcritic', ale#Escape('perlcritic') + \ . ' --verbose ' . ale#Escape('%l:%c %m [%p]\n') . ' --nocolor' + +Execute(The command search for the profile file when set): + let b:ale_perl_perlcritic_profile = 'README.md' + + let b:readme_path = ale#path#Simplify(expand('%:p:h:h:h') . '/README.md') + + AssertLinter 'perlcritic', ale#Escape('perlcritic') + \ . ' --verbose ' . ale#Escape('%l:%c %m\n') . ' --nocolor' + \ . ' --profile ' . ale#Escape(b:readme_path) + +Execute(Extra options should be set appropriately): + let b:ale_perl_perlcritic_options = 'beep boop' + + AssertLinter 'perlcritic', ale#Escape('perlcritic') + \ . ' --verbose ' . ale#Escape('%l:%c %m\n') . ' --nocolor' + \ . ' beep boop' diff --git a/vim-config/plugins/ale/test/linter/test_php.vader b/vim-config/plugins/ale/test/linter/test_php.vader new file mode 100644 index 00000000..670d7196 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_php.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('php', 'php') + let b:command_tail = ' -l -d error_reporting=E_ALL -d display_errors=1' + \ . ' -d log_errors=0 --' + +After: + unlet! b:command_tail + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'php', ale#Escape('php') . b:command_tail + + let b:ale_php_php_executable = '/path/to/php' + + AssertLinter '/path/to/php', ale#Escape('/path/to/php') . b:command_tail diff --git a/vim-config/plugins/ale/test/linter/test_php_intelephense.vader b/vim-config/plugins/ale/test/linter/test_php_intelephense.vader new file mode 100644 index 00000000..d6e2469d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_php_intelephense.vader @@ -0,0 +1,26 @@ +Before: + call ale#assert#SetUpLinterTest('php', 'intelephense') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'intelephense', + \ ale#Escape('intelephense') . ' --stdio' + +Execute(The project path should be correct for .git directories): + call ale#test#SetFilename('../test-files/php/with-git/test.php') + silent! call mkdir('../test-files/php/with-git/.git', 'p') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/php/with-git') + +Execute(The project path should be correct for composer.json file): + call ale#test#SetFilename('../test-files/php/with-composer/test.php') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/php/with-composer') + +Execute(The project cache should be saved in a temp dir): + call ale#test#SetFilename('../test-files/php/with-composer/test.php') + let g:ale_php_intelephense_config = { 'storagePath': '/tmp/intelephense' } + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/php/with-composer') diff --git a/vim-config/plugins/ale/test/linter/test_php_langserver.vader b/vim-config/plugins/ale/test/linter/test_php_langserver.vader new file mode 100644 index 00000000..7fe20b82 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_php_langserver.vader @@ -0,0 +1,30 @@ +Before: + call ale#assert#SetUpLinterTest('php', 'langserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'php-language-server.php', + \ 'php ' . ale#Escape('php-language-server.php') + +Execute(Vendor executables should be detected): + call ale#test#SetFilename('../test-files/php/test.php') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/php/vendor/bin/php-language-server.php'), + \ 'php ' . ale#Escape(ale#path#Simplify( + \ g:dir + \ . '/../test-files/php/vendor/bin/php-language-server.php' + \ )) + +Execute(The project path should be correct for .git directories): + call ale#test#SetFilename('../test-files/php/with-git/test.php') + silent! call mkdir('../test-files/php/with-git/.git') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/php/with-git') + +Execute(The project path should be correct for composer.json file): + call ale#test#SetFilename('../test-files/php/with-composer/test.php') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/php/with-composer') diff --git a/vim-config/plugins/ale/test/linter/test_phpcs.vader b/vim-config/plugins/ale/test/linter/test_phpcs.vader new file mode 100644 index 00000000..afb88e32 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_phpcs.vader @@ -0,0 +1,42 @@ +Before: + call ale#assert#SetUpLinterTest('php', 'phpcs') + +After: + unlet! g:executable + + call ale#assert#TearDownLinterTest() + +Execute(The local phpcs executable should be used): + call ale#test#SetFilename('../test-files/phpcs/project-with-phpcs/foo/test.php') + + let g:executable = ale#path#Simplify(g:dir . '/../test-files/phpcs/project-with-phpcs/vendor/bin/phpcs') + + AssertLinterCwd '%s:h' + AssertLinter g:executable, ale#Escape(g:executable) + \ . ' -s --report=emacs --stdin-path=%s' + +Execute(use_global should override local executable detection): + let g:ale_php_phpcs_use_global = 1 + + call ale#test#SetFilename('../test-files/phpcs/project-with-phpcs/foo/test.php') + + AssertLinter 'phpcs', ale#Escape('phpcs') + \ . ' -s --report=emacs --stdin-path=%s' + +Execute(Projects without local executables should use the global one): + call ale#test#SetFilename('../test-files/phpcs/project-without-phpcs/foo/test.php') + + AssertLinter 'phpcs', ale#Escape('phpcs') + \ . ' -s --report=emacs --stdin-path=%s' + +Execute(User provided options should be used): + let g:ale_php_phpcs_options = '--my-user-provided-option my-value' + + AssertLinter 'phpcs', ale#Escape('phpcs') + \ . ' -s --report=emacs --stdin-path=%s --my-user-provided-option my-value' + +Execute(The _standard option should be used): + let g:ale_php_phpcs_standard = 'foobar' + + AssertLinter 'phpcs', ale#Escape('phpcs') + \ . ' -s --report=emacs --stdin-path=%s --standard=' . ale#Escape('foobar') diff --git a/vim-config/plugins/ale/test/linter/test_phpmd.vader b/vim-config/plugins/ale/test/linter/test_phpmd.vader new file mode 100644 index 00000000..64922820 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_phpmd.vader @@ -0,0 +1,12 @@ +Before: + call ale#assert#SetUpLinterTest('php', 'phpmd') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Custom executables should be used for the executable and command): + let g:ale_php_phpmd_executable = 'phpmd_test' + + AssertLinter 'phpmd_test', + \ ale#Escape('phpmd_test') + \ . ' %s text cleancode,codesize,controversial,design,naming,unusedcode --ignore-violations-on-exit %t' diff --git a/vim-config/plugins/ale/test/linter/test_phpstan.vader b/vim-config/plugins/ale/test/linter/test_phpstan.vader new file mode 100644 index 00000000..b5b3d3b7 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_phpstan.vader @@ -0,0 +1,115 @@ +Before: + call ale#assert#SetUpLinterTest('php', 'phpstan') + + let g:old_dir = g:dir + + " Create a temporary directory and work within it, otherwise these tests + " cannot be run in parallel. + let g:dir = tempname() + call mkdir(g:dir, '', 0750) + silent! execute 'cd ' . fnameescape(g:dir) + silent! noautocmd execute 'file ' . fnameescape(ale#path#Simplify(g:dir . '/test.php')) + + call delete('./phpstan.neon') + + GivenCommandOutput ['0.10.2'] + +After: + silent! execute 'cd ' . fnameescape(g:old_dir) + call delete(g:dir, 'rf') + let g:dir = g:old_dir + unlet! g:old_dir + call ale#assert#TearDownLinterTest() + +Execute(The local phpstan executable should be used): + call mkdir('vendor/bin', 'p', 0750) + call writefile([''], 'vendor/bin/phpstan') + call ale#test#SetFilename('phpstan-test-files/foo/test.php') + + let g:executable = ale#path#Simplify(g:dir . '/vendor/bin/phpstan') + + AssertLinter g:executable, + \ ale#Escape(g:executable) . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('4') . ' %s' + +Execute(use_global should override local executable detection): + let g:ale_php_phpstan_use_global = 1 + + call mkdir('vendor/bin', 'p', 0750) + call writefile([''], 'vendor/bin/phpstan') + call ale#test#SetFilename('phpstan-test-files/foo/test.php') + + AssertLinter 'phpstan', + \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('4') . ' %s' + +Execute(Custom executables should be used for the executable and command): + let g:ale_php_phpstan_executable = 'phpstan_test' + + AssertLinter 'phpstan_test', + \ ale#Escape('phpstan_test') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('4') . ' %s' + +Execute(project with level set to 3): + call ale#test#SetFilename('phpstan-test-files/foo/test.php') + let g:ale_php_phpstan_level = 3 + + AssertLinter 'phpstan', + \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('3') . ' %s' + +Execute(Custom phpstan configuration file): + let g:ale_php_phpstan_configuration = 'phpstan_config' + + AssertLinter 'phpstan', + \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -c ' . ale#Escape('phpstan_config') . ' -l ' . ale#Escape('4') . ' %s' + +Execute(Choose the right format for error format param): + GivenCommandOutput ['0.10.3'] + + AssertLinter 'phpstan', [ + \ ale#Escape('phpstan') . ' --version', + \ ale#Escape('phpstan') . ' analyze --no-progress --error-format json -l ' . ale#Escape('4') . ' %s' + \ ] + +Execute(Configuration file exists in current directory): + call writefile(['parameters:', ' level: 7'], './phpstan.neon') + let g:ale_php_phpstan_level = '' + let g:ale_php_phpstan_configuration = '' + + AssertLinter 'phpstan', [ + \ ale#Escape('phpstan') . ' --version', + \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json %s' + \ ] + +Execute(Configuration dist file exists in current directory): + call writefile(['parameters:', ' level: 7'], './phpstan.neon.dist') + let g:ale_php_phpstan_level = '' + let g:ale_php_phpstan_configuration = '' + + AssertLinter 'phpstan', [ + \ ale#Escape('phpstan') . ' --version', + \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json %s' + \ ] + +Execute(Configuration file exists in current directory, but force phpstan level): + call writefile(['parameters:', ' level: 7'], './phpstan.neon') + let g:ale_php_phpstan_configuration = '' + let g:ale_php_phpstan_level = '7' + + AssertLinter 'phpstan', [ + \ ale#Escape('phpstan') . ' --version', + \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('7') . ' %s' + \ ] + +Execute(Configuration file exists in current directory, but force phpstan configuration): + call writefile(['parameters:', ' level: 7'], './phpstan.neon') + let g:ale_php_phpstan_level = '' + let g:ale_php_phpstan_configuration = 'phpstan.custom.neon' + + AssertLinter 'phpstan', [ + \ ale#Escape('phpstan') . ' --version', + \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -c ' . ale#Escape('phpstan.custom.neon') . ' %s' + \ ] + +Execute(Autoload parameter is added to the command): + let g:ale_php_phpstan_autoload = 'autoload.php' + + AssertLinter 'phpstan', + \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -a ' . ale#Escape('autoload.php') . ' -l ' . ale#Escape('4') . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_pony_ponyc.vader b/vim-config/plugins/ale/test/linter/test_pony_ponyc.vader new file mode 100644 index 00000000..3a3b32ec --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pony_ponyc.vader @@ -0,0 +1,12 @@ +Before: + call ale#assert#SetUpLinterTest('pony', 'ponyc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The options should be used in the command): + AssertLinter 'ponyc', ale#Escape('ponyc') . ' --pass paint' + + let b:ale_pony_ponyc_options = 'foobar' + + AssertLinter 'ponyc', ale#Escape('ponyc') . ' foobar' diff --git a/vim-config/plugins/ale/test/linter/test_prospector.vader b/vim-config/plugins/ale/test/linter/test_prospector.vader new file mode 100644 index 00000000..82e1596d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_prospector.vader @@ -0,0 +1,35 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'prospector') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Setting executable to 'pipenv' appends 'run prospector'): + let g:ale_python_prospector_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') . ' run prospector' + \ . ' --messages-only --absolute-paths --zero-exit --output-format json %s' + +Execute(Pipenv is detected when python_prospector_auto_pipenv is set): + let g:ale_python_prospector_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinter 'pipenv', + \ ale#Escape('pipenv') . ' run prospector' + \ . ' --messages-only --absolute-paths --zero-exit --output-format json %s' + +Execute(Setting executable to 'poetry' appends 'run prospector'): + let g:ale_python_prospector_executable = 'path/to/poetry' + + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') . ' run prospector' + \ . ' --messages-only --absolute-paths --zero-exit --output-format json %s' + +Execute(Poetry is detected when python_prospector_auto_poetry is set): + let g:ale_python_prospector_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinter 'poetry', + \ ale#Escape('poetry') . ' run prospector' + \ . ' --messages-only --absolute-paths --zero-exit --output-format json %s' diff --git a/vim-config/plugins/ale/test/linter/test_proto.vader b/vim-config/plugins/ale/test/linter/test_proto.vader new file mode 100644 index 00000000..726588c0 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_proto.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpLinterTest('proto', 'protoc_gen_lint') + call ale#test#SetFilename('test.proto') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'protoc', + \ 'protoc' . ' -I ' . ale#Escape(getcwd()) . ' --lint_out=. ' . '%s' + +Execute(The callback should include any additional options): + let b:ale_proto_protoc_gen_lint_options = '--some-option' + + AssertLinter 'protoc', + \ 'protoc' . ' -I ' . ale#Escape(getcwd()) . ' --some-option --lint_out=. ' . '%s' diff --git a/vim-config/plugins/ale/test/linter/test_protolint.vader b/vim-config/plugins/ale/test/linter/test_protolint.vader new file mode 100644 index 00000000..4463b629 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_protolint.vader @@ -0,0 +1,24 @@ +Before: + call ale#assert#SetUpLinterTest('proto', 'protolint') + call ale#test#SetFilename('test.proto') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'protolint', + \ ale#Escape('protolint') + \ . ' lint' + \ . ' -reporter=unix' + \ . ' %s' + +Execute(The callback should include any additional options): + let b:ale_proto_protolint_executable = '/tmp/protolint' + let b:ale_proto_protolint_config = '/tmp/protolint.yaml' + + AssertLinter '/tmp/protolint', + \ ale#Escape('/tmp/protolint') + \ . ' lint' + \ . ' -config_path=' . ale#Escape('/tmp/protolint.yaml') + \ . ' -reporter=unix' + \ . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_psalm.vader b/vim-config/plugins/ale/test/linter/test_psalm.vader new file mode 100644 index 00000000..4edb95c8 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_psalm.vader @@ -0,0 +1,38 @@ +Before: + call ale#assert#SetUpLinterTest('php', 'psalm') + +After: + unlet! g:i + unlet! g:matched + + if isdirectory(g:dir . '/.git') + call delete(g:dir . '/.git', 'd') + endif + + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'psalm', + \ ale#Escape('psalm') . ' --language-server' + +Execute(Vendor executables should be detected): + call ale#test#SetFilename('../test-files/psalm/test.php') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/psalm/vendor/bin/psalm'), + \ ale#Escape(ale#path#Simplify( + \ g:dir + \ . '/../test-files/psalm/vendor/bin/psalm' + \ )) . ' --language-server' + + let g:ale_php_psalm_use_global = 1 + + AssertLinter 'psalm', + \ ale#Escape('psalm') . ' --language-server' + +Execute(User provided options should be used): + let g:ale_php_psalm_options = '--my-user-provided-option my-value' + + AssertLinter 'psalm', + \ ale#Escape('psalm') + \ . ' --language-server --my-user-provided-option my-value' diff --git a/vim-config/plugins/ale/test/linter/test_puglint.vader b/vim-config/plugins/ale/test/linter/test_puglint.vader new file mode 100644 index 00000000..8a445408 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_puglint.vader @@ -0,0 +1,48 @@ +Before: + call ale#assert#SetUpLinterTest('pug', 'puglint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(puglint should detect local executables and package.json): + call ale#test#SetFilename('../test-files/puglint/test.pug') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/puglint/node_modules/.bin/pug-lint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/puglint/node_modules/.bin/pug-lint')) + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/puglint/package.json')) + \ . ' -r inline %t' + +Execute(puglint should use global executables if configured): + let g:ale_pug_puglint_use_global = 1 + + call ale#test#SetFilename('../test-files/puglint/test.pug') + + AssertLinter 'pug-lint', + \ ale#Escape('pug-lint') + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/puglint/package.json')) + \ . ' -r inline %t' + +Execute(puglint should detect .pug-lintrc): + call ale#test#SetFilename('../test-files/puglint/puglint_rc_dir/subdir/test.pug') + + AssertLinter ale#path#Simplify(g:dir . '/../test-files/puglint/node_modules/.bin/pug-lint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/puglint/node_modules/.bin/pug-lint')) + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/puglint/puglint_rc_dir/.pug-lintrc')) + \ . ' -r inline %t' + +Execute(puglint should detect .pug-lintrc.js): + call ale#test#SetFilename('../test-files/puglint/puglint_rc_js_dir/subdir/test.pug') + + AssertLinter ale#path#Simplify(g:dir . '/../test-files/puglint/node_modules/.bin/pug-lint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/puglint/node_modules/.bin/pug-lint')) + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/puglint/puglint_rc_js_dir/.pug-lintrc.js')) + \ . ' -r inline %t' + +Execute(puglint should detect .pug-lintrc.json): + call ale#test#SetFilename('../test-files/puglint/puglint_rc_json_dir/subdir/test.pug') + + AssertLinter ale#path#Simplify(g:dir . '/../test-files/puglint/node_modules/.bin/pug-lint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/puglint/node_modules/.bin/pug-lint')) + \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/puglint/puglint_rc_json_dir/.pug-lintrc.json')) + \ . ' -r inline %t' diff --git a/vim-config/plugins/ale/test/linter/test_purescript_ls.vader b/vim-config/plugins/ale/test/linter/test_purescript_ls.vader new file mode 100644 index 00000000..3ef9707a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_purescript_ls.vader @@ -0,0 +1,31 @@ +Before: + call ale#assert#SetUpLinterTest('purescript', 'ls') + +After: + call ale#assert#TearDownLinterTest() + +Execute(should set correct defaults): + AssertLinter 'purescript-language-server', ale#Escape('purescript-language-server') . ' --stdio' + +Execute(should set correct LSP values): + call ale#test#SetFilename('../test-files/purescript/spago/Foo.purs') + + AssertLSPLanguage 'purescript' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/purescript/spago') + +Execute(should set correct project for bower): + call ale#test#SetFilename('../test-files/purescript/bower/Foo.purs') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/purescript/bower') + +Execute(should set correct project for psc-package): + call ale#test#SetFilename('../test-files/purescript/psc-package/Foo.purs') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/purescript/psc-package') + +Execute(should accept configuration settings): + AssertLSPConfig {} + let b:ale_purescript_ls_config = {'purescript': {'addSpagoSources': v:true}} + AssertLSPConfig {'purescript': {'addSpagoSources': v:true}} diff --git a/vim-config/plugins/ale/test/linter/test_pycodestyle.vader b/vim-config/plugins/ale/test/linter/test_pycodestyle.vader new file mode 100644 index 00000000..fac53d9f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pycodestyle.vader @@ -0,0 +1,46 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'pycodestyle') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The pycodestyle command callback should return default string): + AssertLinter 'pycodestyle', ale#Escape('pycodestyle') . ' -' + +Execute(The pycodestyle command callback should allow options): + let g:ale_python_pycodestyle_options = '--exclude=test*.py' + + AssertLinter 'pycodestyle', + \ ale#Escape('pycodestyle') . ' --exclude=test*.py -' + +Execute(The pycodestyle executable should be configurable): + let g:ale_python_pycodestyle_executable = '~/.local/bin/pycodestyle' + + AssertLinter '~/.local/bin/pycodestyle', + \ ale#Escape('~/.local/bin/pycodestyle') . ' -' + +Execute(Setting executable to 'pipenv' appends 'run pycodestyle'): + let g:ale_python_pycodestyle_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') . ' run pycodestyle -' + +Execute(Pipenv is detected when python_pycodestyle_auto_pipenv is set): + let g:ale_python_pycodestyle_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinter 'pipenv', + \ ale#Escape('pipenv') . ' run pycodestyle -' + +Execute(Setting executable to 'poetry' appends 'run pycodestyle'): + let g:ale_python_pycodestyle_executable = 'path/to/poetry' + + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') . ' run pycodestyle -' + +Execute(Poetry is detected when python_pycodestyle_auto_poetry is set): + let g:ale_python_pycodestyle_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinter 'poetry', + \ ale#Escape('poetry') . ' run pycodestyle -' diff --git a/vim-config/plugins/ale/test/linter/test_pydocstyle.vader b/vim-config/plugins/ale/test/linter/test_pydocstyle.vader new file mode 100644 index 00000000..24d669c6 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pydocstyle.vader @@ -0,0 +1,45 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'pydocstyle') + call ale#test#SetFilename('test.py') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The pydocstyle command callback should return default string): + AssertLinterCwd '%s:h' + AssertLinter 'pydocstyle', ale#Escape('pydocstyle') . ' %s:t' + +Execute(The pydocstyle command callback should allow options): + let g:ale_python_pydocstyle_options = '--verbose' + + AssertLinter 'pydocstyle', ale#Escape('pydocstyle') . ' --verbose %s:t' + +Execute(The pydocstyle executable should be configurable): + let g:ale_python_pydocstyle_executable = '~/.local/bin/pydocstyle' + + AssertLinter '~/.local/bin/pydocstyle', + \ ale#Escape('~/.local/bin/pydocstyle') . ' %s:t' + +Execute(Setting executable to 'pipenv' appends 'run pydocstyle'): + let g:ale_python_pydocstyle_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') . ' run pydocstyle %s:t' + +Execute(Pipenv is detected when python_pydocstyle_auto_pipenv is set): + let g:ale_python_pydocstyle_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinter 'pipenv', ale#Escape('pipenv') . ' run pydocstyle %s:t' + +Execute(Setting executable to 'poetry' appends 'run pydocstyle'): + let g:ale_python_pydocstyle_executable = 'path/to/poetry' + + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') . ' run pydocstyle %s:t' + +Execute(Poetry is detected when python_pydocstyle_auto_poetry is set): + let g:ale_python_pydocstyle_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinter 'poetry', ale#Escape('poetry') . ' run pydocstyle %s:t' diff --git a/vim-config/plugins/ale/test/linter/test_pyflakes.vader b/vim-config/plugins/ale/test/linter/test_pyflakes.vader new file mode 100644 index 00000000..bd442098 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pyflakes.vader @@ -0,0 +1,59 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'pyflakes') + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + unlet! b:bin_dir + unlet! b:executable + call ale#assert#TearDownLinterTest() + +Execute(The pyflakes command callback should return default string): + AssertLinter 'pyflakes', ale#Escape('pyflakes') . ' %t' + +Execute(The pyflakes executable should be configurable): + let g:ale_python_pyflakes_executable = '~/.local/bin/pyflakes' + + AssertLinter '~/.local/bin/pyflakes', + \ ale#Escape('~/.local/bin/pyflakes') . ' %t' + +Execute(The pyflakes executable should be run from the virtualenv path): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let b:executable = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/pyflakes' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' %t' + +Execute(You should be able to override the pyflakes virtualenv lookup): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let g:ale_python_pyflakes_use_global = 1 + + AssertLinter 'pyflakes', ale#Escape('pyflakes') . ' %t' + +Execute(Setting executable to 'pipenv' appends 'run pyflakes'): + let g:ale_python_pyflakes_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') . ' run pyflakes %t', + +Execute(Pipenv is detected when python_pyflakes_auto_pipenv is set): + let g:ale_python_pyflakes_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinter 'pipenv', + \ ale#Escape('pipenv') . ' run pyflakes %t' + +Execute(Setting executable to 'poetry' appends 'run pyflakes'): + let g:ale_python_pyflakes_executable = 'path/to/poetry' + + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') . ' run pyflakes %t', + +Execute(Poetry is detected when python_pyflakes_auto_poetry is set): + let g:ale_python_pyflakes_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinter 'poetry', + \ ale#Escape('poetry') . ' run pyflakes %t' diff --git a/vim-config/plugins/ale/test/linter/test_pylama.vader b/vim-config/plugins/ale/test/linter/test_pylama.vader new file mode 100644 index 00000000..3c6a6efa --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pylama.vader @@ -0,0 +1,88 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'pylama') + call ale#test#SetFilename('test.py') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + let b:command_tail = ' %s' + +After: + unlet! b:bin_dir + unlet! b:executable + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The default pylama command should be correct): + AssertLinterCwd ale#path#Simplify(g:dir) + AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail + +Execute(The option for disabling changing directories should work): + let g:ale_python_pylama_change_directory = 0 + + AssertLinterCwd '' + AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail + +Execute(The pylama executable should be configurable, and escaped properly): + let g:ale_python_pylama_executable = 'executable with spaces' + + AssertLinterCwd ale#path#Simplify(g:dir) + AssertLinter 'executable with spaces', + \ ale#Escape('executable with spaces') . b:command_tail + +Execute(The pylama command callback should let you set options): + let g:ale_python_pylama_options = '--some-option' + + AssertLinterCwd ale#path#Simplify(g:dir) + AssertLinter 'pylama', ale#Escape('pylama') . ' --some-option' . b:command_tail + +Execute(The pylama command callback should switch directories to the detected project root): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/no_virtualenv/subdir/foo/bar.py') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/no_virtualenv/subdir') + AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail + +Execute(The pylama command callback shouldn't detect virtualenv directories where they don't exist): + call ale#test#SetFilename('../test-files/python/no_virtualenv/subdir/foo/bar.py') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/no_virtualenv/subdir') + AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail + +Execute(The pylama command callback should detect virtualenv directories and switch to the project root): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + let b:executable = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/pylama' + \) + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/subdir') + AssertLinter b:executable, ale#Escape(b:executable) . b:command_tail + +Execute(You should able able to use the global pylama instead): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + let g:ale_python_pylama_use_global = 1 + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/subdir') + AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail + +Execute(Setting executable to 'pipenv' appends 'run pylama'): + let g:ale_python_pylama_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') . ' run pylama' . b:command_tail + +Execute(Pipenv is detected when python_pylama_auto_pipenv is set): + let g:ale_python_pylama_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinter 'pipenv', ale#Escape('pipenv') . ' run pylama' . b:command_tail + +Execute(Setting executable to 'poetry' appends 'run pylama'): + let g:ale_python_pylama_executable = 'path/to/poetry' + + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') . ' run pylama' . b:command_tail + +Execute(poetry is detected when python_pylama_auto_poetry is set): + let g:ale_python_pylama_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinter 'poetry', ale#Escape('poetry') . ' run pylama' . b:command_tail diff --git a/vim-config/plugins/ale/test/linter/test_pylint.vader b/vim-config/plugins/ale/test/linter/test_pylint.vader new file mode 100644 index 00000000..d15161e6 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pylint.vader @@ -0,0 +1,96 @@ +Before: + Save g:ale_python_auto_pipenv + + let g:ale_python_auto_pipenv = 0 + + call ale#assert#SetUpLinterTest('python', 'pylint') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + let b:command_tail = ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s' + + GivenCommandOutput ['pylint 2.3.0'] + +After: + unlet! b:bin_dir + unlet! b:executable + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The pylint callbacks should return the correct default values): + AssertLinterCwd expand('%:p:h') + AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail + +Execute(Pylint should run with the --from-stdin in new enough versions): + GivenCommandOutput ['pylint 2.4.0'] + + AssertLinterCwd expand('%:p:h') + AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail[:-3] . '--from-stdin %s' + +Execute(The option for disabling changing directories should work): + let g:ale_python_pylint_change_directory = 0 + + AssertLinterCwd '' + AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail + +Execute(The pylint executable should be configurable, and escaped properly): + let g:ale_python_pylint_executable = 'executable with spaces' + + AssertLinter 'executable with spaces', ale#Escape('executable with spaces') . b:command_tail + +Execute(The pylint command callback should let you set options): + let g:ale_python_pylint_options = '--some-option' + + AssertLinter 'pylint', ale#Escape('pylint') . ' --some-option' . b:command_tail + +Execute(The pylint callbacks shouldn't detect virtualenv directories where they don't exist): + call ale#test#SetFilename('../test-files/python/no_virtualenv/subdir/foo/bar.py') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/no_virtualenv/subdir') + AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail + +Execute(The pylint callbacks should detect virtualenv directories): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + let b:executable = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/pylint' + \) + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/subdir') + AssertLinter b:executable, ale#Escape(b:executable) . b:command_tail + +Execute(You should able able to use the global pylint instead): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + let g:ale_python_pylint_use_global = 1 + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/subdir') + AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail + +Execute(Setting executable to 'pipenv' appends 'run pylint'): + let g:ale_python_pylint_executable = 'path/to/pipenv' + let g:ale_python_pylint_use_global = 1 + + AssertLinter 'path/to/pipenv', ale#Escape('path/to/pipenv') . ' run pylint' + \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s' + +Execute(Pipenv is detected when python_pylint_auto_pipenv is set): + let g:ale_python_pylint_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinterCwd expand('%:p:h') + AssertLinter 'pipenv', ale#Escape('pipenv') . ' run pylint' + \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s' + +Execute(Setting executable to 'poetry' appends 'run pylint'): + let g:ale_python_pylint_executable = 'path/to/poetry' + let g:ale_python_pylint_use_global = 1 + + AssertLinter 'path/to/poetry', ale#Escape('path/to/poetry') . ' run pylint' + \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s' + +Execute(poetry is detected when python_pylint_auto_poetry is set): + let g:ale_python_pylint_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinterCwd expand('%:p:h') + AssertLinter 'poetry', ale#Escape('poetry') . ' run pylint' + \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s' diff --git a/vim-config/plugins/ale/test/linter/test_pylsp.vader b/vim-config/plugins/ale/test/linter/test_pylsp.vader new file mode 100644 index 00000000..acee2c3f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pylsp.vader @@ -0,0 +1,69 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'pylsp') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + unlet! b:bin_dir + unlet! b:executable + + call ale#assert#TearDownLinterTest() + +Execute(The pylsp command callback should return default string): + AssertLinter 'pylsp', ale#Escape('pylsp') + +Execute(The pylsp executable should be configurable): + let g:ale_python_pylsp_executable = '~/.local/bin/pylsp' + + AssertLinter '~/.local/bin/pylsp' , ale#Escape('~/.local/bin/pylsp') + +Execute(The pylsp command callback should let you set options): + let g:ale_python_pylsp_options = '--some-option' + + AssertLinter 'pylsp', ale#Escape('pylsp') . ' --some-option' + +Execute(The pylsp executable should be run from the virtualenv path): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let b:executable = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/pylsp' + \) + + AssertEqual ale#Escape(b:executable), + \ ale_linters#python#pylsp#GetCommand(bufnr('')) + +Execute(You should be able to override the pylsp virtualenv lookup): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let g:ale_python_pylsp_use_global = 1 + + AssertLinter 'pylsp', ale#Escape('pylsp') + +Execute(Setting executable to 'pipenv' appends 'run pylsp'): + let g:ale_python_pylsp_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', ale#Escape('path/to/pipenv') . ' run pylsp' + +Execute(Pipenv is detected when python_pylsp_auto_pipenv is set): + let g:ale_python_pylsp_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinter 'pipenv', + \ ale#Escape('pipenv') . ' run pylsp' + +Execute(Setting executable to 'poetry' appends 'run pylsp'): + let g:ale_python_pylsp_executable = 'path/to/poetry' + + AssertLinter 'path/to/poetry', ale#Escape('path/to/poetry') . ' run pylsp' + +Execute(poetry is detected when python_pylsp_auto_poetry is set): + let g:ale_python_pylsp_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinter 'poetry', + \ ale#Escape('poetry') . ' run pylsp' + +Execute(Should accept configuration settings): + AssertLSPConfig {} + let b:ale_python_pylsp_config = {'pylsp': {'plugins': {'preload': {'enabled': v:false}}}} + AssertLSPConfig {'pylsp': {'plugins': {'preload': {'enabled': v:false}}}} diff --git a/vim-config/plugins/ale/test/linter/test_pyre.vader b/vim-config/plugins/ale/test/linter/test_pyre.vader new file mode 100644 index 00000000..53f84e6f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pyre.vader @@ -0,0 +1,66 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'pyre') + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + unlet! b:bin_dir + unlet! b:executable + call ale#assert#TearDownLinterTest() + +Execute(The pyre command callback should return default string): + AssertLinter 'pyre', ale#Escape('pyre') . ' persistent' + +Execute(The pyre executable should be configurable): + let g:ale_python_pyre_executable = '~/.local/bin/pyre' + + AssertLinter '~/.local/bin/pyre', + \ ale#Escape('~/.local/bin/pyre') . ' persistent' + +Execute(The pyre executable should be run from the virtualenv path): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let b:executable = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/pyre' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' persistent' + +Execute(You should be able to override the pyre virtualenv lookup): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let g:ale_python_pyre_use_global = 1 + + AssertLinter 'pyre', ale#Escape('pyre') . ' persistent' + +Execute(Setting executable to 'pipenv' appends 'run pyre'): + let g:ale_python_pyre_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', + \ ale#Escape('path/to/pipenv') . ' run pyre persistent' + +Execute(Pipenv is detected when python_pyre_auto_pipenv is set): + let g:ale_python_pyre_auto_pipenv = 1 + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertLinter 'pipenv', + \ ale#Escape('pipenv') . ' run pyre persistent' + +Execute(Setting executable to 'poetry' appends 'run pyre'): + let g:ale_python_pyre_executable = 'path/to/poetry' + + AssertLinter 'path/to/poetry', + \ ale#Escape('path/to/poetry') . ' run pyre persistent' + +Execute(Poetry is detected when python_pyre_auto_poetry is set): + let g:ale_python_pyre_auto_poetry = 1 + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertLinter 'poetry', + \ ale#Escape('poetry') . ' run pyre persistent' + +Execute(The FindProjectRoot should detect the project root directory for namespace package via .pyre_configuration.local): + silent execute 'file ' . fnameescape(g:dir . '/../test-files/python/pyre_configuration_dir/foo/bar.py') + + AssertEqual + \ ale#path#Simplify(g:dir . '/../test-files/python/pyre_configuration_dir'), + \ ale#python#FindProjectRoot(bufnr('')) diff --git a/vim-config/plugins/ale/test/linter/test_pyrex_cython.vader b/vim-config/plugins/ale/test/linter/test_pyrex_cython.vader new file mode 100644 index 00000000..af86366a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pyrex_cython.vader @@ -0,0 +1,30 @@ +Before: + call ale#assert#SetUpLinterTest('pyrex', 'cython') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default cython command should be correct): + AssertLinter 'cython', ale#Escape('cython') + \ . ' --working %s:h' + \ . ' --include-dir %s:h' + \ . ' --warning-extra' + \ . ' --output-file ' . g:ale#util#nul_file . ' %t' + +Execute(The cython executable should be configurable): + let b:ale_pyrex_cython_executable = 'cython_foobar' + + AssertLinter 'cython_foobar', ale#Escape('cython_foobar') + \ . ' --working %s:h' + \ . ' --include-dir %s:h' + \ . ' --warning-extra' + \ . ' --output-file ' . g:ale#util#nul_file . ' %t' + +Execute(Additional cython options should be configurable): + let b:ale_pyrex_cython_options = '--foobar' + + AssertLinter 'cython', ale#Escape('cython') + \ . ' --working %s:h' + \ . ' --include-dir %s:h' + \ . ' --foobar' + \ . ' --output-file ' . g:ale#util#nul_file . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_pyright.vader b/vim-config/plugins/ale/test/linter/test_pyright.vader new file mode 100644 index 00000000..51510cf2 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_pyright.vader @@ -0,0 +1,116 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'pyright') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + unlet! b:bin_dir + unlet! b:executable + + call ale#assert#TearDownLinterTest() + +Execute(The command callback should return the correct default string): + AssertLinter + \ 'pyright-langserver', + \ ale#Escape('pyright-langserver') . ' --stdio' + +Execute(The executable should be configurable): + let g:ale_python_pyright_executable = '/bin/foo-bar' + + AssertLinter + \ '/bin/foo-bar', + \ ale#Escape('/bin/foo-bar') . ' --stdio' + +Execute(The default configuration should be mostly empty): + " The default configuration needs to have at least one key in it, + " or the server won't start up properly. + AssertLSPConfig {'python': {}} + + let b:ale_python_pyright_config = {} + + AssertLSPConfig {'python': {}} + +Execute(virtualenv paths should be set in configuration by default): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + AssertLSPConfig { + \ 'python': { + \ 'pythonPath': ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/python'), + \ 'venvPath': ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env'), + \ }, + \} + +Execute(The pythonPath should be set based on whatever the ovveride for the venvPath is set to): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + " This overrides the default detection of the path. + let b:ale_python_pyright_config = { + \ 'python': { + \ 'venvPath': '/foo/bar', + \ }, + \} + + AssertLSPConfig { + \ 'python': { + \ 'pythonPath': ale#path#Simplify('/foo/bar/' . b:bin_dir . '/python'), + \ 'venvPath': '/foo/bar', + \ }, + \} + +Execute(You should be able to override pythonPath when venvPath is detected): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + " This overrides the default detection of the path. + let b:ale_python_pyright_config = { + \ 'python': { + \ 'pythonPath': '/bin/python', + \ }, + \} + + AssertLSPConfig { + \ 'python': { + \ 'pythonPath': '/bin/python', + \ 'venvPath': ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env'), + \ }, + \} + +Execute(You should be able to override both pythonPath and venvPath): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + " This overrides the default detection of the path. + let b:ale_python_pyright_config = { + \ 'python': { + \ 'pythonPath': '/bin/python', + \ 'venvPath': '/other/dir', + \ }, + \} + + AssertLSPConfig { + \ 'python': { + \ 'pythonPath': '/bin/python', + \ 'venvPath': '/other/dir', + \ }, + \} + +Execute(You should be able to define other settings): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let b:ale_python_pyright_config = { + \ 'python': { + \ 'analysis': {'logLevel': 'warning'}, + \ }, + \ 'pyright': { + \ 'disableLanguageServices': v:true, + \ }, + \} + + AssertLSPConfig { + \ 'python': { + \ 'analysis': {'logLevel': 'warning'}, + \ 'pythonPath': ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/python'), + \ 'venvPath': ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env'), + \ }, + \ 'pyright': { + \ 'disableLanguageServices': v:true, + \ }, + \} diff --git a/vim-config/plugins/ale/test/linter/test_qmlfmt.vader b/vim-config/plugins/ale/test/linter/test_qmlfmt.vader new file mode 100644 index 00000000..53502f4d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_qmlfmt.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('qml', 'qmlfmt') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The qml qmlfmt command callback should return the correct default string): + AssertLinter 'qmlfmt', ale#Escape('qmlfmt') . ' -e', + +Execute(The qmlfmt executable should be configurable): + let g:ale_qml_qmlfmt_executable = '~/.local/bin/qmlfmt' + + AssertLinter '~/.local/bin/qmlfmt', ale#Escape('~/.local/bin/qmlfmt') . ' -e' diff --git a/vim-config/plugins/ale/test/linter/test_r_languageserver.vader b/vim-config/plugins/ale/test/linter/test_r_languageserver.vader new file mode 100644 index 00000000..1a6fe851 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_r_languageserver.vader @@ -0,0 +1,22 @@ +Before: + call ale#assert#SetUpLinterTest('r', 'languageserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'Rscript', 'Rscript --no-save --no-restore --no-site-file --no-init-file -e ' . ale#Escape('languageserver::run()') + +Execute(The project root should be detected correctly): + AssertLSPProject '.' + + call ale#test#SetFilename('../test-files/r/dummy/test.R') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/r') + +Execute(Should accept configuration settings): + AssertLSPConfig {} + + let b:ale_r_languageserver_config = {'r': {'lsp': {'debug': 'true', 'diagnostics': 'true'}}} + + AssertLSPConfig {'r': {'lsp': {'debug': 'true', 'diagnostics': 'true'}}} diff --git a/vim-config/plugins/ale/test/linter/test_racket_langserver.vader b/vim-config/plugins/ale/test/linter/test_racket_langserver.vader new file mode 100644 index 00000000..021eb565 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_racket_langserver.vader @@ -0,0 +1,45 @@ +" Author: D. Ben Knoble +" Description: Tests for racket-langserver lsp linter. +Before: + call ale#assert#SetUpLinterTest('racket', 'langserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(command callback should return default string): + AssertLinter 'racket', ale#Escape('racket').' -l racket-langserver' + +Execute(should set racket-langserver for deep module 3): + call ale#test#SetFilename('../test-files/racket/many-inits/a/b/c/foo.rkt') + AssertLSPLanguage 'racket' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#test#GetFilename('../test-files/racket/many-inits') + +Execute(should set racket-langserver for deep module 2): + call ale#test#SetFilename('../test-files/racket/many-inits/a/b/foo.rkt') + AssertLSPLanguage 'racket' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#test#GetFilename('../test-files/racket/many-inits') + +Execute(should set racket-langserver for deep module 1): + call ale#test#SetFilename('../test-files/racket/many-inits/a/foo.rkt') + AssertLSPLanguage 'racket' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#test#GetFilename('../test-files/racket/many-inits') + +Execute(should set racket-langserver for top-level module): + call ale#test#SetFilename('../test-files/racket/many-inits/foo.rkt') + AssertLSPLanguage 'racket' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#test#GetFilename('../test-files/racket/many-inits') + +Execute(should set racket-langserver for non-package module or script): + call ale#test#SetFilename('../test-files/racket/simple-script/foo.rkt') + AssertLSPLanguage 'racket' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#test#GetFilename('../test-files/racket/simple-script') diff --git a/vim-config/plugins/ale/test/linter/test_racket_raco.vader b/vim-config/plugins/ale/test/linter/test_racket_raco.vader new file mode 100644 index 00000000..fb83ffa1 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_racket_raco.vader @@ -0,0 +1,10 @@ +Before: + call ale#assert#SetUpLinterTest('racket', 'raco') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command and executable should be correct): + AssertLinter 'raco', 'raco expand %s' + + diff --git a/vim-config/plugins/ale/test/linter/test_rails_best_practices.vader b/vim-config/plugins/ale/test/linter/test_rails_best_practices.vader new file mode 100644 index 00000000..6a6f7a53 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_rails_best_practices.vader @@ -0,0 +1,42 @@ +Before: + call ale#assert#SetUpLinterTest('ruby', 'rails_best_practices') + call ale#test#SetFilename('../test-files/ruby/valid_rails_app/db/test.rb') + + let b:args = '--silent -f json' + \ . ' --output-file ' . (has('win32') ? '%t' : '/dev/stdout') + let b:app_path = ale#path#Simplify(g:dir . '/../test-files/ruby/valid_rails_app') + let b:suffix = has('win32') ? '; type %t' : '' + +After: + unlet! b:args + unlet! b:app_path + unlet! b:suffix + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to rails_best_practices): + AssertLinter 'rails_best_practices', ale#Escape('rails_best_practices') + \ . ' ' . b:args + \ . ' ' . ale#Escape(b:app_path) + \ . b:suffix + +Execute(Should be able to set a custom executable): + let g:ale_ruby_rails_best_practices_executable = 'bin/rails_best_practices' + + AssertLinter 'bin/rails_best_practices', ale#Escape('bin/rails_best_practices') + \ . ' ' . b:args + \ . ' ' . ale#Escape(b:app_path) + \ . b:suffix + +Execute(Setting bundle appends 'exec rails_best_practices'): + let g:ale_ruby_rails_best_practices_executable = 'path to/bundle' + + AssertLinter 'path to/bundle', ale#Escape('path to/bundle') + \ . ' exec rails_best_practices' + \ . ' ' . b:args + \ . ' ' . ale#Escape(b:app_path) + \ . b:suffix + +Execute(Command callback should be empty when not in a valid Rails app): + call ale#test#SetFilename('../test-files/ruby/not_a_rails_app/test.rb') + + AssertLinter 'rails_best_practices', '' diff --git a/vim-config/plugins/ale/test/linter/test_reason_ls.vader b/vim-config/plugins/ale/test/linter/test_reason_ls.vader new file mode 100644 index 00000000..57ea7302 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_reason_ls.vader @@ -0,0 +1,21 @@ +Before: + call ale#assert#SetUpLinterTest('reason', 'ls') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The linter should not be run by default): + AssertLinterNotExecuted + +Execute(The executable should be configurable): + let b:ale_reason_ls_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + +Execute(There should be no default project root): + AssertLSPProject '' + +Execute(The project root should be detected using bsconfig.json): + call ale#test#SetFilename('../test-files/reasonml/test.ml') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/reasonml') diff --git a/vim-config/plugins/ale/test/linter/test_reason_ols.vader b/vim-config/plugins/ale/test/linter/test_reason_ols.vader new file mode 100644 index 00000000..752bd05b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_reason_ols.vader @@ -0,0 +1,41 @@ +Before: + call ale#assert#SetUpLinterTest('reason', 'ols') + + Save &filetype + let &filetype = 'reason' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'reason' + +Execute(The default executable should be correct): + AssertLinter 'ocaml-language-server', + \ ale#Escape('ocaml-language-server') . ' --stdio' + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ols/file.re') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ols') + +Execute(The local executable should be used when available): + call ale#test#SetFilename('../test-files/ols/file.re') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/ols/node_modules/.bin/ocaml-language-server'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/ols/node_modules/.bin/ocaml-language-server')) . ' --stdio' + +Execute(The gloabl executable should always be used when use_global is set): + let g:ale_reason_ols_use_global = 1 + call ale#test#SetFilename('../test-files/ols/file.re') + + AssertLinter 'ocaml-language-server', + \ ale#Escape('ocaml-language-server') . ' --stdio' + +Execute(The executable should be configurable): + let g:ale_reason_ols_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --stdio' diff --git a/vim-config/plugins/ale/test/linter/test_reek.vader b/vim-config/plugins/ale/test/linter/test_reek.vader new file mode 100644 index 00000000..798c3314 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_reek.vader @@ -0,0 +1,49 @@ +Before: + call ale#assert#SetUpLinterTest('ruby', 'reek') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The reek callbacks should return the correct default values): + GivenCommandOutput ['reek 5.0.0'] + AssertLinter 'reek', [ + \ ale#Escape('reek') . ' --version', + \ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s', + \] + + " Try with older versions. + call ale#semver#ResetVersionCache() + + GivenCommandOutput ['reek 4.8.2'] + AssertLinter 'reek', [ + \ ale#Escape('reek') . ' --version', + \ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion', + \] + +Execute(Setting bundle appends 'exec reek'): + let g:ale_ruby_reek_executable = 'bundle' + + GivenCommandOutput ['reek 5.0.0'] + AssertLinter 'bundle', ale#Escape('bundle') + \ . ' exec reek' + \ . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s', + + " Try with older versions. + call ale#semver#ResetVersionCache() + + GivenCommandOutput ['reek 4.8.2'] + AssertLinter 'bundle', ale#Escape('bundle') + \ . ' exec reek' + \ . ' -f json --no-progress --no-color --force-exclusion' + +Execute(The reek version check should be cached): + GivenCommandOutput ['reek 5.0.0'] + AssertLinter 'reek', [ + \ ale#Escape('reek') . ' --version', + \ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s', + \] + + GivenCommandOutput [] + AssertLinter 'reek', [ + \ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s', + \] diff --git a/vim-config/plugins/ale/test/linter/test_remark_lint.vader b/vim-config/plugins/ale/test/linter/test_remark_lint.vader new file mode 100644 index 00000000..a34f0a90 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_remark_lint.vader @@ -0,0 +1,37 @@ +Before: + " This is just one language for the linter. + call ale#assert#SetUpLinterTest('markdown', 'remark_lint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'remark', + \ ale#Escape('remark') . ' --no-stdout --no-color' + +Execute(The executable should be configurable): + let b:ale_markdown_remark_lint_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' --no-stdout --no-color' + +Execute(The options should be configurable): + let b:ale_markdown_remark_lint_options = '--something' + + AssertLinter 'remark', + \ ale#Escape('remark') . ' --something --no-stdout --no-color' + +Execute(The local executable from .bin should be used if available): + call ale#test#SetFilename('../test-files/remark_lint/with_bin_path/foo.md') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/remark_lint/with_bin_path/node_modules/.bin/remark'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/remark_lint/with_bin_path/node_modules/.bin/remark')) + \ . ' --no-stdout --no-color' + +Execute(The global executable should be uesd if the option is set): + let b:ale_markdown_remark_lint_use_global = 1 + call ale#test#SetFilename('../test-files/remark_lint/with_bin_path/foo.md') + + AssertLinter 'remark', ale#Escape('remark') + \ . ' --no-stdout --no-color' diff --git a/vim-config/plugins/ale/test/linter/test_revive.vader b/vim-config/plugins/ale/test/linter/test_revive.vader new file mode 100644 index 00000000..172294f3 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_revive.vader @@ -0,0 +1,30 @@ +Before: + Save g:ale_go_go111module + + call ale#assert#SetUpLinterTest('go', 'revive') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The default revive command should be correct): + AssertLinter 'revive', ale#Escape('revive') . ' %t' + +Execute(The revive executable should be configurable): + let b:ale_go_revive_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' %t' + +Execute(The revive options should be configurable): + let b:ale_go_revive_options = '--foo' + + AssertLinter 'revive', ale#Escape('revive') . ' --foo %t' + +Execute(The revive command should support Go environment variables): + let b:ale_go_go111module = 'on' + + AssertLinter 'revive', + \ ale#Env('GO111MODULE', 'on') . ale#Escape('revive') . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_rflint.vader b/vim-config/plugins/ale/test/linter/test_rflint.vader new file mode 100644 index 00000000..0ee97b30 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_rflint.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('robot', 'rflint') + let b:rflint_format = ' --format' + \ . ' "{filename}:{severity}:{linenumber}:{char}:{rulename}:{message}" %s' + +After: + call ale#assert#TearDownLinterTest() + unlet! b:rflint_format + +Execute(The rflint command callback should return default string): + AssertLinter 'rflint', + \ 'rflint' + \ . b:rflint_format + +Execute(The rflint executable should be configurable): + let g:ale_robot_rflint_executable = '~/.local/bin/rflint' + + AssertLinter '~/.local/bin/rflint', + \ '~/.local/bin/rflint' + \ . b:rflint_format diff --git a/vim-config/plugins/ale/test/linter/test_rnix.vader b/vim-config/plugins/ale/test/linter/test_rnix.vader new file mode 100644 index 00000000..8970ee99 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_rnix.vader @@ -0,0 +1,12 @@ +" Author: jD91mZM2 +" Description: Tests for rnix-lsp language client +Before: + call ale#assert#SetUpLinterTest('nix', 'rnix_lsp') + +After: + call ale#assert#TearDownLinterTest() + +Execute(should start rnix-lsp): + AssertLSPLanguage 'nix' + AssertLSPOptions {} + AssertLSPProject ale#path#Simplify('.') diff --git a/vim-config/plugins/ale/test/linter/test_rst_textlint.vader b/vim-config/plugins/ale/test/linter/test_rst_textlint.vader new file mode 100644 index 00000000..b2d99636 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_rst_textlint.vader @@ -0,0 +1,65 @@ +" Author: januswel, w0rp + +Before: + " This is just one language for the linter. + call ale#assert#SetUpLinterTest('rst', 'textlint') + + " The configuration is shared between many languages. + Save g:ale_textlint_executable + Save g:ale_textlint_use_global + Save g:ale_textlint_options + + let g:ale_textlint_executable = 'textlint' + let g:ale_textlint_use_global = 0 + let g:ale_textlint_options = '' + + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + +After: + unlet! b:command_tail + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' -f json --stdin --stdin-filename %s' + +Execute(The executable should be configurable): + let b:ale_textlint_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -f json --stdin --stdin-filename %s' + +Execute(The options should be configurable): + let b:ale_textlint_options = '--something' + + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' --something -f json --stdin --stdin-filename %s' + +Execute(The local executable from .bin should be used if available): + call ale#test#SetFilename('../test-files/textlint/with_bin_path/foo.txt') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_bin_path/node_modules/.bin/textlint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_bin_path/node_modules/.bin/textlint')) + \ . ' -f json --stdin --stdin-filename %s' + +Execute(The local executable from textlint/bin should be used if available): + call ale#test#SetFilename('../test-files/textlint/with_textlint_bin_path/foo.txt') + + if has('win32') + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape('node.exe') . ' ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + else + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + endif diff --git a/vim-config/plugins/ale/test/linter/test_rubocop.vader b/vim-config/plugins/ale/test/linter/test_rubocop.vader new file mode 100644 index 00000000..e7cc32e8 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_rubocop.vader @@ -0,0 +1,26 @@ +Before: + call ale#assert#SetUpLinterTest('ruby', 'rubocop') + call ale#test#SetFilename('dummy.rb') + + let g:ale_ruby_rubocop_executable = 'rubocop' + let g:ale_ruby_rubocop_options = '' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to rubocop): + AssertLinter 'rubocop', ale#Escape('rubocop') + \ . ' --format json --force-exclusion --stdin %s' + +Execute(Should be able to set a custom executable): + let g:ale_ruby_rubocop_executable = 'bin/rubocop' + + AssertLinter 'bin/rubocop' , ale#Escape('bin/rubocop') + \ . ' --format json --force-exclusion --stdin %s' + +Execute(Setting bundle appends 'exec rubocop'): + let g:ale_ruby_rubocop_executable = 'path to/bundle' + + AssertLinter 'path to/bundle', ale#Escape('path to/bundle') + \ . ' exec rubocop' + \ . ' --format json --force-exclusion --stdin %s' diff --git a/vim-config/plugins/ale/test/linter/test_ruby.vader b/vim-config/plugins/ale/test/linter/test_ruby.vader new file mode 100644 index 00000000..d957079d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ruby.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('ruby', 'ruby') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'ruby', ale#Escape('ruby') . ' -w -c %t' + +Execute(The executable should be configurable): + let g:ale_ruby_ruby_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' -w -c %t' diff --git a/vim-config/plugins/ale/test/linter/test_ruby_debride.vader b/vim-config/plugins/ale/test/linter/test_ruby_debride.vader new file mode 100644 index 00000000..f7628432 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ruby_debride.vader @@ -0,0 +1,8 @@ +Before: + call ale#assert#SetUpLinterTest('ruby', 'debride') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'debride', ale#Escape('debride') . ' %s' diff --git a/vim-config/plugins/ale/test/linter/test_ruby_solargraph.vader b/vim-config/plugins/ale/test/linter/test_ruby_solargraph.vader new file mode 100644 index 00000000..1ae67f50 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ruby_solargraph.vader @@ -0,0 +1,43 @@ +" Author: Horacio Sanson +" Description: Tests for solargraph lsp linter. +Before: + call ale#assert#SetUpLinterTest('ruby', 'solargraph') + +After: + call ale#assert#TearDownLinterTest() + +Execute(command callback should return default string): + AssertLinter 'solargraph', ale#Escape('solargraph') . ' stdio' + +Execute(command callback executable can be overridden): + let g:ale_ruby_solargraph_executable = 'foobar' + AssertLinter 'foobar', ale#Escape('foobar') . ' stdio' + +Execute(should set solargraph for rails app): + call ale#test#SetFilename('../test-files/ruby/valid_rails_app/app/models/thing.rb') + AssertLSPLanguage 'ruby' + AssertLSPOptions {} + AssertLSPProject ale#test#GetFilename('../test-files/ruby/valid_rails_app') + +Execute(should set solargraph for ruby app1): + call ale#test#SetFilename('../test-files/ruby/valid_ruby_app1/lib/file.rb') + AssertLSPLanguage 'ruby' + AssertLSPOptions {} + AssertLSPProject ale#test#GetFilename('../test-files/ruby/valid_ruby_app1') + +Execute(should set solargraph for ruby app2): + call ale#test#SetFilename('../test-files/ruby/valid_ruby_app2/lib/file.rb') + AssertLSPLanguage 'ruby' + AssertLSPOptions {} + AssertLSPProject ale#test#GetFilename('../test-files/ruby/valid_ruby_app2') + +Execute(should set solargraph for ruby app3): + call ale#test#SetFilename('../test-files/ruby/valid_ruby_app3/lib/file.rb') + AssertLSPLanguage 'ruby' + AssertLSPOptions {} + AssertLSPProject ale#test#GetFilename('../test-files/ruby/valid_ruby_app3') + +Execute(should accept initialization options): + AssertLSPOptions {} + let b:ale_ruby_solargraph_options = { 'diagnostics': 'true' } + AssertLSPOptions { 'diagnostics': 'true' } diff --git a/vim-config/plugins/ale/test/linter/test_rust_analyzer.vader b/vim-config/plugins/ale/test/linter/test_rust_analyzer.vader new file mode 100644 index 00000000..82a3adfb --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_rust_analyzer.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('rust', 'analyzer') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'rust-analyzer', ale#Escape('rust-analyzer') + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/rust/test.rs') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/rust') + +Execute(Should accept configuration settings): + AssertLSPConfig {} + let b:ale_rust_analyzer_config = {'diagnostics': {'disabled': ['unresolved-import']}} + AssertLSPOptions {'diagnostics': {'disabled': ['unresolved-import']}} diff --git a/vim-config/plugins/ale/test/linter/test_rust_rls.vader b/vim-config/plugins/ale/test/linter/test_rust_rls.vader new file mode 100644 index 00000000..9ca25619 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_rust_rls.vader @@ -0,0 +1,30 @@ +Before: + call ale#assert#SetUpLinterTest('rust', 'rls') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'rls', ale#Escape('rls') + +Execute(The toolchain should be configurable): + let g:ale_rust_rls_toolchain = 'stable' + + AssertLinter 'rls', ale#Escape('rls') . ' +' . ale#Escape('stable') + +Execute(The toolchain should be ommitted if not given): + let g:ale_rust_rls_toolchain = '' + + AssertLinter 'rls', ale#Escape('rls') + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/rust/test.rs') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/rust') + +Execute(Should accept configuration settings): + AssertLSPConfig {} + let b:ale_rust_rls_config = {'rust': {'clippy_preference': 'on'}} + AssertLSPConfig {'rust': {'clippy_preference': 'on'}} diff --git a/vim-config/plugins/ale/test/linter/test_rustc.vader b/vim-config/plugins/ale/test/linter/test_rustc.vader new file mode 100644 index 00000000..4bceb180 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_rustc.vader @@ -0,0 +1,21 @@ +Before: + call ale#assert#SetUpLinterTest('rust', 'rustc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'rustc', 'rustc --error-format=json -Z no-codegen -' + +Execute(The options should be configurable): + let b:ale_rust_rustc_options = '--foo' + + AssertLinter 'rustc', 'rustc --error-format=json --foo -' + +Execute(Some default paths should be included when the project is a Cargo project): + call ale#test#SetFilename('../test-files/cargo/test.rs') + + AssertLinter 'rustc', 'rustc --error-format=json -Z no-codegen' + \ . ' -L ' . ale#Escape(ale#path#GetAbsPath(g:dir, '../test-files/cargo/target/debug/deps')) + \ . ' -L ' . ale#Escape(ale#path#GetAbsPath(g:dir, '../test-files/cargo/target/release/deps')) + \ . ' -' diff --git a/vim-config/plugins/ale/test/linter/test_ruumba.vader b/vim-config/plugins/ale/test/linter/test_ruumba.vader new file mode 100644 index 00000000..9fa48903 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_ruumba.vader @@ -0,0 +1,26 @@ +Before: + call ale#assert#SetUpLinterTest('eruby', 'ruumba') + call ale#test#SetFilename('dummy.html.erb') + + let g:ale_eruby_ruumba_executable = 'ruumba' + let g:ale_eruby_ruumba_options = '' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to ruumba): + AssertLinter 'ruumba', ale#Escape('ruumba') + \ . ' --format json --force-exclusion --stdin %s' + +Execute(Should be able to set a custom executable): + let g:ale_eruby_ruumba_executable = 'bin/ruumba' + + AssertLinter 'bin/ruumba' , ale#Escape('bin/ruumba') + \ . ' --format json --force-exclusion --stdin %s' + +Execute(Setting bundle appends 'exec ruumba'): + let g:ale_eruby_ruumba_executable = 'path to/bundle' + + AssertLinter 'path to/bundle', ale#Escape('path to/bundle') + \ . ' exec ruumba' + \ . ' --format json --force-exclusion --stdin %s' diff --git a/vim-config/plugins/ale/test/linter/test_sass_sasslint.vader b/vim-config/plugins/ale/test/linter/test_sass_sasslint.vader new file mode 100644 index 00000000..87f0c8ad --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_sass_sasslint.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('sass', 'sasslint') + call ale#test#SetFilename('test.sass') + unlet! b:executable + +After: + call ale#assert#TearDownLinterTest() + +Execute(should default to source, bin/sass-lint.js): + call ale#test#SetFilename('../test-files/sasslint/with-source/test.sass') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/sasslint/with-source/node_modules/sass-lint/bin/sass-lint.js' + \) + + AssertLinter b:executable, + \ (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(b:executable) + \ . ' -v -q -f compact %t' + +Execute(should fallback to bin, .bin/sass-lint): + call ale#test#SetFilename('../test-files/sasslint/with-bin/test.sass') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/sasslint/with-bin/node_modules/.bin/sass-lint' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' -v -q -f compact %t' + +Execute(should fallback to global bin): + AssertLinter 'sass-lint', ale#Escape('sass-lint') . ' -v -q -f compact %t' + +Execute(The global executable should be configurable): + let b:ale_sass_sasslint_executable = 'foo' + + AssertLinter 'foo', ale#Escape('foo') . ' -v -q -f compact %t' + +Execute(The options should be configurable): + let b:ale_sass_sasslint_options = '--bar' + + AssertLinter 'sass-lint', ale#Escape('sass-lint') . ' --bar -v -q -f compact %t' diff --git a/vim-config/plugins/ale/test/linter/test_scala_metals.vader b/vim-config/plugins/ale/test/linter/test_scala_metals.vader new file mode 100644 index 00000000..b14e3e02 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_scala_metals.vader @@ -0,0 +1,21 @@ +" Author: Jeffrey Lau https://github.com/zoonfafer +" Description: Tests for the Scala Metals linter +Before: + call ale#assert#SetUpLinterTest('scala', 'metals') + +After: + call ale#assert#TearDownLinterTest() + +Execute(should set metals for sbt project with build.sbt): + call ale#test#SetFilename('../test-files/scala/valid_sbt_project/Main.scala') + AssertLSPLanguage 'scala' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#test#GetFilename('../test-files/scala/valid_sbt_project') + +Execute(should not set metals for sbt project without build.sbt): + call ale#test#SetFilename('../test-files/scala/invalid_sbt_project/Main.scala') + AssertLSPLanguage 'scala' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject '' diff --git a/vim-config/plugins/ale/test/linter/test_scala_sbtserver.vader b/vim-config/plugins/ale/test/linter/test_scala_sbtserver.vader new file mode 100644 index 00000000..118e090f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_scala_sbtserver.vader @@ -0,0 +1,23 @@ +" Author: ophirr33 +" Description: Tests for the sbt Server lsp linter +Before: + call ale#assert#SetUpLinterTest('scala', 'sbtserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(should set sbtserver for sbt project with build.sbt): + call ale#test#SetFilename('../test-files/scala/valid_sbt_project/Main.scala') + AssertLSPLanguage 'scala' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#test#GetFilename('../test-files/scala/valid_sbt_project') + AssertLSPAddress '127.0.0.1:4273' + +Execute(should not set sbtserver for sbt project without build.sbt): + call ale#test#SetFilename('../test-files/scala/invalid_sbt_project/Main.scala') + AssertLSPLanguage 'scala' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject '' + AssertLSPAddress '127.0.0.1:4273' diff --git a/vim-config/plugins/ale/test/linter/test_scalac.vader b/vim-config/plugins/ale/test/linter/test_scalac.vader new file mode 100644 index 00000000..ea5ae109 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_scalac.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('scala', 'scalac') + +After: + call ale#assert#TearDownLinterTest() + +Given scala(An empty Scala file): +Execute(The default executable and command should be correct): + AssertLinter 'scalac', ale#Escape('scalac') . ' -Ystop-after:parser %t' + +Given scala.sbt(An empty SBT file): +Execute(scalac should not be run for sbt files): + AssertLinterNotExecuted diff --git a/vim-config/plugins/ale/test/linter/test_scalastyle.vader b/vim-config/plugins/ale/test/linter/test_scalastyle.vader new file mode 100644 index 00000000..3c28f7a3 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_scalastyle.vader @@ -0,0 +1,34 @@ +Before: + call ale#assert#SetUpLinterTest('scala', 'scalastyle') + +After: + unlet! g:ale_scalastyle_config_loc + call ale#linter#Reset() + +Execute(Should return the correct default command): + AssertLinter 'scalastyle', 'scalastyle %t' + +Execute(Should allow using a custom config file): + let b:ale_scala_scalastyle_config = '/dooper/config.xml' + + AssertLinter 'scalastyle', 'scalastyle' + \ . ' --config ' . ale#Escape('/dooper/config.xml') + \ . ' %t' + +Execute(Should support a legacy option for the scalastyle config): + unlet! g:ale_scala_scalastyle_config + let g:ale_scalastyle_config_loc = '/dooper/config.xml' + + call ale#linter#Reset() + runtime ale_linters/scala/scalastyle.vim + + AssertLinter 'scalastyle', 'scalastyle' + \ . ' --config ' . ale#Escape('/dooper/config.xml') + \ . ' %t' + +Execute(Should allow using custom options): + let b:ale_scala_scalastyle_options = '--warnings false --quiet true' + + AssertLinter 'scalastyle', 'scalastyle' + \ . ' --warnings false --quiet true' + \ . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_scss_sasslint.vader b/vim-config/plugins/ale/test/linter/test_scss_sasslint.vader new file mode 100644 index 00000000..839761c2 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_scss_sasslint.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('scss', 'sasslint') + call ale#test#SetFilename('test.scss') + unlet! b:executable + +After: + call ale#assert#TearDownLinterTest() + +Execute(should default to source, bin/sass-lint.js): + call ale#test#SetFilename('../test-files/sasslint/with-source/test.scss') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/sasslint/with-source/node_modules/sass-lint/bin/sass-lint.js' + \) + + AssertLinter b:executable, + \ (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(b:executable) + \ . ' -v -q -f compact %t' + +Execute(should fallback to bin, .bin/sass-lint): + call ale#test#SetFilename('../test-files/sasslint/with-bin/test.scss') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/sasslint/with-bin/node_modules/.bin/sass-lint' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' -v -q -f compact %t' + +Execute(should fallback to global bin): + AssertLinter 'sass-lint', ale#Escape('sass-lint') . ' -v -q -f compact %t' + +Execute(The global executable should be configurable): + let b:ale_scss_sasslint_executable = 'foo' + + AssertLinter 'foo', ale#Escape('foo') . ' -v -q -f compact %t' + +Execute(The options should be configurable): + let b:ale_scss_sasslint_options = '--bar' + + AssertLinter 'sass-lint', ale#Escape('sass-lint') . ' --bar -v -q -f compact %t' diff --git a/vim-config/plugins/ale/test/linter/test_scss_stylelint.vader b/vim-config/plugins/ale/test/linter/test_scss_stylelint.vader new file mode 100644 index 00000000..5a1e71c6 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_scss_stylelint.vader @@ -0,0 +1,31 @@ +Before: + call ale#assert#SetUpLinterTest('scss', 'stylelint') + unlet! b:executable + +After: + unlet! b:executable + call ale#assert#TearDownLinterTest() + +Execute(node_modules directories should be discovered): + call ale#test#SetFilename('../test-files/stylelint/nested/testfile.scss') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/stylelint/node_modules/.bin/stylelint' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' --stdin-filename %s' + +Execute(The global override should work): + let b:ale_scss_stylelint_executable = 'foobar' + let b:ale_scss_stylelint_use_global = 1 + + call ale#test#SetFilename('../test-files/stylelint/nested/testfile.scss') + + AssertLinter 'foobar', ale#Escape('foobar') . ' --stdin-filename %s' + +Execute(Extra options should be configurable): + let b:ale_scss_stylelint_options = '--configFile ''/absolute/path/to/file''' + + AssertLinter 'stylelint', + \ ale#Escape('stylelint') . ' --configFile ''/absolute/path/to/file'' --stdin-filename %s' diff --git a/vim-config/plugins/ale/test/linter/test_shellcheck.vader b/vim-config/plugins/ale/test/linter/test_shellcheck.vader new file mode 100644 index 00000000..40995755 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_shellcheck.vader @@ -0,0 +1,106 @@ +Before: + call ale#assert#SetUpLinterTest('sh', 'shellcheck') + call ale#test#SetFilename('test.sh') + + let b:suffix = ' -f gcc -' + +After: + unlet! b:is_bash + unlet! b:suffix + call ale#assert#TearDownLinterTest() + +Execute(The default shellcheck command should be correct): + AssertLinterCwd '%s:h' + AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix + +Execute(The option disabling changing directories should work): + let g:ale_sh_shellcheck_change_directory = 0 + + AssertLinterCwd '' + AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix + +Execute(The shellcheck command should accept options): + let b:ale_sh_shellcheck_options = '--foobar' + + AssertLinter 'shellcheck', ale#Escape('shellcheck') . ' --foobar' . b:suffix + +Execute(The shellcheck command should accept options and exclusions): + let b:ale_sh_shellcheck_options = '--foobar' + let b:ale_sh_shellcheck_exclusions = 'foo,bar' + + AssertLinter 'shellcheck', + \ ale#Escape('shellcheck') . ' --foobar -e foo,bar' . b:suffix + +Execute(The shellcheck command should include the dialect): + let b:is_bash = 1 + + AssertLinter 'shellcheck', ale#Escape('shellcheck') . ' -s bash' . b:suffix + +Execute(The shellcheck command should use ale_sh_shellcheck_dialect): + let b:ale_sh_shellcheck_dialect = 'ksh93' + + AssertLinter 'shellcheck', ale#Escape('shellcheck') . ' -s ksh93' . b:suffix + +Execute(The shellcheck command should allow unspecified dialect): + let b:ale_sh_shellcheck_dialect = '' + + AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix + +Execute(The shellcheck command should include the dialect before options and exclusions): + let b:is_bash = 1 + let b:ale_sh_shellcheck_options = '--foobar' + let b:ale_sh_shellcheck_exclusions = 'foo,bar' + + AssertLinter 'shellcheck', ale#Escape('shellcheck') + \ . ' -s bash --foobar -e foo,bar' + \ . b:suffix + +Execute(The -x option should be added when the version is new enough): + AssertLinter 'shellcheck', [ + \ ale#Escape('shellcheck') . ' --version', + \ ale#Escape('shellcheck') . b:suffix, + \] + + GivenCommandOutput [ + \ 'ShellCheck - shell script analysis tool', + \ 'version: 0.4.4', + \ 'license: GNU General Public License, version 3', + \ 'website: http://www.shellcheck.net', + \] + AssertLinter 'shellcheck', [ + \ ale#Escape('shellcheck') . ' --version', + \ ale#Escape('shellcheck') . ' -x' . b:suffix, + \] + + " We should cache the version check + GivenCommandOutput [] + AssertLinter 'shellcheck', [ + \ ale#Escape('shellcheck') . ' -x' . b:suffix, + \] + +Execute(The -x option should not be added when the version is too old): + GivenCommandOutput [ + \ 'ShellCheck - shell script analysis tool', + \ 'version: 0.3.9', + \ 'license: GNU General Public License, version 3', + \ 'website: http://www.shellcheck.net', + \] + AssertLinter 'shellcheck', [ + \ ale#Escape('shellcheck') . ' --version', + \ ale#Escape('shellcheck') . b:suffix, + \] + +Execute(The version check shouldn't be run again for old versions): + GivenCommandOutput [ + \ 'ShellCheck - shell script analysis tool', + \ 'version: 0.3.9', + \ 'license: GNU General Public License, version 3', + \ 'website: http://www.shellcheck.net', + \] + AssertLinter 'shellcheck', [ + \ ale#Escape('shellcheck') . ' --version', + \ ale#Escape('shellcheck') . b:suffix, + \] + AssertLinter 'shellcheck', [ + \ ale#Escape('shellcheck') . b:suffix, + \] diff --git a/vim-config/plugins/ale/test/linter/test_slimlint.vader b/vim-config/plugins/ale/test/linter/test_slimlint.vader new file mode 100644 index 00000000..33df9ac0 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_slimlint.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('slim', 'slimlint') + let g:default_command = 'slim-lint %t' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'slim-lint', 'slim-lint %t' + +Execute(The command should have the .rubocop.yml prepended as an env var if one exists): + call ale#test#SetFilename('../test-files/slimlint/subdir/file.slim') + + AssertLinter 'slim-lint', + \ ale#Env( + \ 'SLIM_LINT_RUBOCOP_CONF', + \ ale#path#Simplify(g:dir . '/../test-files/slimlint/.rubocop.yml') + \ ) + \ . 'slim-lint %t' diff --git a/vim-config/plugins/ale/test/linter/test_solc.vader b/vim-config/plugins/ale/test/linter/test_solc.vader new file mode 100644 index 00000000..23521f6a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_solc.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('solidity', 'solc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'solc', 'solc %s' + +Execute(The options should be configurable): + let g:ale_solidity_solc_options = '--foobar' + + AssertLinter 'solc', 'solc --foobar %s' diff --git a/vim-config/plugins/ale/test/linter/test_solc_commit.vader b/vim-config/plugins/ale/test/linter/test_solc_commit.vader new file mode 100644 index 00000000..e25c47e7 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_solc_commit.vader @@ -0,0 +1,14 @@ +Before: + call ale#assert#SetUpLinterTest('solidity', 'solc') + let g:ale_solidity_solc_executable = 'solc-v0.8.4+commit.c7e474f2' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The executable command should be configurable): + AssertLinter 'solc-v0.8.4+commit.c7e474f2', 'solc-v0.8.4+commit.c7e474f2 %s' + +Execute(The options should be configurable): + let g:ale_solidity_solc_options = '--foobar' + + AssertLinter 'solc-v0.8.4+commit.c7e474f2', 'solc-v0.8.4+commit.c7e474f2 --foobar %s' diff --git a/vim-config/plugins/ale/test/linter/test_solhint.vader b/vim-config/plugins/ale/test/linter/test_solhint.vader new file mode 100644 index 00000000..fc5afa9b --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_solhint.vader @@ -0,0 +1,28 @@ +Before: + call ale#assert#SetUpLinterTest('solidity', 'solhint') + runtime autoload/ale/handlers/solhint.vim + + let b:args = ' --formatter compact %s' + +After: + unlet! b:args + unlet! b:executable + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinterCwd '' + AssertLinter 'solhint', ale#Escape('solhint') . b:args + +Execute(The options should be configurable): + let g:ale_solidity_solhint_options = '--foobar' + + AssertLinter 'solhint', ale#Escape('solhint') . ' --foobar' . b:args + + +Execute(solhint should be run from a containing project with solhint executable): + call ale#test#SetFilename('../test-files/solhint/Contract.sol') + + let b:executable = ale#path#Simplify(g:dir . '/../test-files/solhint/node_modules/.bin/solhint') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/solhint') + AssertLinter b:executable, ale#Escape(b:executable) . b:args diff --git a/vim-config/plugins/ale/test/linter/test_sorbet.vader b/vim-config/plugins/ale/test/linter/test_sorbet.vader new file mode 100644 index 00000000..fe758635 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_sorbet.vader @@ -0,0 +1,34 @@ + +Before: + call ale#assert#SetUpLinterTest('ruby', 'sorbet') + call ale#test#SetFilename('dummy.rb') + + let g:ale_ruby_sorbet_executable = 'srb' + let g:ale_ruby_sorbet_options = '' + let g:ale_ruby_sorbet_enable_watchman = 0 + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to srb): + AssertLinter 'srb', ale#Escape('srb') + \ . ' tc --lsp --disable-watchman' + +Execute(Able to enable watchman): + let g:ale_ruby_sorbet_enable_watchman = 1 + + AssertLinter 'srb', ale#Escape('srb') + \ . ' tc --lsp' + +Execute(Should be able to set a custom executable): + let g:ale_ruby_sorbet_executable = 'bin/srb' + + AssertLinter 'bin/srb' , ale#Escape('bin/srb') + \ . ' tc --lsp --disable-watchman' + +Execute(Setting bundle appends 'exec srb tc'): + let g:ale_ruby_sorbet_executable = 'path to/bundle' + + AssertLinter 'path to/bundle', ale#Escape('path to/bundle') + \ . ' exec srb' + \ . ' tc --lsp --disable-watchman' diff --git a/vim-config/plugins/ale/test/linter/test_spectral.vader b/vim-config/plugins/ale/test/linter/test_spectral.vader new file mode 100644 index 00000000..cfcf0987 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_spectral.vader @@ -0,0 +1,31 @@ +Before: + call ale#assert#SetUpLinterTest('yaml', 'spectral') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The yaml spectral command callback should return the correct default string): + AssertLinter 'spectral', ale#Escape('spectral') . ' lint --ignore-unknown-format -q -f text %t' + +Execute(The yaml spectral command callback should be configurable): + let g:ale_yaml_spectral_executable = '~/.local/bin/spectral' + + AssertLinter '~/.local/bin/spectral', + \ ale#Escape('~/.local/bin/spectral') + \ . ' lint --ignore-unknown-format -q -f text %t' + +Execute(The yaml spectral command callback should allow a global installation to be used): + let g:ale_yaml_spectral_executable = '/usr/local/bin/spectral' + let g:ale_yaml_spectral_use_global = 1 + + AssertLinter '/usr/local/bin/spectral', + \ ale#Escape('/usr/local/bin/spectral') + \ . ' lint --ignore-unknown-format -q -f text %t' + +Execute(The yaml spectral command callback should allow a local installation to be used): + call ale#test#SetFilename('../test-files/spectral/openapi.yaml') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/spectral/node_modules/.bin/spectral'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/spectral/node_modules/.bin/spectral')) + \ . ' lint --ignore-unknown-format -q -f text %t' diff --git a/vim-config/plugins/ale/test/linter/test_sqllint.vader b/vim-config/plugins/ale/test/linter/test_sqllint.vader new file mode 100644 index 00000000..eea9b4e0 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_sqllint.vader @@ -0,0 +1,12 @@ +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('sql', 'sqllint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'sql-lint', ['sql-lint'] diff --git a/vim-config/plugins/ale/test/linter/test_standard.vader b/vim-config/plugins/ale/test/linter/test_standard.vader new file mode 100644 index 00000000..4722cd4a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_standard.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('javascript', 'standard') + call ale#test#SetFilename('testfile.js') + unlet! b:executable + +After: + call ale#assert#TearDownLinterTest() + +Execute(bin/cmd.js paths should be preferred): + call ale#test#SetFilename('../test-files/standard/with-cmd/testfile.js') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/standard/with-cmd/node_modules/standard/bin/cmd.js' + \) + + AssertLinter b:executable, + \ (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(b:executable) + \ . ' --stdin %s' + +Execute(.bin directories should be used too): + call ale#test#SetFilename('../test-files/standard/with-bin/testfile.js') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/standard/with-bin/node_modules/.bin/standard' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' --stdin %s' + +Execute(The global executable should be used otherwise): + AssertLinter 'standard', ale#Escape('standard') . ' --stdin %s' + +Execute(The global executable should be configurable): + let b:ale_javascript_standard_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --stdin %s' + +Execute(The options should be configurable): + let b:ale_javascript_standard_options = '--wat' + + AssertLinter 'standard', ale#Escape('standard') . ' --wat --stdin %s' diff --git a/vim-config/plugins/ale/test/linter/test_standardrb.vader b/vim-config/plugins/ale/test/linter/test_standardrb.vader new file mode 100644 index 00000000..108dd870 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_standardrb.vader @@ -0,0 +1,26 @@ +Before: + call ale#assert#SetUpLinterTest('ruby', 'standardrb') + call ale#test#SetFilename('dummy.rb') + + let g:ale_ruby_standardrb_executable = 'standardrb' + let g:ale_ruby_standardrb_options = '' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to standardrb): + AssertLinter 'standardrb', ale#Escape('standardrb') + \ . ' --format json --force-exclusion --stdin %s' + +Execute(Should be able to set a custom executable): + let g:ale_ruby_standardrb_executable = 'bin/standardrb' + + AssertLinter 'bin/standardrb' , ale#Escape('bin/standardrb') + \ . ' --format json --force-exclusion --stdin %s' + +Execute(Setting bundle appends 'exec standardrb'): + let g:ale_ruby_standardrb_executable = 'path to/bundle' + + AssertLinter 'path to/bundle', ale#Escape('path to/bundle') + \ . ' exec standardrb' + \ . ' --format json --force-exclusion --stdin %s' diff --git a/vim-config/plugins/ale/test/linter/test_standardts.vader b/vim-config/plugins/ale/test/linter/test_standardts.vader new file mode 100644 index 00000000..33ca8b25 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_standardts.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('typescript', 'standard') + call ale#test#SetFilename('testfile.js') + unlet! b:executable + +After: + call ale#assert#TearDownLinterTest() + +Execute(bin/cmd.js paths should be preferred): + call ale#test#SetFilename('../test-files/standard/with-cmd/testfile.js') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/standard/with-cmd/node_modules/standard/bin/cmd.js' + \) + + AssertLinter b:executable, + \ (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(b:executable) + \ . ' --stdin %s' + +Execute(.bin directories should be used too): + call ale#test#SetFilename('../test-files/standard/with-bin/testfile.js') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/standard/with-bin/node_modules/.bin/standard' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' --stdin %s' + +Execute(The global executable should be used otherwise): + AssertLinter 'standard', ale#Escape('standard') . ' --stdin %s' + +Execute(The global executable should be configurable): + let b:ale_typescript_standard_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --stdin %s' + +Execute(The options should be configurable): + let b:ale_typescript_standard_options = '--wat' + + AssertLinter 'standard', ale#Escape('standard') . ' --wat --stdin %s' diff --git a/vim-config/plugins/ale/test/linter/test_staticcheck.vader b/vim-config/plugins/ale/test/linter/test_staticcheck.vader new file mode 100644 index 00000000..94f24a54 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_staticcheck.vader @@ -0,0 +1,49 @@ +Before: + Save g:ale_go_go111module + Save $GOPATH + + let $GOPATH = '/non/existent/directory' + + call ale#assert#SetUpLinterTest('go', 'staticcheck') + call ale#test#SetFilename('test.go') + +After: + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The staticcheck callback should return the right defaults): + AssertLinterCwd '%s:h' + AssertLinter 'staticcheck', ale#Escape('staticcheck') . ' .' + +Execute(staticcheck should be found in GOPATH): + " This is a directory with a fake executable + let $GOPATH = ale#test#GetFilename('../test-files/go/gopath') + + AssertLinter + \ ale#test#GetFilename('../test-files/go/gopath/bin/staticcheck'), + \ ale#Escape(ale#test#GetFilename('../test-files/go/gopath/bin/staticcheck')) + \ . ' .' + +Execute(The staticcheck callback should use configured options): + let b:ale_go_staticcheck_options = '-test' + + AssertLinter 'staticcheck', ale#Escape('staticcheck') . ' -test .' + +Execute(Unset the staticcheck `lint_package` option should use the correct command): + let b:ale_go_staticcheck_lint_package = 0 + + AssertLinterCwd '%s:h' + AssertLinter 'staticcheck', ale#Escape('staticcheck') . ' %s:t' + +Execute(The staticcheck callback should use the `GO111MODULE` option if set): + let b:ale_go_go111module = 'off' + + AssertLinter 'staticcheck', + \ ale#Env('GO111MODULE', 'off') . ale#Escape('staticcheck') . ' .' + + " Test with lint_package option set + let b:ale_go_staticcheck_lint_package = 0 + + AssertLinter 'staticcheck', + \ ale#Env('GO111MODULE', 'off') . ale#Escape('staticcheck') . ' %s:t' diff --git a/vim-config/plugins/ale/test/linter/test_sugarss_stylelint.vader b/vim-config/plugins/ale/test/linter/test_sugarss_stylelint.vader new file mode 100644 index 00000000..ba42eaf8 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_sugarss_stylelint.vader @@ -0,0 +1,31 @@ +Before: + call ale#assert#SetUpLinterTest('sugarss', 'stylelint') + unlet! b:executable + +After: + unlet! b:executable + call ale#assert#TearDownLinterTest() + +Execute(node_modules directories should be discovered): + call ale#test#SetFilename('../test-files/stylelint/nested/testfile.sss') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/../test-files/stylelint/node_modules/.bin/stylelint' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' --syntax=sugarss --stdin-filename %s' + +Execute(The global override should work): + let b:ale_sugarss_stylelint_executable = 'foobar' + let b:ale_sugarss_stylelint_use_global = 1 + + call ale#test#SetFilename('../test-files/stylelint/nested/testfile.sss') + + AssertLinter 'foobar', ale#Escape('foobar') . ' --syntax=sugarss --stdin-filename %s' + +Execute(Extra options should be configurable): + let b:ale_sugarss_stylelint_options = '--configFile ''/absolute/path/to/file''' + + AssertLinter 'stylelint', + \ ale#Escape('stylelint') . ' --configFile ''/absolute/path/to/file'' --syntax=sugarss --stdin-filename %s' diff --git a/vim-config/plugins/ale/test/linter/test_svelteserver.vader b/vim-config/plugins/ale/test/linter/test_svelteserver.vader new file mode 100644 index 00000000..c09f1682 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_svelteserver.vader @@ -0,0 +1,8 @@ +Before: + call ale#assert#SetUpLinterTest('svelte', 'svelteserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'svelteserver', ale#Escape('svelteserver') . ' --stdio' diff --git a/vim-config/plugins/ale/test/linter/test_swaglint.vader b/vim-config/plugins/ale/test/linter/test_swaglint.vader new file mode 100644 index 00000000..98f0c594 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_swaglint.vader @@ -0,0 +1,29 @@ +Before: + call ale#assert#SetUpLinterTest('yaml', 'swaglint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The yaml swaglint command callback should return the correct default string): + AssertLinter 'swaglint', ale#Escape('swaglint') . ' -r compact --stdin' + +Execute(The yaml swaglint command callback should be configurable): + let g:ale_yaml_swaglint_executable = '~/.local/bin/swaglint' + + AssertLinter '~/.local/bin/swaglint', + \ ale#Escape('~/.local/bin/swaglint') . ' -r compact --stdin' + +Execute(The yaml swaglint command callback should allow a global installation to be used): + let g:ale_yaml_swaglint_executable = '/usr/local/bin/swaglint' + let g:ale_yaml_swaglint_use_global = 1 + + AssertLinter '/usr/local/bin/swaglint', + \ ale#Escape('/usr/local/bin/swaglint') . ' -r compact --stdin' + +Execute(The yaml swaglint command callback should allow a local installation to be used): + call ale#test#SetFilename('../test-files/swaglint/docs/swagger.yaml') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/swaglint/node_modules/.bin/swaglint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/swaglint/node_modules/.bin/swaglint')) + \ . ' -r compact --stdin' diff --git a/vim-config/plugins/ale/test/linter/test_swift_appleswiftformat.vader b/vim-config/plugins/ale/test/linter/test_swift_appleswiftformat.vader new file mode 100644 index 00000000..3dbae8ff --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_swift_appleswiftformat.vader @@ -0,0 +1,42 @@ +Before: + call ale#assert#SetUpLinterTest('swift', 'appleswiftformat') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Should use default command when use_swiftpm is not set): + call ale#test#SetFilename('../test-files/swift/non-swift-package-project/src/folder/dummy.swift') + + let g:ale_swift_appleswiftformat_executable = 'swift-format' + let g:ale_swift_appleswiftformat_use_swiftpm = 0 + + AssertLinter 'swift-format', ale#Escape('swift-format') . ' lint %t' + +Execute(Should use default command and available configuration when use_swiftpm is not set): + call ale#test#SetDirectory('/testplugin/test/test-files/swift/swift-package-project-with-config') + call ale#test#SetFilename('src/folder/dummy.swift') + + let g:ale_swift_appleswiftformat_executable = 'swift-format' + let g:ale_swift_appleswiftformat_use_swiftpm = 0 + + AssertLinter 'swift-format', + \ ale#Escape('swift-format') . ' lint %t ' . '--configuration ' + \ . glob(g:dir . '/.swift-format') + + call ale#test#RestoreDirectory() + +Execute(Should use swift run when use_swiftpm is set to 1): + call ale#test#SetFilename('../test-files/swift/swift-package-project/src/folder/dummy.swift') + + let g:ale_swift_appleswiftformat_use_swiftpm = 1 + + AssertLinter 'swift', ale#Escape('swift') . ' run swift-format lint %t' + +Execute(Should use the provided global executable): + call ale#test#SetFilename('../test-files/swift/swift-package-project/src/folder/dummy.swift') + + let g:ale_swift_appleswiftformat_executable = '/path/to/custom/swift-format' + let g:ale_swift_appleswiftformat_use_swiftpm = 0 + + AssertLinter '/path/to/custom/swift-format', + \ ale#Escape('/path/to/custom/swift-format') . ' lint %t' diff --git a/vim-config/plugins/ale/test/linter/test_swift_sourcekitlsp.vader b/vim-config/plugins/ale/test/linter/test_swift_sourcekitlsp.vader new file mode 100644 index 00000000..1040d590 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_swift_sourcekitlsp.vader @@ -0,0 +1,21 @@ +Before: + call ale#assert#SetUpLinterTest('swift', 'sourcekitlsp') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + call ale#test#SetFilename('../test-files/swift/swift-package-project/src/folder/dummy.swift') + + AssertLinter 'sourcekit-lsp', ale#Escape('sourcekit-lsp') + +Execute(Should let users configure a global executable and override local paths): + call ale#test#SetFilename('../test-files/swift/swift-package-project/src/folder/dummy.swift') + + let g:ale_sourcekit_lsp_executable = '/path/to/custom/sourcekitlsp' + + AssertLinter '/path/to/custom/sourcekitlsp', + \ ale#Escape('/path/to/custom/sourcekitlsp') + +Execute(The language should be correct): + AssertLSPLanguage 'swift' diff --git a/vim-config/plugins/ale/test/linter/test_swiftlint.vader b/vim-config/plugins/ale/test/linter/test_swiftlint.vader new file mode 100644 index 00000000..d2442b0a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_swiftlint.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('swift', 'swiftlint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Global installation should be the default executable): + call ale#test#SetFilename('../test-files/swiftlint/global/testfile.swift') + + AssertEqual + \ 'swiftlint', + \ ale_linters#swift#swiftlint#GetExecutable(bufnr('')) + +Execute(React Native apps using CocoaPods should take precedence over the default executable): + call ale#test#SetFilename('../test-files/swiftlint/react-native/testfile.swift') + + AssertEqual + \ tolower(ale#test#GetFilename('../test-files/swiftlint/react-native/ios/Pods/SwiftLint/swiftlint')), + \ tolower(ale_linters#swift#swiftlint#GetExecutable(bufnr(''))) + +Execute(CocoaPods installation should take precedence over the default executable): + call ale#test#SetFilename('../test-files/swiftlint/cocoapods/testfile.swift') + + AssertEqual + \ tolower(ale#test#GetFilename('../test-files/swiftlint/cocoapods/Pods/SwiftLint/swiftlint')), + \ tolower(ale_linters#swift#swiftlint#GetExecutable(bufnr(''))) + +Execute(Top level CocoaPods installation should take precedence over React Native installation): + call ale#test#SetFilename('../test-files/swiftlint/cocoapods-and-react-native/testfile.swift') + + AssertEqual + \ tolower(ale#test#GetFilename('../test-files/swiftlint/cocoapods-and-react-native/Pods/SwiftLint/swiftlint')), + \ tolower(ale_linters#swift#swiftlint#GetExecutable(bufnr(''))) + +Execute(use-global should override other versions): + let g:ale_swift_swiftlint_use_global = 1 + let g:ale_swift_swiftlint_executable = 'swiftlint_d' + + call ale#test#SetFilename('../test-files/swiftlint/cocoapods-and-react-native/testfile.swift') + + AssertEqual + \ 'swiftlint_d', + \ ale_linters#swift#swiftlint#GetExecutable(bufnr('')) diff --git a/vim-config/plugins/ale/test/linter/test_systemd_analyze.vader b/vim-config/plugins/ale/test/linter/test_systemd_analyze.vader new file mode 100644 index 00000000..d97c87be --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_systemd_analyze.vader @@ -0,0 +1,9 @@ +Before: + call ale#assert#SetUpLinterTest('systemd', 'systemd_analyze') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'systemd-analyze', + \ 'SYSTEMD_LOG_COLOR=0 ' . ale#Escape('systemd-analyze') . ' --user verify %s' diff --git a/vim-config/plugins/ale/test/linter/test_terraform_ls.vader b/vim-config/plugins/ale/test/linter/test_terraform_ls.vader new file mode 100644 index 00000000..9f7d3450 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_terraform_ls.vader @@ -0,0 +1,61 @@ +Before: + call ale#assert#SetUpLinterTest('terraform', 'terraform_ls') + +After: + if isdirectory(g:dir . '/.terraform') + call delete(g:dir . '/.terraform', 'd') + endif + + unlet! b:ale_terraform_terraform_executable + unlet! b:ale_terraform_ls_executable + unlet! b:ale_terraform_ls_options + + call ale#assert#TearDownLinterTest() + +Execute(Should send correct LSP language): + AssertLSPLanguage 'terraform' + +Execute(Should load default executable): + AssertLinter 'terraform-ls', + \ ale#Escape('terraform-ls') . ' serve' + +Execute(Should configure custom executable): + let b:ale_terraform_ls_executable = 'foo' + AssertLinter 'foo', + \ ale#Escape('foo') . ' serve' + +Execute(Should ignore non-absolute custom terraform executable): + let b:ale_terraform_terraform_executable = 'terraform' + AssertLinter 'terraform-ls', + \ ale#Escape('terraform-ls') . ' serve' + +Execute(Should set absolute custom terraform executable): + let b:ale_terraform_terraform_executable = '/bin/terraform' + AssertLinter 'terraform-ls', + \ ale#Escape('terraform-ls') . ' serve -tf-exec /bin/terraform' + +Execute(Should set custom options): + let b:ale_terraform_ls_options = '--bar' + + AssertLinter 'terraform-ls', + \ ale#Escape('terraform-ls') . ' serve --bar' + +Execute(Should return current directory if it contains .terraform directory): + call mkdir(g:dir . '/.terraform') + AssertLSPProject g:dir + +Execute(Should return nearest directory with .terraform if found in parent directory): + call ale#test#SetFilename('../test-files/terraform/main.tf') + + let b:parent_dir = ale#path#Simplify(g:dir . '/..') + let b:tf_dir = b:parent_dir . '/.terraform' + + if !isdirectory(b:tf_dir) + call mkdir(b:tf_dir) + endif + + AssertLSPProject b:parent_dir + + call delete(b:tf_dir, 'd') + unlet!b:parent_dir + unlet!b:tf_dir diff --git a/vim-config/plugins/ale/test/linter/test_terraform_lsp.vader b/vim-config/plugins/ale/test/linter/test_terraform_lsp.vader new file mode 100644 index 00000000..a292fca0 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_terraform_lsp.vader @@ -0,0 +1,48 @@ +Before: + call ale#assert#SetUpLinterTest('terraform', 'terraform_lsp') + +After: + if isdirectory(g:dir . '/.terraform') + call delete(g:dir . '/.terraform', 'd') + endif + + unlet! b:ale_terraform_langserver_executable + unlet! b:ale_terraform_langserver_options + + call ale#assert#TearDownLinterTest() + +Execute(Should send correct LSP language): + AssertLSPLanguage 'terraform' + +Execute(Should load default executable): + AssertLinter 'terraform-lsp', ale#Escape('terraform-lsp') + +Execute(Should configure custom executable): + let b:ale_terraform_langserver_executable = 'foo' + AssertLinter 'foo', ale#Escape('foo') + +Execute(Should set custom options): + let b:ale_terraform_langserver_options = '--bar' + + AssertLinter 'terraform-lsp', + \ ale#Escape('terraform-lsp') . ' --bar' + +Execute(Should return current directory if it contains .terraform directory): + call mkdir(g:dir . '/.terraform') + AssertLSPProject g:dir + +Execute(Should return nearest directory with .terraform if found in parent directory): + call ale#test#SetFilename('../test-files/terraform/main.tf') + + let b:parent_dir = ale#path#Simplify(g:dir . '/..') + let b:tf_dir = b:parent_dir . '/.terraform' + + if !isdirectory(b:tf_dir) + call mkdir(b:tf_dir) + endif + + AssertLSPProject b:parent_dir + + call delete(b:tf_dir, 'd') + unlet!b:parent_dir + unlet!b:tf_dir diff --git a/vim-config/plugins/ale/test/linter/test_terraform_terraform.vader b/vim-config/plugins/ale/test/linter/test_terraform_terraform.vader new file mode 100644 index 00000000..25ca652a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_terraform_terraform.vader @@ -0,0 +1,15 @@ +" Based upon :help ale-development +Before: + call ale#assert#SetUpLinterTest('terraform', 'terraform') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'terraform', + \ ale#Escape('terraform') . ' validate -no-color -json ' + +Execute(The default command should be overriden): + let b:ale_terraform_terraform_executable = '/bin/other/terraform' + AssertLinter '/bin/other/terraform', + \ ale#Escape('/bin/other/terraform') . ' validate -no-color -json ' diff --git a/vim-config/plugins/ale/test/linter/test_terraform_tflint.vader b/vim-config/plugins/ale/test/linter/test_terraform_tflint.vader new file mode 100644 index 00000000..b1963a77 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_terraform_tflint.vader @@ -0,0 +1,28 @@ +Before: + call ale#assert#SetUpLinterTest('terraform', 'tflint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'tflint', ale#Escape('tflint') . ' -f json' + +Execute(The default executable should be configurable): + let b:ale_terraform_tflint_executable = 'asdf' + + AssertLinter 'asdf', ale#Escape('asdf') . ' -f json' + +Execute(Overriding options should work): + let g:ale_terraform_tflint_executable = 'fnord' + let g:ale_terraform_tflint_options = '--whatever' + + AssertLinter 'fnord', ale#Escape('fnord') . ' --whatever -f json' + +Execute(Configuration files should be found): + call ale#test#SetFilename('../test-files/tflint/foo/bar.tf') + + AssertLinter 'tflint', + \ ale#Escape('tflint') + \ . ' --config ' + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/tflint/foo/.tflint.hcl')) + \ . ' -f json' diff --git a/vim-config/plugins/ale/test/linter/test_tex_lacheck.vader b/vim-config/plugins/ale/test/linter/test_tex_lacheck.vader new file mode 100644 index 00000000..b404cc78 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_tex_lacheck.vader @@ -0,0 +1,13 @@ +Before: + call ale#assert#SetUpLinterTest('tex', 'lacheck') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to lacheck): + AssertLinter 'lacheck', ale#Escape('lacheck') . ' %t' + +Execute(Should be able to set a custom executable): + let g:ale_tex_lacheck_executable = 'bin/foo' + + AssertLinter 'bin/foo' , ale#Escape('bin/foo') . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_tex_textlint.vader b/vim-config/plugins/ale/test/linter/test_tex_textlint.vader new file mode 100644 index 00000000..f99e0fd0 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_tex_textlint.vader @@ -0,0 +1,65 @@ +" Author: januswel, w0rp + +Before: + " This is just one language for the linter. + call ale#assert#SetUpLinterTest('tex', 'textlint') + + " The configuration is shared between many languages. + Save g:ale_textlint_executable + Save g:ale_textlint_use_global + Save g:ale_textlint_options + + let g:ale_textlint_executable = 'textlint' + let g:ale_textlint_use_global = 0 + let g:ale_textlint_options = '' + + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + +After: + unlet! b:command_tail + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' -f json --stdin --stdin-filename %s' + +Execute(The executable should be configurable): + let b:ale_textlint_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -f json --stdin --stdin-filename %s' + +Execute(The options should be configurable): + let b:ale_textlint_options = '--something' + + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' --something -f json --stdin --stdin-filename %s' + +Execute(The local executable from .bin should be used if available): + call ale#test#SetFilename('../test-files/textlint/with_bin_path/foo.txt') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_bin_path/node_modules/.bin/textlint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_bin_path/node_modules/.bin/textlint')) + \ . ' -f json --stdin --stdin-filename %s' + +Execute(The local executable from textlint/bin should be used if available): + call ale#test#SetFilename('../test-files/textlint/with_textlint_bin_path/foo.txt') + + if has('win32') + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape('node.exe') . ' ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + else + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + endif diff --git a/vim-config/plugins/ale/test/linter/test_texlab.vader b/vim-config/plugins/ale/test/linter/test_texlab.vader new file mode 100644 index 00000000..75fc2f25 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_texlab.vader @@ -0,0 +1,30 @@ +Before: + call ale#assert#SetUpLinterTest('tex', 'texlab') + + Save &filetype + let &filetype = 'tex' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'tex' + +Execute(The default executable path should be correct): + AssertLinter 'texlab', ale#Escape('texlab') + +Execute(The project root should be detected correctly): + call ale#test#SetFilename('../test-files/tex/sample1.tex') + silent! call mkdir('../test-files/tex/.git') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/tex') + +Execute(The executable should be configurable): + let b:ale_tex_texlab_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + +Execute(The options should be configurable): + let b:ale_tex_texlab_options = '-v' + + AssertLinter 'texlab', ale#Escape('texlab') . ' ' . b:ale_tex_texlab_options diff --git a/vim-config/plugins/ale/test/linter/test_textlint.vader b/vim-config/plugins/ale/test/linter/test_textlint.vader new file mode 100644 index 00000000..6ec42b2d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_textlint.vader @@ -0,0 +1,65 @@ +" Author: januswel, w0rp + +Before: + " This is just one language for the linter. + call ale#assert#SetUpLinterTest('markdown', 'textlint') + + " The configuration is shared between many languages. + Save g:ale_textlint_executable + Save g:ale_textlint_use_global + Save g:ale_textlint_options + + let g:ale_textlint_executable = 'textlint' + let g:ale_textlint_use_global = 0 + let g:ale_textlint_options = '' + + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + +After: + unlet! b:command_tail + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' -f json --stdin --stdin-filename %s' + +Execute(The executable should be configurable): + let b:ale_textlint_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -f json --stdin --stdin-filename %s' + +Execute(The options should be configurable): + let b:ale_textlint_options = '--something' + + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' --something -f json --stdin --stdin-filename %s' + +Execute(The local executable from .bin should be used if available): + call ale#test#SetFilename('../test-files/textlint/with_bin_path/foo.txt') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_bin_path/node_modules/.bin/textlint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_bin_path/node_modules/.bin/textlint')) + \ . ' -f json --stdin --stdin-filename %s' + +Execute(The local executable from textlint/bin should be used if available): + call ale#test#SetFilename('../test-files/textlint/with_textlint_bin_path/foo.txt') + + if has('win32') + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape('node.exe') . ' ' . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + else + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + endif diff --git a/vim-config/plugins/ale/test/linter/test_thrift.vader b/vim-config/plugins/ale/test/linter/test_thrift.vader new file mode 100644 index 00000000..cbada818 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_thrift.vader @@ -0,0 +1,53 @@ +Before: + call ale#assert#SetUpLinterTest('thrift', 'thrift') + let b:suffix = ' -out ' . ale#Escape('TEMP_DIR') . ' %t' + + function! GetCommand(buffer) abort + call ale#engine#InitBufferInfo(a:buffer) + let l:command = ale_linters#thrift#thrift#GetCommand(a:buffer) + call ale#engine#Cleanup(a:buffer) + + let l:split_command = split(l:command) + let l:index = index(l:split_command, '-out') + + if l:index >= 0 + let l:split_command[l:index + 1] = 'TEMP' + endif + + return join(l:split_command) + endfunction + +After: + unlet! b:suffix + delfunction GetCommand + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'thrift', ale#Escape('thrift') . ' --gen cpp -I . -strict' . b:suffix + +Execute(The executable should be configurable): + let b:ale_thrift_thrift_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --gen cpp -I . -strict' . b:suffix + +Execute(The list of generators should be configurable): + let b:ale_thrift_thrift_generators = ['java', 'py:dynamic'] + + AssertLinter 'thrift', ale#Escape('thrift') + \ . ' --gen java --gen py:dynamic -I . -strict' . b:suffix + + let b:ale_thrift_thrift_generators = [] + + AssertLinter 'thrift', ale#Escape('thrift') . ' --gen cpp -I . -strict' . b:suffix + +Execute(The list of include paths should be configurable): + let b:ale_thrift_thrift_includes = ['included/path'] + + AssertLinter 'thrift', ale#Escape('thrift') + \ . ' --gen cpp -I included/path -strict' . b:suffix + +Execute(The string of compiler options should be configurable): + let b:ale_thrift_thrift_options = '-strict --allow-64bit-consts' + + AssertLinter 'thrift', ale#Escape('thrift') + \ . ' --gen cpp -I . -strict --allow-64bit-consts' . b:suffix diff --git a/vim-config/plugins/ale/test/linter/test_thriftcheck.vader b/vim-config/plugins/ale/test/linter/test_thriftcheck.vader new file mode 100644 index 00000000..0da3bd6d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_thriftcheck.vader @@ -0,0 +1,21 @@ +Before: + call ale#assert#SetUpLinterTest('thrift', 'thriftcheck') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'thriftcheck', ale#Escape('thriftcheck') + \ . ' --stdin-filename %s %t' + +Execute(The executable should be configurable): + let b:ale_thrift_thriftcheck_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + \ . ' --stdin-filename %s %t' + +Execute(The string of options should be configurable): + let b:ale_thrift_thriftcheck_options = '--errors-only' + + AssertLinter 'thriftcheck', ale#Escape('thriftcheck') + \ . ' --errors-only --stdin-filename %s %t' diff --git a/vim-config/plugins/ale/test/linter/test_tslint.vader b/vim-config/plugins/ale/test/linter/test_tslint.vader new file mode 100644 index 00000000..1b291d9f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_tslint.vader @@ -0,0 +1,23 @@ +Before: + call ale#assert#SetUpLinterTest('typescript', 'tslint') + call ale#test#SetFilename('test.ts') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default tslint command should be correct): + AssertLinterCwd '%s:h' + AssertLinter 'tslint', ale#Escape('tslint') . ' --format json %t' + +Execute(The rules directory option should be included if set): + let b:ale_typescript_tslint_rules_dir = '/foo/bar' + + AssertLinter 'tslint', + \ ale#Escape('tslint') . ' --format json' + \ . ' -r ' . ale#Escape('/foo/bar') + \ . ' %t' + +Execute(The executable should be configurable and escaped): + let b:ale_typescript_tslint_executable = 'foo bar' + + AssertLinter 'foo bar', ale#Escape('foo bar') . ' --format json %t' diff --git a/vim-config/plugins/ale/test/linter/test_typescript_deno_lsp.vader b/vim-config/plugins/ale/test/linter/test_typescript_deno_lsp.vader new file mode 100644 index 00000000..944f6a0a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_typescript_deno_lsp.vader @@ -0,0 +1,79 @@ +Before: + let g:ale_deno_importMap = 'import_map.json' + let g:ale_deno_unstable = 0 + let g:ale_deno_executable = 'deno' + let g:ale_deno_lsp_project_root = '' + + runtime autoload/ale/handlers/deno.vim + call ale#assert#SetUpLinterTest('typescript', 'deno') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Should set deno lsp for TypeScript projects using stable Deno API): + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false, + \ 'importMap': '' + \} + +Execute(Should set deno lsp using unstable Deno API if enabled by user): + let g:ale_deno_unstable = 1 + + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:true, + \ 'importMap': '' + \} + +Execute(Should set the default importMap filepath): + call ale#test#SetFilename('../test-files/typescript/test.ts') + + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false, + \ 'importMap': ale#path#Simplify(g:dir . '/../test-files/typescript/import_map.json') + \} + +Execute(Should set the importMap filepath from user defined importMap): + let g:ale_deno_importMap = 'custom_import_map.json' + call ale#test#SetFilename('../test-files/typescript/test.ts') + + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false, + \ 'importMap': ale#path#Simplify(g:dir . '/../test-files/typescript/custom_import_map.json') + \} + +Execute(Should set the importMap filepath from user defined importMap with unstable API): + let g:ale_deno_importMap = 'custom_import_map.json' + let g:ale_deno_unstable = 1 + call ale#test#SetFilename('../test-files/typescript/test.ts') + + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:true, + \ 'importMap': ale#path#Simplify(g:dir . '/../test-files/typescript/custom_import_map.json') + \} + +Execute(Should find project root containing tsconfig.json): + call ale#test#SetFilename('../test-files/typescript/test.ts') + + AssertLSPLanguage 'typescript' + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/typescript') + +Execute(Should use user-specified project root): + let g:ale_deno_lsp_project_root = '/' + + call ale#test#SetFilename('../test-files/typescript/test.ts') + + AssertLSPLanguage 'typescript' + AssertLSPProject '/' + +Execute(Check Deno LSP command): + AssertLinter 'deno', ale#Escape('deno') . ' lsp' diff --git a/vim-config/plugins/ale/test/linter/test_typescript_tsserver.vader b/vim-config/plugins/ale/test/linter/test_typescript_tsserver.vader new file mode 100644 index 00000000..719ac184 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_typescript_tsserver.vader @@ -0,0 +1,8 @@ +Before: + call ale#assert#SetUpLinterTest('typescript', 'tsserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'tsserver', ale#Escape('tsserver') diff --git a/vim-config/plugins/ale/test/linter/test_v_command_callback.vader b/vim-config/plugins/ale/test/linter/test_v_command_callback.vader new file mode 100644 index 00000000..17f24ad7 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_v_command_callback.vader @@ -0,0 +1,25 @@ +Before: + Save g:ale_v_v_executable + + call ale#assert#SetUpLinterTest('v', 'v') + + GivenCommandOutput ['/foo/bar', '/foo/baz'] + +After: + Restore + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'v', 'v . -o /tmp/vim-ale-v' + +Execute(Extra options should be supported): + let g:ale_v_v_options = '--foo-bar' + + AssertLinter 'v', 'v --foo-bar . -o /tmp/vim-ale-v' + + let g:ale_v_vbuild_options = '' + +Execute(The executable should be configurable): + let g:ale_v_v_executable = 'foobar' + + AssertLinter 'foobar', 'foobar . -o /tmp/vim-ale-v' diff --git a/vim-config/plugins/ale/test/linter/test_vcom.vader b/vim-config/plugins/ale/test/linter/test_vcom.vader new file mode 100644 index 00000000..77218f74 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_vcom.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('vhdl', 'vcom') + +After: + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'vcom', ale#Escape('vcom') . ' -2008 -quiet -lint %t' + + let b:ale_vhdl_vcom_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' -2008 -quiet -lint %t' + +Execute(The options should be configurable): + let b:ale_vhdl_vcom_options = '--something' + + AssertLinter 'vcom', ale#Escape('vcom') . ' --something %t' diff --git a/vim-config/plugins/ale/test/linter/test_verilator.vader b/vim-config/plugins/ale/test/linter/test_verilator.vader new file mode 100644 index 00000000..b65f3459 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_verilator.vader @@ -0,0 +1,14 @@ +Before: + call ale#assert#SetUpLinterTest('verilog', 'verilator') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default verilator command should be correct): + AssertLinter 'verilator', 'verilator --lint-only -Wall -Wno-DECLFILENAME -I%s:h %t' + +Execute(verilator options should be configurable): + " Additional args for the linter + let g:ale_verilog_verilator_options = '-sv --default-language "1800-2012"' + + AssertLinter 'verilator', 'verilator --lint-only -Wall -Wno-DECLFILENAME -I%s:h -sv --default-language "1800-2012" %t' diff --git a/vim-config/plugins/ale/test/linter/test_vim_vimls.vader b/vim-config/plugins/ale/test/linter/test_vim_vimls.vader new file mode 100644 index 00000000..47826a1a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_vim_vimls.vader @@ -0,0 +1,76 @@ +" Author: Jeffrey Lau https://github.com/zoonfafer +" Description: Tests for the Vim vimls linter + +Before: + call ale#assert#SetUpLinterTest('vim', 'vimls') + +After: + if isdirectory(g:dir . '/.git') + call delete(g:dir . '/.git', 'd') + endif + + call ale#assert#TearDownLinterTest() + +Execute(should set correct defaults): + AssertLinter 'vim-language-server', ale#Escape('vim-language-server') . ' --stdio' + +Execute(should set correct LSP values): + call ale#test#SetFilename('../test-files/vim/path_with_autoload/test.vim') + AssertLSPLanguage 'vim' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/vim/path_with_autoload') + +Execute(should set correct project for .git/): + let b:parent_dir = ale#path#Simplify(g:dir . '/..') + let b:git_dir = b:parent_dir . '/.git' + + call ale#test#SetFilename('../test-files/vim/test.vim') + + if !isdirectory(b:git_dir) + call mkdir(b:git_dir) + endif + + AssertLSPProject ale#path#Simplify(b:parent_dir) + + call delete(b:git_dir, 'd') + unlet! b:git_dir + +Execute(should set correct project for plugin/): + call ale#test#SetFilename('../test-files/vim/path_with_plugin/test.vim') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/vim/path_with_plugin') + +Execute(should accept configuration settings): + AssertLSPConfig {} + + let b:ale_vim_vimls_config = {'vim': {'foobar': v:true}} + AssertLSPConfig {'vim': {'foobar': v:true}} + +Execute(should set correct project for .vimrc): + call ale#test#SetFilename('../test-files/vim/path_with_vimrc/.vimrc') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/vim/path_with_vimrc') + +Execute(should set correct project for init.vim): + call ale#test#SetFilename('../test-files/vim/path_with_initvim/init.vim') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/vim/path_with_initvim') + +Execute(should use the local executable when available): + call ale#test#SetFilename('../test-files/vim/file.vim') + + AssertLinter ale#path#Simplify(g:dir . '/../test-files/vim/node_modules/.bin/vim-language-server'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/vim/node_modules/.bin/vim-language-server')) . ' --stdio' + +Execute(should let the global executable to be used): + let g:ale_vim_vimls_use_global = 1 + call ale#test#SetFilename('../test-files/vim/file.vim') + + AssertLinter 'vim-language-server', + \ ale#Escape('vim-language-server') . ' --stdio' + +Execute(should let the executable to be configured): + let g:ale_vim_vimls_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --stdio' diff --git a/vim-config/plugins/ale/test/linter/test_vint.vader b/vim-config/plugins/ale/test/linter/test_vint.vader new file mode 100644 index 00000000..4a224d01 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_vint.vader @@ -0,0 +1,34 @@ +Before: + call ale#assert#SetUpLinterTest('vim', 'vint') + let b:common_flags = (has('nvim') ? ' --enable-neovim' : '') + \ . ' -f "{file_path}:{line_number}:{column_number}: {severity}: {policy_name} - {description} (see {reference})"' + +After: + unlet! b:common_flags + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'vint', [ + \ ale#Escape('vint') .' --version', + \ ale#Escape('vint') .' -s --no-color' . b:common_flags . ' %t', + \] + +Execute(The executable should be configurable): + let g:ale_vim_vint_executable = 'foobar' + + AssertLinter 'foobar', [ + \ ale#Escape('foobar') .' --version', + \ ale#Escape('foobar') .' -s --no-color' . b:common_flags . ' %t', + \] + +Execute(The --no-color flag should not be used for older Vint versions): + GivenCommandOutput ['v0.3.5'] + + AssertLinter 'vint', ale#Escape('vint') .' -s' . b:common_flags . ' %t' + +Execute(--stdin-display-name should be used in newer versions): + GivenCommandOutput ['v0.4.0'] + + AssertLinter 'vint', ale#Escape('vint') .' -s --no-color' . b:common_flags + \ . ' --stdin-display-name %s -' diff --git a/vim-config/plugins/ale/test/linter/test_vlog.vader b/vim-config/plugins/ale/test/linter/test_vlog.vader new file mode 100644 index 00000000..a07944f7 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_vlog.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('verilog', 'vlog') + +After: + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'vlog', ale#Escape('vlog') . ' -quiet -lint %t' + + let b:ale_verilog_vlog_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' -quiet -lint %t' + +Execute(The options should be configurable): + let b:ale_verilog_vlog_options = '--something' + + AssertLinter 'vlog', ale#Escape('vlog') . ' --something %t' diff --git a/vim-config/plugins/ale/test/linter/test_vulture.vader b/vim-config/plugins/ale/test/linter/test_vulture.vader new file mode 100644 index 00000000..78655bd7 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_vulture.vader @@ -0,0 +1,62 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'vulture') + call ale#test#SetFilename('test.py') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + unlet! b:bin_dir + unlet! b:executable + + call ale#assert#TearDownLinterTest() + +Execute(The vulture command callback should lint file directory by default): + AssertLinterCwd expand('#' . bufnr('') . ':p:h') + AssertLinter 'vulture', ale#Escape('vulture') . ' .' + +Execute(The vulture command callback should lint project root, when present): + call ale#test#SetFilename('../test-files/python/no_virtualenv/subdir/foo/bar.py') + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/no_virtualenv/subdir') + AssertLinter 'vulture', ale#Escape('vulture') . ' .' + +Execute(The option for disabling change directory works and only lints file): + let g:ale_python_vulture_change_directory = 0 + + AssertLinterCwd '' + AssertLinter 'vulture', ale#Escape('vulture') . ' %s' + +Execute(The vulture executable should be configurable, and escaped properly): + let g:ale_python_vulture_executable = 'executable with spaces' + + AssertLinter 'executable with spaces', ale#Escape('executable with spaces') . ' .' + +Execute(The vulture command callback should let you set options): + let g:ale_python_vulture_options = '--some-option' + + AssertLinter 'vulture', ale#Escape('vulture') . ' --some-option .' + +Execute(The vulture command callback should detect virtualenv directories and switch to the project root): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + let b:executable = ale#path#Simplify( + \ g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/vulture' + \) + + AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/subdir') + AssertLinter b:executable, ale#Escape(b:executable) . ' .' + +Execute(You should able able to use the global vulture instead): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + let g:ale_python_vulture_use_global = 1 + + AssertLinter 'vulture', ale#Escape('vulture') . ' .' + +Execute(Setting executable to 'pipenv' appends 'run vulture'): + let g:ale_python_vulture_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', ale#Escape('path/to/pipenv') . ' run vulture' . ' .' +Execute(Setting executable to 'poetry' appends 'run vulture'): + let g:ale_python_vulture_executable = 'path/to/poetry' + + AssertLinter 'path/to/poetry', ale#Escape('path/to/poetry') . ' run vulture' . ' .' diff --git a/vim-config/plugins/ale/test/linter/test_write_good.vader b/vim-config/plugins/ale/test/linter/test_write_good.vader new file mode 100644 index 00000000..8958dd6a --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_write_good.vader @@ -0,0 +1,55 @@ +Before: + " This is just one example of a language using the linter. + call ale#assert#SetUpLinterTest('markdown', 'writegood') + + " The options are shared between many languages. + Save g:ale_writegood_options + Save g:ale_writegood_executable + Save g:ale_writegood_use_global + + unlet! g:ale_writegood_options + unlet! g:ale_writegood_executable + unlet! g:ale_writegood_use_global + + call ale#test#SetFilename('testfile.txt') + call ale#handlers#writegood#ResetOptions() + +After: + call ale#assert#TearDownLinterTest() + +Execute(The global executable should be used when the local one cannot be found): + AssertLinter + \ 'write-good', + \ ale#Escape('write-good') . ' %t', + +Execute(The options should be used in the command): + let g:ale_writegood_options = '--foo --bar' + + AssertLinter + \ 'write-good', + \ ale#Escape('write-good') . ' --foo --bar %t', + +Execute(Should use the node_modules/.bin executable, if available): + call ale#test#SetFilename('../test-files/write-good/node-modules/test.txt') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/write-good/node-modules/node_modules/.bin/write-good'), + \ ale#Escape(ale#path#Simplify(g:dir . '/../test-files/write-good/node-modules/node_modules/.bin/write-good')) + \ . ' %t', + +Execute(Should use the node_modules/write-good executable, if available): + call ale#test#SetFilename('../test-files/write-good/node-modules-2/test.txt') + + AssertLinter + \ ale#path#Simplify(g:dir . '/../test-files/write-good/node-modules-2/node_modules/write-good/bin/write-good.js'), + \ (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../test-files/write-good/node-modules-2/node_modules/write-good/bin/write-good.js')) + \ . ' %t', + +Execute(Should let users configure a global executable and override local paths): + call ale#test#SetFilename('../test-files/write-good/node-modules-2/test.txt') + + let g:ale_writegood_executable = 'foo-bar' + let g:ale_writegood_use_global = 1 + + AssertLinter 'foo-bar', ale#Escape('foo-bar') . ' %t' diff --git a/vim-config/plugins/ale/test/linter/test_xmllint.vader b/vim-config/plugins/ale/test/linter/test_xmllint.vader new file mode 100644 index 00000000..5a2377c2 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_xmllint.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('xml', 'xmllint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The xml xmllint command callback should return the correct default string): + AssertLinter 'xmllint', ale#Escape('xmllint') . ' --noout -' + +Execute(The xml xmllint command callback should let you set options): + let g:ale_xml_xmllint_options = '--xinclude --postvalid' + + AssertLinter 'xmllint', + \ ale#Escape('xmllint') . ' --xinclude --postvalid --noout -' + +Execute(The xmllint executable should be configurable): + let g:ale_xml_xmllint_executable = '~/.local/bin/xmllint' + + AssertLinter '~/.local/bin/xmllint', + \ ale#Escape('~/.local/bin/xmllint') . ' --noout -' diff --git a/vim-config/plugins/ale/test/linter/test_xo.vader b/vim-config/plugins/ale/test/linter/test_xo.vader new file mode 100644 index 00000000..1aa4c3f1 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_xo.vader @@ -0,0 +1,23 @@ +Before: + call ale#assert#SetUpLinterTest('javascript', 'xo') + call ale#test#SetFilename('testfile.jsx') + unlet! b:executable + + set filetype=javascriptreact + runtime autoload/ale/handlers/xo.vim + +After: + call ale#assert#TearDownLinterTest() + +Execute(The XO executable should be called): + AssertLinter 'xo', ale#Escape('xo') . ' --reporter json --stdin --stdin-filename %s' + +Execute(The XO executable should be configurable): + let b:ale_javascript_xo_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --reporter json --stdin --stdin-filename %s' + +Execute(The XO options should be configurable): + let b:ale_javascript_xo_options = '--wat' + + AssertLinter 'xo', ale#Escape('xo') . ' --wat --reporter json --stdin --stdin-filename %s' diff --git a/vim-config/plugins/ale/test/linter/test_xots.vader b/vim-config/plugins/ale/test/linter/test_xots.vader new file mode 100644 index 00000000..cc38ff02 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_xots.vader @@ -0,0 +1,23 @@ +Before: + call ale#assert#SetUpLinterTest('typescript', 'xo') + call ale#test#SetFilename('testfile.tsx') + unlet! b:executable + + set filetype=typescriptreact + runtime autoload/ale/handlers/xo.vim + +After: + call ale#assert#TearDownLinterTest() + +Execute(The XO executable should be called): + AssertLinter 'xo', ale#Escape('xo') . ' --reporter json --stdin --stdin-filename %s' + +Execute(The XO executable should be configurable): + let b:ale_typescript_xo_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --reporter json --stdin --stdin-filename %s' + +Execute(The XO options should be configurable): + let b:ale_typescript_xo_options = '--wat' + + AssertLinter 'xo', ale#Escape('xo') . ' --wat --reporter json --stdin --stdin-filename %s' diff --git a/vim-config/plugins/ale/test/linter/test_xvhdl.vader b/vim-config/plugins/ale/test/linter/test_xvhdl.vader new file mode 100644 index 00000000..86f9a32d --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_xvhdl.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('vhdl', 'xvhdl') + +After: + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'xvhdl', ale#Escape('xvhdl') . ' --2008 %t' + + let b:ale_vhdl_xvhdl_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --2008 %t' + +Execute(The options should be configurable): + let b:ale_vhdl_xvhdl_options = '--something' + + AssertLinter 'xvhdl', ale#Escape('xvhdl') . ' --something %t' diff --git a/vim-config/plugins/ale/test/linter/test_xvlog.vader b/vim-config/plugins/ale/test/linter/test_xvlog.vader new file mode 100644 index 00000000..564ac979 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_xvlog.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('verilog', 'xvlog') + +After: + unlet! b:command_tail + + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'xvlog', ale#Escape('xvlog') . ' %t' + + let b:ale_verilog_xvlog_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' %t' + +Execute(The options should be configurable): + let b:ale_verilog_xvlog_options = '--something' + + AssertLinter 'xvlog', ale#Escape('xvlog') . ' --something %t' diff --git a/vim-config/plugins/ale/test/linter/test_yang_lsp.vader b/vim-config/plugins/ale/test/linter/test_yang_lsp.vader new file mode 100644 index 00000000..5be7501f --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_yang_lsp.vader @@ -0,0 +1,12 @@ +Before: + call ale#assert#SetUpLinterTest('yang', 'yang_lsp') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'yang-language-server', ale#Escape('yang-language-server') + + let b:ale_yang_lsp_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') diff --git a/vim-config/plugins/ale/test/linter/test_zeek.vader b/vim-config/plugins/ale/test/linter/test_zeek.vader new file mode 100644 index 00000000..af58a414 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_zeek.vader @@ -0,0 +1,17 @@ +Before: + call ale#assert#SetUpLinterTest('zeek', 'zeek') + + let b:command_tail = ' --parse-only %s' + +After: + call ale#assert#TearDownLinterTest() + + unlet! b:command_tail + +Execute(The default command should be correct): + AssertLinter 'zeek', ale#Escape('zeek') . b:command_tail + +Execute(The zeek executable should be configurable, and escaped properly): + let g:ale_zeek_zeek_executable = 'executable with spaces' + + AssertLinter 'executable with spaces', ale#Escape('executable with spaces') . b:command_tail diff --git a/vim-config/plugins/ale/test/linter/test_zig_zls.vader b/vim-config/plugins/ale/test/linter/test_zig_zls.vader new file mode 100644 index 00000000..6d814be4 --- /dev/null +++ b/vim-config/plugins/ale/test/linter/test_zig_zls.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('zig', 'zls') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'zls', ale#Escape('zls') + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/zig/main.zig') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/zig') diff --git a/vim-config/plugins/ale/test/lsp/test_closing_documents.vader b/vim-config/plugins/ale/test/lsp/test_closing_documents.vader new file mode 100644 index 00000000..e6e11415 --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_closing_documents.vader @@ -0,0 +1,176 @@ +Before: + runtime autoload/ale/lsp.vim + + let g:message_list = [] + + function! MarkAllConnectionsInitialized() abort + for l:conn in values(ale#lsp#GetConnections()) + let l:conn.initialized = 1 + endfor + endfunction + + function! MarkDocumentOpened() abort + for l:conn in values(ale#lsp#GetConnections()) + let l:conn.open_documents[bufnr('')] = 1 + endfor + endfunction + + function! ale#lsp#Send(conn_id, message) abort + let l:connections = ale#lsp#GetConnections() + + if !l:connections[a:conn_id].initialized + throw 'LSP server not initialized yet!' + endif + + call add(g:message_list, [a:conn_id] + a:message) + endfunction + + call ale#lsp#ResetConnections() + +After: + unlet! g:message_list + delfunction MarkAllConnectionsInitialized + delfunction MarkDocumentOpened + + call ale#lsp#ResetConnections() + + runtime autoload/ale/lsp.vim + +Execute(No errors should be thrown if the connection is not initialized): + call ale#lsp#Register('command', '/foo', {}) + call MarkDocumentOpened() + + call ale#engine#Cleanup(bufnr('')) + AssertEqual [], g:message_list + +Execute(No messages should be sent if the document wasn't opened): + call ale#lsp#Register('command', '/foo', {}) + call MarkAllConnectionsInitialized() + + call ale#engine#Cleanup(bufnr('')) + AssertEqual [], g:message_list + +Execute(A message should be sent if the document was opened): + call ale#lsp#Register('command', '/foo', {}) + call MarkAllConnectionsInitialized() + + call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang') + call ale#engine#Cleanup(bufnr('')) + " We should only send the message once. + call ale#engine#Cleanup(bufnr('')) + + AssertEqual + \ [ + \ ['command:/foo', 1, 'textDocument/didOpen', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ 'languageId': 'lang', + \ 'text': "\n", + \ }, + \ }], + \ ['command:/foo', 1, 'textDocument/didClose', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ }, + \ }], + \ ], + \ g:message_list + +Execute(A message should be sent if the document was opened for tsserver): + call ale#lsp#Register('command', '/foo', {}) + call ale#lsp#MarkConnectionAsTsserver('command:/foo') + + call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang') + call ale#engine#Cleanup(bufnr('')) + " We should only send the message once. + call ale#engine#Cleanup(bufnr('')) + + AssertEqual + \ [ + \ ['command:/foo', 1, 'ts@open', {'file': expand('%:p')}], + \ ['command:/foo', 1, 'ts@close', {'file': expand('%:p')}], + \ ], + \ g:message_list + +Execute(Re-opening and closing the documents should work): + call ale#lsp#Register('command', '/foo', {}) + call MarkAllConnectionsInitialized() + + call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang') + call ale#engine#Cleanup(bufnr('')) + call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang') + call ale#engine#Cleanup(bufnr('')) + + AssertEqual + \ [ + \ ['command:/foo', 1, 'textDocument/didOpen', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 2, + \ 'languageId': 'lang', + \ 'text': "\n", + \ }, + \ }], + \ ['command:/foo', 1, 'textDocument/didClose', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ }, + \ }], + \ ['command:/foo', 1, 'textDocument/didOpen', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ 'languageId': 'lang', + \ 'text': "\n", + \ }, + \ }], + \ ['command:/foo', 1, 'textDocument/didClose', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ }, + \ }], + \ ], + \ g:message_list + +Execute(Messages for closing documents should be sent to each server): + call ale#lsp#Register('command', '/foo', {}) + call ale#lsp#Register('command', '/bar', {}) + call MarkAllConnectionsInitialized() + + call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang') + call ale#lsp#OpenDocument('command:/bar', bufnr(''), 'lang') + call ale#engine#Cleanup(bufnr('')) + " We should only send the message once. + call ale#engine#Cleanup(bufnr('')) + + AssertEqual + \ [ + \ ['command:/foo', 1, 'textDocument/didOpen', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 2, + \ 'languageId': 'lang', + \ 'text': "\n", + \ }, + \ }], + \ ['command:/bar', 1, 'textDocument/didOpen', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ 'languageId': 'lang', + \ 'text': "\n", + \ }, + \ }], + \ ['command:/bar', 1, 'textDocument/didClose', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ }, + \ }], + \ ['command:/foo', 1, 'textDocument/didClose', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ }, + \ }], + \ ], + \ g:message_list diff --git a/vim-config/plugins/ale/test/lsp/test_did_save_event.vader b/vim-config/plugins/ale/test/lsp/test_did_save_event.vader new file mode 100644 index 00000000..fbec10e5 --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_did_save_event.vader @@ -0,0 +1,147 @@ +Before: + Save g:ale_lint_on_save + Save g:ale_enabled + Save g:ale_linters + Save g:ale_run_synchronously + Save g:ale_disable_lsp + + call ale#test#SetDirectory('/testplugin/test/completion') + call ale#test#SetFilename('dummy.txt') + + runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim + + let g:ale_disable_lsp = 0 + unlet! b:ale_disable_lsp + let g:ale_lint_on_save = 1 + let b:ale_enabled = 1 + let g:ale_lsp_next_message_id = 1 + let g:ale_run_synchronously = 1 + let g:conn_id = v:null + let g:message_list = [] + + function! LanguageCallback() abort + return 'foobar' + endfunction + + function! ProjectRootCallback() abort + return expand('.') + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'dummy_linter', + \ 'lsp': 'stdio', + \ 'command': 'cat - > /dev/null', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'language': function('LanguageCallback'), + \ 'project_root': function('ProjectRootCallback'), + \ }) + let g:ale_linters = {'foobar': ['dummy_linter']} + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {}) + call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer) + let l:details = { + \ 'command': 'foobar', + \ 'buffer': a:buffer, + \ 'connection_id': g:conn_id, + \ 'project_root': '/foo/bar', + \} + + call a:Callback(a:linter, l:details) + + return 1 + endfunction + + " Replace the Send function for LSP, so we can monitor calls to it. + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + endfunction + +After: + Restore + + if g:conn_id isnot v:null + call ale#lsp#RemoveConnectionWithID(g:conn_id) + endif + + unlet! b:ale_enabled + unlet! b:ale_linters + unlet! g:message_list + unlet! b:ale_save_event_fired + + delfunction LanguageCallback + delfunction ProjectRootCallback + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + " Stop any timers we left behind. + " This stops the tests from failing randomly. + call ale#completion#StopTimer() + + runtime autoload/ale/completion.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim + +Given foobar (Some imaginary filetype): + + +Execute(Server should be notified on save): + call ale#events#SaveEvent(bufnr('')) + + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}], + \ }], + \ ], + \ g:message_list + +Execute(Server should be notified on save with didSave is supported by server): + + " Replace has capability function to simulate didSave server capability + function! ale#lsp#HasCapability(conn_id, capability) abort + if a:capability == 'did_save' + return 1 + endif + return 0 + endfunction + + call ale#events#SaveEvent(bufnr('')) + + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}], + \ }], + \ [1, 'textDocument/didSave', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ }, + \ }], + \ ], + \ g:message_list + +Execute(Server should be notified on change): + call ale#events#FileChangedEvent(bufnr('')) + + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}], + \ }], + \ ], + \ g:message_list diff --git a/vim-config/plugins/ale/test/lsp/test_engine_lsp_response_handling.vader b/vim-config/plugins/ale/test/lsp/test_engine_lsp_response_handling.vader new file mode 100644 index 00000000..1c5082c5 --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_engine_lsp_response_handling.vader @@ -0,0 +1,428 @@ +Before: + Save g:ale_set_lists_synchronously + Save g:ale_buffer_info + Save g:ale_lsp_error_messages + Save g:ale_set_loclist + Save g:ale_set_signs + Save g:ale_set_quickfix + Save g:ale_set_highlights + Save g:ale_echo_cursor + Save g:ale_disable_lsp + Save g:ale_history_enabled + Save g:ale_history_log_output + + let g:ale_disable_lsp = 0 + let g:ale_set_lists_synchronously = 1 + let g:ale_buffer_info = {} + let g:ale_set_loclist = 1 + " Disable features we don't need for these tests. + let g:ale_set_signs = 0 + let g:ale_set_quickfix = 0 + let g:ale_set_highlights = 0 + let g:ale_echo_cursor = 0 + let g:ale_history_enabled = 1 + let g:ale_history_log_output = 1 + + unlet! g:ale_lsp_error_messages + unlet! b:ale_linters + unlet! b:ale_disable_lsp + + call ale#linter#Reset() + call ale#test#SetDirectory('/testplugin/test') + call setloclist(0, []) + +After: + Restore + + unlet! b:ale_linters + + call setloclist(0, []) + call ale#test#RestoreDirectory() + call ale#linter#Reset() + call ale#lsp_linter#ClearLSPData() + +Given foobar(An empty file): +Execute(tsserver syntax error responses should be handled correctly): + runtime ale_linters/typescript/tsserver.vim + + if has('win32') + call ale#test#SetFilename('filename,[]^$.ts') + else + call ale#test#SetFilename('filename*?,{}[]^$.ts') + endif + + call ale#engine#InitBufferInfo(bufnr('')) + + if has('win32') + AssertEqual 'filename,[]^$.ts', expand('%:p:t') + else + AssertEqual 'filename*?,{}[]^$.ts', expand('%:p:t') + endif + + " When we get syntax errors and no semantic errors, we should keep the + " syntax errors. + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'syntaxDiag', + \ 'body': { + \ 'file': expand('%:p'), + \ 'diagnostics':[ + \ { + \ 'start': { + \ 'line':2, + \ 'offset':14, + \ }, + \ 'end': { + \ 'line':2, + \ 'offset':15, + \ }, + \ 'text': ''','' expected.', + \ "code":1005 + \ }, + \ ], + \ }, + \}) + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'semanticDiag', + \ 'body': { + \ 'file': expand('%:p'), + \ 'diagnostics':[ + \ ], + \ }, + \}) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 14, + \ 'vcol': 0, + \ 'nr': 1005, + \ 'type': 'E', + \ 'text': '1005: '','' expected.', + \ 'valid': 1, + \ 'pattern': '', + \ }, + \ ], + \ ale#test#GetLoclistWithoutModule() + + " After we get empty syntax errors, we should clear them. + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'syntaxDiag', + \ 'body': { + \ 'file': expand('%:p'), + \ 'diagnostics':[ + \ ], + \ }, + \}) + + AssertEqual + \ [ + \ ], + \ ale#test#GetLoclistWithoutModule() + + " Syntax errors on the project root should not populate the LocList. + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'syntaxDiag', + \ 'body': { + \ 'file': g:dir, + \ 'diagnostics':[ + \ { + \ 'start': { + \ 'line':2, + \ 'offset':14, + \ }, + \ 'end': { + \ 'line':2, + \ 'offset':15, + \ }, + \ 'text': ''','' expected.', + \ "code":1005 + \ }, + \ ], + \ }, + \}) + + AssertEqual + \ [ + \ ], + \ ale#test#GetLoclistWithoutModule() + +Execute(tsserver semantic error responses should be handled correctly): + runtime ale_linters/typescript/tsserver.vim + + if has('win32') + call ale#test#SetFilename('filename,[]^$.ts') + else + call ale#test#SetFilename('filename*?,{}[]^$.ts') + endif + + call ale#engine#InitBufferInfo(bufnr('')) + + if has('win32') + AssertEqual 'filename,[]^$.ts', expand('%:p:t') + else + AssertEqual 'filename*?,{}[]^$.ts', expand('%:p:t') + endif + + " When we get syntax errors and no semantic errors, we should keep the + " syntax errors. + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'syntaxDiag', + \ 'body': { + \ 'file': expand('%:p'), + \ 'diagnostics':[ + \ ], + \ }, + \}) + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'semanticDiag', + \ 'body': { + \ 'file': expand('%:p'), + \ 'diagnostics':[ + \ { + \ 'start': { + \ 'line':2, + \ 'offset':14, + \ }, + \ 'end': { + \ 'line':2, + \ 'offset':15, + \ }, + \ 'text': 'Some semantic error', + \ "code":1005 + \ }, + \ ], + \ }, + \}) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 14, + \ 'vcol': 0, + \ 'nr': 1005, + \ 'type': 'E', + \ 'text': '1005: Some semantic error', + \ 'valid': 1, + \ 'pattern': '', + \ }, + \ ], + \ ale#test#GetLoclistWithoutModule() + + " After we get empty syntax errors, we should clear them. + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'semanticDiag', + \ 'body': { + \ 'file': expand('%:p'), + \ 'diagnostics':[ + \ ], + \ }, + \}) + + AssertEqual + \ [ + \ ], + \ ale#test#GetLoclistWithoutModule() + + " Semantic errors on the project root should not populate the LocList. + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'semanticDiag', + \ 'body': { + \ 'file': g:dir, + \ 'diagnostics':[ + \ { + \ 'start': { + \ 'line':2, + \ 'offset':14, + \ }, + \ 'end': { + \ 'line':2, + \ 'offset':15, + \ }, + \ 'text': 'Some semantic error', + \ "code":1005 + \ }, + \ ], + \ }, + \}) + + AssertEqual + \ [ + \ ], + \ ale#test#GetLoclistWithoutModule() + +Execute(tsserver errors should mark tsserver no longer active): + let b:ale_linters = ['tsserver'] + runtime ale_linters/typescript/tsserver.vim + call ale#test#SetFilename('filename.ts') + call ale#engine#InitBufferInfo(bufnr('')) + + let g:ale_buffer_info[bufnr('')].active_linter_list = ale#linter#Get('typescript') + Assert !empty(g:ale_buffer_info[bufnr('')].active_linter_list) + + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'semanticDiag', + \ 'body': { + \ 'file': g:dir . '/filename.ts', + \ 'diagnostics':[], + \ }, + \}) + + AssertEqual [], g:ale_buffer_info[bufnr('')].active_linter_list + +Execute(LSP diagnostics responses should be handled correctly): + let b:ale_linters = ['eclipselsp'] + runtime ale_linters/java/eclipselsp.vim + + if has('win32') + call ale#test#SetFilename('filename,[]^$.ts') + else + call ale#test#SetFilename('filename*?,{}[]^$.java') + endif + + call ale#engine#InitBufferInfo(bufnr('')) + call ale#lsp_linter#SetLSPLinterMap({'1': 'eclipselsp'}) + + if has('win32') + AssertEqual 'filename,[]^$.ts', expand('%:p:t') + else + AssertEqual 'filename*?,{}[]^$.java', expand('%:p:t') + endif + + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'jsonrpc':'2.0', + \ 'method':'textDocument/publishDiagnostics', + \ 'params': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'diagnostics': [ + \ { + \ 'range': { + \ 'start': { + \ 'line': 0, + \ 'character':0 + \ }, + \ 'end': { + \ 'line': 0, + \ 'character':0 + \ } + \ }, + \ 'severity': 2, + \ 'code': "", + \ 'source': 'Java', + \ 'message': 'Missing JRE 1-8' + \ } + \ ] + \ } + \}) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'pattern': '', + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': -1, + \ 'type': 'W', + \ 'text': 'Missing JRE 1-8' + \ } + \ ], + \ ale#test#GetLoclistWithoutModule() + +Execute(LSP diagnostics responses on project root should not populate loclist): + let b:ale_linters = ['eclipselsp'] + runtime ale_linters/java/eclipselsp.vim + call ale#test#SetFilename('filename.java') + call ale#engine#InitBufferInfo(bufnr('')) + call ale#lsp_linter#SetLSPLinterMap({'1': 'eclipselsp'}) + + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'jsonrpc':'2.0', + \ 'method':'textDocument/publishDiagnostics', + \ 'params': { + \ 'uri':'file://' . g:dir, + \ 'diagnostics': [ + \ { + \ 'range': { + \ 'start': { + \ 'line': 0, + \ 'character':0 + \ }, + \ 'end': { + \ 'line': 0, + \ 'character':0 + \ } + \ }, + \ 'severity': 2, + \ 'code': "", + \ 'source': 'Java', + \ 'message': 'Missing JRE 1-8' + \ } + \ ] + \ } + \}) + + AssertEqual + \ [ + \ ], + \ ale#test#GetLoclistWithoutModule() + +Execute(LSP errors should mark linters no longer active): + let b:ale_linters = ['pylsp'] + runtime ale_linters/python/pylsp.vim + call ale#test#SetFilename('filename.py') + call ale#engine#InitBufferInfo(bufnr('')) + call ale#lsp_linter#SetLSPLinterMap({1: 'pylsp'}) + + let g:ale_buffer_info[bufnr('')].active_linter_list = ale#linter#Get('python') + Assert !empty(g:ale_buffer_info[bufnr('')].active_linter_list) + + call ale#lsp_linter#HandleLSPResponse(1, { + \ 'method': 'textDocument/publishDiagnostics', + \ 'params': { + \ 'uri': ale#path#ToURI(g:dir . '/filename.py'), + \ 'diagnostics': [], + \ }, + \}) + + AssertEqual [], g:ale_buffer_info[bufnr('')].active_linter_list + +Execute(LSP errors should be logged in the history): + call ale#lsp_linter#SetLSPLinterMap({'347': 'foobar'}) + call ale#lsp_linter#HandleLSPResponse(347, { + \ 'jsonrpc': '2.0', + \ 'error': { + \ 'code': -32602, + \ 'message': 'xyz', + \ 'data': { + \ 'traceback': ['123', '456'], + \ }, + \ }, + \}) + + AssertEqual + \ {'foobar': ["xyz\n123\n456"]}, + \ get(g:, 'ale_lsp_error_messages', {}) diff --git a/vim-config/plugins/ale/test/lsp/test_handling_window_requests.vader b/vim-config/plugins/ale/test/lsp/test_handling_window_requests.vader new file mode 100644 index 00000000..551d5975 --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_handling_window_requests.vader @@ -0,0 +1,94 @@ +Before: + let g:expr_list = [] + let g:linter_name = 'some_linter' + let g:format = '%severity%:%linter%: %s' + " Get the default value to restore it + let g:default_severity = g:ale_lsp_show_message_severity + let g:ale_lsp_show_message_severity = 'information' + + function! ale#util#ShowMessage(expr) abort + call add(g:expr_list, a:expr) + endfunction + +After: + unlet! g:expr_list + unlet! g:linter_name + unlet! g:format + let g:ale_lsp_show_message_severity = g:default_severity + unlet! g:default_severity + +Execute(ale#lsp_window#HandleShowMessage() should only show errors when severity is set to "error"): + let g:ale_lsp_show_message_severity = 'error' + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'}) + AssertEqual ['Error:some_linter: an error'], g:expr_list + +Execute(ale#lsp_window#HandleShowMessage() should only show errors and warnings when severity is set to "warning"): + let g:ale_lsp_show_message_severity = 'warning' + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'}) + AssertEqual ['Error:some_linter: an error', 'Warning:some_linter: a warning'], g:expr_list + +Execute(ale#lsp_window#HandleShowMessage() should only show errors, warnings and infos when severity is set to "information"): + let g:ale_lsp_show_message_severity = 'information' + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'}) + AssertEqual [ + \ 'Error:some_linter: an error', + \ 'Warning:some_linter: a warning', + \ 'Info:some_linter: an info'], + \ g:expr_list + +Execute(ale#lsp_window#HandleShowMessage() should only show errors, warnings and infos when severity is set to "info"): + let g:ale_lsp_show_message_severity = 'info' + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'}) + AssertEqual [ + \ 'Error:some_linter: an error', + \ 'Warning:some_linter: a warning', + \ 'Info:some_linter: an info'], + \ g:expr_list + +Execute(ale#lsp_window#HandleShowMessage() should show all messages is severity is set to "log"): + let g:ale_lsp_show_message_severity = 'log' + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'}) + AssertEqual [ + \ 'Error:some_linter: an error', + \ 'Warning:some_linter: a warning', + \ 'Info:some_linter: an info', + \ 'Log:some_linter: a log'], + \ g:expr_list + +Execute(ale#lsp_window#HandleShowMessage() should not show anything if severity is configured as disabled): + let g:ale_lsp_show_message_severity = 'disabled' + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'}) + AssertEqual [], g:expr_list + +Execute(ale#lsp_window#HandleShowMessage() should use "warning" when severity is set to an invalid value): + let g:ale_lsp_show_message_severity = 'foo' + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'}) + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'}) + AssertEqual [ + \ 'Error:some_linter: an error', + \ 'Warning:some_linter: a warning'], + \ g:expr_list + +Execute(ale#lsp_window#HandleShowMessage() should escape quotes on messages): + call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':"this is an 'info'"}) + AssertEqual ['Info:some_linter: this is an ''info'''], g:expr_list diff --git a/vim-config/plugins/ale/test/lsp/test_lsp_client_messages.vader b/vim-config/plugins/ale/test/lsp/test_lsp_client_messages.vader new file mode 100644 index 00000000..4c6b0ffa --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_lsp_client_messages.vader @@ -0,0 +1,362 @@ +Before: + let g:ale_lsp_next_version_id = 1 + + call ale#test#SetDirectory('/testplugin/test/lsp') + call ale#test#SetFilename('foo/bar.ts') + +After: + call ale#test#RestoreDirectory() + +Execute(ale#lsp#message#Initialize() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'initialize', + \ { + \ 'processId': getpid(), + \ 'rootPath': '/foo/bar', + \ 'capabilities': {}, + \ 'initializationOptions': {'foo': 'bar'}, + \ 'rootUri': 'file:///foo/bar', + \ } + \ ], + \ ale#lsp#message#Initialize('/foo/bar', {'foo': 'bar'}, {}) + +Execute(ale#lsp#message#Initialized() should return correct messages): + AssertEqual [1, 'initialized', {}], ale#lsp#message#Initialized() + +Execute(ale#lsp#message#Shutdown() should return correct messages): + AssertEqual [0, 'shutdown'], ale#lsp#message#Shutdown() + +Execute(ale#lsp#message#Exit() should return correct messages): + AssertEqual [1, 'exit'], ale#lsp#message#Exit(), + +Given typescript(A TypeScript file with 3 lines): + foo() + bar() + baz() + +Execute(ale#lsp#message#DidOpen() should return correct messages): + let g:ale_lsp_next_version_id = 12 + AssertEqual + \ [ + \ 1, + \ 'textDocument/didOpen', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ 'languageId': 'typescript', + \ 'version': 12, + \ 'text': "foo()\nbar()\nbaz()\n", + \ }, + \ } + \ ], + \ ale#lsp#message#DidOpen(bufnr(''), 'typescript') + +Execute(ale#lsp#message#DidChange() should return correct messages): + let g:ale_lsp_next_version_id = 34 + + AssertEqual + \ [ + \ 1, + \ 'textDocument/didChange', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ 'version': 34, + \ }, + \ 'contentChanges': [{'text': "foo()\nbar()\nbaz()\n"}], + \ } + \ ], + \ ale#lsp#message#DidChange(bufnr('')) + " The version numbers should increment. + AssertEqual + \ 35, + \ ale#lsp#message#DidChange(bufnr(''))[2].textDocument.version + AssertEqual + \ 36, + \ ale#lsp#message#DidChange(bufnr(''))[2].textDocument.version + +Execute(ale#lsp#message#DidSave() should return correct messages): + AssertEqual + \ [ + \ 1, + \ 'textDocument/didSave', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ }, + \ } + \ ], + \ ale#lsp#message#DidSave(bufnr(''), v:false) + +Execute(ale#lsp#message#DidSave() should return correct message with includeText capability): + AssertEqual + \ [ + \ 1, + \ 'textDocument/didSave', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ 'version': 1, + \ }, + \ 'text': ale#util#GetBufferContents(bufnr('')), + \ } + \ ], + \ ale#lsp#message#DidSave(bufnr(''), v:true) + +Execute(ale#lsp#message#DidClose() should return correct messages): + AssertEqual + \ [ + \ 1, + \ 'textDocument/didClose', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ }, + \ } + \ ], + \ ale#lsp#message#DidClose(bufnr('')) + +Execute(ale#lsp#message#Completion() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'textDocument/completion', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ }, + \ 'position': {'line': 11, 'character': 33}, + \ } + \ ], + \ ale#lsp#message#Completion(bufnr(''), 12, 34, '') + +Execute(ale#lsp#message#Completion() should return correct messages with a trigger charaacter): + AssertEqual + \ [ + \ 0, + \ 'textDocument/completion', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ }, + \ 'position': {'line': 11, 'character': 33}, + \ 'context': {'triggerKind': 2, 'triggerCharacter': '.'}, + \ } + \ ], + \ ale#lsp#message#Completion(bufnr(''), 12, 34, '.') + \ +Execute(ale#lsp#message#Definition() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'textDocument/definition', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ }, + \ 'position': {'line': 11, 'character': 33}, + \ } + \ ], + \ ale#lsp#message#Definition(bufnr(''), 12, 34) + +Execute(ale#lsp#message#TypeDefinition() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'textDocument/typeDefinition', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ }, + \ 'position': {'line': 11, 'character': 33}, + \ } + \ ], + \ ale#lsp#message#TypeDefinition(bufnr(''), 12, 34) + +Execute(ale#lsp#message#References() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'textDocument/references', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ }, + \ 'position': {'line': 11, 'character': 33}, + \ 'context': {'includeDeclaration': v:false}, + \ } + \ ], + \ ale#lsp#message#References(bufnr(''), 12, 34) + +Execute(ale#lsp#message#Symbol() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'workspace/symbol', + \ { + \ 'query': 'foobar', + \ } + \ ], + \ ale#lsp#message#Symbol('foobar') + +Execute(ale#lsp#message#Hover() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'textDocument/hover', + \ { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'), + \ }, + \ 'position': {'line': 11, 'character': 33}, + \ } + \ ], + \ ale#lsp#message#Hover(bufnr(''), 12, 34) + +Execute(ale#lsp#message#DidChangeConfiguration() should return correct messages): + let g:ale_lsp_configuration = { + \ 'foo': 'bar' + \ } + AssertEqual + \ [ + \ 1, + \ 'workspace/didChangeConfiguration', + \ { + \ 'settings': { + \ 'foo': 'bar', + \ } + \ } + \ ], + \ ale#lsp#message#DidChangeConfiguration(bufnr(''), g:ale_lsp_configuration) + +Execute(ale#lsp#tsserver_message#Open() should return correct messages): + AssertEqual + \ [ + \ 1, + \ 'ts@open', + \ { + \ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'), + \ } + \ ], + \ ale#lsp#tsserver_message#Open(bufnr('')) + +Execute(ale#lsp#tsserver_message#Close() should return correct messages): + AssertEqual + \ [ + \ 1, + \ 'ts@close', + \ { + \ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'), + \ } + \ ], + \ ale#lsp#tsserver_message#Close(bufnr('')) + +Execute(ale#lsp#tsserver_message#Change() should return correct messages): + AssertEqual + \ [ + \ 1, + \ 'ts@change', + \ { + \ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'), + \ 'line': 1, + \ 'offset': 1, + \ 'endLine': 1073741824, + \ 'endOffset': 1, + \ 'insertString': "foo()\nbar()\nbaz()\n", + \ } + \ ], + \ ale#lsp#tsserver_message#Change(bufnr('')) + +Execute(ale#lsp#tsserver_message#Geterr() should return correct messages): + AssertEqual + \ [ + \ 1, + \ 'ts@geterr', + \ { + \ 'files': [ale#path#Simplify(g:dir . '/foo/bar.ts')], + \ } + \ ], + \ ale#lsp#tsserver_message#Geterr(bufnr('')) + +Execute(ale#lsp#tsserver_message#Completions() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'ts@completions', + \ { + \ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'), + \ 'line': 347, + \ 'offset': 12, + \ 'prefix': 'abc', + \ 'includeExternalModuleExports': 1, + \ } + \ ], + \ ale#lsp#tsserver_message#Completions(bufnr(''), 347, 12, 'abc', 1) + +Execute(ale#lsp#tsserver_message#CompletionEntryDetails() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'ts@completionEntryDetails', + \ { + \ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'), + \ 'line': 347, + \ 'offset': 12, + \ 'entryNames': ['foo', 'bar'], + \ } + \ ], + \ ale#lsp#tsserver_message#CompletionEntryDetails(bufnr(''), 347, 12, ['foo', 'bar']) + +Execute(ale#lsp#tsserver_message#Definition() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'ts@definition', + \ { + \ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'), + \ 'line': 347, + \ 'offset': 12, + \ } + \ ], + \ ale#lsp#tsserver_message#Definition(bufnr(''), 347, 12) + +Execute(ale#lsp#tsserver_message#TypeDefinition() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'ts@typeDefinition', + \ { + \ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'), + \ 'line': 347, + \ 'offset': 12, + \ } + \ ], + \ ale#lsp#tsserver_message#TypeDefinition(bufnr(''), 347, 12) + +Execute(ale#lsp#tsserver_message#References() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'ts@references', + \ { + \ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'), + \ 'line': 347, + \ 'offset': 12, + \ } + \ ], + \ ale#lsp#tsserver_message#References(bufnr(''), 347, 12) + +Execute(ale#lsp#tsserver_message#Quickinfo() should return correct messages): + AssertEqual + \ [ + \ 0, + \ 'ts@quickinfo', + \ { + \ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'), + \ 'line': 347, + \ 'offset': 12, + \ } + \ ], + \ ale#lsp#tsserver_message#Quickinfo(bufnr(''), 347, 12) diff --git a/vim-config/plugins/ale/test/lsp/test_lsp_command_formatting.vader b/vim-config/plugins/ale/test/lsp/test_lsp_command_formatting.vader new file mode 100644 index 00000000..e99e1dad --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_lsp_command_formatting.vader @@ -0,0 +1,44 @@ +Before: + Save g:ale_command_wrapper + + runtime autoload/ale/lsp.vim + + let g:ale_command_wrapper = '' + + let g:args = [] + + " Mock the StartProgram function so we can just capture the arguments. + function! ale#lsp#StartProgram(...) abort + let g:args = a:000[1:] + endfunction + +After: + Restore + + unlet! g:args + + runtime autoload/ale/lsp.vim + +Execute(Command formatting should be applied correctly for LSP linters): + call ale#lsp_linter#StartLSP( + \ bufnr(''), + \ { + \ 'name': 'linter', + \ 'language': {-> 'x'}, + \ 'project_root': {-> '/foo/bar'}, + \ 'lsp': 'stdio', + \ 'executable': has('win32') ? 'cmd': 'true', + \ 'command': '%e --foo', + \ }, + \ {-> 0} + \) + + if has('win32') + AssertEqual + \ ['cmd', 'cmd /s/c "cmd --foo"'], + \ g:args + else + AssertEqual + \ ['true', [&shell, '-c', '''true'' --foo']], + \ g:args + endif diff --git a/vim-config/plugins/ale/test/lsp/test_lsp_connections.vader b/vim-config/plugins/ale/test/lsp/test_lsp_connections.vader new file mode 100644 index 00000000..1c2fceab --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_lsp_connections.vader @@ -0,0 +1,227 @@ +Before: + let g:ale_lsp_next_message_id = 1 + +After: + if exists('b:conn') && has_key(b:conn, 'id') + call ale#lsp#RemoveConnectionWithID(b:conn.id) + endif + + unlet! b:data + unlet! b:conn + +Execute(GetNextMessageID() should increment appropriately): + " We should get the initial ID, and increment a bit. + AssertEqual 1, ale#lsp#GetNextMessageID() + AssertEqual 2, ale#lsp#GetNextMessageID() + AssertEqual 3, ale#lsp#GetNextMessageID() + + " Set the maximum ID. + let g:ale_lsp_next_message_id = 9223372036854775807 + + " When we hit the maximum ID, the next ID afterwards should be 1. + AssertEqual 9223372036854775807, ale#lsp#GetNextMessageID() + AssertEqual 1, ale#lsp#GetNextMessageID() + +Execute(ale#lsp#CreateMessageData() should create an appropriate message): + " NeoVim outputs JSON with spaces, so the output is a little different. + if has('nvim') + " 79 is the size in bytes for UTF-8, not the number of characters. + AssertEqual + \ [ + \ 1, + \ "Content-Length: 79\r\n\r\n" + \ . '{"method": "someMethod", "jsonrpc": "2.0", "id": 1, "params": {"foo": "barÜ"}}', + \ ], + \ ale#lsp#CreateMessageData([0, 'someMethod', {'foo': 'barÜ'}]) + " Check again to ensure that we use the next ID. + AssertEqual + \ [ + \ 2, + \ "Content-Length: 79\r\n\r\n" + \ . '{"method": "someMethod", "jsonrpc": "2.0", "id": 2, "params": {"foo": "barÜ"}}', + \ ], + \ ale#lsp#CreateMessageData([0, 'someMethod', {'foo': 'barÜ'}]) + else + AssertEqual + \ [ + \ 1, + \ "Content-Length: 71\r\n\r\n" + \ . '{"method":"someMethod","jsonrpc":"2.0","id":1,"params":{"foo":"barÜ"}}', + \ ], + \ ale#lsp#CreateMessageData([0, 'someMethod', {'foo': 'barÜ'}]) + AssertEqual + \ [ + \ 2, + \ "Content-Length: 71\r\n\r\n" + \ . '{"method":"someMethod","jsonrpc":"2.0","id":2,"params":{"foo":"barÜ"}}', + \ ], + \ ale#lsp#CreateMessageData([0, 'someMethod', {'foo': 'barÜ'}]) + endif + +Execute(ale#lsp#CreateMessageData() should create messages without params): + if has('nvim') + AssertEqual + \ [ + \ 1, + \ "Content-Length: 56\r\n\r\n" + \ . '{"method": "someOtherMethod", "jsonrpc": "2.0", "id": 1}', + \ ], + \ ale#lsp#CreateMessageData([0, 'someOtherMethod']) + else + AssertEqual + \ [ + \ 1, + \ "Content-Length: 51\r\n\r\n" + \ . '{"method":"someOtherMethod","jsonrpc":"2.0","id":1}', + \ ], + \ ale#lsp#CreateMessageData([0, 'someOtherMethod']) + endif + +Execute(ale#lsp#CreateMessageData() should create notifications): + if has('nvim') + AssertEqual + \ [ + \ 0, + \ "Content-Length: 48\r\n\r\n" + \ . '{"method": "someNotification", "jsonrpc": "2.0"}', + \ ], + \ ale#lsp#CreateMessageData([1, 'someNotification']) + AssertEqual + \ [ + \ 0, + \ "Content-Length: 74\r\n\r\n" + \ . '{"method": "someNotification", "jsonrpc": "2.0", "params": {"foo": "bar"}}', + \ ], + \ ale#lsp#CreateMessageData([1, 'someNotification', {'foo': 'bar'}]) + else + AssertEqual + \ [ + \ 0, + \ "Content-Length: 45\r\n\r\n" + \ . '{"method":"someNotification","jsonrpc":"2.0"}', + \ ], + \ ale#lsp#CreateMessageData([1, 'someNotification']) + AssertEqual + \ [ + \ 0, + \ "Content-Length: 68\r\n\r\n" + \ . '{"method":"someNotification","jsonrpc":"2.0","params":{"foo":"bar"}}', + \ ], + \ ale#lsp#CreateMessageData([1, 'someNotification', {'foo': 'bar'}]) + endif + +Execute(ale#lsp#CreateMessageData() should create tsserver notification messages): + if has('nvim') + AssertEqual + \ [ + \ 0, + \ '{"seq": null, "type": "request", "command": "someNotification"}' + \ . "\n", + \ ], + \ ale#lsp#CreateMessageData([1, 'ts@someNotification']) + AssertEqual + \ [ + \ 0, + \ '{"seq": null, "arguments": {"foo": "bar"}, "type": "request", "command": "someNotification"}' + \ . "\n", + \ ], + \ ale#lsp#CreateMessageData([1, 'ts@someNotification', {'foo': 'bar'}]) + else + AssertEqual + \ [ + \ 0, + \ '{"seq":null,"type":"request","command":"someNotification"}' + \ . "\n", + \ ], + \ ale#lsp#CreateMessageData([1, 'ts@someNotification']) + AssertEqual + \ [ + \ 0, + \ '{"seq":null,"arguments":{"foo":"bar"},"type":"request","command":"someNotification"}' + \ . "\n", + \ ], + \ ale#lsp#CreateMessageData([1, 'ts@someNotification', {'foo': 'bar'}]) + endif + +Execute(ale#lsp#CreateMessageData() should create tsserver messages expecting responses): + if has('nvim') + AssertEqual + \ [ + \ 1, + \ '{"seq": 1, "type": "request", "command": "someMessage"}' + \ . "\n", + \ ], + \ ale#lsp#CreateMessageData([0, 'ts@someMessage']) + AssertEqual + \ [ + \ 2, + \ '{"seq": 2, "arguments": {"foo": "bar"}, "type": "request", "command": "someMessage"}' + \ . "\n", + \ ], + \ ale#lsp#CreateMessageData([0, 'ts@someMessage', {'foo': 'bar'}]) + else + AssertEqual + \ [ + \ 1, + \ '{"seq":1,"type":"request","command":"someMessage"}' + \ . "\n", + \ ], + \ ale#lsp#CreateMessageData([0, 'ts@someMessage']) + AssertEqual + \ [ + \ 2, + \ '{"seq":2,"arguments":{"foo":"bar"},"type":"request","command":"someMessage"}' + \ . "\n", + \ ], + \ ale#lsp#CreateMessageData([0, 'ts@someMessage', {'foo': 'bar'}]) + endif + +Execute(ale#lsp#ReadMessageData() should read single whole messages): + AssertEqual + \ ['', [{'id': 2, 'jsonrpc': '2.0', 'result': {'foo': 'barÜ'}}]], + \ ale#lsp#ReadMessageData( + \ "Content-Length: 49\r\n\r\n" + \ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}' + \ ) + +Execute(ale#lsp#ReadMessageData() should ignore other headers): + AssertEqual + \ ['', [{'id': 2, 'jsonrpc': '2.0', 'result': {'foo': 'barÜ'}}]], + \ ale#lsp#ReadMessageData( + \ "First-Header: 49\r\n" + \ . "Content-Length: 49\r\n" + \ . "Other-Header: 49\r\n" + \ . "\r\n" + \ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}' + \ ) + +Execute(ale#lsp#ReadMessageData() should handle partial messages): + let b:data = "Content-Length: 49\r\n\r\n" . '{"id":2,"jsonrpc":"2.0","result":' + + AssertEqual [b:data, []], ale#lsp#ReadMessageData(b:data) + +Execute(ale#lsp#ReadMessageData() should handle multiple messages): + AssertEqual + \ ['', [ + \ {'id': 2, 'jsonrpc': '2.0', 'result': {'foo': 'barÜ'}}, + \ {'id': 2, 'jsonrpc': '2.0', 'result': {'foo123': 'barÜ'}}, + \ ]], + \ ale#lsp#ReadMessageData( + \ "Content-Length: 49\r\n\r\n" + \ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}' + \ . "Content-Length: 52\r\n\r\n" + \ . '{"id":2,"jsonrpc":"2.0","result":{"foo123":"barÜ"}}' + \ ) + +Execute(ale#lsp#ReadMessageData() should handle a message with part of a second message): + let b:data = "Content-Length: 52\r\n\r\n" . '{"id":2,"jsonrpc":"2.' + + AssertEqual + \ [b:data, [ + \ {'id': 2, 'jsonrpc': '2.0', 'result': {'foo': 'barÜ'}}, + \ ]], + \ ale#lsp#ReadMessageData( + \ "Content-Length: 49\r\n\r\n" + \ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}' + \ . b:data + \ ) diff --git a/vim-config/plugins/ale/test/lsp/test_lsp_custom_request.vader b/vim-config/plugins/ale/test/lsp/test_lsp_custom_request.vader new file mode 100644 index 00000000..c8767e59 --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_lsp_custom_request.vader @@ -0,0 +1,158 @@ +Before: + runtime autoload/ale/linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim + + let g:address = 'ccls_address' + let g:conn_id = -1 + let g:executable = 'ccls' + let g:executable_or_address = '' + let g:linter_name = 'ccls' + let g:magic_number = 42 + let g:no_result = 0 + let g:message_list = [] + let g:message_id = 1 + let g:method = '$ccls/call' + let g:parameters = {} + let g:project_root = '/project/root' + let g:response = '' + let g:return_value = -1 + + let g:linter_list = [{ + \ 'output_stream': 'stdout', + \ 'lint_file': 0, + \ 'language': 'cpp', + \ 'name': g:linter_name, + \ 'project_root': {b -> g:project_root}, + \ 'aliases': [], + \ 'read_buffer': 1, + \ 'command': '%e' + \ }] + + let g:callback_result = g:no_result + + " Encode dictionary to jsonrpc + function! Encode(obj) abort + let l:body = json_encode(a:obj) + return 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body + endfunction + + " Replace the StartLSP function to mock an LSP linter + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:conn_id = ale#lsp#Register(g:executable_or_address, g:project_root, {}) + call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer) + call ale#lsp#HandleMessage(g:conn_id, Encode({'method': 'initialize'})) + + let l:details = { + \ 'command': g:executable, + \ 'buffer': a:buffer, + \ 'connection_id': g:conn_id, + \ 'project_root': g:project_root, + \} + + call ale#lsp_linter#OnInit(a:linter, l:details, a:Callback) + endfunction + + " Dummy callback + function! Callback(response) abort + let g:callback_result = a:response.result.value + endfunction + + " Replace the GetAll function to mock an LSP linter + function! ale#linter#GetAll(filetype) abort + return g:linter_list + endfunction + + " Replace the Send function to mock an LSP linter + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + return g:message_id + endfunction + + " Code for a test case + function! TestCase(is_notification) abort + " Test sending a custom request + let g:return_value = ale#lsp_linter#SendRequest( + \ bufnr('%'), + \ g:linter_name, + \ [a:is_notification, g:method, g:parameters], + \ function('Callback')) + + Assert index(g:message_list, [a:is_notification, g:method, g:parameters]) >= 0 + + " Mock an incoming response to the request + let g:response = Encode({ + \ 'id': g:message_id, + \ 'jsonrpc': '2.0', + \ 'result': {'value': g:magic_number} + \ }) + call ale#lsp#HandleMessage(g:conn_id, g:response) + + AssertEqual + \ a:is_notification ? g:no_result : g:magic_number, + \ g:callback_result + endfunction + +After: + if g:conn_id isnot v:null + call ale#lsp#RemoveConnectionWithID(g:conn_id) + endif + + unlet! g:callback_result + unlet! g:conn_id + unlet! g:executable + unlet! g:is_notification + unlet! g:linter_name + unlet! g:magic_number + unlet! g:message_list + unlet! g:message_id + unlet! g:method + unlet! g:no_result + unlet! g:parameters + unlet! g:project_root + unlet! g:response + unlet! g:return_value + + delfunction Encode + delfunction Callback + delfunction TestCase + + runtime autoload/ale/linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim + +Given cpp(Empty cpp file): +Execute(Test custom request to server identified by executable): + let g:executable_or_address = g:executable + let g:linter_list[0].executable = {b -> g:executable} + let g:linter_list[0].lsp = 'stdio' + let g:is_notification = 0 + + call TestCase(g:is_notification) + +Given cpp(Empty cpp file): +Execute(Test custom notification to server identified by executable): + let g:executable_or_address = g:executable + let g:linter_list[0].executable = {b -> g:executable} + let g:linter_list[0].lsp = 'stdio' + let g:is_notification = 1 + + call TestCase(g:is_notification) + +Given cpp(Empty cpp file): +Execute(Test custom request to server identified by address): + let g:executable_or_address = g:address + let g:linter_list[0].address = {b -> g:address} + let g:linter_list[0].lsp = 'socket' + let g:is_notification = 0 + + call TestCase(g:is_notification) + +Given cpp(Empty cpp file): +Execute(Test custom notification to server identified by address): + let g:executable_or_address = g:address + let g:linter_list[0].address = {b -> g:address} + let g:linter_list[0].lsp = 'socket' + let g:is_notification = 1 + + call TestCase(g:is_notification) diff --git a/vim-config/plugins/ale/test/lsp/test_lsp_error_parsing.vader b/vim-config/plugins/ale/test/lsp/test_lsp_error_parsing.vader new file mode 100644 index 00000000..44169c80 --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_lsp_error_parsing.vader @@ -0,0 +1,74 @@ +Execute(Invalid responses should be handled): + AssertEqual '', ale#lsp#response#GetErrorMessage({}) + AssertEqual '', ale#lsp#response#GetErrorMessage({'error': 0}) + AssertEqual '', ale#lsp#response#GetErrorMessage({'error': {}}) + AssertEqual '', ale#lsp#response#GetErrorMessage({ + \ 'error': { + \ 'code': 0, + \ 'message': 'x', + \ }, + \}) + AssertEqual '', ale#lsp#response#GetErrorMessage({'error': {'code': -32602}}) + AssertEqual '', ale#lsp#response#GetErrorMessage({'error': {'code': -32603}}) + +Execute(Messages without tracebacks should be handled): + AssertEqual 'xyz', ale#lsp#response#GetErrorMessage({ + \ 'error': { + \ 'code': -32602, + \ 'message': 'xyz', + \ }, + \}) + AssertEqual 'abc', ale#lsp#response#GetErrorMessage({ + \ 'error': { + \ 'code': -32603, + \ 'message': 'abc', + \ }, + \}) + +Execute(Invalid traceback data should be tolerated): + AssertEqual 'xyz', ale#lsp#response#GetErrorMessage({ + \ 'error': { + \ 'code': -32602, + \ 'message': 'xyz', + \ 'data': { + \ }, + \ }, + \}) + AssertEqual 'xyz', ale#lsp#response#GetErrorMessage({ + \ 'error': { + \ 'code': -32602, + \ 'message': 'xyz', + \ 'data': { + \ 'traceback': 0, + \ }, + \ }, + \}) + AssertEqual 'xyz', ale#lsp#response#GetErrorMessage({ + \ 'error': { + \ 'code': -32602, + \ 'message': 'xyz', + \ 'data': { + \ 'traceback': [], + \ }, + \ }, + \}) + +Execute(Messages with tracebacks should be handled): + AssertEqual "xyz\n123\n456", ale#lsp#response#GetErrorMessage({ + \ 'error': { + \ 'code': -32602, + \ 'message': 'xyz', + \ 'data': { + \ 'traceback': ['123', '456'], + \ }, + \ }, + \}) + +Execute(Messages with string data should be handled): + AssertEqual "xyz\nUncaught Exception", ale#lsp#response#GetErrorMessage({ + \ 'error': { + \ 'code': -32602, + \ 'message': 'xyz', + \ 'data': 'Uncaught Exception', + \ }, + \}) diff --git a/vim-config/plugins/ale/test/lsp/test_lsp_root_detection.vader b/vim-config/plugins/ale/test/lsp/test_lsp_root_detection.vader new file mode 100644 index 00000000..291300f0 --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_lsp_root_detection.vader @@ -0,0 +1,90 @@ +Before: + Save g:ale_lsp_root + Save g:ale_root + Save b:ale_lsp_root + Save b:ale_root + + unlet! g:ale_lsp_root + let g:ale_root = {} + + call ale#assert#SetUpLinterTest('c', 'clangd') + + function! Hook1(buffer) + return 'abc123' + endfunction + +After: + Restore + + delfunction Hook1 + + call ale#assert#TearDownLinterTest() + +Execute(The buffer-specific variable can be a string): + let b:ale_root = '/some/path' + call ale#test#SetFilename('other-file.c') + + AssertLSPProject '/some/path' + +Execute(The buffer-specific variable can be a dictionary): + let b:ale_root = {'clangd': '/some/path', 'golangserver': '/other/path'} + call ale#test#SetFilename('other-file.c') + + AssertLSPProject '/some/path' + +Execute(The buffer-specific variable can have funcrefs): + let b:ale_root = {'clangd': function('Hook1'), 'golangserver': '/path'} + call ale#test#SetFilename('other-file.c') + + AssertLSPProject 'abc123' + +Execute(The buffer-specific variable can be the old ale_lsp_root setting): + let b:ale_lsp_root = '/some/path' + call ale#test#SetFilename('other-file.c') + + AssertLSPProject '/some/path' + +Execute(The global variable can be a dictionary): + let g:ale_root = {'clangd': '/some/path', 'golangserver': '/other/path'} + call ale#test#SetFilename('other-file.c') + + AssertLSPProject '/some/path' + +Execute(The global variable can have funcrefs): + let g:ale_root = {'clangd': function('Hook1'), 'golangserver': '/path'} + call ale#test#SetFilename('other-file.c') + + AssertLSPProject 'abc123' + +Execute(The buffer-specific variable overrides the global variable): + let b:ale_root = {'clangd': '/some/path', 'golangserver': '/other/path'} + let g:ale_root = {'clangd': '/not/this/path', 'golangserver': '/elsewhere'} + call ale#test#SetFilename('other-file.c') + + AssertLSPProject '/some/path' + +Execute(The global variable is queried if the buffer-specific has no value): + let b:ale_root = {'golangserver': '/other/path'} + let g:ale_root = {'clangd': '/some/path', 'golangserver': '/elsewhere'} + call ale#test#SetFilename('other-file.c') + + AssertLSPProject '/some/path' + +Execute(The global variable can be the old ale_lsp_root setting): + let g:ale_root = {} + let g:ale_lsp_root = {'clangd': '/some/path', 'golangserver': '/other/path'} + call ale#test#SetFilename('other-file.c') + + AssertLSPProject '/some/path' + +Execute(A non-empty ale_root setting should replace the old ale_lsp_root): + let g:ale_root = {'clangd': '/some/path', 'golangserver': '/other/path'} + let g:ale_lsp_root = {'clangd': '/xxx', 'golangserver': '/xxx'} + call ale#test#SetFilename('other-file.c') + + AssertLSPProject '/some/path' + +Execute(No path should be returned by default): + call ale#test#SetFilename(tempname() . '/other-file.c') + + AssertLSPProject '' diff --git a/vim-config/plugins/ale/test/lsp/test_lsp_startup.vader b/vim-config/plugins/ale/test/lsp/test_lsp_startup.vader new file mode 100644 index 00000000..f0afe39c --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_lsp_startup.vader @@ -0,0 +1,483 @@ +Before: + Save g:ale_run_synchronously + + let g:ale_run_synchronously = 1 + unlet! g:ale_run_synchronously_callbacks + unlet! g:ale_run_synchronously_emulate_commands + + runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/engine.vim + runtime autoload/ale/job.vim + runtime autoload/ale/socket.vim + + let g:job_map = {} + let g:emulate_job_failure = 0 + let g:next_job_id = 1 + let g:lsp_started = 0 + + let g:socket_map = {} + let g:emulate_socket_failure = 0 + let g:next_channel_id = 0 + + let g:message_buffer = '' + let g:calls = [] + + function! ale#engine#IsExecutable(buffer, executable) abort + return !empty(a:executable) + endfunction + + function! ale#job#HasOpenChannel(job_id) abort + return has_key(g:job_map, a:job_id) + endfunction + + function! ale#job#Stop(job_id) abort + if has_key(g:job_map, a:job_id) + call remove(g:job_map, a:job_id) + endif + endfunction + + function! ale#job#Start(command, options) abort + if g:emulate_job_failure + return 0 + endif + + let l:job_id = g:next_job_id + let g:next_job_id += 1 + let g:job_map[l:job_id] = [a:command, a:options] + + return l:job_id + endfunction + + function! ale#job#SendRaw(job_id, data) abort + let g:message_buffer .= a:data + endfunction + + function! ale#socket#IsOpen(channel_id) abort + return has_key(g:socket_map, a:channel_id) + endfunction + + function! ale#socket#Close(channel_id) abort + if has_key(g:socket_map, a:channel_id) + call remove(g:socket_map, a:channel_id) + endif + endfunction + + function! ale#socket#Open(address, options) abort + if g:emulate_socket_failure + return -1 + endif + + let l:channel_id = g:next_channel_id + let g:next_channel_id += 1 + let g:socket_map[l:channel_id] = [a:address, a:options] + + return l:channel_id + endfunction + + function! ale#socket#Send(channel_id, data) abort + let g:message_buffer .= a:data + endfunction + + function! PopMessages() abort + let l:message_list = [] + + for l:line in split(g:message_buffer, '\(\r\|\n\|Content-Length\)\+') + if l:line[:0] is '{' + let l:data = json_decode(l:line) + + call add(l:message_list, l:data) + endif + endfor + + let g:message_buffer = '' + + return l:message_list + endfunction + + function! SendMessage(message) abort + let l:conn_id = keys(ale#lsp#GetConnections())[0] + let l:body = json_encode(a:message) + let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body + + call ale#lsp#HandleMessage(l:conn_id, l:data) + endfunction + + function! Start(buffer) abort + let l:linter = values(ale#linter#GetLintersLoaded())[0][0] + + return ale#lsp_linter#StartLSP( + \ a:buffer, + \ l:linter, + \ {linter, details -> add(g:calls, [linter.name, details])}, + \) + endfunction + + function! AssertInitSuccess(linter_name, conn_prefix, language, root, command, buffer) abort + let l:messages = PopMessages() + + if a:linter_name is# 'tsserver' + AssertEqual + \ [ + \ { + \ 'seq': v:null, + \ 'arguments': { + \ 'file': expand('#' . a:buffer . ':p'), + \ }, + \ 'type': 'request', + \ 'command': 'open', + \ }, + \ ], + \ l:messages + else + AssertEqual + \ [ + \ { + \ 'method': 'initialize', + \ 'jsonrpc': '2.0', + \ 'id': 1, + \ 'params': { + \ 'initializationOptions': {}, + \ 'rootUri': ale#path#ToURI(a:root), + \ 'rootPath': a:root, + \ 'processId': getpid(), + \ 'capabilities': { + \ '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, + \ }, + \ }, + \ }, + \ }, + \ }, + \ ], + \ l:messages + + call SendMessage({ + \ 'jsonrpc': '2.0', + \ 'id': 1, + \ 'result': { + \ 'capabilities': { + \ 'renameProvider': v:true, + \ 'executeCommandProvider': { + \ 'commands': [], + \ }, + \ 'hoverProvider': v:true, + \ 'documentSymbolProvider': v:true, + \ 'documentRangeFormattingProvider': v:true, + \ 'codeLensProvider': { + \ 'resolveProvider': v:false + \ }, + \ 'referencesProvider': v:true, + \ 'textDocumentSync': 2, + \ 'documentFormattingProvider': v:true, + \ 'codeActionProvider': v:true, + \ 'signatureHelpProvider': { + \ 'triggerCharacters': ['(', ','], + \ }, + \ 'completionProvider': { + \ 'triggerCharacters': ['.'], + \ 'resolveProvider': v:false + \ }, + \ 'definitionProvider': v:true, + \ 'experimental': {}, + \ 'documentHighlightProvider': v:true, + \ 'workspaceSymbolProvider': v:true, + \ }, + \ }, + \}) + + let l:messages = PopMessages() + + AssertEqual + \ [ + \ { + \ 'method': 'initialized', + \ 'jsonrpc': '2.0', + \ 'params': {}, + \ }, + \ { + \ 'method': 'textDocument/didOpen', + \ 'jsonrpc': '2.0', + \ 'params': { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ 'version': ale#lsp#message#GetNextVersionID() - 1, + \ 'languageId': a:language, + \ 'text': "\n", + \ }, + \ }, + \ }, + \ ], + \ l:messages + endif + + AssertEqual + \ [ + \ [ + \ a:linter_name, + \ { + \ 'connection_id': a:conn_prefix . ':' . a:root, + \ 'project_root': a:root, + \ 'buffer': a:buffer, + \ 'command': !empty(a:command) ? ale#job#PrepareCommand(a:buffer, a:command) : '', + \ }, + \ ], + \ ], + \ g:calls + endfunction + + function! AssertInitFailure() abort + let l:messages = PopMessages() + + AssertEqual [], l:messages + AssertEqual [], g:calls + endfunction + + call ale#linter#Reset() + +After: + Restore + + call ale#linter#Reset() + call ale#lsp#ResetConnections() + + unlet! g:ale_run_synchronously_callbacks + unlet! g:job_map + unlet! g:emulate_job_failure + unlet! g:next_job_id + unlet! g:lsp_started + + unlet! g:socket_map + unlet! g:emulate_socket_failure + unlet! g:next_channel_id + + unlet! g:message_buffer + unlet! g:calls + + augroup VaderTest + autocmd! + augroup END + + augroup! VaderTest + + delfunction PopMessages + delfunction Start + delfunction AssertInitSuccess + delfunction AssertInitFailure + + runtime autoload/ale/engine.vim + runtime autoload/ale/job.vim + runtime autoload/ale/socket.vim + +Execute(tsserver should be started correctly): + runtime ale_linters/typescript/tsserver.vim + + Assert Start(bufnr('')) + call AssertInitSuccess('tsserver', 'tsserver', '', '', ale#Escape('tsserver'), bufnr('')) + +Execute(tsserver failures should be handled appropriately): + runtime ale_linters/typescript/tsserver.vim + + let g:emulate_job_failure = 1 + + Assert !Start(bufnr('')) + call AssertInitFailure() + +Execute(LSP jobs should start correctly): + call ale#linter#Define('foobar', { + \ 'name': 'foo', + \ 'lsp': 'stdio', + \ 'executable': 'foo', + \ 'command': 'foo', + \ 'project_root': '/foo/bar', + \ 'initialization_options': {}, + \}) + + Assert Start(bufnr('')) + call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', 'foo', bufnr('')) + +Execute(LSP job failures should be handled): + call ale#linter#Define('foobar', { + \ 'name': 'foo', + \ 'lsp': 'stdio', + \ 'executable': 'foo', + \ 'command': 'foo', + \ 'project_root': '/foo/bar', + \ 'initialization_options': {}, + \}) + + let g:emulate_job_failure = 1 + + Assert !Start(bufnr('')) + call AssertInitFailure() + +Execute(LSP TCP connections should start correctly): + call ale#linter#Define('foobar', { + \ 'name': 'foo', + \ 'lsp': 'socket', + \ 'address': 'foo', + \ 'project_root': '/foo/bar', + \ 'initialization_options': {}, + \}) + + Assert Start(bufnr('')) + call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '', bufnr('')) + +Execute(LSP TCP connection failures should be handled): + call ale#linter#Define('foobar', { + \ 'name': 'foo', + \ 'lsp': 'socket', + \ 'address': 'foo', + \ 'project_root': '/foo/bar', + \ 'initialization_options': {}, + \}) + + let g:emulate_socket_failure = 1 + + Assert !Start(bufnr('')) + call AssertInitFailure() + +Execute(Deferred executables should be handled correctly): + call ale#linter#Define('foobar', { + \ 'name': 'foo', + \ 'lsp': 'stdio', + \ 'executable': {b -> ale#command#Run(b, 'echo', {-> 'foo'})}, + \ 'command': '%e -c', + \ 'project_root': '/foo/bar', + \ 'initialization_options': {}, + \}) + + Assert Start(bufnr('')) + call ale#test#FlushJobs() + call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', ale#Escape('foo') . ' -c', bufnr('')) + +Execute(Deferred commands should be handled correctly): + call ale#linter#Define('foobar', { + \ 'name': 'foo', + \ 'lsp': 'stdio', + \ 'executable': 'foo', + \ 'command': {b -> ale#command#Run(b, 'echo', {-> '%e -c'})}, + \ 'project_root': '/foo/bar', + \ 'initialization_options': {}, + \}) + + Assert Start(bufnr('')) + call ale#test#FlushJobs() + call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', ale#Escape('foo') . ' -c', bufnr('')) + +Execute(Deferred addresses should be handled correctly): + call ale#linter#Define('foobar', { + \ 'name': 'foo', + \ 'lsp': 'socket', + \ 'address': {b -> ale#command#Run(b, 'echo', {-> 'localhost:1234'})}, + \ 'project_root': '/foo/bar', + \ 'initialization_options': {}, + \}) + + Assert Start(bufnr('')) + call ale#test#FlushJobs() + call AssertInitSuccess('foo', 'localhost:1234', 'foobar', '/foo/bar', '', bufnr('')) + +Execute(Servers that have crashed should be restarted): + call ale#lsp#Register('foo', '/foo/bar', {}) + call extend(ale#lsp#GetConnections()['foo:/foo/bar'], {'initialized': 1}) + + " Starting the program again should reset initialized to `0`. + call ale#lsp#StartProgram('foo:/foo/bar', 'foobar', 'foobar --start') + + AssertEqual 0, ale#lsp#GetConnections()['foo:/foo/bar']['initialized'] + AssertEqual ['initialize'], map(PopMessages(), 'v:val[''method'']') + +Execute(Current LSP buffer should receive ALELSPStarted): + call ale#linter#Define('foobar', { + \ 'name': 'foo', + \ 'lsp': 'socket', + \ 'address': 'foo', + \ 'project_root': '/foo/bar', + \ 'initialization_options': {}, + \}) + + augroup VaderTest + autocmd! + autocmd User ALELSPStarted let g:lsp_started = 1 + augroup END + + Assert Start(bufnr('')) + call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '', bufnr('')) + AssertEqual g:lsp_started, 1 + +Execute(Target LSP buffer should receive ALELSPStarted): + call ale#linter#Define('foobar', { + \ 'name': 'foo', + \ 'lsp': 'socket', + \ 'address': 'foo', + \ 'project_root': '/foo/bar', + \ 'initialization_options': {}, + \}) + + augroup VaderTest + autocmd! + autocmd User ALELSPStarted let g:lsp_started = 1 + augroup END + + let buffer = bufnr('') + + enew! + Assert Start(buffer) + call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '', buffer) + execute 'buffer' . buffer + + AssertEqual g:lsp_started, 1 diff --git a/vim-config/plugins/ale/test/lsp/test_other_initialize_message_handling.vader b/vim-config/plugins/ale/test/lsp/test_other_initialize_message_handling.vader new file mode 100644 index 00000000..f3b53843 --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_other_initialize_message_handling.vader @@ -0,0 +1,214 @@ +Before: + runtime autoload/ale/lsp.vim + + let g:message_list = [] + let b:conn = { + \ 'id': 1, + \ 'is_tsserver': 0, + \ 'data': '', + \ 'root': '/foo/bar', + \ 'open_documents': {}, + \ 'initialized': 0, + \ 'init_request_id': 0, + \ 'init_options': {}, + \ 'config': {}, + \ 'callback_list': [], + \ 'message_queue': [], + \ 'init_queue': [], + \ 'capabilities': { + \ 'hover': 0, + \ 'rename': 0, + \ 'references': 0, + \ 'completion': 0, + \ 'completion_trigger_characters': [], + \ 'definition': 0, + \ 'symbol_search': 0, + \ 'code_actions': 0, + \ }, + \} + + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + + return 42 + endfunction + +After: + unlet! b:conn + unlet! g:message_list + + runtime autoload/ale/lsp.vim + +Execute(Messages with no method and capabilities should initialize projects): + call ale#lsp#HandleInitResponse(b:conn, { + \ 'result': {'capabilities': {}}, + \}) + + AssertEqual 1, b:conn.initialized + AssertEqual [[1, 'initialized', {}]], g:message_list + +Execute(Other messages should not initialize projects): + call ale#lsp#HandleInitResponse(b:conn, {'method': 'lolwat'}) + + AssertEqual 0, b:conn.initialized + AssertEqual [], g:message_list + + call ale#lsp#HandleInitResponse(b:conn, {'result': {'x': {}}}) + + AssertEqual 0, b:conn.initialized + AssertEqual [], g:message_list + +Execute(Capabilities should bet set up correctly): + call ale#lsp#HandleInitResponse(b:conn, { + \ 'jsonrpc': '2.0', + \ 'id': 1, + \ 'result': { + \ 'capabilities': { + \ 'renameProvider': v:true, + \ 'executeCommandProvider': { + \ 'commands': [], + \ }, + \ 'hoverProvider': v:true, + \ 'documentSymbolProvider': v:true, + \ 'documentRangeFormattingProvider': v:true, + \ 'codeLensProvider': { + \ 'resolveProvider': v:false + \ }, + \ 'referencesProvider': v:true, + \ 'textDocumentSync': 2, + \ 'documentFormattingProvider': v:true, + \ 'codeActionProvider': v:true, + \ 'signatureHelpProvider': { + \ 'triggerCharacters': ['(', ','], + \ }, + \ 'completionProvider': { + \ 'triggerCharacters': ['.'], + \ 'resolveProvider': v:false + \ }, + \ 'definitionProvider': v:true, + \ 'experimental': {}, + \ 'documentHighlightProvider': v:true, + \ 'workspaceSymbolProvider': v:true + \ }, + \ }, + \}) + + AssertEqual 1, b:conn.initialized + AssertEqual + \ { + \ 'completion_trigger_characters': ['.'], + \ 'completion': 1, + \ 'references': 1, + \ 'hover': 1, + \ 'definition': 1, + \ 'symbol_search': 1, + \ 'rename': 1, + \ 'code_actions': 1, + \ }, + \ b:conn.capabilities + AssertEqual [[1, 'initialized', {}]], g:message_list + +Execute(Disabled capabilities should be recognised correctly): + call ale#lsp#HandleInitResponse(b:conn, { + \ 'jsonrpc': '2.0', + \ 'id': 1, + \ 'result': { + \ 'capabilities': { + \ 'renameProvider': v:false, + \ 'executeCommandProvider': { + \ 'commands': [], + \ }, + \ 'hoverProvider': v:false, + \ 'documentSymbolProvider': v:true, + \ 'documentRangeFormattingProvider': v:true, + \ 'codeLensProvider': { + \ 'resolveProvider': v:false + \ }, + \ 'referencesProvider': v:false, + \ 'textDocumentSync': 2, + \ 'documentFormattingProvider': v:true, + \ 'codeActionProvider': v:false, + \ 'signatureHelpProvider': { + \ 'triggerCharacters': ['(', ','], + \ }, + \ 'definitionProvider': v:false, + \ 'experimental': {}, + \ 'documentHighlightProvider': v:true, + \ }, + \ }, + \}) + + AssertEqual 1, b:conn.initialized + AssertEqual + \ { + \ 'completion_trigger_characters': [], + \ 'completion': 0, + \ 'references': 0, + \ 'hover': 0, + \ 'definition': 0, + \ 'symbol_search': 0, + \ 'rename': 0, + \ 'code_actions': 0, + \ }, + \ b:conn.capabilities + AssertEqual [[1, 'initialized', {}]], g:message_list + +Execute(Capabilities should be enabled when send as Dictionaries): + call ale#lsp#HandleInitResponse(b:conn, { + \ 'jsonrpc': '2.0', + \ 'id': 1, + \ 'result': { + \ 'capabilities': { + \ 'renameProvider': {}, + \ 'executeCommandProvider': { + \ 'commands': [], + \ }, + \ 'hoverProvider': {}, + \ 'documentSymbolProvider': v:true, + \ 'documentRangeFormattingProvider': v:true, + \ 'codeLensProvider': { + \ 'resolveProvider': v:false + \ }, + \ 'completionProvider': { + \ 'triggerCharacters': ['.'], + \ 'resolveProvider': v:false + \ }, + \ 'referencesProvider': {}, + \ 'textDocumentSync': 2, + \ 'documentFormattingProvider': v:true, + \ 'codeActionProvider': v:true, + \ 'signatureHelpProvider': { + \ 'triggerCharacters': ['(', ','], + \ }, + \ 'definitionProvider': {}, + \ 'typeDefinitionProvider': {}, + \ 'experimental': {}, + \ 'documentHighlightProvider': v:true, + \ 'workspaceSymbolProvider': {} + \ }, + \ }, + \}) + + AssertEqual 1, b:conn.initialized + AssertEqual + \ { + \ 'completion_trigger_characters': ['.'], + \ 'completion': 1, + \ 'references': 1, + \ 'hover': 1, + \ 'definition': 1, + \ 'typeDefinition': 1, + \ 'symbol_search': 1, + \ 'rename': 1, + \ 'code_actions': 1, + \ }, + \ b:conn.capabilities + AssertEqual [[1, 'initialized', {}]], g:message_list + +Execute(Results that are not dictionaries should be handled correctly): + call ale#lsp#HandleInitResponse(b:conn, { + \ 'jsonrpc': '2.0', + \ 'id': 1, + \ 'result': v:null, + \}) + AssertEqual [], g:message_list diff --git a/vim-config/plugins/ale/test/lsp/test_read_lsp_diagnostics.vader b/vim-config/plugins/ale/test/lsp/test_read_lsp_diagnostics.vader new file mode 100644 index 00000000..61ffc73f --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_read_lsp_diagnostics.vader @@ -0,0 +1,257 @@ +Before: + function Range(start_line, start_char, end_line, end_char) abort + return { + \ 'start': {'line': a:start_line, 'character': a:start_char}, + \ 'end': {'line': a:end_line, 'character': a:end_char}, + \} + endfunction + +After: + delfunction Range + +Execute(ale#lsp#response#ReadDiagnostics() should handle errors): + AssertEqual [ + \ { + \ 'type': 'E', + \ 'text': 'Something went wrong!', + \ 'lnum': 3, + \ 'col': 11, + \ 'end_lnum': 5, + \ 'end_col': 15, + \ 'code': 'some-error', + \ } + \ ], + \ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [ + \ { + \ 'severity': 1, + \ 'range': Range(2, 10, 4, 15), + \ 'code': 'some-error', + \ 'message': 'Something went wrong!', + \ }, + \ ]}}) + +Execute(ale#lsp#response#ReadDiagnostics() should handle warnings): + AssertEqual [ + \ { + \ 'type': 'W', + \ 'text': 'Something went wrong!', + \ 'lnum': 2, + \ 'col': 4, + \ 'end_lnum': 2, + \ 'end_col': 3, + \ 'code': 'some-warning', + \ } + \ ], + \ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [ + \ { + \ 'severity': 2, + \ 'range': Range(1, 3, 1, 3), + \ 'code': 'some-warning', + \ 'message': 'Something went wrong!', + \ }, + \ ]}}) + +Execute(ale#lsp#response#ReadDiagnostics() should treat messages with missing severity as errors): + AssertEqual [ + \ { + \ 'type': 'E', + \ 'text': 'Something went wrong!', + \ 'lnum': 3, + \ 'col': 11, + \ 'end_lnum': 5, + \ 'end_col': 15, + \ 'code': 'some-error', + \ } + \ ], + \ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [ + \ { + \ 'range': Range(2, 10, 4, 15), + \ 'code': 'some-error', + \ 'message': 'Something went wrong!', + \ }, + \ ]}}) + +Execute(ale#lsp#response#ReadDiagnostics() should handle messages without codes): + AssertEqual [ + \ { + \ 'type': 'E', + \ 'text': 'Something went wrong!', + \ 'lnum': 3, + \ 'col': 11, + \ 'end_lnum': 5, + \ 'end_col': 15, + \ } + \ ], + \ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [ + \ { + \ 'range': Range(2, 10, 4, 15), + \ 'message': 'Something went wrong!', + \ }, + \ ]}}) + +Execute(ale#lsp#response#ReadDiagnostics() should include sources in detail): + AssertEqual [ + \ { + \ 'type': 'E', + \ 'text': 'Something went wrong!', + \ 'detail': '[tslint] Something went wrong!', + \ 'lnum': 10, + \ 'col': 15, + \ 'end_lnum': 12, + \ 'end_col': 22, + \ } + \ ], + \ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [ + \ { + \ 'range': Range(9, 14, 11, 22), + \ 'message': 'Something went wrong!', + \ 'source': 'tslint', + \ } + \ ]}}) + +Execute(ale#lsp#response#ReadDiagnostics() should keep detail with line breaks but replace with spaces in text): + AssertEqual [ + \ { + \ 'type': 'E', + \ 'text': 'cannot borrow `cap` as mutable more than once at a time mutable borrow starts here in previous iteration of loop', + \ 'detail': "[rustc] cannot borrow `cap` as mutable\r\nmore than once at a time\n\nmutable borrow starts here\rin previous iteration of loop", + \ 'lnum': 10, + \ 'col': 15, + \ 'end_lnum': 12, + \ 'end_col': 22, + \ } + \ ], + \ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [ + \ { + \ 'range': Range(9, 14, 11, 22), + \ 'message': "cannot borrow `cap` as mutable\r\nmore than once at a time\n\nmutable borrow starts here\rin previous iteration of loop", + \ 'source': 'rustc', + \ } + \ ]}}) + +Execute(ale#lsp#response#ReadDiagnostics() should consider -1 to be a meaningless code): + AssertEqual [ + \ { + \ 'type': 'E', + \ 'text': 'Something went wrong!', + \ 'lnum': 3, + \ 'col': 11, + \ 'end_lnum': 5, + \ 'end_col': 15, + \ } + \ ], + \ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [ + \ { + \ 'range': Range(2, 10, 4, 15), + \ 'message': 'Something went wrong!', + \ 'code': -1, + \ }, + \ ]}}) + +Execute(ale#lsp#response#ReadDiagnostics() should handle multiple messages): + AssertEqual [ + \ { + \ 'type': 'E', + \ 'text': 'Something went wrong!', + \ 'lnum': 1, + \ 'col': 3, + \ 'end_lnum': 1, + \ 'end_col': 2, + \ }, + \ { + \ 'type': 'W', + \ 'text': 'A warning', + \ 'lnum': 2, + \ 'col': 5, + \ 'end_lnum': 2, + \ 'end_col': 4, + \ }, + \ ], + \ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [ + \ { + \ 'range': Range(0, 2, 0, 2), + \ 'message': 'Something went wrong!', + \ }, + \ { + \ 'severity': 2, + \ 'range': Range(1, 4, 1, 4), + \ 'message': 'A warning', + \ }, + \ ]}}) + +Execute(ale#lsp#response#ReadDiagnostics() should use relatedInformation for detail): + AssertEqual [ + \ { + \ 'type': 'E', + \ 'text': 'Something went wrong!', + \ 'lnum': 1, + \ 'col': 3, + \ 'end_lnum': 1, + \ 'end_col': 2, + \ 'detail': "Something went wrong!\n/tmp/someotherfile.txt:43:80:\n\tmight be this" + \ } + \ ], + \ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [ + \ { + \ 'range': Range(0, 2, 0, 2), + \ 'message': 'Something went wrong!', + \ 'relatedInformation': [{ + \ 'message': 'might be this', + \ 'location': { + \ 'uri': 'file:///tmp/someotherfile.txt', + \ 'range': { + \ 'start': { 'line': 42, 'character': 79 }, + \ 'end': { 'line': 142, 'character': 179}, + \ } + \ } + \ }] + \ } + \ ]}}) + +Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle tsserver responses): + AssertEqual + \ [ + \ { + \ 'type': 'E', + \ 'nr': 2365, + \ 'code': '2365', + \ 'text': 'Operator ''''+'''' cannot be applied to types ''''3'''' and ''''{}''''.', + \ 'lnum': 1, + \ 'col': 11, + \ 'end_lnum': 1, + \ 'end_col': 16, + \ }, + \ ], + \ ale#lsp#response#ReadTSServerDiagnostics({"seq":0,"type":"event","event":"semanticDiag","body":{"file":"/bar/foo.ts","diagnostics":[{"start":{"line":1,"offset":11},"end":{"line":1,"offset":17},"text":"Operator ''+'' cannot be applied to types ''3'' and ''{}''.","code":2365}]}}) + +Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle warnings from tsserver): + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'col': 3, + \ 'nr': 2515, + \ 'code': '2515', + \ 'end_lnum': 27, + \ 'type': 'W', + \ 'end_col': 13, + \ 'text': 'Calls to ''console.log'' are not allowed. (no-console)', + \ } + \ ], + \ ale#lsp#response#ReadTSServerDiagnostics({"seq":0,"type":"event","event":"semanticDiag","body":{"file":"","diagnostics":[{"start":{"line":27,"offset":3},"end":{"line":27,"offset":14},"text":"Calls to 'console.log' are not allowed. (no-console)","code":2515,"category":"warning","source":"tslint"}]}}) + +Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle suggestions from tsserver): + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'col': 3, + \ 'nr': 2515, + \ 'code': '2515', + \ 'end_lnum': 27, + \ 'type': 'I', + \ 'end_col': 13, + \ 'text': 'Some info', + \ } + \ ], + \ ale#lsp#response#ReadTSServerDiagnostics({"seq":0,"type":"event","event":"semanticDiag","body":{"file":"","diagnostics":[{"start":{"line":27,"offset":3},"end":{"line":27,"offset":14},"text":"Some info","code":2515,"category":"suggestion","source":"tslint"}]}}) diff --git a/vim-config/plugins/ale/test/lsp/test_reset_lsp.vader b/vim-config/plugins/ale/test/lsp/test_reset_lsp.vader new file mode 100644 index 00000000..310b3d62 --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_reset_lsp.vader @@ -0,0 +1,98 @@ +Before: + Save g:ale_enabled + Save g:ale_set_signs + Save g:ale_set_quickfix + Save g:ale_set_loclist + Save g:ale_set_highlights + Save g:ale_echo_cursor + + let g:ale_enabled = 0 + let g:ale_set_signs = 0 + let g:ale_set_quickfix = 0 + let g:ale_set_loclist = 0 + let g:ale_set_highlights = 0 + let g:ale_echo_cursor = 0 + + function EmptyString() abort + return '' + endfunction + + call ale#engine#InitBufferInfo(bufnr('')) + " Call this function first, so we can be sure the module is loaded before we + " check if it exists. + call ale#lsp_linter#ClearLSPData() + + call ale#linter#Define('testft', { + \ 'name': 'lsplinter', + \ 'lsp': 'tsserver', + \ 'executable': function('EmptyString'), + \ 'command': function('EmptyString'), + \ 'project_root': function('EmptyString'), + \ 'language': function('EmptyString'), + \}) + + call ale#linter#Define('testft', { + \ 'name': 'otherlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd': 'true', + \ 'command': 'true', + \ 'read_buffer': 0, + \}) + +After: + Restore + + unlet! b:ale_save_event_fired + + delfunction EmptyString + call ale#linter#Reset() + +Given testft(Some file with an imaginary filetype): +Execute(ALEStopAllLSPs should clear the loclist): + let g:ale_buffer_info[bufnr('')].loclist = [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 0, + \ 'bufnr': bufnr(''), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'lsplinter', + \ }, + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 0, + \ 'bufnr': bufnr(''), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'otherlinter', + \ }, + \] + let g:ale_buffer_info[bufnr('')].active_linter_list = [ + \ {'name': 'lsplinter'}, + \ {'name': 'otherlinter'}, + \] + + ALEStopAllLSPs + + " The loclist should be updated. + AssertEqual g:ale_buffer_info[bufnr('')].loclist, [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 0, + \ 'bufnr': bufnr(''), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'otherlinter', + \ }, + \] + + " The LSP linter should be removed from the active linter list. + AssertEqual + \ ['otherlinter'], + \ map(copy(g:ale_buffer_info[bufnr('')].active_linter_list), 'v:val.name') diff --git a/vim-config/plugins/ale/test/lsp/test_update_config.vader b/vim-config/plugins/ale/test/lsp/test_update_config.vader new file mode 100644 index 00000000..698477ec --- /dev/null +++ b/vim-config/plugins/ale/test/lsp/test_update_config.vader @@ -0,0 +1,21 @@ +Before: + runtime autoload/ale/lsp.vim + + let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {}) + + " Stub out this function, so we test updating configs. + function! ale#lsp#Send(conn_id, message) abort + endfunction + +After: + Restore + + unlet! g:conn_id + + runtime autoload/ale/lsp.vim + +Execute(Only send updates when the configuration dictionary changes): + AssertEqual 0, ale#lsp#UpdateConfig(g:conn_id, bufnr(''), {}) + AssertEqual 1, ale#lsp#UpdateConfig(g:conn_id, bufnr(''), {'a': 1}) + AssertEqual 0, ale#lsp#UpdateConfig(g:conn_id, bufnr(''), {'a': 1}) + AssertEqual 1, ale#lsp#UpdateConfig(g:conn_id, bufnr(''), {}) diff --git a/vim-config/plugins/ale/test/python/test_deoplete_source.py b/vim-config/plugins/ale/test/python/test_deoplete_source.py new file mode 100644 index 00000000..8304fa25 --- /dev/null +++ b/vim-config/plugins/ale/test/python/test_deoplete_source.py @@ -0,0 +1,120 @@ +import unittest +import imp + +ale_module = imp.load_source( + 'deoplete.sources.ale', + '/testplugin/rplugin/python3/deoplete/sources/ale.py', +) + + +class VimMock(object): + def __init__(self, call_list, call_results, commands): + self.__call_list = call_list + self.__call_results = call_results + + self.__commands = commands + + def call(self, function, *args): + self.__call_list.append((function, args)) + + return self.__call_results.get(function, 0) + + def command(self, command): + self.__commands.append(command) + + +class DeopleteSourceTest(unittest.TestCase): + def setUp(self): + super(DeopleteSourceTest, self).setUp() + + self.call_list = [] + self.call_results = {'ale#completion#CanProvideCompletions': 1} + self.commands = [] + self.source = ale_module.Source('vim') + self.source.vim = VimMock( + self.call_list, self.call_results, self.commands) + + def test_attributes(self): + """ + Check all of the attributes we set. + """ + attributes = dict( + (key, getattr(self.source, key)) + for key in + dir(self.source) + if not key.startswith('__') + and key != 'vim' + and not hasattr(getattr(self.source, key), '__self__') + ) + + self.assertEqual(attributes, { + 'input_patterns': { + '_': r'\.\w*$', + 'rust': r'(\.|::)\w*$', + 'typescript': r'(\.|\'|")\w*$', + 'cpp': r'(\.|::|->)\w*$', + }, + 'is_bytepos': True, + 'is_volatile': True, + 'mark': '[L]', + 'min_pattern_length': 1, + 'name': 'ale', + 'rank': 1000, + }) + + def test_complete_position(self): + self.call_results['ale#completion#GetCompletionPositionForDeoplete'] = 2 + context = {'input': 'foo'} + + self.assertEqual(self.source.get_complete_position(context), 2) + self.assertEqual(self.call_list, [ + ('ale#completion#GetCompletionPositionForDeoplete', ('foo',)), + ]) + + def test_request_completion_results(self): + context = {'event': 'TextChangedI', 'is_refresh': True} + + self.assertEqual(self.source.gather_candidates(context), []) + self.assertEqual(self.call_list, [ + ('ale#completion#CanProvideCompletions', ()), + ]) + self.assertEqual(self.commands, [ + "call ale#completion#GetCompletions('ale-callback', " + \ + "{'callback': {completions -> deoplete#auto_complete() }})" + ]) + + def test_request_completion_results_from_buffer_without_providers(self): + self.call_results['ale#completion#CanProvideCompletions'] = 0 + context = {'event': 'TextChangedI', 'is_refresh': True} + + self.assertIsNone(self.source.gather_candidates(context), []) + self.assertEqual(self.call_list, [ + ('ale#completion#CanProvideCompletions', ()), + ]) + + def test_async_event(self): + context = {'event': 'Async', 'is_refresh': True} + self.call_results['ale#completion#GetCompletionResult'] = [ + { + 'word': 'foobar', + 'kind': 'v', + 'icase': 1, + 'menu': '', + 'info': '', + }, + ] + + self.assertEqual(self.source.gather_candidates(context), [ + { + 'word': 'foobar', + 'kind': 'v', + 'icase': 1, + 'menu': '', + 'info': '', + }, + ]) + + self.assertEqual(self.call_list, [ + ('ale#completion#CanProvideCompletions', ()), + ('ale#completion#GetCompletionResult', ()), + ]) diff --git a/vim-config/plugins/ale/test/script/block-padding-checker b/vim-config/plugins/ale/test/script/block-padding-checker new file mode 100755 index 00000000..2feab6d0 --- /dev/null +++ b/vim-config/plugins/ale/test/script/block-padding-checker @@ -0,0 +1,145 @@ +#!/usr/bin/env python +""" +This script checks for missing or forbidden blank lines before or after +particular Vim commands. This script ensures that VimL scripts are padded +correctly, so they are easier to read. +""" + +import sys +import re + +INDENTATION_RE = re.compile(r'^ *') +COMMENT_LINE_RE = re.compile(r'^ *"') +COMMAND_RE = re.compile(r'^ *([a-zA-Z\\]+)') +OPERATOR_END_RE = re.compile(r'(&&|\|\||\+|-|\*\| /)$') + +START_BLOCKS = set(['if', 'for', 'while', 'try', 'function']) +END_BLOCKS = set(['endif', 'endfor', 'endwhile', 'endtry', 'endfunction']) +MIDDLE_BLOCKS = set(['else', 'elseif', 'catch', 'finally']) +TERMINATORS = set(['return', 'throw']) + +WHITESPACE_BEFORE_SET = START_BLOCKS | TERMINATORS +WHITESPACE_FORBIDDEN_BEFORE_SET = END_BLOCKS | MIDDLE_BLOCKS +WHITESPACE_AFTER_SET = END_BLOCKS +WHITESPACE_FORBIDDEN_AFTER_SET = START_BLOCKS | MIDDLE_BLOCKS +SAME_INDENTATION_SET = set(['\\']) + + +def remove_comment_lines(line_iter): + for line_number, line in enumerate(line_iter, 1): + if not COMMENT_LINE_RE.match(line): + yield (line_number, line) + + +def check_lines(line_iter): + previous_indentation_level = None + previous_command = None + previous_line_blank = False + + for line_number, line in remove_comment_lines(line_iter): + if len(line) == 0: + # Check for commands where we shouldn't have blank lines after + # them, like `else` or the start of blocks like `function`. + if ( + previous_command is not None + and previous_command in WHITESPACE_FORBIDDEN_AFTER_SET + ): + yield ( + line_number, + 'Blank line forbidden after `%s`' % (previous_command,) + ) + + previous_line_blank = True + previous_command = None + else: + indentation_level = INDENTATION_RE.match(line).end() + command_match = COMMAND_RE.match(line) + + if command_match: + command = command_match.group(1) + + if ( + command in SAME_INDENTATION_SET + and previous_indentation_level is not None + and indentation_level != previous_indentation_level + ): + yield ( + line_number, + 'Line continuation should match previous indentation' + ) + + if ( + previous_indentation_level is not None + and indentation_level != previous_indentation_level + and abs(indentation_level - previous_indentation_level) != 4 # noqa + ): + yield ( + line_number, + 'Indentation should be 4 spaces' + ) + + # Check for commands requiring blank lines before them, if they + # aren't at the start of a block. + if ( + command in WHITESPACE_BEFORE_SET + and previous_indentation_level is not None + and indentation_level == previous_indentation_level + and previous_line_blank is False + ): + yield ( + line_number, + 'Blank line required before `%s`' % (command,) + ) + + # Check for commands where we shouldn't have blank lines before + # them, like `else` or the end of blocks like `endfunction`. + if ( + command in WHITESPACE_FORBIDDEN_BEFORE_SET + and previous_line_blank is True + ): + yield ( + line_number - 1, + 'Blank line forbidden before `%s`' % (command,) + ) + + # Check for commands requiring blank lines after them, if they + # aren't at the end of a block. + if ( + previous_command is not None + and previous_command in WHITESPACE_AFTER_SET + and previous_indentation_level is not None + and indentation_level == previous_indentation_level + and previous_line_blank is False + ): + yield ( + line_number - 1, + 'Blank line required after `%s`' % (command,) + ) + + previous_command = command + previous_line_blank = False + previous_indentation_level = indentation_level + + if OPERATOR_END_RE.search(line): + yield ( + line_number, + 'Put operators at the start of lines instead' + ) + + +def main(): + status = 0 + + for filename in sys.argv[1:]: + with open(filename) as vim_file: + line_iter = (line.rstrip() for line in vim_file) + + for line_number, message in check_lines(line_iter): + print('%s:%d %s' % (filename, line_number, message)) + status = 1 + + sys.exit(status) + + +if __name__ == "__main__": + main() diff --git a/vim-config/plugins/ale/test/script/check-duplicate-tags b/vim-config/plugins/ale/test/script/check-duplicate-tags new file mode 100755 index 00000000..ec1de788 --- /dev/null +++ b/vim-config/plugins/ale/test/script/check-duplicate-tags @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +grep --exclude=tags -roh '\*.*\*$' doc | sort | uniq -d diff --git a/vim-config/plugins/ale/test/script/check-supported-tools-tables b/vim-config/plugins/ale/test/script/check-supported-tools-tables new file mode 100755 index 00000000..d238e77f --- /dev/null +++ b/vim-config/plugins/ale/test/script/check-supported-tools-tables @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +set -e +set -u + +# This script compares the table of supported tools in both supported-tools.md +# (for GitHub) and doc/ale-supported-languages-and-tools.txt (for vim), so we +# can complain if they don't match up. + +doc_file="$(mktemp -t doc.XXXXXXXX)" +doc_sorted_file="$(mktemp -t doc-sorted.XXXXXXXX)" +readme_file="$(mktemp -t readme.XXXXXXXX)" + +while read -r; do + if [[ "$REPLY" =~ ^! ]]; then + language="${REPLY/!/}" + else + echo "$language - $REPLY" + fi +done < <( + grep '^\*\|^ *\*' doc/ale-supported-languages-and-tools.txt \ + | sed -e '1,2d' \ + | sed 's/^\* */!/' \ + | sed -E 's/^ *\* *|!!|\^|\(.*\)|`//g' \ + | sed 's/ *$//' +) > "$doc_file" + +while read -r; do + if [[ "$REPLY" =~ ^! ]]; then + language="${REPLY/!/}" + else + echo "$language - $REPLY" + fi +done < <( + grep '^\*\|^ *\*' supported-tools.md \ + | sed 's/^\* */!/' \ + | sed -E 's/^ *\* *|:floppy_disk:|:warning:|\(.*\)|\[|\].*|-n flag//g' \ + | sed 's/ *$//' +) > "$readme_file" + +exit_code=0 + +# Sort the tools ignoring case, and complain when things are out of order. +LC_ALL=en_US.UTF-8 sort -f -k1,2 "$doc_file" -o "$doc_sorted_file" + +diff -U0 "$doc_sorted_file" "$doc_file" || exit_code=$? + +if ((exit_code)); then + echo + echo "The supported tools list isn't sorted properly" + echo +fi + +diff -U0 "$readme_file" "$doc_file" || exit_code=$? + +rm "$doc_file" +rm "$doc_sorted_file" +rm "$readme_file" + +exit "$exit_code" diff --git a/vim-config/plugins/ale/test/script/check-tag-alignment b/vim-config/plugins/ale/test/script/check-tag-alignment new file mode 100755 index 00000000..d41db160 --- /dev/null +++ b/vim-config/plugins/ale/test/script/check-tag-alignment @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +exit_code=0 + +# Documentation tags need to be aligned to the right margin, so look for +# tags which aren't at the right margin. +grep ' \*[^*]\+\*$' doc/ -r \ + | awk '{ sep = index($0, ":"); if (length(substr($0, sep + 1 )) < 79) { print } }' \ + | grep . && exit_code=1 + +exit $exit_code diff --git a/vim-config/plugins/ale/test/script/check-tag-references b/vim-config/plugins/ale/test/script/check-tag-references new file mode 100755 index 00000000..45e741fb --- /dev/null +++ b/vim-config/plugins/ale/test/script/check-tag-references @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -e + +exit_code=0 +tag_regex='[gb]\?:\?\(ale\|ALE\)[a-zA-Z_\-]\+' + +tags="$(mktemp -t tags.XXXXXXXX)" +refs="$(mktemp -t refs.XXXXXXXX)" +# Grep for tags and references, and complain if we find a reference without +# a tag for the reference. Only our tags will be included. +grep --exclude=tags -roh "\\*$tag_regex\\*" doc | sed 's/*//g' | sort -u > "$tags" +grep --exclude=tags -roh "|$tag_regex|" doc | sed 's/|//g' | sort -u > "$refs" + +exit_code=0 + +if ! [[ $(comm -23 $refs $tags | wc -l) -eq 0 ]]; then + exit_code=1 +fi + +rm "$tags" +rm "$refs" diff --git a/vim-config/plugins/ale/test/script/check-toc b/vim-config/plugins/ale/test/script/check-toc new file mode 100755 index 00000000..f3f8a9ea --- /dev/null +++ b/vim-config/plugins/ale/test/script/check-toc @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +set -e +set -u + +# This script checks that the table of contents for the supported tools is +# sorted, and that the table matches the files. + +toc_section_start_line="$( + grep -m1 -n '^7\..*\*ale-other-integration-options\*' doc/ale.txt \ + | sed 's/\([0-9]*\).*/\1/' \ +)" +toc_start_offset="$( \ + tail -n +"$toc_section_start_line" doc/ale.txt \ + | grep -m1 -n '^ .*\.\.\.' \ + | sed 's/\([0-9]*\).*/\1/' \ +)" +# shellcheck disable=SC2003 +toc_start_line="$(expr "$toc_section_start_line" + "$toc_start_offset" - 1)" +toc_section_size="$( \ + tail -n +"$toc_start_line" doc/ale.txt \ + | grep -m1 -n '^===*$' \ + | sed 's/\([0-9]*\).*/\1/' \ +)" +# shellcheck disable=SC2003 +toc_end_line="$(expr "$toc_start_line" + "$toc_section_size" - 4)" + +toc_file="$(mktemp -t table-of-contents.XXXXXXXX)" +heading_file="$(mktemp -t headings.XXXXXXXX)" +tagged_toc_file="$(mktemp -t ale.txt.XXXXXXXX)" +sorted_toc_file="$(mktemp -t sorted-ale.txt.XXXXXXXX)" + +sed -n "$toc_start_line,$toc_end_line"p doc/ale.txt \ + | sed 's/^ \( *[^.][^.]*\)\.\.*|\(..*\)|/\1, \2/' \ + > "$toc_file" + +# Get all of the doc files in a natural sorted order. +doc_files="$(/usr/bin/env ls -1v doc | grep '^ale-' | sed 's/^/doc\//' | paste -sd ' ' -)" + +# shellcheck disable=SC2086 +grep -h '\*ale-.*-options\|^[a-z].*\*ale-.*\*$' $doc_files \ + | sed 's/^/ /' \ + | sed 's/ALE Shell Integration/ALE sh Integration/' \ + | sed 's/ALE BibTeX Integration/ALE bib Integration/' \ + | sed 's/ ALE \(.*\) Integration/\1/' \ + | sed 's/ *\*\(..*\)\*$/, \1/' \ + | tr '[:upper:]' '[:lower:]' \ + | sed 's/objective-c/objc/' \ + | sed 's/c++/cpp/' \ + > "$heading_file" + +exit_code=0 +in_section=0 +section_index=0 + +# Prefix numbers to table of contents entries so that sections aren't mixed up +# with sub-sections when they are sorted. +while read -r; do + if [[ "$REPLY" =~ ^\ ]]; then + if ! ((in_section)); then + let section_index='section_index + 1' + in_section=1 + fi + else + if ((in_section)); then + let section_index='section_index + 1' + in_section=0 + fi + fi + + echo "$section_index $REPLY" >> "$tagged_toc_file" +done < "$toc_file" + +# Sort the sections and sub-sections and remove the tags. +sort -sn "$tagged_toc_file" | sed 's/[0-9][0-9]* //' > "$sorted_toc_file" + +echo 'Check for bad ToC sorting:' +echo +diff -U2 "$sorted_toc_file" "$toc_file" || exit_code=$? + +echo 'Check for mismatched ToC and headings:' +echo +diff -U3 "$toc_file" "$heading_file" || exit_code=$? + +rm "$toc_file" +rm "$heading_file" +rm "$tagged_toc_file" +rm "$sorted_toc_file" + +exit "$exit_code" diff --git a/vim-config/plugins/ale/test/script/custom-checks b/vim-config/plugins/ale/test/script/custom-checks new file mode 100755 index 00000000..83afb28c --- /dev/null +++ b/vim-config/plugins/ale/test/script/custom-checks @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +set -e +set -u + +exit_code=0 +docker_flags=(--rm -v "$PWD:/testplugin" -v "$PWD/test:/home" -w /testplugin "$DOCKER_RUN_IMAGE") + +echo '========================================' +echo 'Running custom linting rules' +echo '========================================' +echo 'Custom warnings/errors follow:' +echo + +set -o pipefail +docker run "${docker_flags[@]}" test/script/custom-linting-rules . || exit_code=$? +set +o pipefail +echo + +echo '========================================' +echo 'Checking for duplicate tags' +echo '========================================' +echo 'Duplicate tags follow:' +echo + +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-duplicate-tags . || exit_code=$? +set +o pipefail +echo + +echo '========================================' +echo 'Checking for invalid tag references' +echo '========================================' +echo 'Invalid tag references tags follow:' +echo + +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-tag-references || exit_code=$? +set +o pipefail + +echo '========================================' +echo 'diff supported-tools.md and doc/ale-supported-languages-and-tools.txt tables' +echo '========================================' +echo 'Differences follow:' +echo + +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-supported-tools-tables || exit_code=$? +set +o pipefail + +echo '========================================' +echo 'Look for badly aligned doc tags' +echo '========================================' +echo 'Badly aligned tags follow:' +echo + +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-tag-alignment || exit_code=$? +set +o pipefail + +echo '========================================' +echo 'Look for table of contents issues' +echo '========================================' +echo + +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-toc || exit_code=$? +set +o pipefail + +echo '========================================' +echo 'Check Python code' +echo '========================================' +echo + +docker run --rm -v "$PWD:/testplugin" "$DOCKER_RUN_IMAGE" \ + python -W ignore -m unittest discover /testplugin/test/python \ + || exit_code=$? +echo + +exit $exit_code diff --git a/vim-config/plugins/ale/test/script/custom-linting-rules b/vim-config/plugins/ale/test/script/custom-linting-rules new file mode 100755 index 00000000..12dec4c1 --- /dev/null +++ b/vim-config/plugins/ale/test/script/custom-linting-rules @@ -0,0 +1,155 @@ +#!/usr/bin/env bash + +set -e +set -u + +# This Bash script implements custom sanity checks for scripts beyond what +# Vint covers, which are easy to check with regex. + +# A flag for automatically fixing some errors. +FIX_ERRORS=0 +RETURN_CODE=0 + +function print_help() { + echo "Usage: test/script/custom-linting-rules [--fix] [DIRECTORY]" 1>&2 + echo 1>&2 + echo " -h, --help Print this help text" 1>&2 + echo " --fix Automatically fix some errors" 1>&2 + exit 1 +} + +while [ $# -ne 0 ]; do + case $1 in + -h) ;& --help) + print_help + ;; + --fix) + FIX_ERRORS=1 + shift + ;; + --) + shift + break + ;; + -?*) + echo "Invalid argument: $1" 1>&2 + exit 1 + ;; + *) + break + ;; + esac +done + +if [ $# -eq 0 ] || [ -z "$1" ]; then + print_help +fi + +shopt -s globstar + +directories=("$@") + +check_errors() { + regex="$1" + message="$2" + include_arg='' + exclude_arg='' + + if [ $# -gt 2 ]; then + include_arg="--include $3" + fi + + if [ $# -gt 3 ]; then + shift + shift + shift + + while (( "$#" )); do + exclude_arg="$exclude_arg --exclude $1" + shift + done + fi + + for directory in "${directories[@]}"; do + # shellcheck disable=SC2086 + while read -r; do + RETURN_CODE=1 + echo "$REPLY $message" + done < <(grep -H -n "$regex" $include_arg $exclude_arg "$directory"/**/*.vim \ + | grep -v 'no-custom-checks' \ + | grep -o '^[^:]\+:[0-9]\+' \ + | sed 's:^\./::') + done +} + +if (( FIX_ERRORS )); then + for directory in "${directories[@]}"; do + sed -i "s/^\(function.*)\) *$/\1 abort/" "$directory"/**/*.vim + sed -i "s/shellescape(/ale#Escape(/" "$directory"/**/*.vim + sed -i 's/==#/is#/g' "$directory"/**/*.vim + sed -i 's/==?/is?/g' "$directory"/**/*.vim + sed -i 's/!=#/isnot#/g' "$directory"/**/*.vim + sed -i 's/!=?/isnot?/g' "$directory"/**/*.vim + # Improving type checks. + sed -i $'s/\\(==.\\?\\|is\\) type([\'"]\+)/is v:t_string/g' "$directory"/**/*.vim + sed -i 's/\(==.\?\|is\) type([0-9]\+)/is v:t_number/g' "$directory"/**/*.vim + sed -i 's/\(==.\?\|is\) type(\[\])/is v:t_list/g' "$directory"/**/*.vim + sed -i 's/\(==.\?\|is\) type({})/is v:t_dict/g' "$directory"/**/*.vim + sed -i 's/\(==.\?\|is\) type(function([^)]\+))/is v:t_func/g' "$directory"/**/*.vim + sed -i $'s/\\(!=.\\?\\|isnot\\) type([\'"]\+)/isnot v:t_string/g' "$directory"/**/*.vim + sed -i 's/\(!=.\?\|isnot\) type([0-9]\+)/isnot v:t_number/g' "$directory"/**/*.vim + sed -i 's/\(!=.\?\|isnot\) type(\[\])/isnot v:t_list/g' "$directory"/**/*.vim + sed -i 's/\(!=.\?\|isnot\) type({})/isnot v:t_dict/g' "$directory"/**/*.vim + sed -i 's/\(!=.\?\|isnot\) type(function([^)]\+))/isnot v:t_func/g' "$directory"/**/*.vim + done +fi + +# The arguments are: regex, explanation, [filename_filter], [list, of, exclusions] +check_errors \ + '^function.*) *$' \ + 'Function without abort keyword (See :help except-compat)' +check_errors '^function[^!]' 'function without !' +check_errors ' \+$' 'Trailing whitespace' +check_errors '^ * end\?i\? *$' 'Write endif, not en, end, or endi' +check_errors '^ [^ ]' 'Use four spaces, not two spaces' +check_errors $'\t' 'Use four spaces, not tabs' +# This check should prevent people from using a particular inconsistent name. +check_errors 'let g:ale_\w\+_\w\+_args =' 'Name your option g:ale___options instead' +check_errors 'shellescape(' 'Use ale#Escape instead of shellescape' +check_errors 'simplify(' 'Use ale#path#Simplify instead of simplify' +check_errors 'tempname(' 'Use ale#util#Tempname instead of tempname' +check_errors 'getcurpos(' "Use getpos('.') instead of getcurpos() if you don't need curswant, to avoid a bug that changes curswant" +check_errors "expand(['\"]%" "Use expand('#' . a:buffer . '...') instead. You might get a filename for the wrong buffer." +check_errors 'getcwd()' "Do not use getcwd(), as it could run from the wrong buffer. Use expand('#' . a:buffer . ':p:h') instead." +check_errors '==#' "Use 'is#' instead of '==#'. 0 ==# 'foobar' is true" +check_errors '==?' "Use 'is?' instead of '==?'. 0 ==? 'foobar' is true" +check_errors '!=#' "Use 'isnot#' instead of '!=#'. 0 !=# 'foobar' is false" +check_errors '!=?' "Use 'isnot?' instead of '!=?'. 0 !=? 'foobar' is false" +check_errors '^ *:\?echo' "Stray echo line. Use \`execute echo\` if you want to echo something" +check_errors '^ *:\?redir' 'User execute() instead of redir' +# Exclusions for grandfathered-in exceptions +exclusions="clojure/clj_kondo.vim elixir/elixir_ls.vim go/golangci_lint.vim swift/swiftformat.vim" +# shellcheck disable=SC2086 +check_errors $'name.:.*\'[a-z_]*[^a-z_0-9][a-z_0-9]*\',$' 'Use snake_case names for linters' '*/ale_linters/*' $exclusions +# Checks for improving type checks. +check_errors $'\\(==.\\?\\|is\\) type([\'"]\+)' "Use 'is v:t_string' instead" +check_errors '\(==.\?\|is\) type([0-9]\+)' "Use 'is v:t_number' instead" +check_errors '\(==.\?\|is\) type(\[\])' "Use 'is v:t_list' instead" +check_errors '\(==.\?\|is\) type({})' "Use 'is v:t_dict' instead" +check_errors '\(==.\?\|is\) type(function([^)]\+))' "Use 'is v:t_func' instead" +check_errors $'\\(!=.\\?\\|isnot\\) type([\'"]\+)' "Use 'isnot v:t_string' instead" +check_errors '\(!=.\?\|isnot\) type([0-9]\+)' "Use 'isnot v:t_number' instead" +check_errors '\(!=.\?\|isnot\) type(\[\])' "Use 'isnot v:t_list' instead" +check_errors '\(!=.\?\|isnot\) type({})' "Use 'isnot v:t_dict' instead" +check_errors '\(!=.\?\|isnot\) type(function([^)]\+))' "Use 'isnot v:t_func' instead" + +# Run a Python script to find lines that require padding around them. For +# users without Python installed, we'll skip these checks. GitHub Actions will +# run the script. +if command -v python > /dev/null; then + if ! test/script/block-padding-checker "$directory"/**/*.vim; then + RETURN_CODE=1 + fi +fi + +exit $RETURN_CODE diff --git a/vim-config/plugins/ale/test/script/dumb_named_pipe_server.py b/vim-config/plugins/ale/test/script/dumb_named_pipe_server.py new file mode 100644 index 00000000..a77e538c --- /dev/null +++ b/vim-config/plugins/ale/test/script/dumb_named_pipe_server.py @@ -0,0 +1,42 @@ +""" +This Python script creates a named pipe server that does nothing but send its input +back to the client that connects to it. Only one argument must be given, the path +of a named pipe to bind to. +""" +import os +import socket +import sys + + +def main(): + if len(sys.argv) < 2: + sys.exit('You must specify a filepath') + + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + if os.path.exists(sys.argv[1]): + os.remove(sys.argv[1]) + sock.bind(sys.argv[1]) + sock.listen(0) + + pid = os.fork() + + if pid: + print(pid) + sys.exit() + + while True: + connection = sock.accept()[0] + connection.settimeout(5) + + while True: + try: + connection.send(connection.recv(1024)) + except socket.timeout: + break + + connection.close() + + +if __name__ == "__main__": + main() diff --git a/vim-config/plugins/ale/test/script/dumb_tcp_client.py b/vim-config/plugins/ale/test/script/dumb_tcp_client.py new file mode 100644 index 00000000..3a728b02 --- /dev/null +++ b/vim-config/plugins/ale/test/script/dumb_tcp_client.py @@ -0,0 +1,33 @@ +""" +This is just a script for testing that the dumb TCP server actually works +correctly, for verifying that problems with tests are in Vim. Pass the +same port number given to the test server to check that it's working. +""" +import socket +import sys + + +def main(): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + result = sock.connect_ex(('127.0.0.1', int(sys.argv[1]))) + + if result: + sock.close() + sys.exit("Couldn't connect to the socket!") + + data_sent = 'x' * 1024 + + sock.send(data_sent) + data_received = sock.recv(1024) + + if data_sent != data_received: + sock.close() + sys.exit("Data sent didn't match data received.") + + sock.close() + + print("Everything was just fine.") + + +if __name__ == "__main__": + main() diff --git a/vim-config/plugins/ale/test/script/dumb_tcp_server.py b/vim-config/plugins/ale/test/script/dumb_tcp_server.py new file mode 100644 index 00000000..c15db65e --- /dev/null +++ b/vim-config/plugins/ale/test/script/dumb_tcp_server.py @@ -0,0 +1,40 @@ +""" +This Python script creates a TCP server that does nothing but send its input +back to the client that connects to it. Only one argument must be given, a port +to bind to. +""" +import os +import socket +import sys + + +def main(): + if len(sys.argv) < 2 or not sys.argv[1].isdigit(): + sys.exit('You must specify a port number') + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind(('127.0.0.1', int(sys.argv[1]))) + sock.listen(0) + + pid = os.fork() + + if pid: + print(pid) + sys.exit() + + while True: + connection = sock.accept()[0] + connection.settimeout(5) + + while True: + try: + connection.send(connection.recv(1024)) + except socket.timeout: + break + + connection.close() + + +if __name__ == "__main__": + main() diff --git a/vim-config/plugins/ale/test/script/run-vader-tests b/vim-config/plugins/ale/test/script/run-vader-tests new file mode 100755 index 00000000..c8cdfde4 --- /dev/null +++ b/vim-config/plugins/ale/test/script/run-vader-tests @@ -0,0 +1,151 @@ +#!/usr/bin/env bash + +set -e +set -u + +docker_flags=(--rm -v "$PWD:/testplugin" -v "$PWD/test:/home" -w /testplugin "$DOCKER_RUN_IMAGE") +red='\033[0;31m' +green='\033[0;32m' +nc='\033[0m' +verbose=0 +quiet=0 + +while [ $# -ne 0 ]; do + case $1 in + -v) + verbose=1 + shift + ;; + -q) + quiet=1 + shift + ;; + --) + shift + break + ;; + -?*) + echo "Invalid argument: $1" 1>&2 + exit 1 + ;; + *) + break + ;; + esac +done + +vim="$1" +tests="$2" +# This file will be used to track if tests ran or not. +# We can't use a variable, because we need to set a value in a sub-shell. +run_file="$(mktemp -t tests_ran.XXXXXXXX)" + +function filter-vader-output() { + local hit_first_vader_line=0 + # When verbose mode is off, suppress output until Vader starts. + local start_output="$verbose" + local filtered_data='' + + while read -r; do + # Search for the first Vader output line. + # We can try starting tests again if they don't start. + if ((!hit_first_vader_line)); then + if [[ "$REPLY" = *'Starting Vader:'* ]]; then + hit_first_vader_line=1 + fi + fi + + if ((!start_output)); then + if ((hit_first_vader_line)); then + start_output=1 + else + continue + fi + fi + + if ((quiet)); then + if [[ "$REPLY" = *'Starting Vader:'* ]]; then + filtered_data="$REPLY" + elif [[ "$REPLY" = *'Success/Total'* ]]; then + success="$(echo -n "$REPLY" | grep -o '[0-9]\+/' | head -n1 | cut -d/ -f1)" + total="$(echo -n "$REPLY" | grep -o '/[0-9]\+' | head -n1 | cut -d/ -f2)" + + if [ "$success" -lt "$total" ]; then + echo "$filtered_data" + echo "$REPLY" + fi + + filtered_data='' + else + filtered_data="$filtered_data"$'\n'"$REPLY" + fi + else + echo "$REPLY" + fi + done + + # Note that we managed to get the Vader tests started if we did. + if ((hit_first_vader_line)); then + echo 1 > "$run_file" + fi +} + +function color-vader-output() { + while read -r; do + if [[ "$REPLY" = *'[EXECUTE] (X)'* ]]; then + echo -en "$red" + elif [[ "$REPLY" = *'[EXECUTE]'* ]] || [[ "$REPLY" = *'[ GIVEN]'* ]]; then + echo -en "$nc" + fi + + if [[ "$REPLY" = *'Success/Total'* ]]; then + success="$(echo -n "$REPLY" | grep -o '[0-9]\+/' | head -n1 | cut -d/ -f1)" + total="$(echo -n "$REPLY" | grep -o '/[0-9]\+' | head -n1 | cut -d/ -f2)" + + if [ "$success" -lt "$total" ]; then + echo -en "$red" + else + echo -en "$green" + fi + + echo "$REPLY" + echo -en "$nc" + else + echo "$REPLY" + fi + done + + echo -en "$nc" +} + +echo +echo '========================================' +echo "Running tests for $vim" +echo '========================================' +echo + +tries=0 + +while [ "$tries" -lt 5 ]; do + tries=$((tries + 1)) + + exit_code=0 + set -o pipefail + docker run -a stderr -e VADER_OUTPUT_FILE=/dev/stderr "${docker_flags[@]}" \ + "/vim-build/bin/$vim" -u test/vimrc \ + "+Vader! $tests" 2>&1 | filter-vader-output | color-vader-output || exit_code=$? + set +o pipefail + + if [ -s "$run_file" ]; then + break + fi +done + +if [ "$tries" -gt 1 ]; then + echo + echo "Tried to run tests $tries times" +fi + +rm "$run_file" + +exit "$exit_code" diff --git a/vim-config/plugins/ale/test/script/run-vint b/vim-config/plugins/ale/test/script/run-vint new file mode 100755 index 00000000..ce42ad41 --- /dev/null +++ b/vim-config/plugins/ale/test/script/run-vint @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -e +set -u + +exit_code=0 +docker_flags=(--rm -v "$PWD:/testplugin" -v "$PWD/test:/home" -w /testplugin "$DOCKER_RUN_IMAGE") + +echo '========================================' +echo 'Running Vint to lint our code' +echo '========================================' +echo 'Vint warnings/errors follow:' +echo + +set -o pipefail +docker run -a stdout "${docker_flags[@]}" vint -s . || exit_code=$? +set +o pipefail +echo + +exit $exit_code diff --git a/vim-config/plugins/ale/test/sign/test_linting_sets_signs.vader b/vim-config/plugins/ale/test/sign/test_linting_sets_signs.vader new file mode 100644 index 00000000..1624449a --- /dev/null +++ b/vim-config/plugins/ale/test/sign/test_linting_sets_signs.vader @@ -0,0 +1,76 @@ +Given foobar (Some imaginary filetype): + var y = 3+3; + var y = 3 + +Before: + Save g:ale_buffer_info + Save g:ale_echo_cursor + Save g:ale_run_synchronously + Save g:ale_set_highlights + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_set_signs + Save g:ale_command_wrapper + + let g:ale_command_wrapper = '' + let g:ale_buffer_info = {} + let g:ale_run_synchronously = 1 + unlet! g:ale_run_synchronously_callbacks + let g:ale_set_signs = 1 + " Disable features we don't need for these tests. + let g:ale_set_quickfix = 0 + let g:ale_set_loclist = 0 + let g:ale_set_highlights = 0 + let g:ale_echo_cursor = 0 + + call ale#sign#Clear() + + function! TestCallback(buffer, output) + return [ + \ {'lnum': 1, 'text': 'foo', 'type': 'W'}, + \ {'lnum': 2, 'text': 'foo', 'type': 'E'}, + \] + endfunction + + function! CollectSigns() + redir => l:output + if has('nvim-0.4.2') || has('patch-8.1.614') + silent exec 'sign place group=ale' + else + silent exec 'sign place' + endif + redir END + + let l:actual_sign_list = [] + + for l:line in split(l:output, "\n") + let l:match = matchlist(l:line, ale#sign#ParsePattern()) + + if len(l:match) > 0 + call add(l:actual_sign_list, [l:match[1], l:match[3]]) + endif + endfor + + return l:actual_sign_list + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''', + \}) + +After: + delfunction TestCallback + delfunction CollectSigns + + unlet! g:ale_run_synchronously_callbacks + call ale#sign#Clear() + call ale#linter#Reset() + +Execute(The signs should be updated after linting is done): + ALELint + call ale#test#FlushJobs() + + AssertEqual [['1', 'ALEWarningSign'], ['2', 'ALEErrorSign']], CollectSigns() diff --git a/vim-config/plugins/ale/test/sign/test_sign_column_highlighting.vader b/vim-config/plugins/ale/test/sign/test_sign_column_highlighting.vader new file mode 100644 index 00000000..7ea5eb0f --- /dev/null +++ b/vim-config/plugins/ale/test/sign/test_sign_column_highlighting.vader @@ -0,0 +1,68 @@ +Before: + Save g:ale_change_sign_column_color + Save &verbose + + function! ParseHighlight(name) abort + redir => l:output + silent execute 'highlight ' . a:name + redir end + + return substitute(join(split(l:output)[2:]), ' Last set.*', '', '') + endfunction + + function! SetHighlight(name, syntax) abort + let l:match = matchlist(a:syntax, '\vlinks to (.+)$') + + if !empty(l:match) + execute 'highlight link ' . a:name . ' ' . l:match[1] + else + execute 'highlight ' . a:name . ' ' a:syntax + endif + endfunction + + let g:sign_highlight = ParseHighlight('SignColumn') + +After: + Restore + + delfunction ParseHighlight + call SetHighlight('SignColumn', g:sign_highlight) + delfunction SetHighlight + unlet! g:sign_highlight + + call ale#sign#Clear() + +Execute(The SignColumn highlight shouldn't be changed if the option is off): + let g:ale_change_sign_column_color = 0 + let b:sign_highlight = ParseHighlight('SignColumn') + + call ale#sign#SetSigns(bufnr(''), [ + \ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'W', 'text': 'x'}, + \]) + AssertEqual b:sign_highlight, ParseHighlight('SignColumn') + + call ale#sign#SetSigns(bufnr(''), []) + AssertEqual b:sign_highlight, ParseHighlight('SignColumn') + +Execute(The SignColumn highlight should be set and reset): + let g:ale_change_sign_column_color = 1 + + call ale#sign#SetSigns(bufnr(''), [ + \ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'W', 'text': 'x'}, + \]) + AssertEqual 'links to ALESignColumnWithErrors', ParseHighlight('SignColumn') + + call ale#sign#SetSigns(bufnr(''), []) + AssertEqual 'links to ALESignColumnWithoutErrors', ParseHighlight('SignColumn') + +Execute(The SignColumn should be correctly parsed when verbose=1): + set verbose=1 + highlight SignColumn ctermfg=246 ctermbg=7 guifg=#839496 guibg=Grey + + call ale#sign#SetUpDefaultColumnWithoutErrorsHighlight() + + AssertEqual + \ has('nvim') + \ ? 'ctermfg=246 ctermbg=7 guifg=#839496 guibg=Grey' + \ : 'term=standout ctermfg=246 ctermbg=7 guifg=#839496 guibg=Grey', + \ ParseHighlight('ALESignColumnWithoutErrors') diff --git a/vim-config/plugins/ale/test/sign/test_sign_limits.vader b/vim-config/plugins/ale/test/sign/test_sign_limits.vader new file mode 100644 index 00000000..d7a4e2f5 --- /dev/null +++ b/vim-config/plugins/ale/test/sign/test_sign_limits.vader @@ -0,0 +1,57 @@ +Before: + Save g:ale_max_signs + + let g:ale_max_signs = -1 + + function! SetNProblems(sign_count) + let l:loclist = [] + let l:range = range(1, a:sign_count) + call setline(1, l:range) + + for l:index in l:range + call add(l:loclist, { + \ 'bufnr': bufnr(''), + \ 'lnum': l:index, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'a', + \}) + endfor + + call ale#sign#SetSigns(bufnr(''), l:loclist) + + return sort(map(ale#sign#FindCurrentSigns(bufnr(''))[1], 'v:val[0]'), 'n') + endfunction + +After: + Restore + + unlet! b:ale_max_signs + + delfunction SetNProblems + + call ale#sign#Clear() + +Execute(There should be no limit on signs with negative numbers): + AssertEqual range(1, 42), SetNProblems(42) + +Execute(0 signs should be set when the max is 0): + let g:ale_max_signs = 0 + + AssertEqual [], SetNProblems(42) + +Execute(1 signs should be set when the max is 1): + let g:ale_max_signs = 1 + + AssertEqual [1], SetNProblems(42) + +Execute(10 signs should be set when the max is 10): + let g:ale_max_signs = 10 + + " We'll check that we set signs for the first 10 items, not other lines. + AssertEqual range(1, 10), SetNProblems(42) + +Execute(5 signs should be set when the max is 5 for the buffer): + let b:ale_max_signs = 5 + + AssertEqual range(1, 5), SetNProblems(42) diff --git a/vim-config/plugins/ale/test/sign/test_sign_parsing.vader b/vim-config/plugins/ale/test/sign/test_sign_parsing.vader new file mode 100644 index 00000000..c0967f43 --- /dev/null +++ b/vim-config/plugins/ale/test/sign/test_sign_parsing.vader @@ -0,0 +1,88 @@ +Execute (Parsing English signs should work): + if has('nvim-0.4.2') || has('patch-8.1.614') + AssertEqual + \ [0, [[9, 1000001, 'ALEWarningSign']]], + \ ale#sign#ParseSigns([ + \ 'Signs for app.js:', + \ ' line=9 id=1000001 group=ale name=ALEWarningSign', + \ ]) + else + AssertEqual + \ [0, [[9, 1000001, 'ALEWarningSign']]], + \ ale#sign#ParseSigns([ + \ 'Signs for app.js:', + \ ' line=9 id=1000001 name=ALEWarningSign', + \ ]) + endif + +Execute (Parsing Russian signs should work): + if has('nvim-0.4.2') || has('patch-8.1.614') + AssertEqual + \ [0, [[1, 1000001, 'ALEErrorSign']]], + \ ale#sign#ParseSigns([' строка=1 id=1000001 группа=ale имя=ALEErrorSign']) + else + AssertEqual + \ [0, [[1, 1000001, 'ALEErrorSign']]], + \ ale#sign#ParseSigns([' строка=1 id=1000001 имя=ALEErrorSign']) + endif + +Execute (Parsing Japanese signs should work): + if has('nvim-0.4.2') || has('patch-8.1.614') + AssertEqual + \ [0, [[1, 1000001, 'ALEWarningSign']]], + \ ale#sign#ParseSigns([' 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign']) + else + AssertEqual + \ [0, [[1, 1000001, 'ALEWarningSign']]], + \ ale#sign#ParseSigns([' 行=1 識別子=1000001 名前=ALEWarningSign']) + endif + +Execute (Parsing Spanish signs should work): + if has('nvim-0.4.2') || has('patch-8.1.614') + AssertEqual + \ [0, [[12, 1000001, 'ALEWarningSign']]], + \ ale#sign#ParseSigns([' línea=12 id=1000001 grupo=ale nombre=ALEWarningSign']) + else + AssertEqual + \ [0, [[12, 1000001, 'ALEWarningSign']]], + \ ale#sign#ParseSigns([' línea=12 id=1000001 nombre=ALEWarningSign']) + endif + +Execute (Parsing Italian signs should work): + if has('nvim-0.4.2') || has('patch-8.1.614') + AssertEqual + \ [0, [[1, 1000001, 'ALEWarningSign']]], + \ ale#sign#ParseSigns([' riga=1 id=1000001, gruppo=ale nome=ALEWarningSign']) + else + AssertEqual + \ [0, [[1, 1000001, 'ALEWarningSign']]], + \ ale#sign#ParseSigns([' riga=1 id=1000001, nome=ALEWarningSign']) + endif + +Execute (Parsing German signs should work): + if has('nvim-0.4.2') || has('patch-8.1.614') + AssertEqual + \ [0, [[235, 1000001, 'ALEErrorSign']]], + \ ale#sign#ParseSigns([' Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign']) + else + AssertEqual + \ [0, [[235, 1000001, 'ALEErrorSign']]], + \ ale#sign#ParseSigns([' Zeile=235 id=1000001 Name=ALEErrorSign']) + endif + +Execute (The sign parser should indicate if the dummy sign is set): + if has('nvim-0.4.2') || has('patch-8.1.614') + AssertEqual + \ [1, [[1, 1000001, 'ALEErrorSign']]], + \ ale#sign#ParseSigns([ + \ ' строка=1 id=1000001 group=ale имя=ALEErrorSign', + \ ' line=1 id=1000000 group=ale name=ALEDummySign', + \ ]) + else + AssertEqual + \ [1, [[1, 1000001, 'ALEErrorSign']]], + \ ale#sign#ParseSigns([ + \ ' строка=1 id=1000001 имя=ALEErrorSign', + \ ' line=1 id=1000000 name=ALEDummySign', + \ ]) + endif diff --git a/vim-config/plugins/ale/test/sign/test_sign_placement.vader b/vim-config/plugins/ale/test/sign/test_sign_placement.vader new file mode 100644 index 00000000..7b80d83c --- /dev/null +++ b/vim-config/plugins/ale/test/sign/test_sign_placement.vader @@ -0,0 +1,315 @@ +Before: + Save g:ale_buffer_info + Save g:ale_echo_cursor + Save g:ale_run_synchronously + Save g:ale_set_highlights + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_set_signs + Save g:ale_command_wrapper + + let g:ale_command_wrapper = '' + let g:ale_buffer_info = {} + let g:ale_run_synchronously = 1 + let g:ale_set_signs = 1 + " Disable features we don't need for these tests. + let g:ale_set_quickfix = 0 + let g:ale_set_loclist = 0 + let g:ale_set_highlights = 0 + let g:ale_echo_cursor = 0 + + call ale#linter#Reset() + call ale#sign#Clear() + + function! GenerateResults(buffer, output) + return [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'foo', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'W', + \ 'text': 'bar', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'baz', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'use this one', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 2, + \ 'type': 'W', + \ 'text': 'ignore this one', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 1, + \ 'type': 'W', + \ 'text': 'ignore this one', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 2, + \ 'type': 'E', + \ 'text': 'use this one', + \ }, + \] + endfunction + + function! ParseSigns() + redir => l:output + if has('nvim-0.4.2') || has('patch-8.1.614') + silent sign place group=ale + else + silent sign place + endif + redir END + + return map( + \ split(l:output, '\n')[2:], + \ 'matchlist(v:val, ''' . ale#sign#ParsePattern() . ''')[1:3]', + \) + endfunction + + call ale#linter#Define('testft', { + \ 'name': 'x', + \ 'executable': has('win32') ? 'cmd' : 'true', + \ 'command': 'true', + \ 'callback': 'GenerateResults', + \}) + +After: + Restore + + unlet! g:ale_run_synchronously_callbacks + unlet! g:loclist + delfunction GenerateResults + delfunction ParseSigns + call ale#linter#Reset() + call ale#sign#Clear() + +Execute(ale#sign#GetSignName should return the right sign names): + AssertEqual 'ALEErrorSign', ale#sign#GetSignName([{'type': 'E'}]) + AssertEqual 'ALEStyleErrorSign', ale#sign#GetSignName([{'type': 'E', 'sub_type': 'style'}]) + AssertEqual 'ALEWarningSign', ale#sign#GetSignName([{'type': 'W'}]) + AssertEqual 'ALEStyleWarningSign', ale#sign#GetSignName([{'type': 'W', 'sub_type': 'style'}]) + AssertEqual 'ALEInfoSign', ale#sign#GetSignName([{'type': 'I'}]) + AssertEqual 'ALEErrorSign', ale#sign#GetSignName([ + \ {'type': 'E'}, + \ {'type': 'W'}, + \ {'type': 'I'}, + \ {'type': 'E', 'sub_type': 'style'}, + \ {'type': 'W', 'sub_type': 'style'}, + \]) + AssertEqual 'ALEWarningSign', ale#sign#GetSignName([ + \ {'type': 'W'}, + \ {'type': 'I'}, + \ {'type': 'E', 'sub_type': 'style'}, + \ {'type': 'W', 'sub_type': 'style'}, + \]) + AssertEqual 'ALEInfoSign', ale#sign#GetSignName([ + \ {'type': 'I'}, + \ {'type': 'E', 'sub_type': 'style'}, + \ {'type': 'W', 'sub_type': 'style'}, + \]) + AssertEqual 'ALEStyleErrorSign', ale#sign#GetSignName([ + \ {'type': 'E', 'sub_type': 'style'}, + \ {'type': 'W', 'sub_type': 'style'}, + \]) + AssertEqual 'ALEStyleWarningSign', ale#sign#GetSignName([ + \ {'type': 'W', 'sub_type': 'style'}, + \]) + +Given testft(A file with warnings/errors): + foo + bar + baz + fourth line + fifth line + +Execute(The current signs should be set for running a job): + ALELint + call ale#test#FlushJobs() + + AssertEqual + \ [ + \ ['1', '1000001', 'ALEErrorSign'], + \ ['2', '1000002', 'ALEWarningSign'], + \ ['3', '1000003', 'ALEErrorSign'], + \ ['4', '1000004', 'ALEErrorSign'], + \ ['5', '1000005', 'ALEErrorSign'], + \ ], + \ ParseSigns() + +Execute(Loclist items with sign_id values should be kept): + if has('nvim-0.4.2') || has('patch-8.1.614') + exec 'sign place 1000347 group=ale line=3 name=ALEErrorSign buffer=' . bufnr('') + exec 'sign place 1000348 group=ale line=15 name=ALEErrorSign buffer=' . bufnr('') + exec 'sign place 1000349 group=ale line=16 name=ALEWarningSign buffer=' . bufnr('') + else + exec 'sign place 1000347 line=3 name=ALEErrorSign buffer=' . bufnr('') + exec 'sign place 1000348 line=15 name=ALEErrorSign buffer=' . bufnr('') + exec 'sign place 1000349 line=16 name=ALEWarningSign buffer=' . bufnr('') + endif + + let g:loclist = [ + \ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'E', 'text': 'a', 'sign_id': 1000348}, + \ {'bufnr': bufnr(''), 'lnum': 2, 'col': 1, 'type': 'W', 'text': 'b', 'sign_id': 1000349}, + \ {'bufnr': bufnr(''), 'lnum': 3, 'col': 1, 'type': 'E', 'text': 'c', 'sign_id': 1000347}, + \ {'bufnr': bufnr(''), 'lnum': 4, 'col': 1, 'type': 'W', 'text': 'd'}, + \ {'bufnr': bufnr(''), 'lnum': 15, 'col': 2, 'type': 'W', 'text': 'e'}, + \ {'bufnr': bufnr(''), 'lnum': 16, 'col': 2, 'type': 'E', 'text': 'f'}, + \] + + call ale#sign#SetSigns(bufnr(''), g:loclist) + + " Sign IDs from before should be kept, and new signs should use + " IDs that haven't been used yet. + AssertEqual + \ [ + \ {'bufnr': bufnr(''), 'lnum': 3, 'col': 1, 'type': 'E', 'text': 'c', 'sign_id': 1000347}, + \ {'bufnr': bufnr(''), 'lnum': 4, 'col': 1, 'type': 'W', 'text': 'd', 'sign_id': 1000350}, + \ {'bufnr': bufnr(''), 'lnum': 15, 'col': 1, 'type': 'E', 'text': 'a', 'sign_id': 1000348}, + \ {'bufnr': bufnr(''), 'lnum': 15, 'col': 2, 'type': 'W', 'text': 'e', 'sign_id': 1000348}, + \ {'bufnr': bufnr(''), 'lnum': 16, 'col': 1, 'type': 'W', 'text': 'b', 'sign_id': 1000351}, + \ {'bufnr': bufnr(''), 'lnum': 16, 'col': 2, 'type': 'E', 'text': 'f', 'sign_id': 1000351}, + \ ], + \ g:loclist + + " Items should be grouped again. We should see error signs, where there + " were warnings before, and errors where there were errors and where we + " now have new warnings. + AssertEqual + \ [ + \ ['15', '1000348', 'ALEErrorSign'], + \ ['16', '1000351', 'ALEErrorSign'], + \ ['3', '1000347', 'ALEErrorSign'], + \ ['4', '1000350', 'ALEWarningSign'], + \ ], + \ sort(ParseSigns()) + +Execute(Items for other buffers should be ignored): + let g:loclist = [ + \ {'bufnr': bufnr('') - 1, 'lnum': 1, 'col': 1, 'type': 'E', 'text': 'a'}, + \ {'bufnr': bufnr('') - 1, 'lnum': 2, 'col': 1, 'type': 'E', 'text': 'a', 'sign_id': 1000347}, + \ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'E', 'text': 'a'}, + \ {'bufnr': bufnr(''), 'lnum': 2, 'col': 1, 'type': 'W', 'text': 'b'}, + \ {'bufnr': bufnr(''), 'lnum': 3, 'col': 1, 'type': 'E', 'text': 'c'}, + \ {'bufnr': bufnr(''), 'lnum': 4, 'col': 1, 'type': 'W', 'text': 'd'}, + \ {'bufnr': bufnr(''), 'lnum': 15, 'col': 2, 'type': 'W', 'text': 'e'}, + \ {'bufnr': bufnr(''), 'lnum': 16, 'col': 2, 'type': 'E', 'text': 'f'}, + \ {'bufnr': bufnr('') + 1, 'lnum': 1, 'col': 1, 'type': 'E', 'text': 'a'}, + \] + + call ale#sign#SetSigns(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ ['1', '1000001', 'ALEErrorSign'], + \ ['15', '1000005', 'ALEWarningSign'], + \ ['16', '1000006', 'ALEErrorSign'], + \ ['2', '1000002', 'ALEWarningSign'], + \ ['3', '1000003', 'ALEErrorSign'], + \ ['4', '1000004', 'ALEWarningSign'], + \ ], + \ sort(ParseSigns()) + +Execute(Signs should be downgraded correctly): + call ale#sign#SetSigns(bufnr(''), [ + \ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'E', 'text': 'x'}, + \ {'bufnr': bufnr(''), 'lnum': 2, 'col': 1, 'type': 'W', 'text': 'x'}, + \]) + + AssertEqual + \ [ + \ ['1', '1000001', 'ALEErrorSign'], + \ ['2', '1000002', 'ALEWarningSign'], + \ ], + \ sort(ParseSigns()) + + call ale#sign#SetSigns(bufnr(''), [ + \ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'W', 'text': 'x'}, + \ {'bufnr': bufnr(''), 'lnum': 2, 'col': 1, 'type': 'I', 'text': 'x'}, + \]) + + AssertEqual + \ [ + \ ['1', '1000003', 'ALEWarningSign'], + \ ['2', '1000004', 'ALEInfoSign'], + \ ], + \ sort(ParseSigns()) + +Execute(Signs should be upgraded correctly): + call ale#sign#SetSigns(bufnr(''), [ + \ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'W', 'text': 'x'}, + \ {'bufnr': bufnr(''), 'lnum': 2, 'col': 1, 'type': 'I', 'text': 'x'}, + \]) + + AssertEqual + \ [ + \ ['1', '1000001', 'ALEWarningSign'], + \ ['2', '1000002', 'ALEInfoSign'], + \ ], + \ sort(ParseSigns()) + + call ale#sign#SetSigns(bufnr(''), [ + \ {'bufnr': bufnr(''), 'lnum': 1, 'col': 1, 'type': 'E', 'text': 'x'}, + \ {'bufnr': bufnr(''), 'lnum': 2, 'col': 1, 'type': 'W', 'text': 'x'}, + \]) + + AssertEqual + \ [ + \ ['1', '1000003', 'ALEErrorSign'], + \ ['2', '1000004', 'ALEWarningSign'], + \ ], + \ sort(ParseSigns()) + +Execute(It should be possible to clear signs with empty lists): + let g:loclist = [ + \ {'bufnr': bufnr(''), 'lnum': 16, 'col': 2, 'type': 'E', 'text': 'f'}, + \] + + call ale#sign#SetSigns(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ ['16', '1000001', 'ALEErrorSign'], + \ ], + \ sort(ParseSigns()) + + call ale#sign#SetSigns(bufnr(''), []) + + AssertEqual [], ParseSigns() + +Execute(No exceptions should be thrown when setting signs for invalid buffers): + call ale#sign#SetSigns(123456789, [{'lnum': 15, 'col': 2, 'type': 'W', 'text': 'e'}]) + +Execute(Signs should be removed when lines have multiple sign IDs on them): + " We can fail to remove signs if there are multiple signs on one line, + " say after deleting lines in Vim, etc. + if has('nvim-0.4.2') || has('patch-8.1.614') + exec 'sign place 1000347 group=ale line=3 name=ALEErrorSign buffer=' . bufnr('') + exec 'sign place 1000348 group=ale line=3 name=ALEWarningSign buffer=' . bufnr('') + exec 'sign place 1000349 group=ale line=10 name=ALEErrorSign buffer=' . bufnr('') + exec 'sign place 1000350 group=ale line=10 name=ALEWarningSign buffer=' . bufnr('') + else + exec 'sign place 1000347 line=3 name=ALEErrorSign buffer=' . bufnr('') + exec 'sign place 1000348 line=3 name=ALEWarningSign buffer=' . bufnr('') + exec 'sign place 1000349 line=10 name=ALEErrorSign buffer=' . bufnr('') + exec 'sign place 1000350 line=10 name=ALEWarningSign buffer=' . bufnr('') + endif + + call ale#sign#SetSigns(bufnr(''), []) + AssertEqual [], ParseSigns() diff --git a/vim-config/plugins/ale/test/smoke_test.vader b/vim-config/plugins/ale/test/smoke_test.vader new file mode 100644 index 00000000..58206049 --- /dev/null +++ b/vim-config/plugins/ale/test/smoke_test.vader @@ -0,0 +1,181 @@ +Before: + Save g:ale_enabled + Save g:ale_set_lists_synchronously + Save g:ale_buffer_info + Save &shell + + let g:ale_enabled = 1 + let g:ale_buffer_info = {} + let g:ale_set_lists_synchronously = 1 + + function! TestCallback(buffer, output) + " Windows adds extra spaces to the text from echo. + return [{ + \ 'lnum': 2, + \ 'col': 3, + \ 'text': substitute(a:output[0], ' *$', '', ''), + \}] + endfunction + function! TestCallback2(buffer, output) + return [{ + \ 'lnum': 3, + \ 'col': 4, + \ 'text': substitute(a:output[0], ' *$', '', ''), + \}] + endfunction + + " Running the command in another subshell seems to help here. + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''', + \}) + +After: + Restore + + unlet! g:i + unlet! g:results + unlet! g:expected_results + + delfunction TestCallback + delfunction TestCallback2 + call ale#engine#Cleanup(bufnr('')) + call ale#linter#Reset() + +Given foobar (Some imaginary filetype): + foo + bar + baz + +Execute(Linters should run with the default options): + AssertEqual 'foobar', &filetype + + let g:expected_results = [{ + \ 'bufnr': bufnr('%'), + \ 'lnum': 2, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'foo bar', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }] + + " Try the test a few times over in NeoVim 0.3 or Windows or Vim 8.2, + " where tests fail randomly. + for g:i in range(has('nvim-0.3') || has('win32') || has('patch-8.2.2401') ? 5 : 1) + call ale#Queue(0, '') + call ale#test#WaitForJobs(2000) + + let g:results = ale#test#GetLoclistWithoutModule() + + if g:results == g:expected_results + break + endif + endfor + + AssertEqual g:expected_results, g:results + +Execute(Linters should run in PowerShell too): + if has('win32') + set shell=powershell + + AssertEqual 'foobar', &filetype + + " Replace the callback to handle two lines. + function! TestCallback(buffer, output) + " Windows adds extra spaces to the text from echo. + return [ + \ { + \ 'lnum': 1, + \ 'col': 3, + \ 'text': substitute(a:output[0], ' *$', '', ''), + \ }, + \ { + \ 'lnum': 2, + \ 'col': 3, + \ 'text': substitute(a:output[1], ' *$', '', ''), + \ }, + \] + endfunction + + " Recreate the command string to use &&, which PowerShell does not support. + call ale#linter#Reset() + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': 'cmd', + \ 'command': 'echo foo && echo bar', + \}) + + call ale#Queue(0, '') + call ale#test#WaitForJobs(4000) + + AssertEqual [ + \ { + \ 'bufnr': bufnr('%'), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'foo', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }, + \ { + \ 'bufnr': bufnr('%'), + \ 'lnum': 2, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'bar', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }, + \], ale#test#GetLoclistWithoutModule() + endif + +Execute(Previous errors should be removed when linters change): + call ale#Queue(0, '') + call ale#test#WaitForJobs(2000) + + call ale#linter#Reset() + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter2', + \ 'callback': 'TestCallback2', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': has('win32') ? 'echo baz boz' : '/bin/sh -c ''echo baz boz''', + \}) + + let g:expected_results = [{ + \ 'bufnr': bufnr('%'), + \ 'lnum': 3, + \ 'vcol': 0, + \ 'col': 4, + \ 'text': 'baz boz', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \}] + + " Try the test a few times over in NeoVim 0.3 or VIm 8.2 or Windows, + " where tests fail randomly. + for g:i in range(has('nvim-0.3') || has('win32') || has('patch-8.2.2401') ? 5 : 1) + call ale#Queue(0, '') + call ale#test#WaitForJobs(2000) + + let g:results = ale#test#GetLoclistWithoutModule() + + if g:results == g:expected_results + break + endif + endfor + + AssertEqual g:expected_results, g:results diff --git a/vim-config/plugins/ale/test/test-files/.circleci/config.yml b/vim-config/plugins/ale/test/test-files/.circleci/config.yml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/.gitignore b/vim-config/plugins/ale/test/test-files/.gitignore new file mode 100644 index 00000000..7d6563e0 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/.gitignore @@ -0,0 +1,2 @@ +# Don't ignore hidden files for this directory +!.* diff --git a/vim-config/plugins/ale/test/test-files/ada/testfile.adb b/vim-config/plugins/ale/test/test-files/ada/testfile.adb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/alex/node-modules-2/node_modules/alex/cli.js b/vim-config/plugins/ale/test/test-files/alex/node-modules-2/node_modules/alex/cli.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/alex/node-modules/node_modules/.bin/alex b/vim-config/plugins/ale/test/test-files/alex/node-modules/node_modules/.bin/alex new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/angular/node_modules/@angular/language-server/bin/ngserver b/vim-config/plugins/ale/test/test-files/angular/node_modules/@angular/language-server/bin/ngserver new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/angular/node_modules/@angular/language-service/dummy b/vim-config/plugins/ale/test/test-files/angular/node_modules/@angular/language-service/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ant/ant-project/build.xml b/vim-config/plugins/ale/test/test-files/ant/ant-project/build.xml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ant/bin/ant b/vim-config/plugins/ale/test/test-files/ant/bin/ant new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ant/bin/ant.exe b/vim-config/plugins/ale/test/test-files/ant/bin/ant.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/bazel/BUILD b/vim-config/plugins/ale/test/test-files/bazel/BUILD new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/bazel/WORKSPACE b/vim-config/plugins/ale/test/test-files/bazel/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/bazel/defs.bzl b/vim-config/plugins/ale/test/test-files/bazel/defs.bzl new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/bib/dummy.bib b/vim-config/plugins/ale/test/test-files/bib/dummy.bib new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/build_compile_commands_project/build/bad_folder_to_test_priority b/vim-config/plugins/ale/test/test-files/c/build_compile_commands_project/build/bad_folder_to_test_priority new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/build_compile_commands_project/build/compile_commands.json b/vim-config/plugins/ale/test/test-files/c/build_compile_commands_project/build/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/configure_project/Makefile b/vim-config/plugins/ale/test/test-files/c/configure_project/Makefile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/configure_project/configure b/vim-config/plugins/ale/test/test-files/c/configure_project/configure new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/configure_project/include/test.h b/vim-config/plugins/ale/test/test-files/c/configure_project/include/test.h new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/configure_project/subdir/Makefile b/vim-config/plugins/ale/test/test-files/c/configure_project/subdir/Makefile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/dummy.c b/vim-config/plugins/ale/test/test-files/c/dummy.c new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/git_and_nested_makefiles/include/test.h b/vim-config/plugins/ale/test/test-files/c/git_and_nested_makefiles/include/test.h new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/git_and_nested_makefiles/src/Makefile b/vim-config/plugins/ale/test/test-files/c/git_and_nested_makefiles/src/Makefile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/gnumakefile_project/GNUmakefile b/vim-config/plugins/ale/test/test-files/c/gnumakefile_project/GNUmakefile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/gnumakefile_project/file.c b/vim-config/plugins/ale/test/test-files/c/gnumakefile_project/file.c new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/h_file_project/Makefile b/vim-config/plugins/ale/test/test-files/c/h_file_project/Makefile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/h_file_project/subdir/dummy b/vim-config/plugins/ale/test/test-files/c/h_file_project/subdir/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/h_file_project/test.h b/vim-config/plugins/ale/test/test-files/c/h_file_project/test.h new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/hpp_file_project/Makefile b/vim-config/plugins/ale/test/test-files/c/hpp_file_project/Makefile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/hpp_file_project/subdir/dummy b/vim-config/plugins/ale/test/test-files/c/hpp_file_project/subdir/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/hpp_file_project/test.hpp b/vim-config/plugins/ale/test/test-files/c/hpp_file_project/test.hpp new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/json_project/build/compile_commands.json b/vim-config/plugins/ale/test/test-files/c/json_project/build/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/json_project/include/test.h b/vim-config/plugins/ale/test/test-files/c/json_project/include/test.h new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/json_project/subdir/dummy b/vim-config/plugins/ale/test/test-files/c/json_project/subdir/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/makefile_project/Makefile b/vim-config/plugins/ale/test/test-files/c/makefile_project/Makefile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/makefile_project/_astylerc b/vim-config/plugins/ale/test/test-files/c/makefile_project/_astylerc new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/makefile_project/args b/vim-config/plugins/ale/test/test-files/c/makefile_project/args new file mode 100644 index 00000000..ccaf82ad --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/c/makefile_project/args @@ -0,0 +1,3 @@ +foolib.a +-DARGS1 +@subdir/args diff --git a/vim-config/plugins/ale/test/test-files/c/makefile_project/include/test.h b/vim-config/plugins/ale/test/test-files/c/makefile_project/include/test.h new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/args b/vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/args new file mode 100644 index 00000000..3fe9c3fe --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/args @@ -0,0 +1 @@ +-DARGS2 diff --git a/vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/dummy b/vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/file.c b/vim-config/plugins/ale/test/test-files/c/makefile_project/subdir/file.c new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cargo/Cargo.toml b/vim-config/plugins/ale/test/test-files/cargo/Cargo.toml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cargo/workspace_paths/Cargo.toml b/vim-config/plugins/ale/test/test-files/cargo/workspace_paths/Cargo.toml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cargo/workspace_paths/subpath/Cargo.toml b/vim-config/plugins/ale/test/test-files/cargo/workspace_paths/subpath/Cargo.toml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ccls/with_build_dir/unusual_build_dir_name/compile_commands.json b/vim-config/plugins/ale/test/test-files/ccls/with_build_dir/unusual_build_dir_name/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ccls/with_ccls-root/.ccls-root b/vim-config/plugins/ale/test/test-files/ccls/with_ccls-root/.ccls-root new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ccls/with_ccls/.ccls b/vim-config/plugins/ale/test/test-files/ccls/with_ccls/.ccls new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ccls/with_compile_commands_json/compile_commands.json b/vim-config/plugins/ale/test/test-files/ccls/with_compile_commands_json/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/checkstyle/other_config.xml b/vim-config/plugins/ale/test/test-files/checkstyle/other_config.xml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/clangd/with_build_dir/unusual_build_dir_name/compile_commands.json b/vim-config/plugins/ale/test/test-files/clangd/with_build_dir/unusual_build_dir_name/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/clangd/with_compile_commands/compile_commands.json b/vim-config/plugins/ale/test/test-files/clangd/with_compile_commands/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/clangformat/with_clangformat/.clang-format b/vim-config/plugins/ale/test/test-files/clangformat/with_clangformat/.clang-format new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cpp/.astylerc b/vim-config/plugins/ale/test/test-files/cpp/.astylerc new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cpp/dummy.cpp b/vim-config/plugins/ale/test/test-files/cpp/dummy.cpp new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cppcheck/one/compile_commands.json b/vim-config/plugins/ale/test/test-files/cppcheck/one/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cppcheck/one/two/three/file.c b/vim-config/plugins/ale/test/test-files/cppcheck/one/two/three/file.c new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cppcheck/one/two/three/file.cpp b/vim-config/plugins/ale/test/test-files/cppcheck/one/two/three/file.cpp new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cppcheck/with_build_dir/build/compile_commands.json b/vim-config/plugins/ale/test/test-files/cppcheck/with_build_dir/build/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cquery/build/compile_commands.json b/vim-config/plugins/ale/test/test-files/cquery/build/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cquery/with_cquery/.cquery b/vim-config/plugins/ale/test/test-files/cquery/with_cquery/.cquery new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/csslint/other-app/testfile.css b/vim-config/plugins/ale/test/test-files/csslint/other-app/testfile.css new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/csslint/some-app/.csslintrc b/vim-config/plugins/ale/test/test-files/csslint/some-app/.csslintrc new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/csslint/some-app/subdir/testfile.css b/vim-config/plugins/ale/test/test-files/csslint/some-app/subdir/testfile.css new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cucumber/features/cuke.feature b/vim-config/plugins/ale/test/test-files/cucumber/features/cuke.feature new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/cucumber/features/step_definitions/base_steps.rb b/vim-config/plugins/ale/test/test-files/cucumber/features/step_definitions/base_steps.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/d/test.d b/vim-config/plugins/ale/test/test-files/d/test.d new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/dart/.packages b/vim-config/plugins/ale/test/test-files/dart/.packages new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/dart/testfile.dart b/vim-config/plugins/ale/test/test-files/dart/testfile.dart new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elixir/mix_project/lib/app.ex b/vim-config/plugins/ale/test/test-files/elixir/mix_project/lib/app.ex new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elixir/mix_project/mix.exs b/vim-config/plugins/ale/test/test-files/elixir/mix_project/mix.exs new file mode 100644 index 00000000..419685ae --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/elixir/mix_project/mix.exs @@ -0,0 +1,3 @@ +defmodule Test.MixProject do + # fake mix project file +end diff --git a/vim-config/plugins/ale/test/test-files/elixir/testfile.ex b/vim-config/plugins/ale/test/test-files/elixir/testfile.ex new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app1/lib/app.ex b/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app1/lib/app.ex new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app1/mix.exs b/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app1/mix.exs new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app2/lib/app.ex b/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app2/lib/app.ex new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app2/mix.exs b/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/apps/app2/mix.exs new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/mix.exs b/vim-config/plugins/ale/test/test-files/elixir/umbrella_project/mix.exs new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/newapp-notests/elm.json b/vim-config/plugins/ale/test/test-files/elm/newapp-notests/elm.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/newapp-notests/node_modules/.bin/elm b/vim-config/plugins/ale/test/test-files/elm/newapp-notests/node_modules/.bin/elm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/newapp-notests/tests/TestMain.elm b/vim-config/plugins/ale/test/test-files/elm/newapp-notests/tests/TestMain.elm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/newapp/elm.json b/vim-config/plugins/ale/test/test-files/elm/newapp/elm.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/newapp/node_modules/.bin/elm b/vim-config/plugins/ale/test/test-files/elm/newapp/node_modules/.bin/elm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/newapp/node_modules/.bin/elm-test b/vim-config/plugins/ale/test/test-files/elm/newapp/node_modules/.bin/elm-test new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/newapp/src/Main.elm b/vim-config/plugins/ale/test/test-files/elm/newapp/src/Main.elm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/newapp/tests/TestSuite.elm b/vim-config/plugins/ale/test/test-files/elm/newapp/tests/TestSuite.elm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/node_modules/.bin/elm-format b/vim-config/plugins/ale/test/test-files/elm/node_modules/.bin/elm-format new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/oldapp/elm-package.json b/vim-config/plugins/ale/test/test-files/elm/oldapp/elm-package.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/oldapp/node_modules/.bin/elm b/vim-config/plugins/ale/test/test-files/elm/oldapp/node_modules/.bin/elm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/oldapp/node_modules/.bin/elm-test b/vim-config/plugins/ale/test/test-files/elm/oldapp/node_modules/.bin/elm-test new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/oldapp/src/Main.elm b/vim-config/plugins/ale/test/test-files/elm/oldapp/src/Main.elm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/oldapp/tests/TestSuite.elm b/vim-config/plugins/ale/test/test-files/elm/oldapp/tests/TestSuite.elm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/elm/src/subdir/testfile.elm b/vim-config/plugins/ale/test/test-files/elm/src/subdir/testfile.elm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eruby/dummy.html.erb b/vim-config/plugins/ale/test/test-files/eruby/dummy.html.erb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/app-with-eslint-d/node_modules/.bin/eslint_d b/vim-config/plugins/ale/test/test-files/eslint/app-with-eslint-d/node_modules/.bin/eslint_d new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/node_modules/.bin/eslint b/vim-config/plugins/ale/test/test-files/eslint/node_modules/.bin/eslint new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/other-app/subdir/testfile.js b/vim-config/plugins/ale/test/test-files/eslint/other-app/subdir/testfile.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/package.json b/vim-config/plugins/ale/test/test-files/eslint/package.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/.eslintrc.js b/vim-config/plugins/ale/test/test-files/eslint/react-app/.eslintrc.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/eslint/bin/eslint.js b/vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/eslint/bin/eslint.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/standard/bin/cmd.js b/vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/standard/bin/cmd.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/stylelint/bin/stylelint.js b/vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/stylelint/bin/stylelint.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/xo/cli.js b/vim-config/plugins/ale/test/test-files/eslint/react-app/node_modules/xo/cli.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir-with-config/.eslintrc b/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir-with-config/.eslintrc new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir-with-package-json/node_modules/.gitkeep b/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir-with-package-json/node_modules/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir-with-package-json/package.json b/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir-with-package-json/package.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir/testfile.css b/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir/testfile.css new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir/testfile.js b/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir/testfile.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir/testfile.ts b/vim-config/plugins/ale/test/test-files/eslint/react-app/subdir/testfile.ts new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/yarn2-app/.yarn/sdks/eslint/bin/eslint.js b/vim-config/plugins/ale/test/test-files/eslint/yarn2-app/.yarn/sdks/eslint/bin/eslint.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/eslint/yarn2-app/subdir/testfile.js b/vim-config/plugins/ale/test/test-files/eslint/yarn2-app/subdir/testfile.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/fecs/fecs b/vim-config/plugins/ale/test/test-files/fecs/fecs new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/fecs/fecs.exe b/vim-config/plugins/ale/test/test-files/fecs/fecs.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/fish/testfile.fish b/vim-config/plugins/ale/test/test-files/fish/testfile.fish new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/flow/a/.flowconfig b/vim-config/plugins/ale/test/test-files/flow/a/.flowconfig new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/flow/a/sub/dummy b/vim-config/plugins/ale/test/test-files/flow/a/sub/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/flow/b/sub/dummy b/vim-config/plugins/ale/test/test-files/flow/b/sub/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/fortls-project/.fortls b/vim-config/plugins/ale/test/test-files/fortls-project/.fortls new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/fortls-project/.fortls @@ -0,0 +1,2 @@ +{ +} diff --git a/vim-config/plugins/ale/test/test-files/go/go.mod b/vim-config/plugins/ale/test/test-files/go/go.mod new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/go/go.mod @@ -0,0 +1 @@ + diff --git a/vim-config/plugins/ale/test/test-files/go/go1/prj1/file.go b/vim-config/plugins/ale/test/test-files/go/go1/prj1/file.go new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/go/go2/prj2/file.go b/vim-config/plugins/ale/test/test-files/go/go2/prj2/file.go new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/go/gopath/bin/gopls b/vim-config/plugins/ale/test/test-files/go/gopath/bin/gopls new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/go/gopath/bin/staticcheck b/vim-config/plugins/ale/test/test-files/go/gopath/bin/staticcheck new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/go/testfile.go b/vim-config/plugins/ale/test/test-files/go/testfile.go new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/go/testfile2.go b/vim-config/plugins/ale/test/test-files/go/testfile2.go new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/build-gradle-project/build.gradle b/vim-config/plugins/ale/test/test-files/gradle/build-gradle-project/build.gradle new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/build-gradle-project/src/main/kotlin/dummy.kt b/vim-config/plugins/ale/test/test-files/gradle/build-gradle-project/src/main/kotlin/dummy.kt new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/gradle b/vim-config/plugins/ale/test/test-files/gradle/gradle new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/non-gradle-project/src/main/kotlin/dummy.kt b/vim-config/plugins/ale/test/test-files/gradle/non-gradle-project/src/main/kotlin/dummy.kt new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/settings-gradle-project/settings.gradle b/vim-config/plugins/ale/test/test-files/gradle/settings-gradle-project/settings.gradle new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/settings-gradle-project/src/main/kotlin/dummy.kt b/vim-config/plugins/ale/test/test-files/gradle/settings-gradle-project/src/main/kotlin/dummy.kt new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/unwrapped-project/build.gradle b/vim-config/plugins/ale/test/test-files/gradle/unwrapped-project/build.gradle new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/unwrapped-project/settings.gradle b/vim-config/plugins/ale/test/test-files/gradle/unwrapped-project/settings.gradle new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/unwrapped-project/src/main/kotlin/dummy.kt b/vim-config/plugins/ale/test/test-files/gradle/unwrapped-project/src/main/kotlin/dummy.kt new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/wrapped-project/build.gradle b/vim-config/plugins/ale/test/test-files/gradle/wrapped-project/build.gradle new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/wrapped-project/gradlew b/vim-config/plugins/ale/test/test-files/gradle/wrapped-project/gradlew new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/wrapped-project/settings.gradle b/vim-config/plugins/ale/test/test-files/gradle/wrapped-project/settings.gradle new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/gradle/wrapped-project/src/main/kotlin/dummy.kt b/vim-config/plugins/ale/test/test-files/gradle/wrapped-project/src/main/kotlin/dummy.kt new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-and-rubocop/.haml-lint.yml b/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-and-rubocop/.haml-lint.yml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-and-rubocop/.rubocop.yml b/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-and-rubocop/.rubocop.yml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-and-rubocop/subdir/file.haml b/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-and-rubocop/subdir/file.haml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-yml/.haml-lint.yml b/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-yml/.haml-lint.yml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-yml/subdir/file.haml b/vim-config/plugins/ale/test/test-files/hamllint/haml-lint-yml/subdir/file.haml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hamllint/rubocop-yml/.rubocop.yml b/vim-config/plugins/ale/test/test-files/hamllint/rubocop-yml/.rubocop.yml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hamllint/rubocop-yml/subdir/file.haml b/vim-config/plugins/ale/test/test-files/hamllint/rubocop-yml/subdir/file.haml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hdl_server/foo.vhd b/vim-config/plugins/ale/test/test-files/hdl_server/foo.vhd new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hdl_server/with_config_file/.hdl_checker.config b/vim-config/plugins/ale/test/test-files/hdl_server/with_config_file/.hdl_checker.config new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hdl_server/with_config_file/_hdl_checker.config b/vim-config/plugins/ale/test/test-files/hdl_server/with_config_file/_hdl_checker.config new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hdl_server/with_config_file/foo.vhd b/vim-config/plugins/ale/test/test-files/hdl_server/with_config_file/foo.vhd new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/hdl_server/with_git/files/foo.vhd b/vim-config/plugins/ale/test/test-files/hdl_server/with_git/files/foo.vhd new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/hdl_server/with_git/files/foo.vhd @@ -0,0 +1 @@ + diff --git a/vim-config/plugins/ale/test/test-files/html_beautify/html-beautify b/vim-config/plugins/ale/test/test-files/html_beautify/html-beautify new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/html_beautify/test.html b/vim-config/plugins/ale/test/test-files/html_beautify/test.html new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/htmlhint/node_modules/.bin/htmlhint b/vim-config/plugins/ale/test/test-files/htmlhint/node_modules/.bin/htmlhint new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/htmlhint/with_config/.htmlhintrc b/vim-config/plugins/ale/test/test-files/htmlhint/with_config/.htmlhintrc new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ink/story/main.ink b/vim-config/plugins/ale/test/test-files/ink/story/main.ink new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/inko/test.inko b/vim-config/plugins/ale/test/test-files/inko/test.inko new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/inko/tests/test/test_foo.inko b/vim-config/plugins/ale/test/test-files/inko/tests/test/test_foo.inko new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/java/no_main/src/test/java/com/something/dummy b/vim-config/plugins/ale/test/test-files/java/no_main/src/test/java/com/something/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/java/with_jaxb/src/main/java/com/something/dummy b/vim-config/plugins/ale/test/test-files/java/with_jaxb/src/main/java/com/something/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/java/with_jaxb/src/main/jaxb/com/something/dummy b/vim-config/plugins/ale/test/test-files/java/with_jaxb/src/main/jaxb/com/something/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/java/with_main/build/gen/main/java/com/something/dummy b/vim-config/plugins/ale/test/test-files/java/with_main/build/gen/main/java/com/something/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/java/with_main/build/gen2/main/java/com/something/dummy b/vim-config/plugins/ale/test/test-files/java/with_main/build/gen2/main/java/com/something/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/java/with_main/src/main/java/com/something/dummy b/vim-config/plugins/ale/test/test-files/java/with_main/src/main/java/com/something/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/java/with_main/src/test/java/com/something/dummy b/vim-config/plugins/ale/test/test-files/java/with_main/src/test/java/com/something/dummy new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/javascript/test.js b/vim-config/plugins/ale/test/test-files/javascript/test.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/javascript_deno/custom_import_map.json b/vim-config/plugins/ale/test/test-files/javascript_deno/custom_import_map.json new file mode 100644 index 00000000..9f5a19a1 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/javascript_deno/custom_import_map.json @@ -0,0 +1,3 @@ +{ + "imports": {} +} diff --git a/vim-config/plugins/ale/test/test-files/javascript_deno/import_map.json b/vim-config/plugins/ale/test/test-files/javascript_deno/import_map.json new file mode 100644 index 00000000..9f5a19a1 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/javascript_deno/import_map.json @@ -0,0 +1,3 @@ +{ + "imports": {} +} diff --git a/vim-config/plugins/ale/test/test-files/javascript_deno/main.js b/vim-config/plugins/ale/test/test-files/javascript_deno/main.js new file mode 100644 index 00000000..accefceb --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/javascript_deno/main.js @@ -0,0 +1 @@ +console.log("Hello World"); diff --git a/vim-config/plugins/ale/test/test-files/javascript_deno/tsconfig.json b/vim-config/plugins/ale/test/test-files/javascript_deno/tsconfig.json new file mode 100644 index 00000000..152b034e --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/javascript_deno/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "allowJs": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "isolatedModules": true, + "jsx": "react", + "lib": ["deno.window"], + "module": "esnext", + "strict": true, + "target": "esnext", + "useDefineForClassFields": true + }, + "includes": ["main.js"] +} diff --git a/vim-config/plugins/ale/test/test-files/json/testfile.json b/vim-config/plugins/ale/test/test-files/json/testfile.json new file mode 100644 index 00000000..fe317ebb --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/json/testfile.json @@ -0,0 +1 @@ +{"answer":42} diff --git a/vim-config/plugins/ale/test/test-files/jsonlint/app-without-jsonlint/src/app.json b/vim-config/plugins/ale/test/test-files/jsonlint/app-without-jsonlint/src/app.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/jsonlint/app/node_modules/.bin/jsonlint b/vim-config/plugins/ale/test/test-files/jsonlint/app/node_modules/.bin/jsonlint new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/jsonlint/app/src/app.json b/vim-config/plugins/ale/test/test-files/jsonlint/app/src/app.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/jsonlint/node_modules/jsonlint/lib/cli.js b/vim-config/plugins/ale/test/test-files/jsonlint/node_modules/jsonlint/lib/cli.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/julia/REQUIRE b/vim-config/plugins/ale/test/test-files/julia/REQUIRE new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/julia/test.jl b/vim-config/plugins/ale/test/test-files/julia/test.jl new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/kotlin/testfile.kt b/vim-config/plugins/ale/test/test-files/kotlin/testfile.kt new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/lessc/node_modules/.bin/lessc b/vim-config/plugins/ale/test/test-files/lessc/node_modules/.bin/lessc new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/long-line/setup.cfg b/vim-config/plugins/ale/test/test-files/long-line/setup.cfg new file mode 100644 index 00000000..43d7a3a1 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/long-line/setup.cfg @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 90 diff --git a/vim-config/plugins/ale/test/test-files/lua/testfile.lua b/vim-config/plugins/ale/test/test-files/lua/testfile.lua new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/markdown/testfile.md b/vim-config/plugins/ale/test/test-files/markdown/testfile.md new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/mvnw b/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/mvnw new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/mvnw.cmd b/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/mvnw.cmd new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/pom.xml b/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/pom.xml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/pom.xml @@ -0,0 +1 @@ + diff --git a/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/src/main/java/dummy1.java b/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module1/src/main/java/dummy1.java new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module2/pom.xml b/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module2/pom.xml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module2/pom.xml @@ -0,0 +1 @@ + diff --git a/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module2/src/main/java/dummy2.java b/vim-config/plugins/ale/test/test-files/maven/maven-java-project/module2/src/main/java/dummy2.java new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/maven/maven-kotlin-project/pom.xml b/vim-config/plugins/ale/test/test-files/maven/maven-kotlin-project/pom.xml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/maven/maven-kotlin-project/pom.xml @@ -0,0 +1 @@ + diff --git a/vim-config/plugins/ale/test/test-files/maven/maven-kotlin-project/src/main/kotlin/dummy.kt b/vim-config/plugins/ale/test/test-files/maven/maven-kotlin-project/src/main/kotlin/dummy.kt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/maven/maven-kotlin-project/src/main/kotlin/dummy.kt @@ -0,0 +1 @@ + diff --git a/vim-config/plugins/ale/test/test-files/maven/mvn b/vim-config/plugins/ale/test/test-files/maven/mvn new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/maven/non-maven-project/src/main/java/dummy.java b/vim-config/plugins/ale/test/test-files/maven/non-maven-project/src/main/java/dummy.java new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/nim/with-git/src/source.nim b/vim-config/plugins/ale/test/test-files/nim/with-git/src/source.nim new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ocaml/testfile.ml b/vim-config/plugins/ale/test/test-files/ocaml/testfile.ml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ocamllsp/dune-project b/vim-config/plugins/ale/test/test-files/ocamllsp/dune-project new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ols/.merlin b/vim-config/plugins/ale/test/test-files/ols/.merlin new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ols/node_modules/.bin/ocaml-language-server b/vim-config/plugins/ale/test/test-files/ols/node_modules/.bin/ocaml-language-server new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/pascal/test.pas b/vim-config/plugins/ale/test/test-files/pascal/test.pas new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/project-with-php-cs-fixer/test.php b/vim-config/plugins/ale/test/test-files/php/project-with-php-cs-fixer/test.php new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/project-with-php-cs-fixer/vendor/bin/php-cs-fixer b/vim-config/plugins/ale/test/test-files/php/project-with-php-cs-fixer/vendor/bin/php-cs-fixer new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/project-with-phpcbf/foo/test.php b/vim-config/plugins/ale/test/test-files/php/project-with-phpcbf/foo/test.php new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/project-with-phpcbf/vendor/bin/phpcbf b/vim-config/plugins/ale/test/test-files/php/project-with-phpcbf/vendor/bin/phpcbf new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/project-without-php-cs-fixer/test.php b/vim-config/plugins/ale/test/test-files/php/project-without-php-cs-fixer/test.php new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/project-without-phpcbf/foo/test.php b/vim-config/plugins/ale/test/test-files/php/project-without-phpcbf/foo/test.php new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/vendor/bin/php-language-server.php b/vim-config/plugins/ale/test/test-files/php/vendor/bin/php-language-server.php new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/with-composer/composer.json b/vim-config/plugins/ale/test/test-files/php/with-composer/composer.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/with-composer/vendor/bin/php-language-server.php b/vim-config/plugins/ale/test/test-files/php/with-composer/vendor/bin/php-language-server.php new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/php/with-git/vendor/bin/php-language-server.php b/vim-config/plugins/ale/test/test-files/php/with-git/vendor/bin/php-language-server.php new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/phpcs/project-with-phpcs/foo/test.php b/vim-config/plugins/ale/test/test-files/phpcs/project-with-phpcs/foo/test.php new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/phpcs/project-with-phpcs/vendor/bin/phpcs b/vim-config/plugins/ale/test/test-files/phpcs/project-with-phpcs/vendor/bin/phpcs new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/phpcs/project-without-phpcs/foo/test.php b/vim-config/plugins/ale/test/test-files/phpcs/project-without-phpcs/foo/test.php new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/testfile b/vim-config/plugins/ale/test/test-files/prettier/testfile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/testfile.css b/vim-config/plugins/ale/test/test-files/prettier/testfile.css new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/testfile.js b/vim-config/plugins/ale/test/test-files/prettier/testfile.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/testfile.json b/vim-config/plugins/ale/test/test-files/prettier/testfile.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/testfile.scss b/vim-config/plugins/ale/test/test-files/prettier/testfile.scss new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/testfile.ts b/vim-config/plugins/ale/test/test-files/prettier/testfile.ts new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/with_config/.prettierrc b/vim-config/plugins/ale/test/test-files/prettier/with_config/.prettierrc new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/with_config/testfile.js b/vim-config/plugins/ale/test/test-files/prettier/with_config/testfile.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/with_prettierignore/.prettierignore b/vim-config/plugins/ale/test/test-files/prettier/with_prettierignore/.prettierignore new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/prettier/with_prettierignore/src/testfile.js b/vim-config/plugins/ale/test/test-files/prettier/with_prettierignore/src/testfile.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/psalm/vendor/bin/psalm b/vim-config/plugins/ale/test/test-files/psalm/vendor/bin/psalm new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puglint/node_modules/.bin/pug-lint b/vim-config/plugins/ale/test/test-files/puglint/node_modules/.bin/pug-lint new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puglint/package.json b/vim-config/plugins/ale/test/test-files/puglint/package.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puglint/puglint_rc_dir/.pug-lintrc b/vim-config/plugins/ale/test/test-files/puglint/puglint_rc_dir/.pug-lintrc new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puglint/puglint_rc_js_dir/.pug-lintrc.js b/vim-config/plugins/ale/test/test-files/puglint/puglint_rc_js_dir/.pug-lintrc.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puglint/puglint_rc_json_dir/.pug-lintrc.json b/vim-config/plugins/ale/test/test-files/puglint/puglint_rc_json_dir/.pug-lintrc.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puppet/dummy.pp b/vim-config/plugins/ale/test/test-files/puppet/dummy.pp new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puppet/new-style-module/lib/puppet/types/exampletype.rb b/vim-config/plugins/ale/test/test-files/puppet/new-style-module/lib/puppet/types/exampletype.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puppet/new-style-module/metadata.json b/vim-config/plugins/ale/test/test-files/puppet/new-style-module/metadata.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puppet/new-style-module/template/template.epp b/vim-config/plugins/ale/test/test-files/puppet/new-style-module/template/template.epp new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puppet/old-style-module/manifests/init.pp b/vim-config/plugins/ale/test/test-files/puppet/old-style-module/manifests/init.pp new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/puppet/old-style-module/templates/template.epp b/vim-config/plugins/ale/test/test-files/puppet/old-style-module/templates/template.epp new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/purescript/bower/Foo.purs b/vim-config/plugins/ale/test/test-files/purescript/bower/Foo.purs new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/purescript/bower/bower.json b/vim-config/plugins/ale/test/test-files/purescript/bower/bower.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/purescript/psc-package/Foo.purs b/vim-config/plugins/ale/test/test-files/purescript/psc-package/Foo.purs new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/purescript/psc-package/psc-package.json b/vim-config/plugins/ale/test/test-files/purescript/psc-package/psc-package.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/purescript/spago/Foo.purs b/vim-config/plugins/ale/test/test-files/purescript/spago/Foo.purs new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/purescript/spago/spago.dhall b/vim-config/plugins/ale/test/test-files/purescript/spago/spago.dhall new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/MANIFEST.in b/vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/MANIFEST.in new file mode 100644 index 00000000..4617b0eb --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/MANIFEST.in @@ -0,0 +1,3 @@ +include README.md +include *.ini *.cfg *.txt +include requirements/*.txt diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/namespace/foo/__init__.py b/vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/namespace/foo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/namespace/foo/bar.py b/vim-config/plugins/ale/test/test-files/python/namespace_package_manifest/namespace/foo/bar.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/namespace/foo/__init__.py b/vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/namespace/foo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/namespace/foo/bar.py b/vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/namespace/foo/bar.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/pytest.ini b/vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/pytest.ini new file mode 100644 index 00000000..1433c6c6 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/python/namespace_package_pytest/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +DJANGO_SETTINGS_MODULE=foo.settings diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_setup/namespace/foo/__init__.py b/vim-config/plugins/ale/test/test-files/python/namespace_package_setup/namespace/foo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_setup/namespace/foo/bar.py b/vim-config/plugins/ale/test/test-files/python/namespace_package_setup/namespace/foo/bar.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_setup/setup.cfg b/vim-config/plugins/ale/test/test-files/python/namespace_package_setup/setup.cfg new file mode 100644 index 00000000..791f075d --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/python/namespace_package_setup/setup.cfg @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 119 diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_tox/namespace/foo/__init__.py b/vim-config/plugins/ale/test/test-files/python/namespace_package_tox/namespace/foo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_tox/namespace/foo/bar.py b/vim-config/plugins/ale/test/test-files/python/namespace_package_tox/namespace/foo/bar.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/namespace_package_tox/tox.ini b/vim-config/plugins/ale/test/test-files/python/namespace_package_tox/tox.ini new file mode 100644 index 00000000..edd8788c --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/python/namespace_package_tox/tox.ini @@ -0,0 +1,3 @@ +[tox] +envlist = + py352 diff --git a/vim-config/plugins/ale/test/test-files/python/no_virtualenv/subdir/foo/COMMIT_EDITMSG b/vim-config/plugins/ale/test/test-files/python/no_virtualenv/subdir/foo/COMMIT_EDITMSG new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/no_virtualenv/subdir/foo/__init__.py b/vim-config/plugins/ale/test/test-files/python/no_virtualenv/subdir/foo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/no_virtualenv/subdir/foo/bar.py b/vim-config/plugins/ale/test/test-files/python/no_virtualenv/subdir/foo/bar.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/pipenv/Pipfile.lock b/vim-config/plugins/ale/test/test-files/python/pipenv/Pipfile.lock new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/poetry/poetry.lock b/vim-config/plugins/ale/test/test-files/python/poetry/poetry.lock new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/pyre_configuration_dir/.pyre_configuration.local b/vim-config/plugins/ale/test/test-files/python/pyre_configuration_dir/.pyre_configuration.local new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/pyre_configuration_dir/foo/__init__.py b/vim-config/plugins/ale/test/test-files/python/pyre_configuration_dir/foo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/pyre_configuration_dir/foo/bar.py b/vim-config/plugins/ale/test/test-files/python/pyre_configuration_dir/foo/bar.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/python-package-project/.flake8 b/vim-config/plugins/ale/test/test-files/python/python-package-project/.flake8 new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/python-package-project/package-name/module.py b/vim-config/plugins/ale/test/test-files/python/python-package-project/package-name/module.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_bandit/.bandit b/vim-config/plugins/ale/test/test-files/python/with_bandit/.bandit new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_bandit/namespace/foo/__init__.py b/vim-config/plugins/ale/test/test-files/python/with_bandit/namespace/foo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_bandit/namespace/foo/bar.py b/vim-config/plugins/ale/test/test-files/python/with_bandit/namespace/foo/bar.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_mypy_ini_and_pytest_ini/mypy.ini b/vim-config/plugins/ale/test/test-files/python/with_mypy_ini_and_pytest_ini/mypy.ini new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_mypy_ini_and_pytest_ini/tests/pytest.ini b/vim-config/plugins/ale/test/test-files/python/with_mypy_ini_and_pytest_ini/tests/pytest.ini new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py b/vim-config/plugins/ale/test/test-files/python/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/dir_with_yapf_config/.style.yapf b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/dir_with_yapf_config/.style.yapf new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/activate b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/activate new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/autoflake.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/autoflake.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/autoimport.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/autoimport.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/autopep8.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/autopep8.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/black.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/black.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/flake8.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/flake8.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/flakehell.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/flakehell.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/gitlint.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/gitlint.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/isort.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/isort.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/mypy.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/mypy.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pyflakes.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pyflakes.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pylama.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pylama.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pylint.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pylint.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pylsp.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pylsp.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pyre.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/pyre.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/reorder-python-imports.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/reorder-python-imports.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/vulture.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/vulture.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/yamlfix.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/yamlfix.exe new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/yapf.exe b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/Scripts/yapf.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/activate b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/activate new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/autoflake b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/autoflake new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/autoimport b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/autoimport new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/autopep8 b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/autopep8 new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/black b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/black new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/flake8 b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/flake8 new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/flakehell b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/flakehell new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/gitlint b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/gitlint new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/isort b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/isort new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/mypy b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/mypy new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pyflakes b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pyflakes new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pylama b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pylama new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pylint b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pylint new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pylsp b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pylsp new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pyre b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/pyre new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/reorder-python-imports b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/reorder-python-imports new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/vulture b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/vulture new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/yamlfix b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/yamlfix new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/yapf b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/env/bin/yapf new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/COMMIT_EDITMSG b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/COMMIT_EDITMSG new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/__init__.py b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/bar.py b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/bar.py new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/bar.pyi b/vim-config/plugins/ale/test/test-files/python/with_virtualenv/subdir/foo/bar.pyi new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/r/.Rprofile b/vim-config/plugins/ale/test/test-files/r/.Rprofile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/c/foo.rkt b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/c/foo.rkt new file mode 100644 index 00000000..622f3eea --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/c/foo.rkt @@ -0,0 +1,3 @@ +#lang racket/base + +(displayln "foo") diff --git a/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/c/init.rkt b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/c/init.rkt new file mode 100644 index 00000000..e0c94f27 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/c/init.rkt @@ -0,0 +1 @@ +#lang info diff --git a/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/foo.rkt b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/foo.rkt new file mode 100644 index 00000000..622f3eea --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/foo.rkt @@ -0,0 +1,3 @@ +#lang racket/base + +(displayln "foo") diff --git a/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/init.rkt b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/init.rkt new file mode 100644 index 00000000..e0c94f27 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/b/init.rkt @@ -0,0 +1 @@ +#lang info diff --git a/vim-config/plugins/ale/test/test-files/racket/many-inits/a/foo.rkt b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/foo.rkt new file mode 100644 index 00000000..622f3eea --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/foo.rkt @@ -0,0 +1,3 @@ +#lang racket/base + +(displayln "foo") diff --git a/vim-config/plugins/ale/test/test-files/racket/many-inits/a/init.rkt b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/init.rkt new file mode 100644 index 00000000..e0c94f27 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/racket/many-inits/a/init.rkt @@ -0,0 +1 @@ +#lang info diff --git a/vim-config/plugins/ale/test/test-files/racket/many-inits/foo.rkt b/vim-config/plugins/ale/test/test-files/racket/many-inits/foo.rkt new file mode 100644 index 00000000..622f3eea --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/racket/many-inits/foo.rkt @@ -0,0 +1,3 @@ +#lang racket/base + +(displayln "foo") diff --git a/vim-config/plugins/ale/test/test-files/racket/many-inits/init.rkt b/vim-config/plugins/ale/test/test-files/racket/many-inits/init.rkt new file mode 100644 index 00000000..e0c94f27 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/racket/many-inits/init.rkt @@ -0,0 +1 @@ +#lang info diff --git a/vim-config/plugins/ale/test/test-files/racket/simple-script/foo.rkt b/vim-config/plugins/ale/test/test-files/racket/simple-script/foo.rkt new file mode 100644 index 00000000..622f3eea --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/racket/simple-script/foo.rkt @@ -0,0 +1,3 @@ +#lang racket/base + +(displayln "foo") diff --git a/vim-config/plugins/ale/test/test-files/reasonml/bsconfig.json b/vim-config/plugins/ale/test/test-files/reasonml/bsconfig.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/reasonml/testfile.re b/vim-config/plugins/ale/test/test-files/reasonml/testfile.re new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/remark_lint/with_bin_path/node_modules/.bin/remark b/vim-config/plugins/ale/test/test-files/remark_lint/with_bin_path/node_modules/.bin/remark new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/dummy.rb b/vim-config/plugins/ale/test/test-files/ruby/dummy.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/not_a_rails_app/file.rb b/vim-config/plugins/ale/test/test-files/ruby/not_a_rails_app/file.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/app/dummy.rb b/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/app/dummy.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/app/models/thing.rb b/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/app/models/thing.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/app/views/my_great_view.html.erb b/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/app/views/my_great_view.html.erb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/config/dummy.rb b/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/config/dummy.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/db/dummy.rb b/vim-config/plugins/ale/test/test-files/ruby/valid_rails_app/db/dummy.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app1/Rakefile b/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app1/Rakefile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app1/lib/file.rb b/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app1/lib/file.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app2/Gemfile b/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app2/Gemfile new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app2/lib/file.rb b/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app2/lib/file.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app3/.solargraph.yml b/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app3/.solargraph.yml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app3/lib/file.rb b/vim-config/plugins/ale/test/test-files/ruby/valid_ruby_app3/lib/file.rb new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/with_config/.rubocop.yml b/vim-config/plugins/ale/test/test-files/ruby/with_config/.rubocop.yml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/ruby/with_config/.standard.yml b/vim-config/plugins/ale/test/test-files/ruby/with_config/.standard.yml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/rust/Cargo.toml b/vim-config/plugins/ale/test/test-files/rust/Cargo.toml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/rust/testfile.rs b/vim-config/plugins/ale/test/test-files/rust/testfile.rs new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/sasslint/with-bin/node_modules/.bin/sass-lint b/vim-config/plugins/ale/test/test-files/sasslint/with-bin/node_modules/.bin/sass-lint new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/sasslint/with-source/node_modules/sass-lint/bin/sass-lint.js b/vim-config/plugins/ale/test/test-files/sasslint/with-source/node_modules/sass-lint/bin/sass-lint.js new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/scala/dummy.scala b/vim-config/plugins/ale/test/test-files/scala/dummy.scala new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/scala/invalid_sbt_project/Main.scala b/vim-config/plugins/ale/test/test-files/scala/invalid_sbt_project/Main.scala new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/scala/valid_sbt_project/Main.scala b/vim-config/plugins/ale/test/test-files/scala/valid_sbt_project/Main.scala new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/scala/valid_sbt_project/build.sbt b/vim-config/plugins/ale/test/test-files/scala/valid_sbt_project/build.sbt new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/slimlint/.rubocop.yml b/vim-config/plugins/ale/test/test-files/slimlint/.rubocop.yml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/slimlint/subdir/file.slim b/vim-config/plugins/ale/test/test-files/slimlint/subdir/file.slim new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/smlnj/cm/foo.sml b/vim-config/plugins/ale/test/test-files/smlnj/cm/foo.sml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/smlnj/cm/path/to/bar.sml b/vim-config/plugins/ale/test/test-files/smlnj/cm/path/to/bar.sml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/smlnj/cm/sources.cm b/vim-config/plugins/ale/test/test-files/smlnj/cm/sources.cm new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/smlnj/file/qux.sml b/vim-config/plugins/ale/test/test-files/smlnj/file/qux.sml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/solhint/Contract.sol b/vim-config/plugins/ale/test/test-files/solhint/Contract.sol new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/solhint/node_modules/.bin/solhint b/vim-config/plugins/ale/test/test-files/solhint/node_modules/.bin/solhint new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/solhint/node_modules/solhint/index.js b/vim-config/plugins/ale/test/test-files/solhint/node_modules/solhint/index.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/solhint/package.json b/vim-config/plugins/ale/test/test-files/solhint/package.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/spectral/node_modules/.bin/spectral b/vim-config/plugins/ale/test/test-files/spectral/node_modules/.bin/spectral new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/spectral/openapi.yaml b/vim-config/plugins/ale/test/test-files/spectral/openapi.yaml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/stack/stack.yaml b/vim-config/plugins/ale/test/test-files/stack/stack.yaml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/standard/with-bin/node_modules/.bin/standard b/vim-config/plugins/ale/test/test-files/standard/with-bin/node_modules/.bin/standard new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/standard/with-cmd/node_modules/standard/bin/cmd.js b/vim-config/plugins/ale/test/test-files/standard/with-cmd/node_modules/standard/bin/cmd.js new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/stylelint/node_modules/.bin/stylelint b/vim-config/plugins/ale/test/test-files/stylelint/node_modules/.bin/stylelint new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swaglint/docs/swagger.yaml b/vim-config/plugins/ale/test/test-files/swaglint/docs/swagger.yaml new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swaglint/node_modules/.bin/swaglint b/vim-config/plugins/ale/test/test-files/swaglint/node_modules/.bin/swaglint new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swift/dummy.swift b/vim-config/plugins/ale/test/test-files/swift/dummy.swift new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swift/non-swift-package-project/src/folder/dummy.swift b/vim-config/plugins/ale/test/test-files/swift/non-swift-package-project/src/folder/dummy.swift new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/.swift-format b/vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/.swift-format new file mode 100644 index 00000000..19fb8b96 --- /dev/null +++ b/vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/.swift-format @@ -0,0 +1,10 @@ +{ + "version": 1, + "lineLength": 100, + "indentation": { + "spaces": 4 + }, + "respectsExistingLineBreaks": true, + "lineBreakBeforeControlFlowKeywords": true, + "lineBreakBeforeEachArgument": true +} diff --git a/vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/Package.swift b/vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/Package.swift new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/src/folder/dummy.swift b/vim-config/plugins/ale/test/test-files/swift/swift-package-project-with-config/src/folder/dummy.swift new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swift/swift-package-project/Package.swift b/vim-config/plugins/ale/test/test-files/swift/swift-package-project/Package.swift new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swift/swift-package-project/src/folder/dummy.swift b/vim-config/plugins/ale/test/test-files/swift/swift-package-project/src/folder/dummy.swift new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swiftlint/cocoapods-and-react-native/Pods/SwiftLint/swiftlint b/vim-config/plugins/ale/test/test-files/swiftlint/cocoapods-and-react-native/Pods/SwiftLint/swiftlint new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swiftlint/cocoapods-and-react-native/ios/Pods/SwiftLint/swiftlint b/vim-config/plugins/ale/test/test-files/swiftlint/cocoapods-and-react-native/ios/Pods/SwiftLint/swiftlint new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swiftlint/cocoapods/Pods/SwiftLint/swiftlint b/vim-config/plugins/ale/test/test-files/swiftlint/cocoapods/Pods/SwiftLint/swiftlint new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/swiftlint/react-native/ios/Pods/SwiftLint/swiftlint b/vim-config/plugins/ale/test/test-files/swiftlint/react-native/ios/Pods/SwiftLint/swiftlint new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/terraform/main.tf b/vim-config/plugins/ale/test/test-files/terraform/main.tf new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tex/sample1.tex b/vim-config/plugins/ale/test/test-files/tex/sample1.tex new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tex/sample2.tex b/vim-config/plugins/ale/test/test-files/tex/sample2.tex new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tex/testfile.tex b/vim-config/plugins/ale/test/test-files/tex/testfile.tex new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/textlint/with_bin_path/node_modules/.bin/textlint b/vim-config/plugins/ale/test/test-files/textlint/with_bin_path/node_modules/.bin/textlint new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js b/vim-config/plugins/ale/test/test-files/textlint/with_textlint_bin_path/node_modules/textlint/bin/textlint.js new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tflint/foo/.tflint.hcl b/vim-config/plugins/ale/test/test-files/tflint/foo/.tflint.hcl new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tflint/foo/bar.tf b/vim-config/plugins/ale/test/test-files/tflint/foo/bar.tf new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tidy/.tidyrc b/vim-config/plugins/ale/test/test-files/tidy/.tidyrc new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tidy/test.html b/vim-config/plugins/ale/test/test-files/tidy/test.html new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tidy/tidy b/vim-config/plugins/ale/test/test-files/tidy/tidy new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tidy/tidy.exe b/vim-config/plugins/ale/test/test-files/tidy/tidy.exe new file mode 100755 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/top/ale-special-directory-name-dont-use-this-please/empty-file b/vim-config/plugins/ale/test/test-files/top/ale-special-directory-name-dont-use-this-please/empty-file new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/top/example.ini b/vim-config/plugins/ale/test/test-files/top/example.ini new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/top/middle/bottom/dummy.txt b/vim-config/plugins/ale/test/test-files/top/middle/bottom/dummy.txt new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tsserver/src/file1.ts b/vim-config/plugins/ale/test/test-files/tsserver/src/file1.ts new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tsserver/src/level-1/file2.ts b/vim-config/plugins/ale/test/test-files/tsserver/src/level-1/file2.ts new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tsserver/src/level-1/level-2/file3.ts b/vim-config/plugins/ale/test/test-files/tsserver/src/level-1/level-2/file3.ts new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tsserver/src/level-1/tsconfig.json b/vim-config/plugins/ale/test/test-files/tsserver/src/level-1/tsconfig.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/tsserver/tsconfig.json b/vim-config/plugins/ale/test/test-files/tsserver/tsconfig.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/typescript/custom_import_map.json b/vim-config/plugins/ale/test/test-files/typescript/custom_import_map.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/typescript/import_map.json b/vim-config/plugins/ale/test/test-files/typescript/import_map.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/typescript/test.ts b/vim-config/plugins/ale/test/test-files/typescript/test.ts new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/typescript/tsconfig.json b/vim-config/plugins/ale/test/test-files/typescript/tsconfig.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/vim/invalid_vim_project/test.vim b/vim-config/plugins/ale/test/test-files/vim/invalid_vim_project/test.vim new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/vim/node_modules/.bin/vim-language-server b/vim-config/plugins/ale/test/test-files/vim/node_modules/.bin/vim-language-server new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/vim/path_with_autoload/autoload/test.vim b/vim-config/plugins/ale/test/test-files/vim/path_with_autoload/autoload/test.vim new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/vim/path_with_autoload/test.vim b/vim-config/plugins/ale/test/test-files/vim/path_with_autoload/test.vim new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/vim/path_with_initvim/init.vim b/vim-config/plugins/ale/test/test-files/vim/path_with_initvim/init.vim new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/vim/path_with_plugin/plugin/test.vim b/vim-config/plugins/ale/test/test-files/vim/path_with_plugin/plugin/test.vim new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/vim/path_with_plugin/test.vim b/vim-config/plugins/ale/test/test-files/vim/path_with_plugin/test.vim new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/vim/path_with_vimrc/.vimrc b/vim-config/plugins/ale/test/test-files/vim/path_with_vimrc/.vimrc new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/write-good/node-modules-2/node_modules/write-good/bin/write-good.js b/vim-config/plugins/ale/test/test-files/write-good/node-modules-2/node_modules/write-good/bin/write-good.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/write-good/node-modules/node_modules/.bin/write-good b/vim-config/plugins/ale/test/test-files/write-good/node-modules/node_modules/.bin/write-good new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/xo/monorepo/node_modules/xo/cli.js b/vim-config/plugins/ale/test/test-files/xo/monorepo/node_modules/xo/cli.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/xo/monorepo/package.json b/vim-config/plugins/ale/test/test-files/xo/monorepo/package.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/xo/monorepo/packages/a/index.js b/vim-config/plugins/ale/test/test-files/xo/monorepo/packages/a/index.js new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/xo/monorepo/packages/a/index.ts b/vim-config/plugins/ale/test/test-files/xo/monorepo/packages/a/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/xo/monorepo/packages/a/package.json b/vim-config/plugins/ale/test/test-files/xo/monorepo/packages/a/package.json new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test-files/zig/build.zig b/vim-config/plugins/ale/test/test-files/zig/build.zig new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/test_ale_has.vader b/vim-config/plugins/ale/test/test_ale_has.vader new file mode 100644 index 00000000..df4ca302 --- /dev/null +++ b/vim-config/plugins/ale/test/test_ale_has.vader @@ -0,0 +1,12 @@ +Execute(Checks for versions below the current version should succeed): + AssertEqual 1, ale#Has('ale-3.1.0') + AssertEqual 1, ale#Has('ale-3.0.0') + AssertEqual 1, ale#Has('ale-2.7.0') + AssertEqual 1, ale#Has('ale-2.6.0') + AssertEqual 1, ale#Has('ale-2.5.0') + AssertEqual 1, ale#Has('ale-2.4.0') + AssertEqual 1, ale#Has('ALE-2.2.1') + AssertEqual 1, ale#Has('ALE-1.0.0') + +Execute(Checks for newer versions should fail): + AssertEqual 0, ale#Has('ALE-20.0.0') diff --git a/vim-config/plugins/ale/test/test_ale_info.vader b/vim-config/plugins/ale/test/test_ale_info.vader new file mode 100644 index 00000000..2e0965a9 --- /dev/null +++ b/vim-config/plugins/ale/test/test_ale_info.vader @@ -0,0 +1,777 @@ +Before: + Save g:ale_buffer_info + Save g:ale_cache_executable_check_failures + Save g:ale_change_sign_column_color + Save g:ale_command_wrapper + Save g:ale_completion_delay + Save g:ale_completion_enabled + Save g:ale_completion_max_suggestions + Save g:ale_disable_lsp + Save g:ale_echo_cursor + Save g:ale_echo_msg_error_str + Save g:ale_echo_msg_format + Save g:ale_echo_msg_info_str + Save g:ale_echo_msg_warning_str + Save g:ale_fix_on_save + Save g:ale_fixers + Save g:ale_history_enabled + Save g:ale_history_log_output + Save g:ale_keep_list_window_open + Save g:ale_lint_delay + Save g:ale_lint_on_enter + Save g:ale_lint_on_filetype_changed + Save g:ale_lint_on_insert_leave + Save g:ale_lint_on_save + Save g:ale_lint_on_text_changed + Save g:ale_linters + Save g:ale_linters_explicit + Save g:ale_linters_ignore + Save g:ale_list_vertical + Save g:ale_list_window_size + Save g:ale_loclist_msg_format + Save g:ale_lsp_error_messages + Save g:ale_max_buffer_history_size + Save g:ale_max_signs + Save g:ale_maximum_file_size + Save g:ale_open_list + Save g:ale_pattern_options + Save g:ale_pattern_options_enabled + Save g:ale_root + Save g:ale_set_balloons + Save g:ale_set_highlights + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_set_signs + Save g:ale_sign_column_always + Save g:ale_sign_error + Save g:ale_sign_info + Save g:ale_sign_offset + Save g:ale_sign_style_error + Save g:ale_sign_style_warning + Save g:ale_sign_warning + Save g:ale_sign_highlight_linenrs + Save g:ale_statusline_format + Save g:ale_type_map + Save g:ale_use_global_executables + Save g:ale_virtualtext_cursor + Save g:ale_warn_about_trailing_blank_lines + Save g:ale_warn_about_trailing_whitespace + + unlet! b:ale_history + + let g:ale_buffer_info = {} + let g:ale_cache_executable_check_failures = 0 + let g:ale_change_sign_column_color = 0 + let g:ale_command_wrapper = '' + let g:ale_completion_delay = 100 + let g:ale_completion_enabled = 0 + let g:ale_completion_max_suggestions = 50 + let g:ale_disable_lsp = 0 + let g:ale_echo_cursor = 1 + let g:ale_echo_msg_error_str = 'Error' + let g:ale_echo_msg_format = '%code: %%s' + let g:ale_echo_msg_info_str = 'Info' + let g:ale_echo_msg_warning_str = 'Warning' + let g:ale_fix_on_save = 0 + let g:ale_history_enabled = 1 + let g:ale_history_log_output = 1 + let g:ale_keep_list_window_open = 0 + let g:ale_lint_delay = 200 + let g:ale_lint_on_enter = 1 + let g:ale_lint_on_filetype_changed = 1 + let g:ale_lint_on_insert_leave = 1 + let g:ale_lint_on_save = 1 + let g:ale_lint_on_text_changed = 'normal' + let g:ale_linters_explicit = 0 + let g:ale_linters_ignore = {'python': ['pyright']} + let g:ale_list_vertical = 0 + let g:ale_list_window_size = 10 + let g:ale_loclist_msg_format = '%code: %%s' + let g:ale_lsp_error_messages = {} + let g:ale_max_buffer_history_size = 20 + let g:ale_max_signs = -1 + let g:ale_maximum_file_size = 0 + let g:ale_open_list = 0 + let g:ale_pattern_options = {} + let g:ale_pattern_options_enabled = 0 + let g:ale_root = {} + let g:ale_set_balloons = 0 + let g:ale_set_highlights = 1 + let g:ale_set_loclist = 1 + let g:ale_set_quickfix = 0 + let g:ale_set_signs = 1 + let g:ale_sign_column_always = 0 + let g:ale_sign_error = '>>' + let g:ale_sign_info = '--' + let g:ale_sign_offset = 1000000 + let g:ale_sign_style_error = '>>' + let g:ale_sign_style_warning = '--' + let g:ale_sign_warning = '--' + let g:ale_sign_highlight_linenrs = 0 + let g:ale_statusline_format = ['%d error(s)', '%d warning(s)', 'OK'] + let g:ale_type_map = {} + let g:ale_use_global_executables = v:null + let g:ale_virtualtext_cursor = 0 + let g:ale_warn_about_trailing_blank_lines = 1 + let g:ale_warn_about_trailing_whitespace = 1 + + let g:testlinter1 = {'name': 'testlinter1', 'executable': 'testlinter1', 'command': 'testlinter1', 'callback': 'testCB1', 'output_stream': 'stdout'} + let g:testlinter2 = {'name': 'testlinter2', 'executable': 'testlinter2', 'command': 'testlinter2', 'callback': 'testCB2', 'output_stream': 'stdout'} + + call ale#engine#ResetExecutableCache() + call ale#linter#Reset() + call ale#linter#PreventLoading('testft') + let g:ale_linters = {} + let g:ale_fixers = {} + let g:ale_linter_aliases = {} + let g:ale_buffer_info = {} + let g:fixer_lines = [ + \ ' Suggested Fixers: ', + \ ' ''foo'' - Fix things the foo way', + \] + let g:variables_lines = [ + \ ' Linter Variables:', + \ '', + \] + let g:globals_lines = [ + \ ' Global Variables:', + \ '', + \ 'let g:ale_cache_executable_check_failures = 0', + \ 'let g:ale_change_sign_column_color = 0', + \ 'let g:ale_command_wrapper = ''''', + \ 'let g:ale_completion_delay = 100', + \ 'let g:ale_completion_enabled = 0', + \ 'let g:ale_completion_max_suggestions = 50', + \ 'let g:ale_disable_lsp = 0', + \ 'let g:ale_echo_cursor = 1', + \ 'let g:ale_echo_msg_error_str = ''Error''', + \ 'let g:ale_echo_msg_format = ''%code: %%s''', + \ 'let g:ale_echo_msg_info_str = ''Info''', + \ 'let g:ale_echo_msg_warning_str = ''Warning''', + \ 'let g:ale_enabled = 1', + \ 'let g:ale_fix_on_save = 0', + \ 'let g:ale_fixers = {}', + \ 'let g:ale_history_enabled = 1', + \ 'let g:ale_history_log_output = 1', + \ 'let g:ale_keep_list_window_open = 0', + \ 'let g:ale_lint_delay = 200', + \ 'let g:ale_lint_on_enter = 1', + \ 'let g:ale_lint_on_filetype_changed = 1', + \ 'let g:ale_lint_on_insert_leave = 1', + \ 'let g:ale_lint_on_save = 1', + \ 'let g:ale_lint_on_text_changed = ''normal''', + \ 'let g:ale_linter_aliases = {}', + \ 'let g:ale_linters = {}', + \ 'let g:ale_linters_explicit = 0', + \ 'let g:ale_linters_ignore = {''python'': [''pyright'']}', + \ 'let g:ale_list_vertical = 0', + \ 'let g:ale_list_window_size = 10', + \ 'let g:ale_loclist_msg_format = ''%code: %%s''', + \ 'let g:ale_max_buffer_history_size = 20', + \ 'let g:ale_max_signs = -1', + \ 'let g:ale_maximum_file_size = 0', + \ 'let g:ale_open_list = 0', + \ 'let g:ale_pattern_options = {}', + \ 'let g:ale_pattern_options_enabled = 0', + \ 'let g:ale_root = {}', + \ 'let g:ale_set_balloons = 0', + \ 'let g:ale_set_highlights = 1', + \ 'let g:ale_set_loclist = 1', + \ 'let g:ale_set_quickfix = 0', + \ 'let g:ale_set_signs = 1', + \ 'let g:ale_sign_column_always = 0', + \ 'let g:ale_sign_error = ''>>''', + \ 'let g:ale_sign_info = ''--''', + \ 'let g:ale_sign_offset = 1000000', + \ 'let g:ale_sign_style_error = ''>>''', + \ 'let g:ale_sign_style_warning = ''--''', + \ 'let g:ale_sign_warning = ''--''', + \ 'let g:ale_sign_highlight_linenrs = 0', + \ 'let g:ale_statusline_format = [''%d error(s)'', ''%d warning(s)'', ''OK'']', + \ 'let g:ale_type_map = {}', + \ 'let g:ale_use_global_executables = v:null', + \ 'let g:ale_virtualtext_cursor = 0', + \ 'let g:ale_warn_about_trailing_blank_lines = 1', + \ 'let g:ale_warn_about_trailing_whitespace = 1', + \] + let g:command_header = [ + \ ' Command History:', + \] + + function CheckInfo(expected_list) abort + let l:output = '' + + redir => l:output + noautocmd silent ALEInfo + redir END + + AssertEqual a:expected_list, split(l:output, "\n") + endfunction + + call ale#test#SetDirectory('/testplugin/test') + + call ale#fix#registry#Clear() + call ale#fix#registry#Add('foo', 'x', [], 'Fix things the foo way') + +After: + Restore + + if exists('g:info_test_file') && filereadable(g:info_test_file) + call delete(g:info_test_file) + endif + + unlet! g:testlinter1 + unlet! g:testlinter2 + unlet! b:ale_history + unlet! b:ale_linters + unlet! g:output + unlet! g:fixer_lines + unlet! g:variables_lines + unlet! g:globals_string + unlet! g:command_header + unlet! g:ale_testft_testlinter1_foo + unlet! g:ale_testft_testlinter1_bar + unlet! g:ale_testft2_testlinter2_foo + unlet! b:ale_testft2_testlinter2_foo + unlet! g:ale_testft2_testlinter2_bar + unlet! g:info_test_file + unlet! g:ale_testft_build_dir_names + unlet! g:ale_testft_testlinter2_option + delfunction CheckInfo + + call ale#test#RestoreDirectory() + call ale#fix#registry#ResetToDefaults() + +Given nolintersft (Empty buffer with no linters): +Execute (ALEInfo with no linters should return the right output): + call CheckInfo( + \ [ + \ ' Current Filetype: nolintersft', + \ 'Available Linters: []', + \ ' Enabled Linters: []', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given (Empty buffer with no filetype): +Execute (ALEInfo should return buffer-local global ALE settings): + let b:ale_linters = {'x': ['y']} + + call insert( + \ g:globals_lines, + \ 'let b:ale_linters = {''x'': [''y'']}', + \ index(g:globals_lines, 'let g:ale_linters = {}') + 1 + \) + + call CheckInfo( + \ [ + \ ' Current Filetype: ', + \ 'Available Linters: []', + \ ' Enabled Linters: []', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given (Empty buffer with no filetype): +Execute (ALEInfo with no filetype should return the right output): + call CheckInfo( + \ [ + \ ' Current Filetype: ', + \ 'Available Linters: []', + \ ' Enabled Linters: []', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given testft (Empty buffer): +Execute (ALEInfo with a single linter should return the right output): + call ale#linter#Define('testft', g:testlinter1) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft', + \ 'Available Linters: [''testlinter1'']', + \ ' Enabled Linters: [''testlinter1'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given testft (Empty buffer): +Execute (ALEInfo with two linters should return the right output): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given testft (Empty buffer): +Execute (ALEInfo should calculate enabled linters correctly): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + let g:ale_linters = {'testft': ['testlinter2']} + + let g:globals_lines[index(g:globals_lines, 'let g:ale_linters = {}')] + \ = 'let g:ale_linters = {''testft'': [''testlinter2'']}' + + call CheckInfo( + \ [ + \ ' Current Filetype: testft', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given testft (Empty buffer): +Execute (ALEInfo should only return linters for current filetype): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft', + \ 'Available Linters: [''testlinter1'']', + \ ' Enabled Linters: [''testlinter1'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given testft.testft2 (Empty buffer with two filetypes): +Execute (ALEInfo with compound filetypes should return linters for both of them): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given testft.testft2 (Empty buffer with two filetypes): +Execute (ALEInfo should return appropriately named global variables): + let g:ale_testft_testlinter1_foo = 'abc' + let g:ale_testft_testlinter1_bar = ['abc'] + let g:ale_testft2_testlinter2_foo = 123 + let g:ale_testft2_testlinter2_bar = {'x': 'y'} + + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + [ + \ ' Linter Variables:', + \ '', + \ 'let g:ale_testft2_testlinter2_bar = {''x'': ''y''}', + \ 'let g:ale_testft2_testlinter2_foo = 123', + \ 'let g:ale_testft_testlinter1_bar = [''abc'']', + \ 'let g:ale_testft_testlinter1_foo = ''abc''', + \ ] + \ + g:globals_lines + \ + g:command_header + \) + +Execute (ALEInfoToFile should write to a file correctly): + let g:ale_testft_testlinter1_foo = 'abc' + let g:ale_testft_testlinter1_bar = ['abc'] + let g:ale_testft2_testlinter2_foo = 123 + let g:ale_testft2_testlinter2_bar = {'x': 'y'} + + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + let g:info_test_file = tempname() + execute 'ALEInfoToFile ' . fnameescape(g:info_test_file) + + AssertEqual + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + [ + \ ' Linter Variables:', + \ '', + \ 'let g:ale_testft2_testlinter2_bar = {''x'': ''y''}', + \ 'let g:ale_testft2_testlinter2_foo = 123', + \ 'let g:ale_testft_testlinter1_bar = [''abc'']', + \ 'let g:ale_testft_testlinter1_foo = ''abc''', + \ ] + \ + g:globals_lines + \ + g:command_header, + \ readfile(g:info_test_file) + +Given testft.testft2 (Empty buffer with two filetypes): +Execute (ALEInfo should buffer-local linter variables): + let g:ale_testft2_testlinter2_foo = 123 + let b:ale_testft2_testlinter2_foo = 456 + + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + [ + \ ' Linter Variables:', + \ '', + \ 'let g:ale_testft2_testlinter2_foo = 123', + \ 'let b:ale_testft2_testlinter2_foo = 456', + \ ] + \ + g:globals_lines + \ + g:command_header + \) + +Given testft.testft2 (Empty buffer with two filetypes): +Execute (ALEInfo should output linter aliases): + let g:testlinter1.aliases = ['testftalias1', 'testftalias2'] + let g:testlinter2.aliases = ['testftalias3', 'testftalias4'] + + let g:ale_testft2_testlinter2_foo = 123 + let b:ale_testft2_testlinter2_foo = 456 + + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Linter Aliases:', + \ '''testlinter1'' -> [''testftalias1'', ''testftalias2'']', + \ '''testlinter2'' -> [''testftalias3'', ''testftalias4'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + [ + \ ' Linter Variables:', + \ '', + \ 'let g:ale_testft2_testlinter2_foo = 123', + \ 'let b:ale_testft2_testlinter2_foo = 456', + \ ] + \ + g:globals_lines + \ + g:command_header + \) + +Given testft.testft2 (Empty buffer with two filetypes): +Execute (ALEInfo should return command history): + let b:ale_history = [ + \ {'status': 'started', 'job_id': 347, 'command': 'first command'}, + \ {'status': 'started', 'job_id': 347, 'command': ['/bin/bash', '\c', 'last command']}, + \] + + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \ + [ + \ '', + \ '(started) ''first command''', + \ '(started) [''/bin/bash'', ''\c'', ''last command'']', + \ ] + \) + +Given testft.testft2 (Empty buffer with two filetypes): +Execute (ALEInfo command history should print exit codes correctly): + let b:ale_history = [ + \ {'status': 'finished', 'exit_code': 0, 'job_id': 347, 'command': 'first command'}, + \ {'status': 'finished', 'exit_code': 1, 'job_id': 347, 'command': ['/bin/bash', '\c', 'last command']}, + \] + + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \ + [ + \ '', + \ '(finished - exit code 0) ''first command''', + \ '(finished - exit code 1) [''/bin/bash'', ''\c'', ''last command'']', + \ ] + \) + +Given testft.testft2 (Empty buffer with two filetypes): +Execute (ALEInfo command history should print command output if logging is on): + let g:ale_history_log_output = 1 + + let b:ale_history = [ + \ { + \ 'status': 'finished', + \ 'exit_code': 0, + \ 'job_id': 347, + \ 'command': 'first command', + \ 'output': ['some', 'first command output'], + \ }, + \ { + \ 'status': 'finished', + \ 'exit_code': 1, + \ 'job_id': 347, + \ 'command': ['/bin/bash', '\c', 'last command'], + \ 'output': ['different second command output'], + \ }, + \ { + \ 'status': 'finished', + \ 'exit_code': 0, + \ 'job_id': 347, + \ 'command': 'command with no output', + \ 'output': [], + \ }, + \] + + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \ + [ + \ '', + \ '(finished - exit code 0) ''first command''', + \ '', + \ '<<>>', + \ 'some', + \ 'first command output', + \ '<<>>', + \ '', + \ '(finished - exit code 1) [''/bin/bash'', ''\c'', ''last command'']', + \ '', + \ '<<>>', + \ 'different second command output', + \ '<<>>', + \ '', + \ '(finished - exit code 0) ''command with no output''', + \ '', + \ '<<>>', + \ ] + \) + +Execute (ALEInfo should include executable checks in the history): + call ale#linter#Define('testft', g:testlinter1) + call ale#engine#IsExecutable(bufnr(''), has('win32') ? 'cmd' : 'echo') + call ale#engine#IsExecutable(bufnr(''), has('win32') ? 'cmd' : 'echo') + call ale#engine#IsExecutable(bufnr(''), 'TheresNoWayThisIsExecutable') + call ale#engine#IsExecutable(bufnr(''), 'TheresNoWayThisIsExecutable') + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'']', + \ ' Enabled Linters: [''testlinter1'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \ + [ + \ '', + \ '(executable check - success) ' . (has('win32') ? 'cmd' : 'echo'), + \ '(executable check - failure) TheresNoWayThisIsExecutable', + \ '(executable check - failure) TheresNoWayThisIsExecutable', + \ ] + \) + +Execute (The option for caching failing executable checks should work): + let g:ale_cache_executable_check_failures = 1 + let g:globals_lines[2] = 'let g:ale_cache_executable_check_failures = 1' + + call ale#linter#Define('testft', g:testlinter1) + + call ale#engine#IsExecutable(bufnr(''), has('win32') ? 'cmd' : 'echo') + call ale#engine#IsExecutable(bufnr(''), has('win32') ? 'cmd' : 'echo') + call ale#engine#IsExecutable(bufnr(''), 'TheresNoWayThisIsExecutable') + call ale#engine#IsExecutable(bufnr(''), 'TheresNoWayThisIsExecutable') + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'']', + \ ' Enabled Linters: [''testlinter1'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \ + [ + \ '', + \ '(executable check - success) ' . (has('win32') ? 'cmd' : 'echo'), + \ '(executable check - failure) TheresNoWayThisIsExecutable', + \ ] + \) + +Given testft (Empty buffer): +Execute (LSP errors for a linter should be outputted): + let g:ale_lsp_error_messages = {'testlinter1': ['foo', 'bar']} + call ale#linter#Define('testft', g:testlinter1) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft', + \ 'Available Linters: [''testlinter1'']', + \ ' Enabled Linters: [''testlinter1'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + [ + \ ' LSP Error Messages:', + \ '', + \ '(Errors for testlinter1)', + \ 'foo', + \ 'bar', + \ ] + \ + g:command_header + \) + +Given testft (Empty buffer): +Execute (LSP errors for other linters shouldn't appear): + let g:ale_lsp_error_messages = {'testlinter2': ['foo']} + call ale#linter#Define('testft', g:testlinter1) + + call CheckInfo( + \ [ + \ ' Current Filetype: testft', + \ 'Available Linters: [''testlinter1'']', + \ ' Enabled Linters: [''testlinter1'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given testft.testft2 (Empty buffer with two filetypes): +Execute (ALEInfo should include linter global options): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + " eg: like g:c_build_dir_names + let g:ale_testft_build_dir_names = ['build', 'bin'] + + call add(g:variables_lines, 'let g:ale_testft_build_dir_names = [''build'', ''bin'']') + + call CheckInfo( + \ [ + \ ' Current Filetype: testft.testft2', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + +Given testft (Empty buffer with two filetypes): +Execute (ALEInfo should include linter global options for enabled linters): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + + let g:ale_linters = {'testft': ['testlinter1']} + + " should not appear, since not enabled + let g:ale_testft_testlinter2_option = 'test' + + let g:globals_lines[index(g:globals_lines, 'let g:ale_linters = {}')] + \ = 'let g:ale_linters = {''testft'': [''testlinter1'']}' + + call CheckInfo( + \ [ + \ ' Current Filetype: testft', + \ 'Available Linters: [''testlinter1'', ''testlinter2'']', + \ ' Enabled Linters: [''testlinter1'']', + \ ' Ignored Linters: []', + \ ] + \ + g:fixer_lines + \ + g:variables_lines + \ + g:globals_lines + \ + g:command_header + \) + + diff --git a/vim-config/plugins/ale/test/test_ale_info_to_clipboard.vader b/vim-config/plugins/ale/test/test_ale_info_to_clipboard.vader new file mode 100644 index 00000000..2014a310 --- /dev/null +++ b/vim-config/plugins/ale/test/test_ale_info_to_clipboard.vader @@ -0,0 +1,15 @@ +After: + unlet! g:output + +Execute(ALEInfoToClipboard should that clipboard support is required): + " When run in the Docker image, there's no clipboard support, so this test + " will actually run. + if !has('clipboard') + let g:output = '' + + redir => g:output + :ALEInfoToClipboard + redir END + + AssertEqual 'clipboard not available. Try :ALEInfoToFile instead.', join(split(g:output)) + endif diff --git a/vim-config/plugins/ale/test/test_ale_lint_command.vader b/vim-config/plugins/ale/test/test_ale_lint_command.vader new file mode 100644 index 00000000..ba7308dd --- /dev/null +++ b/vim-config/plugins/ale/test/test_ale_lint_command.vader @@ -0,0 +1,77 @@ +Before: + Save g:ale_buffer_info + Save g:ale_enabled + + let g:ale_buffer_info = {} + let g:ale_enabled = 1 + + let g:expected_loclist = [{ + \ 'bufnr': bufnr('%'), + \ 'lnum': 2, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'foo bar', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \}] + + function! ToggleTestCallback(buffer, output) + return [{ + \ 'bufnr': a:buffer, + \ 'lnum': 2, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': join(split(a:output[0])), + \ 'type': 'E', + \ 'nr': -1, + \}] + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'ToggleTestCallback', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': 'echo foo bar', + \}) + +After: + Restore + + unlet! g:expected_loclist + unlet! b:i + + call ale#engine#Cleanup(bufnr('')) + call ale#linter#Reset() + + let g:ale_buffer_info = {} + + delfunction ToggleTestCallback + +Given foobar (Some imaginary filetype): + foo + bar + baz + +Execute(ALELint should run the linters): + AssertEqual 'foobar', &filetype + + " Try to run the linter a few times, as it fails randomly in NeoVim. + for b:i in range(5) + ALELint + call ale#test#WaitForJobs(2000) + + if !has('nvim') + " Sleep so the delayed list function can run. + " This breaks the tests in NeoVim for some reason. + sleep 1ms + endif + + if ale#test#GetLoclistWithoutModule() == g:expected_loclist + break + endif + endfor + + " Check the loclist + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() diff --git a/vim-config/plugins/ale/test/test_ale_lint_stop_command.vader b/vim-config/plugins/ale/test/test_ale_lint_stop_command.vader new file mode 100644 index 00000000..c50db5a8 --- /dev/null +++ b/vim-config/plugins/ale/test/test_ale_lint_stop_command.vader @@ -0,0 +1,27 @@ +Before: + Save g:ale_buffer_info + + let g:ale_buffer_info = {} + + call ale#linter#PreventLoading('testft') + call ale#linter#Define('testft', { + \ 'name': 'testlinter', + \ 'callback': {-> []}, + \ 'executable': has('win32') ? 'cmd' : 'true', + \ 'command': 'sleep 9001', + \}) + +After: + Restore + + call ale#linter#Reset() + +Given testft (An empty file): +Execute(ALELintStop should stop ALE from linting): + ALELint + + Assert ale#engine#IsCheckingBuffer(bufnr('')), 'ALE did not start checking the buffer' + + ALELintStop + + Assert !ale#engine#IsCheckingBuffer(bufnr('')), 'ALELintStop didn''t work' diff --git a/vim-config/plugins/ale/test/test_ale_toggle.vader b/vim-config/plugins/ale/test/test_ale_toggle.vader new file mode 100644 index 00000000..1debcee6 --- /dev/null +++ b/vim-config/plugins/ale/test/test_ale_toggle.vader @@ -0,0 +1,444 @@ +Before: + Save g:ale_buffer_info + Save g:ale_set_signs + Save g:ale_set_lists_synchronously + Save g:ale_run_synchronously + Save g:ale_pattern_options + Save g:ale_pattern_options_enabled + Save g:ale_set_balloons + + let g:ale_set_signs = 1 + let g:ale_set_lists_synchronously = 1 + let g:ale_run_synchronously = 1 + unlet! g:ale_run_synchronously_callbacks + let g:ale_pattern_options = {} + let g:ale_pattern_options_enabled = 1 + let g:ale_set_balloons = + \ has('balloon_eval') && has('gui_running') || + \ has('balloon_eval_term') && !has('gui_running') + + unlet! b:ale_enabled + + let g:ale_buffer_info = {} + let g:expected_loclist = [{ + \ 'bufnr': bufnr('%'), + \ 'lnum': 2, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'foo bar', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \}] + let g:expected_groups = [ + \ 'ALECleanupGroup', + \ 'ALEEvents', + \ 'ALEHighlightBufferGroup', + \] + let g:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace') + + function! ToggleTestCallback(buffer, output) + return [{ + \ 'bufnr': a:buffer, + \ 'lnum': 2, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'foo bar', + \ 'type': 'E', + \ 'nr': -1, + \}] + endfunction + + function! ParseAuGroups() + redir => l:output + silent exec 'autocmd' + redir end + + let l:results = [] + + for l:line in split(l:output, "\n") + let l:match = matchlist(l:line, '^ALE[a-zA-Z]\+') + + " We don't care about some groups here. + if !empty(l:match) + \&& l:match[0] !=# 'ALECompletionGroup' + \&& l:match[0] !=# 'ALEBufferFixGroup' + \&& l:match[0] !=# 'ALEPatternOptionsGroup' + call add(l:results, l:match[0]) + endif + endfor + + call uniq(sort(l:results)) + + return l:results + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'ToggleTestCallback', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': 'echo', + \ 'read_buffer': 0, + \}) + + call ale#sign#Clear() + +After: + Restore + + unlet! g:ale_run_synchronously_callbacks + unlet! g:expected_loclist + unlet! g:expected_groups + unlet! b:ale_enabled + unlet! g:output + unlet! g:has_nvim_highlight + + call ale#linter#Reset() + + " Toggle ALE back on if we fail when it's disabled. + if !g:ale_enabled + ALEToggle + endif + + delfunction ToggleTestCallback + delfunction ParseAuGroups + + call setloclist(0, []) + call ale#sign#Clear() + call clearmatches() + +Given foobar (Some imaginary filetype): + foo + bar + baz + +Execute(ALEToggle should reset everything and then run again): + AssertEqual 'foobar', &filetype + + ALELint + call ale#test#FlushJobs() + + " First check that everything is there... + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) + + " Only check the legacy matches if not using the new NeoVIM API. + if !g:has_nvim_highlight + AssertEqual + \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], + \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}') + endif + + AssertEqual g:expected_groups, ParseAuGroups() + AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist + + " Now Toggle ALE off. + ALEToggle + + " Everything should be cleared. + Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed' + AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared' + AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared' + + if !g:has_nvim_highlight + AssertEqual [], getmatches(), 'The highlights were not cleared' + endif + + AssertEqual g:expected_groups, ParseAuGroups() + + " Toggle ALE on, everything should be set up and run again. + ALEToggle + call ale#test#FlushJobs() + + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) + + if !g:has_nvim_highlight + AssertEqual + \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], + \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}') + endif + + AssertEqual g:expected_groups, ParseAuGroups() + AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist + +Execute(ALEToggle should skip filename keys and preserve them): + AssertEqual 'foobar', &filetype + + let g:ale_buffer_info['/foo/bar/baz.txt'] = { + \ 'job_list': [], + \ 'active_linter_list': [], + \ 'loclist': [], + \ 'temporary_file_list': [], + \ 'temporary_directory_list': [], + \ 'history': [], + \} + + ALELint + call ale#test#FlushJobs() + + " Now Toggle ALE off. + ALEToggle + + AssertEqual + \ { + \ 'job_list': [], + \ 'active_linter_list': [], + \ 'loclist': [], + \ 'temporary_file_list': [], + \ 'temporary_directory_list': [], + \ 'history': [], + \ }, + \ get(g:ale_buffer_info, '/foo/bar/baz.txt', {}) + + " Toggle ALE on again. + ALEToggle + call ale#test#FlushJobs() + + AssertEqual + \ { + \ 'job_list': [], + \ 'active_linter_list': [], + \ 'loclist': [], + \ 'temporary_file_list': [], + \ 'temporary_directory_list': [], + \ 'history': [], + \ }, + \ get(g:ale_buffer_info, '/foo/bar/baz.txt', {}) + +Execute(ALEDisable should reset everything and stay disabled): + ALELint + call ale#test#FlushJobs() + + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + + ALEDisable + call ale#test#FlushJobs() + + AssertEqual [], ale#test#GetLoclistWithoutModule() + AssertEqual 0, g:ale_enabled + + ALEDisable + call ale#test#FlushJobs() + + AssertEqual [], ale#test#GetLoclistWithoutModule() + AssertEqual 0, g:ale_enabled + +Execute(ALEEnable should enable ALE and lint again): + let g:ale_enabled = 0 + + ALEEnable + call ale#test#FlushJobs() + + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + AssertEqual 1, g:ale_enabled + +Execute(ALEReset should reset everything for a buffer): + AssertEqual 'foobar', &filetype + + ALELint + call ale#test#FlushJobs() + + " First check that everything is there... + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) + + if !g:has_nvim_highlight + AssertEqual + \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], + \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}') + endif + + AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist + + " Now Toggle ALE off. + ALEReset + call ale#test#FlushJobs() + + " Everything should be cleared. + Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed' + AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared' + AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared' + + if !g:has_nvim_highlight + AssertEqual [], getmatches(), 'The highlights were not cleared' + endif + + AssertEqual 1, g:ale_enabled + +Execute(ALEToggleBuffer should reset everything and then run again): + AssertEqual 'foobar', &filetype + + ALELint + call ale#test#FlushJobs() + + " First check that everything is there... + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) + + if !g:has_nvim_highlight + AssertEqual + \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], + \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}') + endif + + AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist + + " Now Toggle ALE off. + ALEToggleBuffer + + " Everything should be cleared. + Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed' + AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared' + AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared' + + if !g:has_nvim_highlight + AssertEqual [], getmatches(), 'The highlights were not cleared' + endif + + " Toggle ALE on, everything should be set up and run again. + ALEToggleBuffer + call ale#test#FlushJobs() + + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) + + if !g:has_nvim_highlight + AssertEqual + \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], + \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}') + endif + + AssertEqual g:expected_groups, ParseAuGroups() + AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist + +Execute(ALEDisableBuffer should reset everything and stay disabled): + ALELint + call ale#test#FlushJobs() + + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + + ALEDisableBuffer + call ale#test#FlushJobs() + + AssertEqual [], ale#test#GetLoclistWithoutModule() + AssertEqual 0, b:ale_enabled + +Execute(ALEEnableBuffer should enable ALE and lint again): + let b:ale_enabled = 0 + + ALEEnableBuffer + call ale#test#FlushJobs() + + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + AssertEqual 1, b:ale_enabled + +Execute(ALEEnableBuffer should complain when ALE is disabled globally): + let g:ale_enabled = 0 + let b:ale_enabled = 0 + + redir => g:output + ALEEnableBuffer + redir END + + AssertEqual [], ale#test#GetLoclistWithoutModule() + AssertEqual 0, b:ale_enabled + AssertEqual 0, g:ale_enabled + AssertEqual + \ 'ALE cannot be enabled locally when disabled globally', + \ join(split(g:output)) + +Execute(ALEResetBuffer should reset everything for a buffer): + AssertEqual 'foobar', &filetype + + ALELint + call ale#test#FlushJobs() + + " First check that everything is there... + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() + AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) + + if !g:has_nvim_highlight + AssertEqual + \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], + \ map(getmatches(), '{''group'': v:val.group, ''pos1'': v:val.pos1}') + endif + + AssertEqual [{'lnum': 2, 'bufnr': bufnr(''), 'col': 3, 'linter_name': 'testlinter', 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'foo bar', 'sign_id': 1000001}], g:ale_buffer_info[bufnr('')].loclist + + " Now Toggle ALE off. + ALEResetBuffer + call ale#test#FlushJobs() + + " Everything should be cleared. + Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed' + AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared' + AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared' + + if !g:has_nvim_highlight + AssertEqual [], getmatches(), 'The highlights were not cleared' + endif + + AssertEqual 1, g:ale_enabled + AssertEqual 1, get(b:, 'ale_enabled', 1) + +Execute(Disabling ALE should disable balloons): + " These tests won't run in the console, but we can run them manually in GVim. + if has('balloon_eval') && has('gui_running') + \|| (has('balloon_eval_term') && !has('gui_running')) + call ale#linter#Reset() + + " Enable balloons, so we can check the expr value. + call ale#balloon#Enable() + + if has('balloon_eval') && has('gui_running') + AssertEqual 1, &ballooneval + else + AssertEqual 1, &balloonevalterm + endif + + AssertEqual 'ale#balloon#Expr()', &balloonexpr + + " Toggle ALE off. + ALEToggle + + " The balloon settings should be reset. + if has('balloon_eval') && has('gui_running') + AssertEqual 0, &ballooneval + else + AssertEqual 0, &balloonevalterm + endif + + AssertEqual '', &balloonexpr + endif + +Execute(Enabling ALE should enable balloons if the setting is on): + if has('balloon_eval') && has('gui_running') + \|| (has('balloon_eval_term') && !has('gui_running')) + call ale#linter#Reset() + call ale#balloon#Disable() + ALEDisable + let g:ale_set_balloons = 0 + ALEEnable + + if has('balloon_eval') && has('gui_running') + AssertEqual 0, &ballooneval + else + AssertEqual 0, &balloonevalterm + endif + + AssertEqual '', &balloonexpr + + ALEDisable + let g:ale_set_balloons = 1 + ALEEnable + + if has('balloon_eval') && has('gui_running') + AssertEqual 1, &ballooneval + else + AssertEqual 1, &balloonevalterm + endif + + AssertEqual 'ale#balloon#Expr()', &balloonexpr + endif diff --git a/vim-config/plugins/ale/test/test_ale_var.vader b/vim-config/plugins/ale/test/test_ale_var.vader new file mode 100644 index 00000000..419a9983 --- /dev/null +++ b/vim-config/plugins/ale/test/test_ale_var.vader @@ -0,0 +1,24 @@ +Before: + let g:ale_some_variable = 'abc' + +After: + unlet! g:ale_some_variable + unlet! b:undefined_variable_name + +Execute(ale#Var should return global variables): + AssertEqual 'abc', ale#Var(bufnr(''), 'some_variable') + +Execute(ale#Var should return buffer overrides): + let b:ale_some_variable = 'def' + + AssertEqual 'def', ale#Var(bufnr(''), 'some_variable') + +Execute(ale#Var should return buffer overrides for buffer numbers as strings): + let b:ale_some_variable = 'def' + + AssertEqual 'def', ale#Var(string(bufnr('')), 'some_variable') + +Execute(ale#Var should throw exceptions for undefined variables): + let b:undefined_variable_name = 'def' + + AssertThrows call ale#Var(bufnr(''), 'undefined_variable_name') diff --git a/vim-config/plugins/ale/test/test_alejobstarted_autocmd.vader b/vim-config/plugins/ale/test/test_alejobstarted_autocmd.vader new file mode 100644 index 00000000..6fa1ff8e --- /dev/null +++ b/vim-config/plugins/ale/test/test_alejobstarted_autocmd.vader @@ -0,0 +1,46 @@ +Before: + Save g:ale_buffer_info + + let g:job_started_success = 0 + let g:ale_run_synchronously = 1 + + unlet! b:ale_linted + + function! TestCallback(buffer, output) + return [] + endfunction + + call ale#linter#PreventLoading('testft') + call ale#linter#Define('testft', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'true', + \ 'command': 'true', + \}) + +After: + Restore + + let g:ale_run_synchronously = 0 + + augroup VaderTest + autocmd! + augroup END + + augroup! VaderTest + + unlet! g:job_started_success + + delfunction TestCallback + call ale#linter#Reset() + +Given testft (An empty file): +Execute(Run a lint cycle with an actual job to check for ALEJobStarted): + augroup VaderTest + autocmd! + autocmd User ALEJobStarted let g:job_started_success = 1 + augroup END + + ALELint + + AssertEqual g:job_started_success, 1 diff --git a/vim-config/plugins/ale/test/test_alelint_autocmd.vader b/vim-config/plugins/ale/test/test_alelint_autocmd.vader new file mode 100644 index 00000000..332cb36f --- /dev/null +++ b/vim-config/plugins/ale/test/test_alelint_autocmd.vader @@ -0,0 +1,40 @@ +Before: + let g:pre_success = 0 + let g:post_success = 0 + let g:ale_run_synchronously = 1 + + unlet! b:ale_linted + +After: + let g:ale_run_synchronously = 0 + let g:ale_buffer_info = {} + + augroup VaderTest + autocmd! + augroup END + + augroup! VaderTest + +Given testft(An empty file): +Execute(Run a lint cycle, and check that a variable is set in the autocmd): + augroup VaderTest + autocmd! + autocmd User ALELintPre let g:pre_success = 1 + autocmd User ALELintPost let g:post_success = 1 + augroup END + + call ale#Queue(0) + + AssertEqual g:pre_success, 1 + AssertEqual g:post_success, 1 + +Execute(b:ale_linted should be increased after each lint cycle): + AssertEqual get(b:, 'ale_linted'), 0 + + call ale#Queue(0) + + AssertEqual get(b:, 'ale_linted'), 1 + + call ale#Queue(0) + + AssertEqual get(b:, 'ale_linted'), 2 diff --git a/vim-config/plugins/ale/test/test_ant_build_classpath_command.vader b/vim-config/plugins/ale/test/test_ant_build_classpath_command.vader new file mode 100644 index 00000000..b97dc594 --- /dev/null +++ b/vim-config/plugins/ale/test/test_ant_build_classpath_command.vader @@ -0,0 +1,27 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + runtime ale_linters/java/javac.vim + + Save $PATH + let $PATH = ale#path#Simplify(g:dir . '/test-files/ant/bin') + +After: + Restore + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Should return `cd '[dir]' && 'ant' classpath -S -q`): + call ale#test#SetFilename('test-files/ant/ant-project/Main.java') + + AssertEqual + \ [ + \ ale#path#Simplify(g:dir . '/test-files/ant/ant-project'), + \ ale#Escape('ant') . ' classpath' . ' -S' . ' -q', + \ ], + \ ale#ant#BuildClasspathCommand(bufnr('')) + +Execute(Should return empty string if ant cannot be executed): + call ale#test#SetFilename('test-files/ant/not-an-ant-project/Main.java') + + AssertEqual ['', ''], ale#ant#BuildClasspathCommand(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_ant_find_project_root.vader b/vim-config/plugins/ale/test/test_ant_find_project_root.vader new file mode 100644 index 00000000..b0868ad7 --- /dev/null +++ b/vim-config/plugins/ale/test/test_ant_find_project_root.vader @@ -0,0 +1,35 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + runtime ale_linters/java/javac.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Should return current directory if called on the project root): + call ale#test#SetFilename('test-files/ant/ant-project/Main.java') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/ant/ant-project'), + \ ale#ant#FindProjectRoot(bufnr('')) + +Execute(Should return root directory if called on a deeply nested source file): + call ale#test#SetFilename('test-files/ant/ant-project/src/several/namespace/layers/A.java') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/ant/ant-project'), + \ ale#ant#FindProjectRoot(bufnr('')) + +Execute(Should return empty string if called on a non-ant project): + call ale#test#SetFilename('test-files/ant/non-ant-project/Main.java') + + AssertEqual + \ '', + \ ale#ant#FindProjectRoot(bufnr('')) + +Execute(Should return empty string if called on a file in a non-ant project): + call ale#test#SetFilename('test-files/ant/non-ant-project/several/namespace/layers/A.java') + + AssertEqual + \ '', + \ ale#ant#FindProjectRoot(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_autocmd_commands.vader b/vim-config/plugins/ale/test/test_autocmd_commands.vader new file mode 100644 index 00000000..2f0a893f --- /dev/null +++ b/vim-config/plugins/ale/test/test_autocmd_commands.vader @@ -0,0 +1,238 @@ +Before: + function! CheckAutocmd(group) + call ale#events#Init() + + redir => l:output + execute 'silent! autocmd ' . a:group + redir END + + let l:matches = [] + let l:header = '' + " Some event names have aliases, and NeoVim and Vim produce + " different output. The names are remapped to fix this. + let l:event_name_corrections = { + \ 'BufWrite': 'BufWritePre', + \ 'BufRead': 'BufReadPost', + \} + + " autocmd commands are split across two lines in output, so we + " must merge the lines back into one simple line. + for l:line in split(l:output, "\n") + if l:line =~# '^ALE' && split(l:line)[0] ==# a:group + let l:header = split(l:line)[1] + let l:header = get(l:event_name_corrections, l:header, l:header) + elseif !empty(l:header) + " There's an extra line for buffer events, and we should only look + " for the one matching the current buffer. + if l:line =~# '' + let l:header .= ' ' + elseif l:line[:0] is# ' ' + call add(l:matches, join(split(l:header . l:line))) + else + let l:header = '' + endif + endif + endfor + + call sort(l:matches) + + return l:matches + endfunction + + Save g:ale_completion_enabled + Save g:ale_echo_cursor + Save g:ale_enabled + Save g:ale_fix_on_save + Save g:ale_lint_on_enter + Save g:ale_lint_on_filetype_changed + Save g:ale_lint_on_insert_leave + Save g:ale_lint_on_save + Save g:ale_lint_on_text_changed + Save g:ale_pattern_options_enabled + Save g:ale_hover_cursor + + " Turn everything on by defaul for these tests. + let g:ale_completion_enabled = 1 + let g:ale_echo_cursor = 1 + let g:ale_enabled = 1 + let g:ale_fix_on_save = 1 + let g:ale_lint_on_enter = 1 + let g:ale_lint_on_filetype_changed = 1 + let g:ale_lint_on_insert_leave = 1 + let g:ale_lint_on_save = 1 + let g:ale_lint_on_text_changed = 1 + let g:ale_pattern_options_enabled = 1 + let g:ale_hover_cursor = 1 + +After: + delfunction CheckAutocmd + Restore + + if g:ale_completion_enabled + call ale#completion#Enable() + else + call ale#completion#Disable() + endif + + call ale#events#Init() + +Execute (All events should be set up when everything is on): + let g:ale_echo_cursor = 1 + + AssertEqual + \ [ + \ 'BufEnter * call ale#events#ReadOrEnterEvent(str2nr(expand('''')))', + \ 'BufReadPost * call ale#events#ReadOrEnterEvent(str2nr(expand('''')))', + \ 'BufWinEnter * call ale#events#LintOnEnter(str2nr(expand('''')))', + \ 'BufWritePost * call ale#events#SaveEvent(str2nr(expand('''')))', + \ 'CursorHold * if exists(''*ale#engine#Cleanup'') | call ale#cursor#EchoCursorWarningWithDelay() | endif', + \ 'CursorHold if exists(''*ale#lsp#Send'') | call ale#hover#ShowTruncatedMessageAtCursor() | endif', + \ 'CursorMoved * if exists(''*ale#engine#Cleanup'') | call ale#cursor#EchoCursorWarningWithDelay() | endif', + \ 'FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('''')))', + \ 'FileType * call ale#events#FileTypeEvent( str2nr(expand('''')), expand(''''))', + \ 'InsertLeave * if ale#Var(str2nr(expand('''')), ''lint_on_insert_leave'') | call ale#Queue(0) | endif', + \ 'InsertLeave if exists(''*ale#engine#Cleanup'') | call ale#cursor#EchoCursorWarning() | endif', + \ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand('''')), ''lint_delay''))', + \ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand('''')), ''lint_delay''))', + \ ], + \ CheckAutocmd('ALEEvents') + +Execute (Only the required events should be bound even if various settings are off): + let g:ale_enabled = 1 + let g:ale_completion_enabled = 0 + let g:ale_echo_cursor = 0 + let g:ale_fix_on_save = 0 + let g:ale_lint_on_enter = 0 + let g:ale_lint_on_filetype_changed = 0 + let g:ale_lint_on_insert_leave = 0 + let g:ale_lint_on_save = 0 + let g:ale_lint_on_text_changed = 0 + let g:ale_pattern_options_enabled = 0 + let g:ale_hover_cursor = 0 + + AssertEqual + \ [ + \ 'BufEnter * call ale#events#ReadOrEnterEvent(str2nr(expand('''')))', + \ 'BufReadPost * call ale#events#ReadOrEnterEvent(str2nr(expand('''')))', + \ 'BufWritePost * call ale#events#SaveEvent(str2nr(expand('''')))', + \ ], + \ CheckAutocmd('ALEEvents') + +Execute (The cursor hoever event should be enabled with g:ale_hover_cursor = 1): + let g:ale_enabled = 1 + let g:ale_completion_enabled = 0 + let g:ale_echo_cursor = 0 + let g:ale_fix_on_save = 0 + let g:ale_lint_on_enter = 0 + let g:ale_lint_on_filetype_changed = 0 + let g:ale_lint_on_insert_leave = 0 + let g:ale_lint_on_save = 0 + let g:ale_lint_on_text_changed = 0 + let g:ale_pattern_options_enabled = 0 + let g:ale_hover_cursor = 1 + + AssertEqual + \ [ + \ 'BufEnter * call ale#events#ReadOrEnterEvent(str2nr(expand('''')))', + \ 'BufReadPost * call ale#events#ReadOrEnterEvent(str2nr(expand('''')))', + \ 'BufWritePost * call ale#events#SaveEvent(str2nr(expand('''')))', + \ 'CursorHold * if exists(''*ale#lsp#Send'') | call ale#hover#ShowTruncatedMessageAtCursor() | endif', + \ ], + \ CheckAutocmd('ALEEvents') + +Execute (g:ale_lint_on_text_changed = 1 bind both events): + let g:ale_lint_on_text_changed = 1 + + AssertEqual + \ [ + \ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand('''')), ''lint_delay''))', + \ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand('''')), ''lint_delay''))', + \ ], + \ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''') + +Execute (g:ale_lint_on_text_changed = 'always' should bind both events): + let g:ale_lint_on_text_changed = 'always' + + AssertEqual + \ [ + \ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand('''')), ''lint_delay''))', + \ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand('''')), ''lint_delay''))', + \ ], + \ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''') + +Execute (g:ale_lint_on_text_changed = 'normal' should bind only TextChanged): + let g:ale_lint_on_text_changed = 'normal' + + AssertEqual + \ [ + \ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand('''')), ''lint_delay''))', + \ ], + \ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''') + +Execute (g:ale_lint_on_text_changed = 'insert' should bind only TextChangedI): + let g:ale_lint_on_text_changed = 'insert' + + AssertEqual + \ [ + \ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand('''')), ''lint_delay''))', + \ ], + \ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''') + +Execute (g:ale_lint_on_insert_leave = 1 should bind InsertLeave): + let g:ale_lint_on_insert_leave = 1 + let g:ale_echo_cursor = 0 + + AssertEqual + \ [ + \ 'InsertLeave * if ale#Var(str2nr(expand('''')), ''lint_on_insert_leave'') | call ale#Queue(0) | endif', + \ ], + \ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^InsertLeave''') + +Execute (g:ale_lint_on_filetype_changed = 1 should bind the FileType event): + let g:ale_lint_on_filetype_changed = 1 + + AssertEqual + \ [ + \ 'FileType * call ale#events#FileTypeEvent( ' + \ . 'str2nr(expand('''')), ' + \ . 'expand('''')' + \ . ')', + \ ], + \ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''\v^FileType''') + +Execute (ALECleanupGroup should include the right commands): + if exists('##VimSuspend') + AssertEqual [ + \ 'BufDelete * if exists(''*ale#engine#Cleanup'') | call ale#engine#Cleanup(str2nr(expand(''''))) | endif', + \ 'QuitPre * call ale#events#QuitEvent(str2nr(expand('''')))', + \ 'VimSuspend * if exists(''*ale#engine#CleanupEveryBuffer'') | call ale#engine#CleanupEveryBuffer() | endif', + \], CheckAutocmd('ALECleanupGroup') + else + AssertEqual [ + \ 'BufDelete * if exists(''*ale#engine#Cleanup'') | call ale#engine#Cleanup(str2nr(expand(''''))) | endif', + \ 'QuitPre * call ale#events#QuitEvent(str2nr(expand('''')))', + \], CheckAutocmd('ALECleanupGroup') + endif + +Execute(ALECompletionActions should always be set up): + AssertEqual [ + \ 'CompleteDone * call ale#completion#HandleUserData(v:completed_item)', + \], CheckAutocmd('ALECompletionActions') + +Execute(Enabling completion should set up autocmd events correctly): + let g:ale_completion_enabled = 0 + call ale#completion#Enable() + + AssertEqual [ + \ 'CompleteDone * call ale#completion#Done()', + \ 'TextChangedI * call ale#completion#Queue()', + \], CheckAutocmd('ALECompletionGroup') + AssertEqual 1, g:ale_completion_enabled + +Execute(Disabling completion should remove autocmd events correctly): + let g:ale_completion_enabled = 1 + call ale#completion#Enable() + call ale#completion#Disable() + + AssertEqual [], CheckAutocmd('ALECompletionGroup') + AssertEqual 0, g:ale_completion_enabled diff --git a/vim-config/plugins/ale/test/test_backwards_compatibility.vader b/vim-config/plugins/ale/test/test_backwards_compatibility.vader new file mode 100644 index 00000000..e4e3756f --- /dev/null +++ b/vim-config/plugins/ale/test/test_backwards_compatibility.vader @@ -0,0 +1,19 @@ +" These tests, and the code that it covers, may be removed upon a major release. + +After: + unlet! g:ale_linters_sh_shellcheck_exclusions + unlet! g:ale_sh_shellcheck_exclusions + unlet! g:ale_linters_sh_shell_default_shell + unlet! g:ale_sh_shell_default_shell + +Execute(Old variable name for the 'shellcheck' linter should still work): + let g:ale_linters_sh_shellcheck_exclusions = 'SC1234' + runtime ale_linters/sh/shellcheck.vim + + AssertEqual 'SC1234', g:ale_sh_shellcheck_exclusions + +Execute (Old variable name for the 'shell' linter should still work): + let g:ale_linters_sh_shell_default_shell = 'woosh' + runtime ale_linters/sh/shell.vim + + AssertEqual 'woosh', g:ale_sh_shell_default_shell diff --git a/vim-config/plugins/ale/test/test_balloon_messages.vader b/vim-config/plugins/ale/test/test_balloon_messages.vader new file mode 100644 index 00000000..d0724c21 --- /dev/null +++ b/vim-config/plugins/ale/test/test_balloon_messages.vader @@ -0,0 +1,87 @@ +Before: + Save g:ale_buffer_info + Save g:ale_enabled + Save g:ale_set_balloons + + let g:ale_set_balloons = 1 + + let g:ale_buffer_info[bufnr('')] = {'loclist': [ + \ { + \ 'bufnr': bufnr('%'), + \ 'lnum': 1, + \ 'col': 10, + \ 'linter_name': 'eslint', + \ 'type': 'W', + \ 'text': 'Ignore me.', + \ }, + \ { + \ 'bufnr': bufnr(''), + \ 'lnum': 1, + \ 'col': 10, + \ 'text': 'Missing semicolon. (semi)', + \ 'type': 'E', + \ }, + \ { + \ 'bufnr': bufnr(''), + \ 'lnum': 2, + \ 'col': 10, + \ 'text': 'Infix operators must be spaced. (space-infix-ops)' + \ }, + \ { + \ 'bufnr': bufnr(''), + \ 'lnum': 2, + \ 'col': 15, + \ 'text': 'Missing radix parameter (radix)' + \ }, + \]} + +After: + Restore + + unlet! b:ale_enabled + unlet! b:ale_set_balloons + +Execute(Balloon messages should be shown for the correct lines): + AssertEqual + \ 'Missing semicolon. (semi)', + \ ale#balloon#MessageForPos(bufnr(''), 1, 1) + +Execute(Balloon messages should be shown for earlier columns): + AssertEqual + \ 'Infix operators must be spaced. (space-infix-ops)', + \ ale#balloon#MessageForPos(bufnr(''), 2, 1) + +Execute(Balloon messages should be shown for later columns): + AssertEqual + \ 'Missing radix parameter (radix)', + \ ale#balloon#MessageForPos(bufnr(''), 2, 16) + +Execute(Balloon messages should be disabled if ALE is disabled globally): + let g:ale_enabled = 0 + " Enabling the buffer should not make a difference. + let b:ale_enabled = 1 + + AssertEqual '', ale#balloon#MessageForPos(bufnr(''), 1, 1) + +Execute(Balloon messages should be disabled if ALE is disabled for a buffer): + let b:ale_enabled = 0 + + AssertEqual '', ale#balloon#MessageForPos(bufnr(''), 1, 1) + +Execute(Balloon messages should be disabled if the global setting is off): + let g:ale_set_balloons = 0 + + AssertEqual '', ale#balloon#MessageForPos(bufnr(''), 1, 1) + +Execute(Balloon messages should be disabled if the buffer setting is off): + let b:ale_set_balloons = 0 + + AssertEqual '', ale#balloon#MessageForPos(bufnr(''), 1, 1) + +Execute(The balloon buffer setting should override the global one): + let g:ale_set_balloons = 0 + let b:ale_set_balloons = 1 + + AssertEqual + \ 'Missing semicolon. (semi)', + \ ale#balloon#MessageForPos(bufnr(''), 1, 1) diff --git a/vim-config/plugins/ale/test/test_c_flag_parsing.vader b/vim-config/plugins/ale/test/test_c_flag_parsing.vader new file mode 100644 index 00000000..c661651e --- /dev/null +++ b/vim-config/plugins/ale/test/test_c_flag_parsing.vader @@ -0,0 +1,689 @@ +Before: + Save g:ale_c_parse_makefile + Save g:ale_c_always_make + Save b:ale_c_always_make + + call ale#test#SetDirectory('/testplugin/test') + + let g:ale_c_parse_makefile = 1 + let g:ale_c_always_make = 1 + let b:ale_c_always_make = 1 + + function SplitAndParse(path_prefix, command) abort + let l:args = ale#c#ShellSplit(a:command) + + return ale#c#ParseCFlags(a:path_prefix, 0, l:args) + endfunction + +After: + delfunction SplitAndParse + + Restore + + call ale#test#RestoreDirectory() + +Execute(The make command should be correct): + call ale#test#SetFilename('test-files/c/makefile_project/subdir/file.c') + + AssertEqual + \ [ + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 'make -n --always-make', + \ ], + \ ale#c#GetMakeCommand(bufnr('')) + + " You should be able to disable --always-make for a buffer. + let b:ale_c_always_make = 0 + + AssertEqual + \ [ + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 'make -n', + \ ], + \ ale#c#GetMakeCommand(bufnr('')) + +Execute(Should recognize GNUmakefile as a makefile): + call ale#test#SetFilename('test-files/c/gnumakefile_project/file.c') + + AssertEqual + \ [ + \ ale#path#Simplify(g:dir. '/test-files/c/gnumakefile_project'), + \ 'make -n --always-make', + \ ], + \ ale#c#GetMakeCommand(bufnr('')) + +Execute(The CFlags parser should be able to parse include directives): + call ale#test#SetFilename('test-files/c/makefile_project/subdir/file.c') + + AssertEqual + \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')), + \ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -c file.c']) + + AssertEqual + \ '-isystem ' . ale#Escape('/usr/include/dir'), + \ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -isystem /usr/include/dir -c file.c']) + +Execute(ParseCFlags should ignore -c and -o): + call ale#test#SetFilename('test-files/c/makefile_project/subdir/file.c') + + AssertEqual + \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')), + \ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -c file.c -o a.out']) + +Execute(The CFlags parser should be able to parse macro directives): + call ale#test#SetFilename('test-files/c/makefile_project/subdir/file.c') + + AssertEqual + \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')) + \ . ' -DTEST=1', + \ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -DTEST=1 -c file.c']) + +Execute(The CFlags parser should be able to parse macro directives with spaces): + call ale#test#SetFilename('test-files/c/makefile_project/subdir/file.c') + + AssertEqual + \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')) + \ . ' -DTEST=$(( 2 * 4 ))', + \ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -DTEST=$(( 2 * 4 )) -c file.c']) + +Execute(The CFlags parser should be able to parse shell directives with spaces): + call ale#test#SetFilename('test-files/c/makefile_project/subdir/file.c') + + AssertEqual + \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')) + \ . ' -DTEST=`date +%s`', + \ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -DTEST=`date +%s` -c file.c']) + +Execute(ParseCFlags should be able to parse flags with relative paths): + AssertEqual + \ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/kernel/include')) + \ . ' -DTEST=`date +%s`', + \ SplitAndParse( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 'gcc -Isubdir ' + \ . '-I'. ale#path#Simplify('kernel/include') + \ . ' -DTEST=`date +%s` -c file.c' + \ ) + +Execute(We should handle paths with spaces in double quotes): + AssertEqual + \ '-Dgoal=9' + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/dir with spaces')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/kernel/include')) + \ . ' -DTEST=`date +%s`', + \ SplitAndParse( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' + \ . '-I"dir with spaces"' . ' -I'. ale#path#Simplify('kernel/include') + \ . ' -DTEST=`date +%s` -c file.c' + \ ) + +Execute(ParseCFlags should handle paths with spaces in single quotes): + AssertEqual + \ '-Dgoal=9' + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/dir with spaces')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/kernel/include')) + \ . ' -DTEST=`date +%s`', + \ SplitAndParse( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' + \ . '-I''dir with spaces''' . ' -I'. ale#path#Simplify('kernel/include') + \ . ' -DTEST=`date +%s` -c file.c' + \ ) + +Execute(ParseCFlags should handle paths with minuses): + AssertEqual + \ '-Dgoal=9' + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/dir with spaces')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/dir-with-dash')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/kernel/include')) + \ . ' -DTEST=`date +%s`', + \ SplitAndParse( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' + \ . '-I''dir with spaces''' . ' -Idir-with-dash' + \ . ' -I'. ale#path#Simplify('kernel/include') + \ . ' -DTEST=`date +%s` -c file.c' + \ ) + +Execute(We should handle -D with minuses): + AssertEqual + \ '-Dgoal=9' + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')) + \ . ' -Dmacro-with-dash' + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/dir with spaces')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/dir-with-dash')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/kernel/include')) + \ . ' -DTEST=`date +%s`', + \ SplitAndParse( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' + \ . '-Dmacro-with-dash ' + \ . '-I''dir with spaces''' . ' -Idir-with-dash' + \ . ' -I'. ale#path#Simplify('kernel/include') + \ . ' -DTEST=`date +%s` -c file.c' + \ ) + +Execute(We should handle flags at the end of the line): + AssertEqual + \ '-Dgoal=9' + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/subdir')) + \ . ' -Dmacro-with-dash' + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/dir with spaces')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/dir-with-dash')) + \ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/kernel/include')), + \ SplitAndParse( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' + \ . '-Dmacro-with-dash ' + \ . '-I''dir with spaces''' . ' -Idir-with-dash' + \ . ' -I'. ale#path#Simplify('kernel/include') + \ ) + +Execute(FlagsFromCompileCommands should tolerate empty values): + AssertEqual '', ale#c#FlagsFromCompileCommands(bufnr(''), '') + +Execute(ParseCompileCommandsFlags should tolerate empty values): + AssertEqual '', ale#c#ParseCompileCommandsFlags(bufnr(''), {}, {}) + +Execute(ParseCompileCommandsFlags should parse some basic flags): + silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c')) + + " We should read the absolute path filename entry, not the other ones. + AssertEqual + \ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')), + \ ale#c#ParseCompileCommandsFlags( + \ bufnr(''), + \ { + \ ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'): [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ }, + \ ], + \ "xmms2-mpris.c": [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ }, + \ ], + \ }, + \ { + \ ale#path#Simplify('/foo/bar/xmms2-mpris/src'): [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris/src'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': 'other.c', + \ }, + \ ], + \ "src": [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'), + \ }, + \ ], + \ }, + \ ) + +Execute(ParseCompileCommandsFlags should fall back to files with the same name): + silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c')) + + " We should prefer the basename file flags, not the base dirname flags. + AssertEqual + \ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')), + \ ale#c#ParseCompileCommandsFlags( + \ bufnr(''), + \ { + \ "xmms2-mpris.c": [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ }, + \ ], + \ }, + \ { + \ "src": [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'), + \ }, + \ ], + \ }, + \ ) + +Execute(ParseCompileCommandsFlags should parse flags for exact directory matches): + silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c')) + + " We should ues the exact directory flags, not the file basename flags. + AssertEqual + \ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')), + \ ale#c#ParseCompileCommandsFlags( + \ bufnr(''), + \ { + \ "xmms2-mpris.c": [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ }, + \ ], + \ }, + \ { + \ ale#path#Simplify('/foo/bar/xmms2-mpris/src'): [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris/src'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': 'other.c', + \ }, + \ ], + \ "src": [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'), + \ }, + \ ], + \ }, + \ ) + +Execute(ParseCompileCommandsFlags should fall back to files in the same directory): + silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c')) + + AssertEqual + \ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')), + \ ale#c#ParseCompileCommandsFlags( + \ bufnr(''), + \ {}, + \ { + \ "src": [ + \ { + \ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'), + \ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2') + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'), + \ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'), + \ }, + \ ], + \ }, + \ ) + +Execute(ParseCompileCommandsFlags should tolerate items without commands): + silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c')) + + AssertEqual + \ '', + \ ale#c#ParseCompileCommandsFlags( + \ bufnr(''), + \ { + \ "xmms2-mpris.c": [ + \ { + \ 'directory': '/foo/bar/xmms2-mpris', + \ 'file': '/foo/bar/xmms2-mpris/src/xmms2-mpris.c', + \ }, + \ ], + \ }, + \ {}, + \ ) + +Execute(ParseCompileCommandsFlags should take commands from matching .c files for .h files): + silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.h')) + + AssertEqual + \ '-I ' . ale#Escape('/usr/include/xmms2'), + \ ale#c#ParseCompileCommandsFlags( + \ bufnr(''), + \ { + \ 'xmms2-mpris.c': [ + \ { + \ 'directory': '/foo/bar/xmms2-mpris', + \ 'file': (has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-mpris.c', + \ 'command': '/usr/bin/cc -I' . '/usr/include/xmms2' + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . '/foo/bar/xmms2-mpris/src/xmms2-mpris.c', + \ }, + \ ], + \ }, + \ {}, + \ ) + +Execute(ParseCompileCommandsFlags should take commands from matching .cpp files for .hpp files): + silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.hpp')) + + AssertEqual + \ '-I ' . ale#Escape('/usr/include/xmms2'), + \ ale#c#ParseCompileCommandsFlags( + \ bufnr(''), + \ { + \ 'xmms2-mpris.cpp': [ + \ { + \ 'directory': '/foo/bar/xmms2-mpris', + \ 'file': (has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-mpris.cpp', + \ 'command': '/usr/bin/cc -I' . '/usr/include/xmms2' + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . '/foo/bar/xmms2-mpris/src/xmms2-mpris.cpp', + \ }, + \ ], + \ }, + \ { + \ }, + \ ) + +Execute(ParseCompileCommandsFlags should take commands from matching .cpp files for .h files): + silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.h')) + + AssertEqual + \ '-I ' . ale#Escape('/usr/include/xmms2'), + \ ale#c#ParseCompileCommandsFlags( + \ bufnr(''), + \ { + \ 'xmms2-mpris.cpp': [ + \ { + \ 'directory': '/foo/bar/xmms2-mpris', + \ 'file': (has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-mpris.cpp', + \ 'command': '/usr/bin/cc -I' . '/usr/include/xmms2' + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . '/foo/bar/xmms2-mpris/src/xmms2-mpris.cpp', + \ }, + \ ], + \ }, + \ { + \ }, + \ ) + +Execute(ParseCompileCommandsFlags should not take commands from .c files for .h files with different names): + silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/other.h')) + + AssertEqual + \ '', + \ ale#c#ParseCompileCommandsFlags( + \ bufnr(''), + \ { + \ 'xmms2-mpris.c': [ + \ { + \ 'directory': '/foo/bar/xmms2-mpris', + \ 'file': (has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-mpris.c', + \ 'command': '/usr/bin/cc -I' . '/usr/include/xmms2' + \ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o' + \ . ' -c ' . '/foo/bar/xmms2-mpris/src/xmms2-mpris.c', + \ }, + \ ], + \ }, + \ { + \ }, + \ ) + +Execute(ShellSplit should not merge flags): + AssertEqual + \ [ + \ 'gcc', + \ '-Dgoal=9', + \ '-Tlinkerfile.ld', + \ 'blabla', + \ '-Isubdir', + \ 'subdir/somedep1.o', + \ 'subdir/somedep2.o', + \ '-I''dir with spaces''', + \ '-Idir-with-dash', + \ 'subdir/somedep3.o', + \ 'subdir/somedep4.o', + \ '-I' . ale#path#Simplify('kernel/include'), + \ 'subdir/somedep5.o', + \ 'subdir/somedep6.o', + \ ], + \ ale#c#ShellSplit( + \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' + \ . 'subdir/somedep1.o ' . 'subdir/somedep2.o ' + \ . '-I''dir with spaces''' . ' -Idir-with-dash ' + \ . 'subdir/somedep3.o ' . 'subdir/somedep4.o ' + \ . ' -I'. ale#path#Simplify('kernel/include') . ' ' + \ . 'subdir/somedep5.o ' . 'subdir/somedep6.o' + \ ) + +Execute(ShellSplit should handle parenthesis and quotes): + AssertEqual + \ [ + \ 'gcc', + \ '-Dgoal=9', + \ '-Tlinkerfile.ld', + \ 'blabla', + \ '-Dtest1="('' '')"', + \ 'file1.o', + \ '-Dtest2=''(` `)''', + \ 'file2.o', + \ '-Dtest3=`(" ")`', + \ 'file3.o', + \ ] , + \ ale#c#ShellSplit( + \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla ' + \ . '-Dtest1="('' '')" file1.o ' + \ . '-Dtest2=''(` `)'' file2.o ' + \ . '-Dtest3=`(" ")` file3.o' + \ ) + +Execute(We should include several important flags): + AssertEqual + \ '-I ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/inc')) + \ . ' -I ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/include')) + \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/incquote')) + \ . ' -isystem ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/incsystem')) + \ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/incafter')) + \ . ' -iframework ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/incframework')) + \ . ' -include file.h' + \ . ' -imacros macros.h' + \ . ' -Dmacro="value"' + \ . ' -DGoal=9' + \ . ' -D macro2' + \ . ' -D macro3="value"' + \ . ' -Bbdir' + \ . ' -B bdir2' + \ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3' + \ . ' -isysroot sysroot --sysroot=test --no-sysroot-suffix -imultilib multidir' + \ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi' + \ . ' -foption -O2 -C -CC -trigraphs -nostdinc -nostdinc++' + \ . ' -iplugindir=dir -march=native -w', + \ ale#c#ParseCFlags( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 0, + \ [ + \ 'gcc', + \ '-Iinc', + \ '-I', + \ 'include', + \ '-iquote', + \ 'incquote', + \ '-isystem', + \ 'incsystem', + \ '-idirafter', + \ 'incafter', + \ '-iframework', + \ 'incframework', + \ '-include', + \ 'file.h', + \ '-imacros', + \ 'macros.h', + \ '-Dmacro="value"', + \ '-DGoal=9', + \ '-D', + \ 'macro2', + \ '-D', + \ 'macro3="value"', + \ '-Bbdir', + \ '-B', + \ 'bdir2', + \ '-iprefix', + \ 'prefix', + \ '-iwithprefix', + \ 'prefix2', + \ '-iwithprefixbefore', + \ 'prefix3', + \ '-isysroot', + \ 'sysroot', + \ '--sysroot=test', + \ '--no-sysroot-suffix', + \ '-imultilib', + \ 'multidir', + \ '-Wsome-warning', + \ '-std=c89', + \ '-pedantic', + \ '-pedantic-errors', + \ '-ansi', + \ '-foption', + \ '-O2', + \ '-C', + \ '-CC', + \ '-trigraphs', + \ '-nostdinc', + \ '-nostdinc++', + \ '-iplugindir=dir', + \ '-march=native', + \ '-w', + \ ], + \ ) + +Execute(We should quote the flags we need to quote): + AssertEqual + \ '-I ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/inc')) + \ . ' -I ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/include')) + \ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/incquote')) + \ . ' -isystem ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/incsystem')) + \ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test-files/c/makefile_project/incafter')) + \ . ' -iframework ' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/c/makefile_project/incframework')) + \ . ' -include file.h' + \ . ' -imacros macros.h' + \ . ' ' . ale#Escape('-Dmacro="value"') + \ . ' -DGoal=9' + \ . ' -D macro2' + \ . ' -D ' . ale#Escape('macro3="value"') + \ . ' -Bbdir' + \ . ' -B bdir2' + \ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3' + \ . ' -isysroot sysroot --sysroot=test' + \ . ' ' . ale#Escape('--sysroot="quoted"') + \ . ' ' . ale#Escape('--sysroot=foo bar') + \ . ' --no-sysroot-suffix -imultilib multidir' + \ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi' + \ . ' -foption -O2 -C -CC -trigraphs -nostdinc -nostdinc++' + \ . ' -iplugindir=dir -march=native -w', + \ ale#c#ParseCFlags( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 1, + \ [ + \ 'gcc', + \ '-Iinc', + \ '-I', + \ 'include', + \ '-iquote', + \ 'incquote', + \ '-isystem', + \ 'incsystem', + \ '-idirafter', + \ 'incafter', + \ '-iframework', + \ 'incframework', + \ '-include', + \ 'file.h', + \ '-imacros', + \ 'macros.h', + \ '-Dmacro="value"', + \ '-DGoal=9', + \ '-D', + \ 'macro2', + \ '-D', + \ 'macro3="value"', + \ '-Bbdir', + \ '-B', + \ 'bdir2', + \ '-iprefix', + \ 'prefix', + \ '-iwithprefix', + \ 'prefix2', + \ '-iwithprefixbefore', + \ 'prefix3', + \ '-isysroot', + \ 'sysroot', + \ '--sysroot=test', + \ '--sysroot="quoted"', + \ '--sysroot=foo bar', + \ '--no-sysroot-suffix', + \ '-imultilib', + \ 'multidir', + \ '-Wsome-warning', + \ '-std=c89', + \ '-pedantic', + \ '-pedantic-errors', + \ '-ansi', + \ '-foption', + \ '-O2', + \ '-C', + \ '-CC', + \ '-trigraphs', + \ '-nostdinc', + \ '-nostdinc++', + \ '-iplugindir=dir', + \ '-march=native', + \ '-w', + \ ], + \ ) + +Execute(We should exclude other flags that cause problems): + AssertEqual + \ '', + \ ale#c#ParseCFlags( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 0, + \ [ + \ 'gcc', + \ '-Wl,option', + \ '-Wa,option', + \ '-Wp,option', + \ '-c', + \ 'filename.c', + \ 'somelib.a', + \ '-fdump-file=name', + \ '-fdiagnostics-arg', + \ '-fno-show-column', + \ '-fstack-usage', + \ '-Tlinkerfile.ld', + \ ], + \ ) + +Execute(We should expand @file in CFlags): + AssertEqual + \ '-DARGS1 -DARGS2 -O2', + \ ale#c#ParseCFlags( + \ ale#path#Simplify(g:dir. '/test-files/c/makefile_project'), + \ 0, + \ [ + \ 'gcc', + \ '-g', + \ '@./args', + \ '-O2', + \ ], + \ ) diff --git a/vim-config/plugins/ale/test/test_checkingbuffer_autocmd.vader b/vim-config/plugins/ale/test/test_checkingbuffer_autocmd.vader new file mode 100644 index 00000000..9e642b15 --- /dev/null +++ b/vim-config/plugins/ale/test/test_checkingbuffer_autocmd.vader @@ -0,0 +1,57 @@ +Before: + Save g:ale_run_synchronously + Save g:ale_buffer_info + + let g:ale_run_synchronously = 1 + let g:ale_buffer_info = {} + + let g:checking_buffer = 0 + + unlet! b:ale_linted + + function! TestCallback(buffer, output) + return [] + endfunction + + call ale#linter#PreventLoading('testft') + call ale#linter#Define('testft', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'true', + \ 'command': 'true', + \}) + +After: + Restore + + unlet! g:checking_buffer + + delfunction TestCallback + call ale#linter#Reset() + + augroup VaderTest + autocmd! + augroup END + + augroup! VaderTest + +Given testft (An empty file): +Execute(ALELintPre should not return success on ale#engine#IsCheckingBuffer): + augroup VaderTest + autocmd! + autocmd User ALELintPre let g:checking_buffer = ale#engine#IsCheckingBuffer(bufnr('')) ? 1 : 0 + augroup END + + ALELint + + AssertEqual g:checking_buffer, 0 + +Execute(ALEJobStarted should return success on ale#engine#IsCheckingBuffer): + augroup VaderTest + autocmd! + autocmd User ALEJobStarted let g:checking_buffer = ale#engine#IsCheckingBuffer(bufnr('')) ? 1 : 0 + augroup END + + ALELint + + AssertEqual g:checking_buffer, 1 diff --git a/vim-config/plugins/ale/test/test_cleanup.vader b/vim-config/plugins/ale/test/test_cleanup.vader new file mode 100644 index 00000000..232874aa --- /dev/null +++ b/vim-config/plugins/ale/test/test_cleanup.vader @@ -0,0 +1,14 @@ +After: + unlet! g:buffer + let g:ale_buffer_info = {} + +Execute('ALE globals should be cleared when the buffer is deleted): + new + + let g:ale_buffer_info = { + \ bufnr(''): {'temporary_file_list': [], 'temporary_directory_list': []}, + \ 10347: {'temporary_file_list': [], 'temporary_directory_list': []}, + \} + + bdelete + AssertEqual {10347: {'temporary_file_list': [], 'temporary_directory_list': []}}, g:ale_buffer_info diff --git a/vim-config/plugins/ale/test/test_code_action.vader b/vim-config/plugins/ale/test/test_code_action.vader new file mode 100644 index 00000000..c613222c --- /dev/null +++ b/vim-config/plugins/ale/test/test_code_action.vader @@ -0,0 +1,408 @@ +Before: + Save g:ale_enabled + let g:ale_enabled = 0 + + let g:file1 = tempname() + let g:file2 = tempname() + let g:test = {} + + let g:test.create_change = {line, offset, end_line, end_offset, value -> + \{ + \ 'changes': [{ + \ 'fileName': g:file1, + \ 'textChanges': [{ + \ 'start': { + \ 'line': line, + \ 'offset': offset, + \ }, + \ 'end': { + \ 'line': end_line, + \ 'offset': end_offset, + \ }, + \ 'newText': value, + \ }], + \ }] + \}} + + function! WriteFileAndEdit() abort + let g:test.text = [ + \ 'class Name {', + \ ' value: string', + \ '}', + \] + call writefile(g:test.text, g:file1, 'S') + execute 'edit ' . g:file1 + endfunction! + +After: + " Close the extra buffers if we opened it. + if bufnr(g:file1) != -1 + execute ':bp! | :bd! ' . bufnr(g:file1) + endif + if bufnr(g:file2) != -1 + execute ':bp! | :bd! ' . bufnr(g:file2) + endif + + if filereadable(g:file1) + call delete(g:file1) + endif + if filereadable(g:file2) + call delete(g:file2) + endif + + unlet! g:file1 + unlet! g:file2 + unlet! g:test + unlet! g:changes + delfunction WriteFileAndEdit + + Restore + + +Execute(It should modify and save multiple files): + call writefile([ + \ 'class Name {', + \ ' value: string', + \ '}', + \ '', + \ 'class B {', + \ ' constructor(readonly a: Name) {}', + \ '}' + \], g:file1, 'S') + call writefile([ + \ 'import A from "A"', + \ 'import {', + \ ' B,', + \ ' C,', + \ '} from "module"', + \ 'import D from "D"', + \], g:file2, 'S') + + call ale#code_action#HandleCodeAction( + \ { + \ 'changes': [{ + \ 'fileName': g:file1, + \ 'textChanges': [{ + \ 'start': { + \ 'line': 1, + \ 'offset': 7, + \ }, + \ 'end': { + \ 'line': 1, + \ 'offset': 11, + \ }, + \ 'newText': 'Value', + \ }, { + \ 'start': { + \ 'line': 6, + \ 'offset': 27, + \ }, + \ 'end': { + \ 'line': 6, + \ 'offset': 31, + \ }, + \ 'newText': 'Value', + \ }], + \ }, { + \ 'fileName': g:file2, + \ 'textChanges': [{ + \ 'start': { + \ 'line': 2, + \ 'offset': 1, + \ }, + \ 'end': { + \ 'line': 6, + \ 'offset': 1, + \ }, + \ 'newText': "import {A, B} from 'module'\n\n", + \ }] + \ }], + \ }, + \ {'should_save': 1}, + \) + + AssertEqual [ + \ 'class Value {', + \ ' value: string', + \ '}', + \ '', + \ 'class B {', + \ ' constructor(readonly a: Value) {}', + \ '}', + \ '', + \], readfile(g:file1, 'b') + + AssertEqual [ + \ 'import A from "A"', + \ 'import {A, B} from ''module''', + \ '', + \ 'import D from "D"', + \ '', + \], readfile(g:file2, 'b') + + +Execute(Beginning of file can be modified): + let g:test.text = [ + \ 'class Name {', + \ ' value: string', + \ '}', + \] + call writefile(g:test.text, g:file1, 'S') + + call ale#code_action#HandleCodeAction( + \ { + \ 'changes': [{ + \ 'fileName': g:file1, + \ 'textChanges': [{ + \ 'start': { + \ 'line': 1, + \ 'offset': 1, + \ }, + \ 'end': { + \ 'line': 1, + \ 'offset': 1, + \ }, + \ 'newText': "type A: string\ntype B: number\n", + \ }], + \ }] + \ }, + \ {'should_save': 1}, + \) + + AssertEqual [ + \ 'type A: string', + \ 'type B: number', + \] + g:test.text + [''], readfile(g:file1, 'b') + + +Execute(End of file can be modified): + let g:test.text = [ + \ 'class Name {', + \ ' value: string', + \ '}', + \] + call writefile(g:test.text, g:file1, 'S') + + call ale#code_action#HandleCodeAction( + \ { + \ 'changes': [{ + \ 'fileName': g:file1, + \ 'textChanges': [{ + \ 'start': { + \ 'line': 4, + \ 'offset': 1, + \ }, + \ 'end': { + \ 'line': 4, + \ 'offset': 1, + \ }, + \ 'newText': "type A: string\ntype B: number\n", + \ }], + \ }] + \ }, + \ {'should_save': 1}, + \) + + AssertEqual g:test.text + [ + \ 'type A: string', + \ 'type B: number', + \ '', + \], readfile(g:file1, 'b') + + +Execute(Current buffer contents will be reloaded): + let g:test.text = [ + \ 'class Name {', + \ ' value: string', + \ '}', + \] + call writefile(g:test.text, g:file1, 'S') + + execute 'edit ' . g:file1 + let g:test.buffer = bufnr(g:file1) + + call ale#code_action#HandleCodeAction( + \ { + \ 'changes': [{ + \ 'fileName': g:file1, + \ 'textChanges': [{ + \ 'start': { + \ 'line': 1, + \ 'offset': 1, + \ }, + \ 'end': { + \ 'line': 1, + \ 'offset': 1, + \ }, + \ 'newText': "type A: string\ntype B: number\n", + \ }], + \ }] + \ }, + \ {'should_save': 1}, + \) + + AssertEqual [ + \ 'type A: string', + \ 'type B: number', + \] + g:test.text + [''], readfile(g:file1, 'b') + + AssertEqual [ + \ 'type A: string', + \ 'type B: number', + \] + g:test.text, getbufline(g:test.buffer, 1, '$') + + +# Tests for cursor repositioning. In comments `=` designates change range, and +# `C` cursor position + +# C === +Execute(Cursor will not move when it is before text change): + call WriteFileAndEdit() + let g:test.changes = g:test.create_change(2, 3, 2, 8, 'value2') + + call setpos('.', [0, 1, 1, 0]) + call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1}) + AssertEqual [1, 1], getpos('.')[1:2] + + call setpos('.', [0, 2, 2, 0]) + call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1}) + AssertEqual [2, 2], getpos('.')[1:2] + +# ====C==== +Execute(Cursor column will move to the change end when cursor between start/end): + let g:test.changes = g:test.create_change(2, 3, 2, 8, 'value2') + + for r in range(3, 8) + call WriteFileAndEdit() + call setpos('.', [0, 2, r, 0]) + AssertEqual ' value: string', getline('.') + call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1}) + AssertEqual ' value2: string', getline('.') + AssertEqual [2, 9], getpos('.')[1:2] + endfor + + +# ====C +Execute(Cursor column will move back when new text is shorter): + call WriteFileAndEdit() + call setpos('.', [0, 2, 8, 0]) + AssertEqual ' value: string', getline('.') + call ale#code_action#HandleCodeAction( + \ g:test.create_change(2, 3, 2, 8, 'val'), + \ {'should_save': 1}, + \) + AssertEqual ' val: string', getline('.') + AssertEqual [2, 6], getpos('.')[1:2] + + +# ==== C +Execute(Cursor column will move forward when new text is longer): + call WriteFileAndEdit() + + call setpos('.', [0, 2, 8, 0]) + AssertEqual ' value: string', getline('.') + call ale#code_action#HandleCodeAction( + \ g:test.create_change(2, 3, 2, 8, 'longValue'), {'should_save': 1}) + AssertEqual ' longValue: string', getline('.') + AssertEqual [2, 12], getpos('.')[1:2] + +# ========= +# = +# C +Execute(Cursor line will move when updates are happening on lines above): + call WriteFileAndEdit() + call setpos('.', [0, 3, 1, 0]) + AssertEqual '}', getline('.') + call ale#code_action#HandleCodeAction( + \ g:test.create_change(1, 1, 2, 1, "test\ntest\n"), {'should_save': 1}) + AssertEqual '}', getline('.') + AssertEqual [4, 1], getpos('.')[1:2] + + +# ========= +# =C +Execute(Cursor line and column will move when change on lines above and just before cursor column): + call WriteFileAndEdit() + call setpos('.', [0, 2, 2, 0]) + AssertEqual ' value: string', getline('.') + call ale#code_action#HandleCodeAction( + \ g:test.create_change(1, 1, 2, 1, "test\ntest\n123"), {'should_save': 1}) + AssertEqual '123 value: string', getline('.') + AssertEqual [3, 5], getpos('.')[1:2] + +# ========= +# ======C== +# = +Execute(Cursor line and column will move at the end of changes): + call WriteFileAndEdit() + call setpos('.', [0, 2, 10, 0]) + AssertEqual ' value: string', getline('.') + call ale#code_action#HandleCodeAction( + \ g:test.create_change(1, 1, 3, 1, "test\n"), {'should_save': 1}) + AssertEqual '}', getline('.') + AssertEqual [2, 1], getpos('.')[1:2] + +# C == +# === +Execute(Cursor will not move when changes happening on lines >= cursor, but after cursor): + call WriteFileAndEdit() + call setpos('.', [0, 2, 3, 0]) + AssertEqual ' value: string', getline('.') + call ale#code_action#HandleCodeAction( + \ g:test.create_change(2, 10, 3, 1, "number\n"), {'should_save': 1}) + AssertEqual ' value: number', getline('.') + AssertEqual [2, 3], getpos('.')[1:2] + +Execute(Cursor will not move when change covers entire file): + call WriteFileAndEdit() + call setpos('.', [0, 2, 3, 0]) + call ale#code_action#HandleCodeAction( + \ g:test.create_change(1, 1, len(g:test.text) + 1, 1, + \ join(g:test.text + ['x'], "\n")), + \ {'should_save': 1}) + AssertEqual [2, 3], getpos('.')[1:2] + +Execute(It should just modify file when should_save is set to v:false): + call WriteFileAndEdit() + let g:test.change = g:test.create_change(1, 1, 1, 1, "import { writeFile } from 'fs';\n") + call ale#code_action#HandleCodeAction(g:test.change, {}) + AssertEqual 1, getbufvar(bufnr(''), '&modified') + AssertEqual [ + \ 'import { writeFile } from ''fs'';', + \ 'class Name {', + \ ' value: string', + \ '}', + \], getline(1, '$') + +Given typescript(An example TypeScript file): + type Foo = {} + + export interface ISomething { + fooLongName: Foo | null + } + + export class SomethingElse implements ISomething { + // Bindings + fooLongName!: ISomething['fooLongName'] + } + +Execute(): + let g:changes = [ + \ {'end': {'offset': 14, 'line': 4}, 'newText': 'foo', 'start': {'offset': 3, 'line': 4}}, + \ {'end': {'offset': 40, 'line': 9}, 'newText': 'foo', 'start': {'offset': 29, 'line': 9}}, + \ {'end': {'offset': 14, 'line': 9}, 'newText': 'foo', 'start': {'offset': 3, 'line': 9}}, + \] + + call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0) + +Expect(The changes should be applied correctly): + type Foo = {} + + export interface ISomething { + foo: Foo | null + } + + export class SomethingElse implements ISomething { + // Bindings + foo!: ISomething['foo'] + } diff --git a/vim-config/plugins/ale/test/test_code_action_corner_cases.vader b/vim-config/plugins/ale/test/test_code_action_corner_cases.vader new file mode 100644 index 00000000..c44cf0ea --- /dev/null +++ b/vim-config/plugins/ale/test/test_code_action_corner_cases.vader @@ -0,0 +1,179 @@ +" Tests for various corner cases of applying code changes from LSP. +" +" These can be verified against the reference vscode implementation using the +" following javascript program: +" +" const { TextDocument } = require('vscode-languageserver-textdocument'); +" const { TextEdit, Position, Range } = require('vscode-languageserver-types'); +" function MkPos(line, offset) { return Position.create(line - 1, offset - 1); } +" function MkInsert(pos, newText) { return TextEdit.insert(pos, newText); } +" function MkDelete(start, end) { return TextEdit.del(Range.create(start, end)); } +" function TestChanges(s, es) { +" return TextDocument.applyEdits(TextDocument.create(null, null, null, s), es); +" } +" +" const fs = require("fs"); +" const assert = require('assert').strict; +" const testRegex = /(? ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)} + endfunction + + function! ale#lsp#HasCapability(conn_id, capability) abort + let g:capability_checked = a:capability + + return 1 + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + + return 42 + endfunction + + function! ale#util#Execute(expr) abort + call add(g:expr_list, a:expr) + endfunction + + function! ale#code_action#HandleCodeAction(code_action, options) abort + let g:handle_code_action_called = 1 + Assert !get(a:options, 'should_save') + call add(g:code_actions, a:code_action) + endfunction + + function! ale#util#Input(message, value) abort + return '2' + endfunction + +After: + Restore + + if g:conn_id isnot v:null + call ale#lsp#RemoveConnectionWithID(g:conn_id) + endif + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + unlet! g:capability_checked + unlet! g:InitCallback + unlet! g:old_filename + unlet! g:conn_id + unlet! g:Callback + unlet! g:message_list + unlet! g:expr_list + unlet! b:ale_linters + unlet! g:options + unlet! g:code_actions + unlet! g:handle_code_action_called + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/codefix.vim + runtime autoload/ale/code_action.vim + +Execute(Failed codefix responses should be handled correctly): + call ale#codefix#HandleTSServerResponse( + \ 1, + \ {'command': 'getCodeFixes', 'request_seq': 3} + \) + AssertEqual g:handle_code_action_called, 0 + +Given typescript(Some typescript file): + foo + somelongerline () + bazxyzxyzxyz + +Execute(getCodeFixes from tsserver should be handled): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, { + \ 'command': 'getCodeFixes', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'type': 'response', + \ 'body': [ + \ { + \ 'description': 'Import default "x" from module "./z"', + \ 'fixName': 'import', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1, + \ }, + \ 'newText': 'import x from "./z";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1, + \ } + \ } + \ ] + \ } + \ ] + \ } + \ ] + \}) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [ + \ { + \ 'description': 'codefix', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1 + \ }, + \ 'newText': 'import x from "./z";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1 + \ } + \ } + \ ] + \ } + \ ] + \ } + \ ], + \ g:code_actions + +Execute(getCodeFixes from tsserver should be handled with user input if there are more than one action): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, { + \ 'command': 'getCodeFixes', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'type': 'response', + \ 'body': [ + \ { + \ 'description': 'Import default "x" from module "./z"', + \ 'fixName': 'import', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1, + \ }, + \ 'newText': 'import x from "./z";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1, + \ } + \ } + \ ] + \ } + \ ] + \ }, + \ { + \ 'description': 'Import default "x" from module "./y"', + \ 'fixName': 'import', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1, + \ }, + \ 'newText': 'import x from "./y";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1, + \ } + \ } + \ ] + \ } + \ ] + \ } + \ ] + \}) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [ + \ { + \ 'description': 'codefix', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1 + \ }, + \ 'newText': 'import x from "./y";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1 + \ } + \ } + \ ] + \ } + \ ] + \ } + \ ], + \ g:code_actions + +Execute(Prints a tsserver error message when getCodeFixes unsuccessful): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, { + \ 'command': 'getCodeFixes', + \ 'request_seq': 3, + \ 'success': v:false, + \ 'message': 'something is wrong', + \}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''Error while getting code fixes. Reason: something is wrong'''], g:expr_list + +Execute(Does nothing when where are no code fixes): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, { + \ 'command': 'getCodeFixes', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': [] + \}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''No code fixes available.'''], g:expr_list + +Execute(tsserver codefix requests should be sent): + call ale#linter#Reset() + + runtime ale_linters/typescript/tsserver.vim + let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'code': 2304, 'linter_name': 'tsserver'}]}} + call setpos('.', [bufnr(''), 2, 16, 0]) + + " ALECodeAction + call ale#codefix#Execute(0) + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'code_actions', g:capability_checked + AssertEqual + \ 'function(''ale#codefix#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@getCodeFixes', { + \ 'startLine': 2, + \ 'startOffset': 16, + \ 'endLine': 2, + \ 'endOffset': 17, + \ 'file': expand('%:p'), + \ 'errorCodes': [2304], + \ }] + \ ], + \ g:message_list + +Execute(tsserver codefix requests should be sent only for error with code): + call ale#linter#Reset() + + runtime ale_linters/typescript/tsserver.vim + let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 16, 'linter_name': 'tsserver'}, {'lnum': 2, 'col': 16, 'code': 2304, 'linter_name': 'tsserver'}]}} + call setpos('.', [bufnr(''), 2, 16, 0]) + + " ALECodeAction + call ale#codefix#Execute(0) + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'code_actions', g:capability_checked + AssertEqual + \ 'function(''ale#codefix#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@getCodeFixes', { + \ 'startLine': 2, + \ 'startOffset': 16, + \ 'endLine': 2, + \ 'endOffset': 17, + \ 'file': expand('%:p'), + \ 'errorCodes': [2304], + \ }] + \ ], + \ g:message_list + +Execute(getApplicableRefactors from tsserver should be handled): + call ale#codefix#SetMap({3: { + \ 'buffer': expand('%:p'), + \ 'line': 1, + \ 'column': 2, + \ 'end_line': 3, + \ 'end_column': 4, + \ 'connection_id': 0, + \}}) + call ale#codefix#HandleTSServerResponse(1, + \ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [{'actions': [{'description': 'Extract to constant in enclosing scope', 'name': 'constant_scope_0'}], 'description': 'Extract constant', 'name': 'Extract Symbol'}, {'actions': [{'description': 'Extract to function in module scope', 'name': 'function_scope_1'}], 'description': 'Extract function', 'name': 'Extract Symbol'}], 'command': 'getApplicableRefactors'}) + + AssertEqual + \ [ + \ [0, 'ts@getEditsForRefactor', { + \ 'startLine': 1, + \ 'startOffset': 2, + \ 'endLine': 3, + \ 'endOffset': 5, + \ 'file': expand('%:p'), + \ 'refactor': 'Extract Symbol', + \ 'action': 'function_scope_1', + \ }] + \ ], + \ g:message_list + +Execute(getApplicableRefactors should print error on failure): + call ale#codefix#SetMap({3: { + \ 'buffer': expand('%:p'), + \ 'line': 1, + \ 'column': 2, + \ 'end_line': 3, + \ 'end_column': 4, + \ 'connection_id': 0, + \}}) + call ale#codefix#HandleTSServerResponse(1, + \ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getApplicableRefactors'}) + + AssertEqual ['echom ''Error while getting applicable refactors. Reason: oops'''], g:expr_list + +Execute(getApplicableRefactors should do nothing if there are no refactors): + call ale#codefix#SetMap({3: { + \ 'buffer': expand('%:p'), + \ 'line': 1, + \ 'column': 2, + \ 'end_line': 3, + \ 'end_column': 4, + \ 'connection_id': 0, + \}}) + call ale#codefix#HandleTSServerResponse(1, + \ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [], 'command': 'getApplicableRefactors'}) + + AssertEqual ['echom ''No applicable refactors available.'''], g:expr_list + +Execute(getEditsForRefactor from tsserver should be handled): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, + \{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': {'edits': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}], 'renameLocation': {'offset': 3, 'line': 8}, 'renameFilename': '/foo/bar/file.ts'}, 'command': 'getEditsForRefactor' } + \) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [ + \ { + \ 'description': 'editsForRefactor', + \ 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}], + \ } + \ ], + \ g:code_actions + +Execute(getEditsForRefactor should print error on failure): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, + \{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getEditsForRefactor' } + \) + + AssertEqual ['echom ''Error while getting edits for refactor. Reason: oops'''], g:expr_list + +Execute(Failed LSP responses should be handled correctly): + call ale#codefix#HandleLSPResponse( + \ 1, + \ {'method': 'workspace/applyEdit', 'request_seq': 3} + \) + AssertEqual g:handle_code_action_called, 0 + +Given python(Some python file): + def main(): + a = 1 + b = a + 2 + +Execute("workspace/applyEdit" from LSP should be handled): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 0, 'jsonrpc': '2.0', 'method': 'workspace/applyEdit', 'params': {'edit': {'changes': {'file:///foo/bar/file.ts': [{'range': {'end': {'character': 27, 'line': 7}, 'start': {'character': 27, 'line': 7}}, 'newText': ', Config'}, {'range': {'end': {'character': 12, 'line': 96}, 'start': {'character': 2, 'line': 94}}, 'newText': 'await newFunction(redis, imageKey, cover, config);'}, {'range': {'end': {'character': 2, 'line': 99}, 'start': {'character': 2, 'line': 99}}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@'}]}}}}) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [{'description': 'applyEdit', 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 28, 'line': 8}, 'newText': ', Config', 'start': {'offset': 28, 'line': 8}}, {'end': {'offset': 13, 'line': 97}, 'newText': 'await newFunction(redis, imageKey, cover, config);', 'start': {'offset': 3, 'line': 95}}, {'end': {'offset': 3, 'line': 100}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@', 'start': {'offset': 3, 'line': 100}}]}]}], + \ g:code_actions + +Execute(Code Actions from LSP should be handled when returned with documentChanges): + call ale#codefix#SetMap({2: {}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 2, 'jsonrpc': '2.0', 'result': [{'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 4, 'line': 1}}, 'newText': ''}, {'range': {'end': {'character': 9, 'line': 2}, 'start': {'character': 8, 'line': 2}}, 'newText': '(1)'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.inline', 'title': 'Inline variable', 'command': v:null}, {'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 0, 'line': 0}, 'start': {'character': 0, 'line': 0}}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@'}, {'range': {'end': {'character': 9, 'line': 1}, 'start': {'character': 8, 'line': 1}}, 'newText': 'func_bomdjnxh()^@'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.extract', 'title': 'Extract expression into function ''func_bomdjnxh''', 'command': v:null}]}) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [{'description': 'codeaction', 'changes': [{'fileName': '/foo/bar/test.py', 'textChanges': [{'end': {'offset': 1, 'line': 1}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@', 'start': {'offset': 1, 'line': 1}}, {'end': {'offset': 10, 'line': 2}, 'newText': 'func_bomdjnxh()^@', 'start': {'offset': 9, 'line': 2}}]}]}], + \ g:code_actions + +Execute(LSP Code Actions handles CodeAction responses): + call ale#codefix#SetMap({3: { + \ 'connection_id': 0, + \}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 3, 'jsonrpc': '2.0', 'result': [{'kind': 'refactor', 'title': 'Extract to inner function in function ''getVideo''', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_0', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to inner function in function ''getVideo''', 'command': '_typescript.applyRefactoring'}}, {'kind': 'refactor', 'title': 'Extract to function in module scope', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_1', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to function in module scope', 'command': '_typescript.applyRefactoring'}}]}) + + AssertEqual + \ [[0, 'workspace/executeCommand', {'arguments': [{'file': '/foo/bar/file.ts', 'action': 'function_scope_1', 'endOffset': 0, 'refactor': 'Extract Symbol', 'endLine': 68, 'startLine': 65, 'startOffset': 1}], 'command': '_typescript.applyRefactoring'}]], + \ g:message_list + +Execute(LSP Code Actions handles Command responses): + call ale#codefix#SetMap({2: { + \ 'connection_id': 2, + \}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 2, 'jsonrpc': '2.0', 'result': [{'title': 'fake for testing'}, {'arguments': [{'documentChanges': [{'edits': [{'range': {'end': {'character': 31, 'line': 2}, 'start': {'character': 31, 'line': 2}}, 'newText': ', createVideo'}], 'textDocument': {'uri': 'file:///foo/bar/file.ts', 'version': 1}}]}], 'title': 'Add ''createVideo'' to existing import declaration from "./video"', 'command': '_typescript.applyWorkspaceEdit'}]}) + + AssertEqual + \ [[0, 'workspace/executeCommand', {'arguments': [{'documentChanges': [{'edits': [{'range': {'end': {'character': 31, 'line': 2}, 'start': {'character': 31, 'line': 2}}, 'newText': ', createVideo'}], 'textDocument': {'uri': 'file:///foo/bar/file.ts', 'version': 1}}]}], 'command': '_typescript.applyWorkspaceEdit'}]], + \ g:message_list + +Execute(Prints message when LSP code action returns no results): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 3, 'jsonrpc': '2.0', 'result': []}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''No code actions received from server'''], g:expr_list + +Execute(LSP code action requests should be sent): + call ale#linter#Reset() + + runtime ale_linters/python/jedils.vim + let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}} + call setpos('.', [bufnr(''), 2, 5, 0]) + + " ALECodeAction + call ale#codefix#Execute(0) + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'code_actions', g:capability_checked + AssertEqual + \ 'function(''ale#codefix#HandleLSPResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ [0, 'textDocument/codeAction', { + \ 'context': { + \ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] + \ }, + \ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))} + \ }] + \ ], + \ g:message_list[-1:] + +Execute(LSP code action requests should be sent only for error with code): + call ale#linter#Reset() + + runtime ale_linters/python/jedils.vim + let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}} + call setpos('.', [bufnr(''), 2, 5, 0]) + + " ALECodeAction + call ale#codefix#Execute(0) + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'code_actions', g:capability_checked + AssertEqual + \ 'function(''ale#codefix#HandleLSPResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ [0, 'textDocument/codeAction', { + \ 'context': { + \ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] + \ }, + \ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))} + \ }] + \ ], + \ g:message_list[-1:] diff --git a/vim-config/plugins/ale/test/test_computed_lint_file_values.vader b/vim-config/plugins/ale/test/test_computed_lint_file_values.vader new file mode 100644 index 00000000..ed0d4c0c --- /dev/null +++ b/vim-config/plugins/ale/test/test_computed_lint_file_values.vader @@ -0,0 +1,150 @@ +Before: + Save g:ale_enabled + Save g:ale_run_synchronously + Save g:ale_set_lists_synchronously + Save g:ale_buffer_info + + let g:ale_enabled = 1 + let g:ale_buffer_info = {} + let g:ale_run_synchronously = 1 + let g:ale_set_lists_synchronously = 1 + + function! TestCallback(buffer, output) + " Windows adds extra spaces to the text from echo. + return [{ + \ 'lnum': 2, + \ 'col': 3, + \ 'text': 'testlinter1', + \}] + endfunction + function! TestCallback2(buffer, output) + " Windows adds extra spaces to the text from echo. + return [{ + \ 'lnum': 1, + \ 'col': 3, + \ 'text': 'testlinter2', + \}] + endfunction + function! TestCallback3(buffer, output) + " Windows adds extra spaces to the text from echo. + return [{ + \ 'lnum': 3, + \ 'col': 3, + \ 'text': 'testlinter3', + \}] + endfunction + + " These two linters computer their lint_file values after running commands. + call ale#linter#Define('foobar', { + \ 'name': 'testlinter1', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''', + \ 'lint_file': {b -> ale#command#Run(b, 'echo', {-> 1})}, + \}) + call ale#linter#Define('foobar', { + \ 'name': 'testlinter2', + \ 'callback': 'TestCallback2', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''', + \ 'lint_file': {b -> ale#command#Run(b, 'echo', {-> ale#command#Run(b, 'echo', {-> 1})})}, + \}) + " This one directly computes the result. + call ale#linter#Define('foobar', { + \ 'name': 'testlinter3', + \ 'callback': 'TestCallback3', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''', + \ 'lint_file': {b -> 1}, + \}) + + let g:filename = tempname() + call writefile([], g:filename) + call ale#test#SetFilename(g:filename) + +After: + delfunction TestCallback + + call ale#engine#Cleanup(bufnr('')) + Restore + call ale#linter#Reset() + + " Items and markers, etc. + call setloclist(0, []) + call clearmatches() + call ale#sign#Clear() + + if filereadable(g:filename) + call delete(g:filename) + endif + + unlet g:filename + +Given foobar(A file with some lines): + foo + bar + baz + +Execute(lint_file results where the result is eventually computed should be run): + call ale#Queue(0, 'lint_file') + call ale#test#FlushJobs() + + AssertEqual + \ [ + \ { + \ 'bufnr': bufnr('%'), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'testlinter2', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }, + \ { + \ 'bufnr': bufnr('%'), + \ 'lnum': 2, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'testlinter1', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }, + \ { + \ 'bufnr': bufnr('%'), + \ 'lnum': 3, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'testlinter3', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }, + \ ], + \ ale#test#GetLoclistWithoutModule() + +Execute(Linters where lint_file eventually evaluates to 1 shouldn't be run if we don't want to run them): + call ale#Queue(0, '') + call ale#test#FlushJobs() + + AssertEqual [], ale#test#GetLoclistWithoutModule() + +Execute(Keeping computed lint_file jobs running should work): + AssertEqual 'testlinter2', ale#linter#Get('foobar')[1].name + + call ale#engine#InitBufferInfo(bufnr('')) + + call ale#engine#MarkLinterActive( + \ g:ale_buffer_info[bufnr('')], + \ ale#linter#Get('foobar')[1] + \) + call ale#engine#RunLinters(bufnr(''), ale#linter#Get('foobar'), 0) + + Assert !empty(g:ale_buffer_info[bufnr('')].active_linter_list), + \ 'The active linter list was empty' + Assert ale#engine#IsCheckingBuffer(bufnr('')), + \ 'The IsCheckingBuffer function returned 0' diff --git a/vim-config/plugins/ale/test/test_csslint_config_detection.vader b/vim-config/plugins/ale/test/test_csslint_config_detection.vader new file mode 100644 index 00000000..c8e5fa98 --- /dev/null +++ b/vim-config/plugins/ale/test/test_csslint_config_detection.vader @@ -0,0 +1,29 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + + runtime ale_linters/css/csslint.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(--config should be set when the .csslintrc file is found): + call ale#test#SetFilename('test-files/csslint/some-app/subdir/testfile.js') + + AssertEqual + \ ( + \ 'csslint --format=compact ' + \ . '--config=' . ale#Escape(ale#path#Simplify(g:dir . '/test-files/csslint/some-app/.csslintrc')) + \ . ' %t' + \ ), + \ ale_linters#css#csslint#GetCommand(bufnr('')) + +Execute(--config should not be used when no .csslintrc file exists): + call ale#test#SetFilename('test-files/csslint/other-app/testfile.css') + + AssertEqual + \ ( + \ 'csslint --format=compact ' + \ . ' %t' + \ ), + \ ale_linters#css#csslint#GetCommand(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_cursor_warnings.vader b/vim-config/plugins/ale/test/test_cursor_warnings.vader new file mode 100644 index 00000000..ef385061 --- /dev/null +++ b/vim-config/plugins/ale/test/test_cursor_warnings.vader @@ -0,0 +1,256 @@ +Before: + Save g:ale_echo_msg_format + Save g:ale_echo_cursor + Save b:ale_lint_on_insert_leave + + let g:ale_echo_msg_format = '%code: %%s' + let b:ale_lint_on_insert_leave = 0 + + " We should prefer the error message at column 10 instead of the warning. + let g:ale_buffer_info = { + \ bufnr('%'): { + \ 'loclist': [ + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'bettercode', + \ 'nr': -1, + \ 'type': 'W', + \ 'code': 'semi', + \ 'text': 'Ignore me.', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'bettercode', + \ 'nr': -1, + \ 'type': 'E', + \ 'code': 'semi', + \ 'text': "Missing semicolon.\r", + \ 'detail': "Every statement should end with a semicolon\nsecond line", + \ }, + \ { + \ 'lnum': 1, + \ 'col': 14, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'bettercode', + \ 'nr': -1, + \ 'type': 'I', + \ 'text': 'Some information', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 10, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'bettercode', + \ 'nr': -1, + \ 'type': 'W', + \ 'code': 'space-infix-ops', + \ 'text': 'Infix operators must be spaced.', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 15, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'bettercode', + \ 'nr': -1, + \ 'type': 'E', + \ 'code': 'radix', + \ 'text': 'Missing radix parameter', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 1, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'bettercode', + \ 'nr': -1, + \ 'type': 'E', + \ 'text': 'lowercase error', + \ }, + \ ], + \ }, + \} + + " Turn off other features, we only care about this one feature in this test. + let g:ale_set_loclist = 0 + let g:ale_set_signs = 0 + let g:ale_set_highlights = 0 + let g:ale_echo_cursor = 1 + + function GetLastMessage() + redir => l:output + silent mess + redir END + + let l:lines = split(l:output, "\n") + + return empty(l:lines) ? '' : l:lines[-1] + endfunction + + call ale#linter#Reset() + call ale#linter#PreventLoading('javascript') + +After: + Restore + + call cursor(1, 1) + + let g:ale_set_loclist = 1 + let g:ale_set_signs = 1 + let g:ale_set_highlights = 1 + + let g:ale_buffer_info = {} + + unlet! g:output + unlet! b:ale_loclist_msg_format + + delfunction GetLastMessage + + " Clearing the messages breaks tests on NeoVim for some reason, but all + " we need to do for these tests is just make it so the last message isn't + " carried over between test cases. + echomsg '' + + " Close the preview window if it's open. + if &filetype is# 'ale-preview' + noautocmd :q! + endif + + call ale#linter#Reset() + +Given javascript(A Javscript file with warnings/errors): + var x = 3 + 12345678 + var x = 5*2 + parseInt("10"); + // comment + +Execute(Messages should be shown for the correct lines): + call cursor(1, 1) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'semi: Missing semicolon.', GetLastMessage() + +Execute(Messages should be shown for earlier columns): + call cursor(2, 1) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'space-infix-ops: Infix operators must be spaced.', GetLastMessage() + +Execute(Messages should be shown for later columns): + call cursor(2, 16) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'radix: Missing radix parameter', GetLastMessage() + +Execute(The message at the cursor should be shown when linting ends): + call cursor(1, 1) + call ale#engine#SetResults( + \ bufnr('%'), + \ g:ale_buffer_info[bufnr('%')].loclist, + \) + + AssertEqual 'semi: Missing semicolon.', GetLastMessage() + +Execute(The message at the cursor should be shown on InsertLeave): + call cursor(2, 9) + doautocmd InsertLeave + + AssertEqual 'space-infix-ops: Infix operators must be spaced.', GetLastMessage() + +Execute(ALEDetail should print 'detail' attributes): + call cursor(1, 1) + + ALEDetail + + AssertEqual + \ ['Every statement should end with a semicolon', 'second line'], + \ getline(1, '$') + +Execute(ALEDetail should print regular 'text' attributes): + call cursor(2, 10) + + ALEDetail + + " ALEDetail opens a window, so check the text in it. + AssertEqual + \ ['Infix operators must be spaced.'], + \ getline(1, '$') + +Execute(ALEDetail should not capitlise cursor messages): + call cursor(3, 1) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'lowercase error', GetLastMessage() + +Execute(The linter name should be formatted into the message correctly): + let g:ale_echo_msg_format = '%linter%: %s' + + call cursor(2, 9) + call ale#cursor#EchoCursorWarning() + + AssertEqual + \ 'bettercode: Infix operators must be spaced.', + \ GetLastMessage() + +Execute(The severity should be formatted into the message correctly): + let g:ale_echo_msg_format = '%severity%: %s' + + call cursor(2, 9) + call ale#cursor#EchoCursorWarning() + + AssertEqual + \ 'Warning: Infix operators must be spaced.', + \ GetLastMessage() + + call cursor(1, 10) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'Error: Missing semicolon.', GetLastMessage() + + call cursor(1, 14) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'Info: Some information', GetLastMessage() + +Execute(The %code% and %ifcode% should show the code and some text): + let g:ale_echo_msg_format = '%(code) %%s' + + call cursor(2, 9) + call ale#cursor#EchoCursorWarning() + + AssertEqual + \ '(space-infix-ops) Infix operators must be spaced.', + \ GetLastMessage() + +Execute(The %code% and %ifcode% should be removed when there's no code): + let g:ale_echo_msg_format = '%(code) %%s' + + call cursor(1, 14) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'Some information', GetLastMessage() + +Execute(The buffer message format option should take precedence): + let g:ale_echo_msg_format = '%(code) %%s' + let b:ale_echo_msg_format = 'FOO %s' + + call cursor(1, 14) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'FOO Some information', GetLastMessage() + +Execute(The cursor message shouldn't be echoed if the option is off): + let g:ale_echo_cursor = 0 + echom 'foo' + + call cursor(1, 1) + call ale#cursor#EchoCursorWarning() + + AssertEqual 'foo', GetLastMessage() diff --git a/vim-config/plugins/ale/test/test_deferred_command_string.vader b/vim-config/plugins/ale/test/test_deferred_command_string.vader new file mode 100644 index 00000000..173b6bb2 --- /dev/null +++ b/vim-config/plugins/ale/test/test_deferred_command_string.vader @@ -0,0 +1,50 @@ +Before: + Save g:ale_run_synchronously + Save g:ale_emulate_job_failure + Save g:ale_buffer_info + + let g:ale_run_synchronously = 1 + let g:ale_buffer_info = {} + let b:ale_history = [] + + call ale#linter#Reset() + call ale#assert#SetUpLinterTestCommands() + call ale#linter#Define('foobar', { + \ 'name': 'lint_file_linter', + \ 'callback': 'LintFileCallback', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': {b -> ale#command#Run(b, 'echo', {-> ale#command#Run(b, 'echo', {-> 'foo'})})}, + \ 'read_buffer': 0, + \}) + + " Run the test commands in the shell. + let g:ale_run_synchronously_emulate_commands = 0 + +After: + Restore + + call ale#assert#TearDownLinterTest() + unlet! g:ale_run_synchronously_callbacks + +Given foobar (Some imaginary filetype): +Execute(It should be possible to compute an executable to check based on the result of commands): + AssertLinter has('win32') ? 'cmd' : 'echo', 'foo' + + ALELint + call ale#test#FlushJobs() + + AssertEqual + \ 1, + \ len(filter(copy(b:ale_history), 'string(v:val.command) =~# ''foo''')) + +Execute(It handle the deferred command failing): + let g:ale_emulate_job_failure = 1 + + AssertLinter has('win32') ? 'cmd' : 'echo', 0 + + ALELint + call ale#test#FlushJobs() + + AssertEqual + \ 0, + \ len(filter(copy(b:ale_history), 'string(v:val.command) =~# ''foo''')) diff --git a/vim-config/plugins/ale/test/test_deferred_executable_string.vader b/vim-config/plugins/ale/test/test_deferred_executable_string.vader new file mode 100644 index 00000000..3bdc5251 --- /dev/null +++ b/vim-config/plugins/ale/test/test_deferred_executable_string.vader @@ -0,0 +1,46 @@ +Before: + Save g:ale_run_synchronously + Save g:ale_emulate_job_failure + Save g:ale_buffer_info + + let g:ale_run_synchronously = 1 + let g:ale_buffer_info = {} + let b:ale_history = [] + + call ale#linter#Reset() + call ale#assert#SetUpLinterTestCommands() + call ale#linter#Define('foobar', { + \ 'name': 'lint_file_linter', + \ 'callback': 'LintFileCallback', + \ 'executable': {b -> ale#command#Run(b, 'echo', {-> ale#command#Run(b, 'echo', {-> 'foo'})})}, + \ 'command': 'echo', + \ 'read_buffer': 0, + \}) + +After: + Restore + + call ale#assert#TearDownLinterTest() + +Given foobar (Some imaginary filetype): +Execute(It should be possible to compute an executable to check based on the result of commands): + AssertLinter 'foo', 'echo' + + ALELint + call ale#test#FlushJobs() + + AssertEqual + \ [{'status': 0, 'job_id': 'executable', 'command': 'foo'}], + \ filter(copy(b:ale_history), 'v:val.job_id is# ''executable''') + +Execute(It handle the deferred command failing): + let g:ale_emulate_job_failure = 1 + + AssertLinter 0, 'echo' + + ALELint + call ale#test#FlushJobs() + + AssertEqual + \ [], + \ filter(copy(b:ale_history), 'v:val.job_id is# ''executable''') diff --git a/vim-config/plugins/ale/test/test_deno_executable_detection.vader b/vim-config/plugins/ale/test/test_deno_executable_detection.vader new file mode 100644 index 00000000..87690bfe --- /dev/null +++ b/vim-config/plugins/ale/test/test_deno_executable_detection.vader @@ -0,0 +1,20 @@ +Before: + Save g:ale_deno_executable + runtime autoload/ale/handlers/deno.vim + +After: + unlet! b:ale_deno_executable + + call ale#linter#Reset() + +Execute(Default executable should be detected correctly): + AssertEqual + \ 'deno', + \ ale#handlers#deno#GetExecutable(bufnr('')) + +Execute(User specified executable should override default): + let g:ale_deno_executable = '/path/to/deno-bin' + AssertEqual + \ '/path/to/deno-bin', + \ ale#handlers#deno#GetExecutable(bufnr('')) + diff --git a/vim-config/plugins/ale/test/test_disabling_ale.vader b/vim-config/plugins/ale/test/test_disabling_ale.vader new file mode 100644 index 00000000..6159f793 --- /dev/null +++ b/vim-config/plugins/ale/test/test_disabling_ale.vader @@ -0,0 +1,119 @@ +Before: + Save g:ale_buffer_info + Save g:ale_enabled + Save b:ale_enabled + Save g:ale_maximum_file_size + Save b:ale_maximum_file_size + + function! SetUpCursorData() + let g:ale_buffer_info = { + \ bufnr('%'): { + \ 'loclist': [ + \ { + \ 'lnum': 2, + \ 'col': 10, + \ 'linter_name': 'testlinter', + \ 'type': 'W', + \ 'text': 'X' + \ }, + \ ], + \ }, + \} + + call cursor(2, 16) + endfunction + + function! TestCallback(buffer, output) + return [] + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': 'echo', + \ 'command': 'true', + \}) + + function GetLastMessage() + redir => l:output + silent mess + redir END + + let l:lines = split(l:output, "\n") + + return empty(l:lines) ? '' : l:lines[-1] + endfunction + + echomsg '' + +After: + Restore + call ale#linter#Reset() + delfunction TestCallback + delfunction GetLastMessage + delfunction SetUpCursorData + +Given foobar (Some imaginary filetype): + foo + bar + baz + +Execute(Linting shouldn't happen when ALE is disabled globally): + let g:ale_enabled = 0 + let g:ale_buffer_info = {} + + call ale#Queue(0) + + AssertEqual {}, g:ale_buffer_info + +Execute(Linting shouldn't happen when the file is too large with a global options): + let g:ale_maximum_file_size = 12 + let g:ale_buffer_info = {} + + call ale#Queue(0) + + AssertEqual {}, g:ale_buffer_info + +Execute(Linting shouldn't happen when ALE is disabled locally): + let b:ale_enabled = 0 + let g:ale_buffer_info = {} + + call ale#Queue(0) + + AssertEqual {}, g:ale_buffer_info + +Execute(Linting shouldn't happen when the file is too large with a local options): + let b:ale_maximum_file_size = 12 + let g:ale_buffer_info = {} + + call ale#Queue(0) + + AssertEqual {}, g:ale_buffer_info + +Execute(Cursor warnings shouldn't be echoed when ALE is disabled globally): + let g:ale_enabled = 0 + + call SetUpCursorData() + call ale#cursor#EchoCursorWarning() + AssertEqual '', GetLastMessage() + +Execute(Cursor warnings shouldn't be echoed when the file is too large with global options): + let g:ale_maximum_file_size = 12 + + call SetUpCursorData() + call ale#cursor#EchoCursorWarning() + AssertEqual '', GetLastMessage() + +Execute(Cursor warnings shouldn't be echoed when ALE is disabled locally): + let b:ale_enabled = 0 + + call SetUpCursorData() + call ale#cursor#EchoCursorWarning() + AssertEqual '', GetLastMessage() + +Execute(Cursor warnings shouldn't be echoed when the file is too large with local options): + let b:ale_maximum_file_size = 12 + + call SetUpCursorData() + call ale#cursor#EchoCursorWarning() + AssertEqual '', GetLastMessage() diff --git a/vim-config/plugins/ale/test/test_dockerfile_hadolint_linter.vader b/vim-config/plugins/ale/test/test_dockerfile_hadolint_linter.vader new file mode 100644 index 00000000..6e02b212 --- /dev/null +++ b/vim-config/plugins/ale/test/test_dockerfile_hadolint_linter.vader @@ -0,0 +1,90 @@ +" NOTE: We use the 'b:' forms below to ensure that we're properly using +" ale#Var() + +Given dockerfile: + # + +Before: + Save g:ale_dockerfile_hadolint_use_docker + Save g:ale_dockerfile_hadolint_docker_image + silent! unlet g:ale_dockerfile_hadolint_use_docker + silent! unlet g:ale_dockerfile_hadolint_docker_image + + " enable loading inside test container + silent! cd /testplugin + source ale_linters/dockerfile/hadolint.vim + + +After: + Restore + silent! unlet b:ale_dockerfile_hadolint_use_docker + silent! unlet b:ale_dockerfile_hadolint_docker_image + + +Execute(linter honors ..._use_docker correctly): + + " default: never + AssertEqual + \ 'hadolint', + \ ale_linters#dockerfile#hadolint#GetExecutable(bufnr('')) + + " explicit never + let b:ale_dockerfile_hadolint_use_docker = 'never' + AssertEqual + \ 'hadolint', + \ ale_linters#dockerfile#hadolint#GetExecutable(bufnr('')) + + let b:ale_dockerfile_hadolint_use_docker = 'always' + AssertEqual + \ 'docker', + \ ale_linters#dockerfile#hadolint#GetExecutable(bufnr('')) + + " hadolint if present, otherwise docker + let command = 'docker' + if executable('hadolint') + let command = 'hadolint' + endif + + let b:ale_dockerfile_hadolint_use_docker = 'yes' + AssertEqual + \ command, + \ ale_linters#dockerfile#hadolint#GetExecutable(bufnr('')) + + +Execute(command is correct when using docker): + let b:ale_dockerfile_hadolint_use_docker = 'always' + + AssertEqual + \ "docker run --rm -i hadolint/hadolint hadolint --no-color -", + \ ale_linters#dockerfile#hadolint#GetCommand(bufnr('')) + + +Execute(command is correct when not docker): + let b:ale_dockerfile_hadolint_use_docker = 'never' + + AssertEqual + \ "hadolint --no-color -", + \ ale_linters#dockerfile#hadolint#GetCommand(bufnr('')) + +Execute(test warnings from hadolint): + AssertEqual + \ [{'lnum': 10, 'col': 0, 'type': 'W', 'code': 'DL3007', 'text': 'DL3007: Using latest is prone to errors', 'detail': "DL3007 ( https://github.com/hadolint/hadolint/wiki/DL3007 )\n\nUsing latest is prone to errors"}], + \ ale_linters#dockerfile#hadolint#Handle(bufnr(''), [ + \ '-:10 DL3007 warning: Using latest is prone to errors', + \ ]) + +Execute(test warnings from shellcheck): + AssertEqual + \ [{'lnum': 3, 'col': 0, 'type': 'W', 'code': 'SC2154', 'text': 'SC2154: bar is referenced but not assigned.', 'detail': "SC2154 ( https://github.com/koalaman/shellcheck/wiki/SC2154 )\n\nbar is referenced but not assigned."}], + \ ale_linters#dockerfile#hadolint#Handle(bufnr(''), [ + \ '-:3 SC2154 warning: bar is referenced but not assigned.', + \ ]) + +Execute(test errors from dockerfile parser): + AssertEqual + \ [{'lnum': 3, 'col': 4, 'type': 'E', 'text': 'unexpected "A" expecting at least one space after ''RUN''', 'detail': 'hadolint could not parse the file because of a syntax error.'}], + \ ale_linters#dockerfile#hadolint#Handle(bufnr(''), [ + \ "/dev/stdin:3:4 unexpected \"A\" expecting at least one space after 'RUN'", + \ ]) + +" fin... diff --git a/vim-config/plugins/ale/test/test_env_function.vader b/vim-config/plugins/ale/test/test_env_function.vader new file mode 100644 index 00000000..856a3f57 --- /dev/null +++ b/vim-config/plugins/ale/test/test_env_function.vader @@ -0,0 +1,8 @@ +Execute(ale#Env should produce the correct syntax): + if has('win32') + AssertEqual 'set name=xxx && ', ale#Env('name', 'xxx') + AssertEqual 'set name="foo bar" && ', ale#Env('name', 'foo bar') + else + AssertEqual 'name=''xxx'' ', ale#Env('name', 'xxx') + AssertEqual 'name=''foo bar'' ', ale#Env('name', 'foo bar') + endif diff --git a/vim-config/plugins/ale/test/test_errors_removed_after_filetype_changed.vader b/vim-config/plugins/ale/test/test_errors_removed_after_filetype_changed.vader new file mode 100644 index 00000000..7ad97f94 --- /dev/null +++ b/vim-config/plugins/ale/test/test_errors_removed_after_filetype_changed.vader @@ -0,0 +1,78 @@ +Before: + Save &filetype + Save g:ale_buffer_info + Save g:ale_echo_cursor + Save g:ale_run_synchronously + Save g:ale_set_highlights + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_set_signs + + let g:ale_buffer_info = {} + + " Enable only the one feature we need. + let g:ale_set_signs = 0 + let g:ale_set_quickfix = 0 + let g:ale_set_loclist = 1 + let g:ale_set_highlights = 0 + let g:ale_echo_cursor = 0 + + let g:ale_run_synchronously = 1 + unlet! g:ale_run_synchronously_callbacks + call setloclist(0, []) + + noautocmd let &filetype = 'foobar' + + function! TestCallback(buffer, output) + return [{'text': 'x', 'lnum': 1}] + endfunction + + call ale#linter#PreventLoading('foobar') + call ale#linter#Define('foobar', { + \ 'name': 'buffer_linter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd': 'true', + \ 'command': 'true', + \ 'read_buffer': 0, + \}) + call ale#linter#PreventLoading('foobar2') + call ale#linter#Define('foobar2', { + \ 'name': 'buffer_linter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd': 'true', + \ 'command': 'true', + \ 'read_buffer': 0, + \}) + +After: + Restore + + unlet! g:ale_run_synchronously_callbacks + delfunction TestCallback + + call ale#linter#Reset() + call setloclist(0, []) + +Execute(Error should be removed when the filetype changes to something else we cannot check): + call ale#Queue(0) + call ale#test#FlushJobs() + sleep 1ms + + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()) + + noautocmd let &filetype = 'foobar2' + + call ale#Queue(0) + call ale#test#FlushJobs() + sleep 1ms + + " We should get some items from the second filetype. + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()) + + noautocmd let &filetype = 'xxx' + + call ale#Queue(0) + call ale#test#FlushJobs() + sleep 1ms + + AssertEqual 0, len(ale#test#GetLoclistWithoutModule()) diff --git a/vim-config/plugins/ale/test/test_filename_mapping.vader b/vim-config/plugins/ale/test/test_filename_mapping.vader new file mode 100644 index 00000000..e9af539a --- /dev/null +++ b/vim-config/plugins/ale/test/test_filename_mapping.vader @@ -0,0 +1,62 @@ +Before: + Save g:ale_filename_mappings + Save b:ale_filename_mappings + + let g:ale_filename_mappings = {} + unlet! b:ale_filename_mappings + +After: + Restore + +Execute(ale#GetFilenameMappings should return the correct mappings for given linters/fixers): + let g:ale_filename_mappings = {'a': [['foo', 'bar']], 'b': [['baz', 'foo']]} + + AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a') + AssertEqual [['baz', 'foo']], ale#GetFilenameMappings(bufnr(''), 'b') + AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'c') + + let b:ale_filename_mappings = {'b': [['abc', 'xyz']]} + + AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'a') + AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'b') + AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'c') + +Execute(ale#GetFilenameMappings should return Lists set for use with all tools): + let g:ale_filename_mappings = [['foo', 'bar']] + + AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a') + AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), '') + AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), v:null) + + let b:ale_filename_mappings = [['abc', 'xyz']] + + AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'a') + AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), '') + AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), v:null) + +Execute(ale#GetFilenameMappings should let you use * as a fallback): + let g:ale_filename_mappings = {'a': [['foo', 'bar']], '*': [['abc', 'xyz']]} + + AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a') + AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'b') + AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), '') + AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), v:null) + +Execute(ale#filename_mapping#Invert should invert filename mappings): + AssertEqual + \ [['b', 'a'], ['y', 'x']], + \ ale#filename_mapping#Invert([['a', 'b'], ['x', 'y']]) + \ +Execute(ale#filename_mapping#Map return the filename as-is if there are no mappings): + AssertEqual + \ '/foo//bar', + \ ale#filename_mapping#Map('/foo//bar', [['/bar', '/data/']]) + +Execute(ale#filename_mapping#Map should map filenames): + AssertEqual + \ '/data/bar', + \ ale#filename_mapping#Map('/foo//bar', [ + \ ['/data/', '/baz/'], + \ ['/foo/', '/data/'], + \ ['/foo/', '/xyz/'], + \ ]) diff --git a/vim-config/plugins/ale/test/test_filetype_linter_defaults.vader b/vim-config/plugins/ale/test/test_filetype_linter_defaults.vader new file mode 100644 index 00000000..563a093f --- /dev/null +++ b/vim-config/plugins/ale/test/test_filetype_linter_defaults.vader @@ -0,0 +1,79 @@ +Before: + Save g:ale_linters + Save g:ale_linters_explicit + + let g:ale_linters_explicit = 0 + let g:ale_linters = {} + + function! GetLinterNames(filetype) abort + return map(ale#linter#Get(a:filetype), 'v:val.name') + endfunction + +After: + Restore + + call ale#linter#Reset() + +Execute(The defaults for the csh filetype should be correct): + AssertEqual ['shell'], GetLinterNames('csh') + + let g:ale_linters_explicit = 1 + + AssertEqual [], GetLinterNames('csh') + +Execute(The defaults for the go filetype should be correct): + AssertEqual ['gofmt', 'golint', 'gopls', 'govet'], GetLinterNames('go') + + let g:ale_linters_explicit = 1 + + AssertEqual [], GetLinterNames('go') + +Execute(The defaults for the help filetype should be correct): + AssertEqual [], GetLinterNames('help') + +Execute(The defaults for the python filetype should be correct): + AssertEqual ['flake8', 'mypy', 'pylint', 'pyright'], GetLinterNames('python') + + let g:ale_linters_explicit = 1 + + AssertEqual [], GetLinterNames('python') + +Execute(The defaults for the rust filetype should be correct): + AssertEqual ['cargo', 'rls'], GetLinterNames('rust') + + let g:ale_linters_explicit = 1 + + AssertEqual [], GetLinterNames('rust') + +Execute(The defaults for the spec filetype should be correct): + AssertEqual [], GetLinterNames('spec') + +Execute(The defaults for the text filetype should be correct): + AssertEqual [], GetLinterNames('text') + +Execute(The defaults for the zsh filetype should be correct): + AssertEqual ['shell'], GetLinterNames('zsh') + + let g:ale_linters_explicit = 1 + + AssertEqual [], GetLinterNames('zsh') + +Execute(The defaults for the verilog filetype should be correct): + " This filetype isn't configured with default, so we can test loading all + " available linters with this. + AssertEqual ['hdl-checker', 'iverilog', 'verilator', 'vlog', 'xvlog', 'yosys'], GetLinterNames('verilog') + + let g:ale_linters_explicit = 1 + + AssertEqual [], GetLinterNames('verilog') + +Execute(Default aliases for React should be defined): + AssertEqual ['javascript', 'jsx'], ale#linter#ResolveFiletype('javascriptreact') + AssertEqual ['typescript', 'tsx'], ale#linter#ResolveFiletype('typescriptreact') + +Execute(The defaults for the apkbuild filetype should be correct): + AssertEqual ['apkbuild_lint', 'secfixes_check'], GetLinterNames('apkbuild') + + let g:ale_linters_explicit = 1 + + AssertEqual [], GetLinterNames('apkbuild') diff --git a/vim-config/plugins/ale/test/test_filetype_mapping.vader b/vim-config/plugins/ale/test/test_filetype_mapping.vader new file mode 100644 index 00000000..2d72491d --- /dev/null +++ b/vim-config/plugins/ale/test/test_filetype_mapping.vader @@ -0,0 +1,29 @@ +Before: + augroup TestFiletypeGroup + autocmd! + autocmd BufEnter,BufRead *.x setf xfiletype + autocmd BufEnter,BufRead *.y set filetype=yfiletype + autocmd BufEnter,BufRead *.z setlocal filetype=zfiletype + autocmd BufEnter,BufRead *.jsx set filetype=javascript.jsx + augroup END + +After: + unlet! g:map + augroup TestFiletypeGroup + autocmd! + augroup END + augroup! TestFiletypeGroup + +Execute(ALE should parse autocmd filetypes correctly): + let g:map = ale#filetypes#LoadExtensionMap() + + AssertEqual '.x', g:map['xfiletype'] + AssertEqual '.y', g:map['yfiletype'] + AssertEqual '.z', g:map['zfiletype'] + AssertEqual '.jsx', g:map['javascript.jsx'] + +Execute(ALE should guess file extensions appropriately): + " The whole string should be used, if there's a match. + AssertEqual '.jsx', ale#filetypes#GuessExtension('javascript.jsx') + " The first part should be used. + AssertEqual '.x', ale#filetypes#GuessExtension('xfiletype.yfiletype') diff --git a/vim-config/plugins/ale/test/test_find_nearest_directory.vader b/vim-config/plugins/ale/test/test_find_nearest_directory.vader new file mode 100644 index 00000000..740668da --- /dev/null +++ b/vim-config/plugins/ale/test/test_find_nearest_directory.vader @@ -0,0 +1,17 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + +After: + call ale#test#RestoreDirectory() + +Execute(We should be able to find a directory some directory down): + call ale#test#SetFilename('test-files/top/middle/bottom/dummy.txt') + + AssertEqual + \ ale#path#Simplify(expand('%:p:h:h:h:h:h') . '/test-files/top/ale-special-directory-name-dont-use-this-please/'), + \ ale#path#FindNearestDirectory(bufnr('%'), 'ale-special-directory-name-dont-use-this-please') + +Execute(We shouldn't find anything for files which don't match): + AssertEqual + \ '', + \ ale#path#FindNearestDirectory(bufnr('%'), 'ale-this-should-never-match-anything') diff --git a/vim-config/plugins/ale/test/test_find_references.vader b/vim-config/plugins/ale/test/test_find_references.vader new file mode 100644 index 00000000..9931e740 --- /dev/null +++ b/vim-config/plugins/ale/test/test_find_references.vader @@ -0,0 +1,392 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('dummy.txt') + + Save g:ale_default_navigation + + let g:old_filename = expand('%:p') + let g:Callback = '' + let g:expr_list = [] + let g:message_list = [] + let g:preview_called = 0 + let g:item_list = [] + let g:options = {} + let g:capability_checked = '' + let g:conn_id = v:null + let g:InitCallback = v:null + let g:ale_default_navigation = 'buffer' + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/preview.vim + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {}) + call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer) + + if a:linter.lsp is# 'tsserver' + call ale#lsp#MarkConnectionAsTsserver(g:conn_id) + endif + + let l:details = { + \ 'command': 'foobar', + \ 'buffer': a:buffer, + \ 'connection_id': g:conn_id, + \ 'project_root': '/foo/bar', + \} + + let g:InitCallback = {-> ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)} + endfunction + + function! ale#lsp#HasCapability(conn_id, capability) abort + let g:capability_checked = a:capability + + return 1 + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + + return 42 + endfunction + + function! ale#util#Execute(expr) abort + call add(g:expr_list, a:expr) + endfunction + + function! ale#preview#ShowSelection(item_list, options) abort + let g:preview_called = 1 + let g:item_list = a:item_list + let g:options = a:options + + call ale#preview#SetLastSelection(a:item_list, a:options) + endfunction + +After: + Restore + + if g:conn_id isnot v:null + call ale#lsp#RemoveConnectionWithID(g:conn_id) + endif + + call ale#references#SetMap({}) + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + unlet! g:capability_checked + unlet! g:InitCallback + unlet! g:old_filename + unlet! g:conn_id + unlet! g:Callback + unlet! g:message_list + unlet! g:expr_list + unlet! b:ale_linters + unlet! g:options + unlet! g:item_list + unlet! g:preview_called + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/preview.vim + +Execute(Other messages for the tsserver handler should be ignored): + call ale#references#HandleTSServerResponse(1, {'command': 'foo'}) + +Execute(Failed reference responses should be handled correctly): + call ale#references#SetMap({3: {}}) + call ale#references#HandleTSServerResponse( + \ 1, + \ {'command': 'references', 'request_seq': 3} + \) + AssertEqual {}, ale#references#GetMap() + +Given typescript(Some typescript file): + foo + somelongerline + bazxyzxyzxyz + +Execute(Results should be shown for tsserver responses): + " We should remember these options when we repeat the selection. + call ale#references#SetMap( + \ { + \ 3: { + \ 'ignorethis': 'x', + \ 'open_in': 'tab', + \ 'use_relative_paths': 1, + \ } + \ } + \) + call ale#references#HandleTSServerResponse(1, { + \ 'command': 'references', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'symbolStartOffset': 9, + \ 'refs': [ + \ { + \ 'file': '/foo/bar/app.ts', + \ 'isWriteAccess': v:true, + \ 'lineText': 'import {doSomething} from ''./whatever''', + \ 'end': {'offset': 24, 'line': 9}, + \ 'start': {'offset': 9, 'line': 9}, + \ 'isDefinition': v:true, + \ }, + \ { + \ 'file': '/foo/bar/app.ts', + \ 'isWriteAccess': v:false, + \ 'lineText': ' doSomething()', + \ 'end': {'offset': 18, 'line': 804}, + \ 'start': {'offset': 3, 'line': 804}, + \ 'isDefinition': v:false, + \ }, + \ { + \ 'file': '/foo/bar/other/app.ts', + \ 'isWriteAccess': v:false, + \ 'lineText': ' doSomething()', + \ 'end': {'offset': 18, 'line': 51}, + \ 'start': {'offset': 3, 'line': 51}, + \ 'isDefinition': v:false, + \ }, + \ ], + \ 'symbolDisplayString': 'import doSomething', + \ 'symbolName': 'doSomething()', + \ }, + \}) + + AssertEqual + \ [ + \ {'filename': '/foo/bar/app.ts', 'column': 9, 'line': 9, 'match': 'import {doSomething} from ''./whatever'''}, + \ {'filename': '/foo/bar/app.ts', 'column': 3, 'line': 804, 'match': 'doSomething()'}, + \ {'filename': '/foo/bar/other/app.ts', 'column': 3, 'line': 51, 'match': 'doSomething()'}, + \ ], + \ g:item_list + AssertEqual {}, ale#references#GetMap() + + " We should be able to repeat selections with ALERepeatSelection + let g:item_list = [] + ALERepeatSelection + + AssertEqual + \ [ + \ {'filename': '/foo/bar/app.ts', 'column': 9, 'line': 9, 'match': 'import {doSomething} from ''./whatever'''}, + \ {'filename': '/foo/bar/app.ts', 'column': 3, 'line': 804, 'match': 'doSomething()'}, + \ {'filename': '/foo/bar/other/app.ts', 'column': 3, 'line': 51, 'match': 'doSomething()'}, + \ ], + \ g:item_list + AssertEqual {}, ale#references#GetMap() + AssertEqual + \ { + \ 'open_in': 'tab', + \ 'use_relative_paths': 1, + \ }, + \ g:options + +Execute(The preview window should not be opened for empty tsserver responses): + call ale#references#SetMap({3: {}}) + call ale#references#HandleTSServerResponse(1, { + \ 'command': 'references', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'symbolStartOffset': 9, + \ 'refs': [ + \ ], + \ 'symbolDisplayString': 'import doSomething', + \ 'symbolName': 'doSomething()', + \ }, + \}) + + Assert !g:preview_called + AssertEqual {}, ale#references#GetMap() + AssertEqual ['echom ''No references found.'''], g:expr_list + +Execute(tsserver reference requests should be sent): + call ale#linter#Reset() + + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + ALEFindReferences + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'references', g:capability_checked + AssertEqual + \ 'function(''ale#references#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@references', {'file': expand('%:p'), 'line': 2, 'offset': 5}] + \ ], + \ g:message_list + AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 0}}, ale#references#GetMap() + +Execute('-relative' argument should enable 'use_relative_paths' in HandleTSServerResponse): + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + ALEFindReferences -relative + + call g:InitCallback() + + AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 1}}, ale#references#GetMap() + +Execute(`-tab` should display results in tabs): + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + ALEFindReferences -tab + + call g:InitCallback() + + AssertEqual {'42': {'open_in': 'tab', 'use_relative_paths': 0}}, ale#references#GetMap() + +Execute(The default navigation type should be used): + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + let g:ale_default_navigation = 'tab' + ALEFindReferences + + call g:InitCallback() + + AssertEqual {'42': {'open_in': 'tab', 'use_relative_paths': 0}}, ale#references#GetMap() + +Execute(`-split` should display results in splits): + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + ALEFindReferences -split + + call g:InitCallback() + + AssertEqual {'42': {'open_in': 'split', 'use_relative_paths': 0}}, ale#references#GetMap() + +Execute(`-vsplit` should display results in vsplits): + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + ALEFindReferences -vsplit + + call g:InitCallback() + + AssertEqual {'42': {'open_in': 'vsplit', 'use_relative_paths': 0}}, ale#references#GetMap() + +Given python(Some Python file): + foo + somelongerline + bazxyzxyzxyz + +Execute(LSP reference responses should be handled): + call ale#references#SetMap({3: {}}) + call ale#references#HandleLSPResponse( + \ 1, + \ { + \ 'id': 3, + \ 'result': [ + \ { + \ 'uri': ale#path#ToURI(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ 'range': { + \ 'start': {'line': 2, 'character': 7}, + \ }, + \ }, + \ { + \ 'uri': ale#path#ToURI(ale#path#Simplify(g:dir . '/other_file')), + \ 'range': { + \ 'start': {'line': 7, 'character': 15}, + \ }, + \ }, + \ ], + \ } + \) + + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Simplify(g:dir . '/completion_dummy_file'), + \ 'line': 3, + \ 'column': 8, + \ }, + \ { + \ 'filename': ale#path#Simplify(g:dir . '/other_file'), + \ 'line': 8, + \ 'column': 16, + \ }, + \ ], + \ g:item_list + AssertEqual {}, ale#references#GetMap() + +Execute(Preview windows should not be opened for empty LSP reference responses): + call ale#references#SetMap({3: {}}) + call ale#references#HandleLSPResponse(1, {'id': 3, 'result': []}) + + Assert !g:preview_called + AssertEqual {}, ale#references#GetMap() + AssertEqual ['echom ''No references found.'''], g:expr_list + +Execute(LSP reference responses with a null result should be handled): + call ale#references#SetMap({3: {}}) + call ale#references#HandleLSPResponse(1, {'id': 3, 'result': v:null}) + + Assert !g:preview_called + AssertEqual {}, ale#references#GetMap() + AssertEqual ['echom ''No references found.'''], g:expr_list + +Execute(LSP reference requests should be sent): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + call setpos('.', [bufnr(''), 1, 5, 0]) + + ALEFindReferences + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'references', g:capability_checked + AssertEqual + \ 'function(''ale#references#HandleLSPResponse'')', + \ string(g:Callback) + + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}] + \ }], + \ [0, 'textDocument/references', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'line': 0, 'character': 2}, + \ 'context': {'includeDeclaration': v:false}, + \ }], + \ ], + \ g:message_list + + AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 0}}, ale#references#GetMap() + +Execute('-relative' argument should enable 'use_relative_paths' in HandleLSPResponse): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + call setpos('.', [bufnr(''), 1, 5, 0]) + + ALEFindReferences -relative + + call g:InitCallback() + + AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 1}}, ale#references#GetMap() diff --git a/vim-config/plugins/ale/test/test_floating_preview.vader b/vim-config/plugins/ale/test/test_floating_preview.vader new file mode 100644 index 00000000..43415556 --- /dev/null +++ b/vim-config/plugins/ale/test/test_floating_preview.vader @@ -0,0 +1,92 @@ +Before: + let g:ale_floating_preview = 0 + let g:ale_hover_to_floating_preview = 0 + let g:ale_detail_to_floating_preview = 0 + + runtime autoload/ale/floating_preview.vim + + let g:floated_lines = [] + let g:floating_preview_show_called = 0 + + " Stub out so we can track the call + function! ale#floating_preview#Show(lines, ...) abort + let g:floating_preview_show_called = 1 + let g:floated_lines = a:lines + endfunction + + let g:ale_buffer_info = { + \ bufnr('%'): { + \ 'loclist': [ + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'notalinter', + \ 'nr': -1, + \ 'type': 'E', + \ 'code': 'semi', + \ 'text': "Missing semicolon.\r", + \ 'detail': "Every statement should end with a semicolon\nsecond line", + \ }, + \ ], + \ } + \} + + call ale#linter#Reset() + call ale#linter#PreventLoading('javascript') + +After: + Restore + + let g:ale_floating_preview = 0 + let g:ale_hover_to_floating_preview = 0 + let g:ale_detail_to_floating_preview = 0 + + call cursor(1, 1) + + let g:ale_buffer_info = {} + + " Close the preview window if it's open. + if &filetype is# 'ale-preview' + noautocmd :q! + endif + + call ale#linter#Reset() + + +Given javascript(A file with warnings/errors): + var x = 3 + 12345678 + var x = 5*2 + parseInt("10"); + // comment + +Execute(Floating preview is used with ALEDetail when g:ale_floating_preview set): + let g:ale_floating_preview = 1 + + call cursor(1, 10) + + ALEDetail + + let expected = ["Every statement should end with a semicolon", "second line"] + + AssertEqual 1, g:floating_preview_show_called + AssertEqual expected, g:floated_lines + +Execute(Floating preview is used with ALEDetail when g:ale_detail_to_floating_preview set): + let g:ale_detail_to_floating_preview = 1 + + call cursor(1, 10) + + ALEDetail + + let expected = ["Every statement should end with a semicolon", "second line"] + + AssertEqual 1, g:floating_preview_show_called + AssertEqual expected, g:floated_lines + +Execute(Floating preview is not used with ALEDetail by default): + call cursor(1, 10) + + ALEDetail + + AssertEqual 0, g:floating_preview_show_called diff --git a/vim-config/plugins/ale/test/test_format_command.vader b/vim-config/plugins/ale/test/test_format_command.vader new file mode 100644 index 00000000..b0440dcd --- /dev/null +++ b/vim-config/plugins/ale/test/test_format_command.vader @@ -0,0 +1,186 @@ +Before: + silent! cd /testplugin/test + silent file top/middle/bottom/dummy.txt + + function! CheckTempFile(filename) abort + " Check every part of the temporary filename, except the random part. + AssertEqual fnamemodify(tempname(), ':h'), fnamemodify(a:filename, ':h:h') + AssertEqual 'dummy.txt', fnamemodify(a:filename, ':t') + endfunction + + runtime autoload/ale/command.vim + + function! ale#command#CreateTempFile(buffer, temporary_file, input) abort + return !empty(a:temporary_file) + endfunction + +After: + unlet! g:result + unlet! g:match + + delfunction CheckTempFile + + runtime autoload/ale/command.vim + +Execute(FormatCommand should do nothing to basic command strings): + AssertEqual + \ ['', 'awesome-linter do something', 0], + \ ale#command#FormatCommand(bufnr('%'), '', 'awesome-linter do something', 0, v:null, v:null, []) + +Execute(FormatCommand should handle %%, and ignore other percents): + AssertEqual + \ ['', '% %%d %%f %x %', 0], + \ ale#command#FormatCommand(bufnr('%'), '', '%% %%%d %%%f %x %', 0, v:null, v:null, []) + +Execute(FormatCommand should convert %s to the current filename): + AssertEqual + \ [ + \ '', + \ 'foo ' . ale#Escape(expand('%:p')) . ' bar ' . ale#Escape(expand('%:p')), + \ 0, + \ ], + \ ale#command#FormatCommand(bufnr('%'), '', 'foo %s bar %s', 0, v:null, v:null, []) + +Execute(FormatCommand should convert %t to a new temporary filename): + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:null, v:null, []) + + call CheckTempFile(g:result[0]) + + let g:match = matchlist(g:result[1], '\v^foo (.*) bar (.*)$') + + Assert !empty(g:match), 'No match found! Result was: ' . g:result[1] + " The first item of the result should be a temporary filename, and it should + " be the same as the escaped name in the command string. + AssertEqual ale#Escape(g:result[0]), g:match[1] + " The two temporary filenames formatted in should be the same. + AssertEqual g:match[1], g:match[2] + +Execute(FormatCommand should not convert %t to a new temporary filename when the input is given as v:false): + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:false, v:null, []) + + AssertEqual ['', 'foo %t bar %t', 0], g:result + +Execute(FormatCommand should signal that files are created when temporary files are needed): + AssertEqual + \ 1, + \ ale#command#FormatCommand(bufnr('%'), '', 'foo %t', 0, v:null, v:null, [])[2] + + AssertEqual + \ 0, + \ ale#command#FormatCommand(bufnr('%'), '', 'foo %s', 0, v:null, v:null, [])[2] + +Execute(FormatCommand should let you combine %s and %t): + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %s', 0, v:null, v:null, []) + + call CheckTempFile(g:result[0]) + + let g:match = matchlist(g:result[1], '\v^foo (.*) bar (.*)$') + + Assert !empty(g:match), 'No match found! Result was: ' . g:result[1] + " The first item of the result should be a temporary filename, and it should + " be the same as the escaped name in the command string. + AssertEqual ale#Escape(g:result[0]), g:match[1] + " The second item should be equal to the original filename. + AssertEqual ale#Escape(expand('%:p')), g:match[2] + +Execute(FormatCommand should replace %e with the escaped executable): + if has('win32') + AssertEqual + \ ['', 'foo foo', 0], + \ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, v:null, []) + AssertEqual + \ ['', '"foo bar"', 0], + \ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, v:null, []) + AssertEqual + \ ['', '%e %e', 0], + \ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, v:null, []) + else + AssertEqual + \ ['', '''foo'' ''foo''', 0], + \ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, v:null, []) + AssertEqual + \ ['', '''foo bar''', 0], + \ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, v:null, []) + AssertEqual + \ ['', '%e %e', 0], + \ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, v:null, []) + endif + +Execute(EscapeCommandPart should escape all percent signs): + AssertEqual '%%s %%t %%%% %%s %%t %%%%', ale#engine#EscapeCommandPart('%s %t %% %s %t %%') + +Execute(EscapeCommandPart should pipe in temporary files appropriately): + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar', 1, v:null, v:null, []) + + call CheckTempFile(g:result[0]) + + let g:match = matchlist(g:result[1], '\v^foo bar \< (.*)$') + Assert !empty(g:match), 'No match found! Result was: ' . g:result[1] + AssertEqual ale#Escape(g:result[0]), g:match[1] + + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar %t', 1, v:null, v:null, []) + + call CheckTempFile(g:result[0]) + + let g:match = matchlist(g:result[1], '\v^foo bar (.*)$') + Assert !empty(g:match), 'No match found! Result was: ' . g:result[1] + AssertEqual ale#Escape(g:result[0]), g:match[1] + +Execute(FormatCommand should apply filename modifiers to the current file): + AssertEqual + \ ale#Escape(expand('%:p:h')) + \ . ' ' . ale#Escape('dummy.txt') + \ . ' ' . ale#Escape(expand('%:p:h:t')) + \ . ' ' . ale#Escape('txt') + \ . ' ' . ale#Escape(expand('%:p:r')), + \ ale#command#FormatCommand(bufnr(''), '', '%s:h %s:t %s:h:t %s:e %s:r', 0, v:null, v:null, [])[1] + +Execute(FormatCommand should apply filename modifiers to the temporary file): + let g:result = ale#command#FormatCommand(bufnr(''), '', '%t:h %t:t %t:h:t %t:e %t:r', 0, v:null, v:null, []) + + AssertEqual + \ ale#Escape(fnamemodify(g:result[0], ':h')) + \ . ' ' . ale#Escape('dummy.txt') + \ . ' ' . ale#Escape(fnamemodify(g:result[0], ':h:t')) + \ . ' ' . ale#Escape('txt') + \ . ' ' . ale#Escape(fnamemodify(g:result[0], ':r')), + \ g:result[1] + +Execute(FormatCommand should apply filename mappings the current file): + let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s', 0, v:null, v:null, [ + \ [expand('%:p:h'), '/foo/bar'], + \]) + + Assert g:result[1] =~# '/foo/bar' + +Execute(FormatCommand should apply filename mappings to temporary files): + let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t', 0, v:null, v:null, [ + \ [fnamemodify(tempname(), ':h:h'), '/foo/bar'] + \]) + + Assert g:result[1] =~# '/foo/bar' + +Execute(FormatCommand should apply filename modifiers to mapped filenames): + let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s:h', 0, v:null, v:null, [ + \ [expand('%:p:h'), '/foo/bar'], + \]) + + AssertEqual ale#Escape('/foo/bar'), g:result[1] + + let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t:h:h:h', 0, v:null, v:null, [ + \ [fnamemodify(tempname(), ':h:h'), '/foo/bar'] + \]) + + AssertEqual ale#Escape('/foo/bar'), g:result[1] + +Execute(FormatCommand should apply regular cwd paths): + AssertEqual + \ 'cd ' . (has('unix') ? '' : '/d ') . ale#Escape('/foo /bar') . ' && abc', + \ ale#command#FormatCommand(bufnr('%'), '', 'abc', 0, v:null, '/foo /bar', [])[1] + \ +Execute(FormatCommand should apply cwd subsitution and formatting): + call ale#test#SetFilename('foo.txt') + + AssertEqual + \ 'cd ' . (has('unix') ? '' : '/d ') . ale#Escape(getcwd()) . ' && abc', + \ ale#command#FormatCommand(bufnr('%'), '', 'abc', 0, v:null, '%s:h', [])[1] diff --git a/vim-config/plugins/ale/test/test_format_temporary_file_creation.vader b/vim-config/plugins/ale/test/test_format_temporary_file_creation.vader new file mode 100644 index 00000000..10409400 --- /dev/null +++ b/vim-config/plugins/ale/test/test_format_temporary_file_creation.vader @@ -0,0 +1,63 @@ +Before: + Save g:ale_buffer_info + Save g:ale_echo_cursor + Save g:ale_enabled + Save g:ale_run_synchronously + Save g:ale_set_highlights + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_set_signs + + " Disable the features we don't need to check. + let g:ale_buffer_info = {} + let g:ale_echo_cursor = 0 + let g:ale_enabled = 1 + let g:ale_run_synchronously = 1 + unlet! g:ale_run_synchronously_callbacks + let g:ale_set_highlights = 0 + let g:ale_set_loclist = 0 + let g:ale_set_quickfix = 0 + let g:ale_set_signs = 0 + + let g:output = [] + + function! TestCallback(buffer, output) + " Extract just letters from the output. + let g:output = filter( + \ map(a:output, 'matchstr(v:val, ''[a-zA-Z]\+'')'), + \ '!empty(v:val)' + \) + + return [] + endfunction + + call ale#linter#PreventLoading('foobar') + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'cat', + \ 'command': has('win32') ? 'type %t' : 'cat %t', + \}) + +After: + Restore + + unlet! g:ale_run_synchronously_callbacks + unlet! g:output + delfunction TestCallback + + call ale#engine#Cleanup(bufnr('')) + call ale#linter#Reset() + +Given foobar (Some imaginary filetype): + foo + bar + baz + +Execute(ALE should be able to read the %t file): + AssertEqual 'foobar', &filetype + + ALELint + call ale#test#FlushJobs() + + AssertEqual ['foo', 'bar', 'baz'], g:output diff --git a/vim-config/plugins/ale/test/test_function_arg_count.vader b/vim-config/plugins/ale/test/test_function_arg_count.vader new file mode 100644 index 00000000..d256c403 --- /dev/null +++ b/vim-config/plugins/ale/test/test_function_arg_count.vader @@ -0,0 +1,45 @@ +Before: + function! Func0() + endfunction + function! Func1(x) + endfunction + function! Func2(x,y) + endfunction + function! Func3(x,y,z) + endfunction + function! Func3a(x,y,z,...) + endfunction + +After: + delfunction Func0 + delfunction Func1 + delfunction Func2 + delfunction Func3 + delfunction Func3a + +Execute(We should be able to compute the argument count for function names): + AssertEqual 0, ale#util#FunctionArgCount('Func0') + AssertEqual 1, ale#util#FunctionArgCount('Func1') + AssertEqual 2, ale#util#FunctionArgCount('Func2') + AssertEqual 3, ale#util#FunctionArgCount('Func3') + AssertEqual 3, ale#util#FunctionArgCount('Func3a') + +Execute(We should be able to compute the argument count for Funcrefs): + AssertEqual 0, ale#util#FunctionArgCount(function('Func0')) + AssertEqual 1, ale#util#FunctionArgCount(function('Func1')) + AssertEqual 2, ale#util#FunctionArgCount(function('Func2')) + AssertEqual 3, ale#util#FunctionArgCount(function('Func3')) + AssertEqual 3, ale#util#FunctionArgCount(function('Func3a')) + +Execute(We should be able to compute the argument count for lambdas): + if has('lambda') + AssertEqual 0, ale#util#FunctionArgCount({->1}) + AssertEqual 1, ale#util#FunctionArgCount({x->1}) + AssertEqual 2, ale#util#FunctionArgCount({x,y->1}) + AssertEqual 3, ale#util#FunctionArgCount({x,y,z->1}) + AssertEqual 3, ale#util#FunctionArgCount({x,y,z,...->1}) + endif + +Execute(We should be able to compute the argument count autoload functions not yet loaded): + AssertEqual 1, ale#util#FunctionArgCount(function('ale#fixers#yapf#Fix')) + AssertEqual 1, ale#util#FunctionArgCount('ale#fixers#yapf#Fix') diff --git a/vim-config/plugins/ale/test/test_fuzzy_json_decode.vader b/vim-config/plugins/ale/test/test_fuzzy_json_decode.vader new file mode 100644 index 00000000..4b1c6088 --- /dev/null +++ b/vim-config/plugins/ale/test/test_fuzzy_json_decode.vader @@ -0,0 +1,29 @@ +Execute(FuzzyJSONDecode should return the default for empty Lists): + AssertEqual [], ale#util#FuzzyJSONDecode([], []) + AssertEqual {}, ale#util#FuzzyJSONDecode([], {}) + +Execute(FuzzyJSONDecode should return the default for empty Strings): + AssertEqual [], ale#util#FuzzyJSONDecode('', []) + AssertEqual {}, ale#util#FuzzyJSONDecode('', {}) + +Execute(FuzzyJSONDecode should return the default value for ['']): + AssertEqual [], ale#util#FuzzyJSONDecode([''], []) + AssertEqual {}, ale#util#FuzzyJSONDecode([''], {}) + +Execute(FuzzyJSONDecode should return the default value for only whitespace lines): + AssertEqual [], ale#util#FuzzyJSONDecode(['', "\n"], []) + AssertEqual {}, ale#util#FuzzyJSONDecode(['', "\n"], {}) + +Execute(FuzzyJSONDecode should return the default for Lists with invalid JSON): + AssertEqual [], ale#util#FuzzyJSONDecode(['x'], []) + AssertEqual {}, ale#util#FuzzyJSONDecode(['x'], {}) + +Execute(FuzzyJSONDecode should return the default for Strings with invalid JSON): + AssertEqual [], ale#util#FuzzyJSONDecode('x', []) + AssertEqual {}, ale#util#FuzzyJSONDecode('x', {}) + +Execute(FuzzyJSONDecode should return the JSON from the JSON string): + AssertEqual {'x': 3}, ale#util#FuzzyJSONDecode('{"x": 3}', []) + AssertEqual {'x': 3}, ale#util#FuzzyJSONDecode('{"x": 3}', {}) + AssertEqual {'x': 3}, ale#util#FuzzyJSONDecode(['{"x"', ': 3}'], []) + AssertEqual {'x': 3}, ale#util#FuzzyJSONDecode(['{"x"', ': 3}'], {}) diff --git a/vim-config/plugins/ale/test/test_get_abspath.vader b/vim-config/plugins/ale/test/test_get_abspath.vader new file mode 100644 index 00000000..7e1b5930 --- /dev/null +++ b/vim-config/plugins/ale/test/test_get_abspath.vader @@ -0,0 +1,29 @@ +Execute(Relative paths should be resolved correctly): + AssertEqual + \ has('win32') ? '\foo\bar\baz\whatever.txt' : '/foo/bar/baz/whatever.txt', + \ ale#path#GetAbsPath('/foo/bar/xyz', '../baz/whatever.txt') + AssertEqual + \ has('win32') ? '\foo\bar\xyz\whatever.txt' : '/foo/bar/xyz/whatever.txt', + \ ale#path#GetAbsPath('/foo/bar/xyz', './whatever.txt') + AssertEqual + \ has('win32') ? '\foo\bar\xyz\whatever.txt' : '/foo/bar/xyz/whatever.txt', + \ ale#path#GetAbsPath('/foo/bar/xyz', 'whatever.txt') + + if has('win32') + AssertEqual + \ 'C:\foo\bar\baz\whatever.txt', + \ ale#path#GetAbsPath('C:\foo\bar\baz\xyz', '../whatever.txt') + endif + +Execute(Absolute paths should be resolved correctly): + AssertEqual + \ has('win32') ? '\ding\dong' : '/ding/dong', + \ ale#path#GetAbsPath('/foo/bar/xyz', '/ding/dong') + + AssertEqual + \ has('win32') ? '\ding\dong' : '/ding/dong', + \ ale#path#GetAbsPath('/foo/bar/xyz', '//ding/dong') + + if has('win32') + AssertEqual '\ding', ale#path#GetAbsPath('/foo/bar/xyz', '\\ding') + endif diff --git a/vim-config/plugins/ale/test/test_get_loclist.vader b/vim-config/plugins/ale/test/test_get_loclist.vader new file mode 100644 index 00000000..14696998 --- /dev/null +++ b/vim-config/plugins/ale/test/test_get_loclist.vader @@ -0,0 +1,31 @@ +Before: + let g:loclist = [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'eslint', + \ 'nr': -1, + \ 'type': 'E', + \ 'col': 10, + \ 'text': 'Missing semicolon. (semi)' + \ }, + \ { + \ 'lnum': 2, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'eslint', + \ 'nr': -1, + \ 'type': 'W', + \ 'col': 10, + \ 'text': 'Infix operators must be spaced. (space-infix-ops)' + \ }, + \] + let g:ale_buffer_info = {'1': {'loclist': g:loclist}} + +After: + unlet g:loclist + let g:ale_buffer_info = {} + +Execute(GetLoclist should return the loclist): + AssertEqual g:loclist, ale#engine#GetLoclist(1) diff --git a/vim-config/plugins/ale/test/test_getmatches.vader b/vim-config/plugins/ale/test/test_getmatches.vader new file mode 100644 index 00000000..edf84f6e --- /dev/null +++ b/vim-config/plugins/ale/test/test_getmatches.vader @@ -0,0 +1,163 @@ +Execute (ale#util#GetMatches should return matches for many lines): + AssertEqual + \ [ + \ [ + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '47', + \ '14', + \ 'Missing trailing comma.', + \ 'Warning/comma-dangle', + \ '', + \ '', + \ '', + \ '', + \ '', + \ ], + \ [ + \ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]', + \ '56', + \ '41', + \ 'Missing semicolon.', + \ 'Error/semi', + \ '', + \ '', + \ '', + \ '', + \ '', + \ ], + \ ], + \ ale#util#GetMatches( + \ [ + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]', + \ ], + \ [ + \ '^.*:\(\d\+\):\(\d\+\): \(.\+\) \[\(.\+\)\]$', + \ ] + \ ) + +Execute (ale#util#GetMatches should accept a string for a single pattern): + AssertEqual + \ [ + \ [ + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '47', + \ '14', + \ 'Missing trailing comma.', + \ 'Warning/comma-dangle', + \ '', + \ '', + \ '', + \ '', + \ '', + \ ], + \ [ + \ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]', + \ '56', + \ '41', + \ 'Missing semicolon.', + \ 'Error/semi', + \ '', + \ '', + \ '', + \ '', + \ '', + \ ], + \ ], + \ ale#util#GetMatches( + \ [ + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]', + \ ], + \ '^.*:\(\d\+\):\(\d\+\): \(.\+\) \[\(.\+\)\]$' + \ ) + +Execute (ale#util#MapMatches should map matches): + AssertEqual + \ [ + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]', + \ ], + \ ale#util#MapMatches( + \ [ + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]', + \ ], + \ '^.*:\(\d\+\):\(\d\+\): \(.\+\) \[\(.\+\)\]$', + \ {match -> match[0]} + \ ) + +Execute (ale#util#GetMatches should accept a single line as a string): + AssertEqual + \ [ + \ [ + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '47', + \ '14', + \ 'Missing trailing comma.', + \ 'Warning/comma-dangle', + \ '', + \ '', + \ '', + \ '', + \ '', + \ ], + \ ], + \ ale#util#GetMatches( + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ [ + \ '^.*:\(\d\+\):\(\d\+\): \(.\+\) \[\(.\+\)\]$', + \ ] + \ ) + +Execute (ale#util#GetMatches should match multiple patterns correctly): + AssertEqual + \ [ + \ [ + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '47', + \ '14', + \ 'Missing trailing comma.', + \ 'Warning/comma-dangle', + \ '', + \ '', + \ '', + \ '', + \ '', + \ ], + \ [ + \ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]', + \ '56', + \ '41', + \ 'Missing semicolon.', + \ 'Error/semi', + \ '', + \ '', + \ '', + \ '', + \ '', + \ ], + \ [ + \ '/path/to/some-filename.js:13:3: Parsing error: Unexpected token', + \ '13', + \ '3', + \ 'Parsing error: Unexpected token', + \ '', + \ '', + \ '', + \ '', + \ '', + \ '', + \ ], + \ ], + \ ale#util#GetMatches( + \ [ + \ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]', + \ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]', + \ '/path/to/some-filename.js:13:3: Parsing error: Unexpected token', + \ ], + \ [ + \ '^.*:\(\d\+\):\(\d\+\): \(.\+\) \[\(.\+\)\]$', + \ '^.*:\(\d\+\):\(\d\+\): \(.\+\)$', + \ ] + \ ) diff --git a/vim-config/plugins/ale/test/test_go_to_definition.vader b/vim-config/plugins/ale/test/test_go_to_definition.vader new file mode 100644 index 00000000..90e49979 --- /dev/null +++ b/vim-config/plugins/ale/test/test_go_to_definition.vader @@ -0,0 +1,593 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('dummy.txt') + + Save g:ale_default_navigation + + let g:old_filename = expand('%:p') + let g:Callback = '' + let g:message_list = [] + let g:expr_list = [] + let g:capability_checked = '' + let g:conn_id = v:null + let g:InitCallback = v:null + let g:ale_default_navigation = 'buffer' + + runtime autoload/ale/linter.vim + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {}) + call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer) + + if a:linter.lsp is# 'tsserver' + call ale#lsp#MarkConnectionAsTsserver(g:conn_id) + endif + + let l:details = { + \ 'command': 'foobar', + \ 'buffer': a:buffer, + \ 'connection_id': g:conn_id, + \ 'project_root': '/foo/bar', + \} + + let g:InitCallback = {-> ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)} + endfunction + + function! ale#lsp#HasCapability(conn_id, capability) abort + let g:capability_checked = a:capability + + return 1 + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + + return 42 + endfunction + + function! ale#util#Execute(expr) abort + call add(g:expr_list, a:expr) + endfunction + +After: + Restore + + if g:conn_id isnot v:null + call ale#lsp#RemoveConnectionWithID(g:conn_id) + endif + + call ale#definition#SetMap({}) + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + unlet! g:capability_checked + unlet! g:InitCallback + unlet! g:old_filename + unlet! g:conn_id + unlet! g:Callback + unlet! g:message_list + unlet! g:expr_list + unlet! b:ale_linters + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + +Execute(Other messages for the tsserver handler should be ignored): + call ale#definition#HandleTSServerResponse(1, {'command': 'foo'}) + +Execute(Tagstack should be incremented if supported): + if exists('*gettagstack') && exists('*settagstack') + let original_stack_depth = gettagstack().length + endif + call ale#definition#UpdateTagStack() + if exists('*gettagstack') && exists('*settagstack') + AssertEqual original_stack_depth + 1, gettagstack().length + endif + +Execute(Failed definition responses should be handled correctly): + call ale#definition#SetMap({3: {'open_in': 'current-buffer'}}) + call ale#definition#HandleTSServerResponse( + \ 1, + \ {'command': 'definition', 'request_seq': 3} + \) + AssertEqual {}, ale#definition#GetMap() + +Execute(Failed definition responses with no files should be handled correctly): + call ale#definition#SetMap({3: {'open_in': 'current-buffer'}}) + call ale#definition#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'definition', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': [], + \ } + \) + AssertEqual {}, ale#definition#GetMap() + +Given typescript(Some typescript file): + foo + somelongerline + bazxyzxyzxyz + +Execute(Other files should be jumped to for definition responses): + call ale#definition#SetMap({3: {'open_in': 'current-buffer'}}) + call ale#definition#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'definition', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': [ + \ { + \ 'file': ale#path#Simplify(g:dir . '/completion_dummy_file'), + \ 'start': {'line': 3, 'offset': 7}, + \ }, + \ ], + \ } + \) + + AssertEqual + \ [ + \ 'edit +3 ' . fnameescape(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ ], + \ g:expr_list + AssertEqual [3, 7], getpos('.')[1:2] + AssertEqual {}, ale#definition#GetMap() + +Execute(Other files should be jumped to for definition responses in tabs too): + call ale#definition#SetMap({3: {'open_in': 'tab'}}) + call ale#definition#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'definition', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': [ + \ { + \ 'file': ale#path#Simplify(g:dir . '/completion_dummy_file'), + \ 'start': {'line': 3, 'offset': 7}, + \ }, + \ ], + \ } + \) + + AssertEqual + \ [ + \ 'tabedit +3 ' . fnameescape(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ ], + \ g:expr_list + AssertEqual [3, 7], getpos('.')[1:2] + AssertEqual {}, ale#definition#GetMap() + +Execute(Other files should be jumped to for definition responses in splits too): + call ale#definition#SetMap({3: {'open_in': 'split'}}) + call ale#definition#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'definition', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': [ + \ { + \ 'file': ale#path#Simplify(g:dir . '/completion_dummy_file'), + \ 'start': {'line': 3, 'offset': 7}, + \ }, + \ ], + \ } + \) + + AssertEqual + \ [ + \ 'split +3 ' . fnameescape(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ ], + \ g:expr_list + AssertEqual [3, 7], getpos('.')[1:2] + AssertEqual {}, ale#definition#GetMap() + +Execute(Other files should be jumped to for definition responses in vsplits too): + call ale#definition#SetMap({3: {'open_in': 'vsplit'}}) + call ale#definition#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'definition', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': [ + \ { + \ 'file': ale#path#Simplify(g:dir . '/completion_dummy_file'), + \ 'start': {'line': 3, 'offset': 7}, + \ }, + \ ], + \ } + \) + + AssertEqual + \ [ + \ 'vsplit +3 ' . fnameescape(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ ], + \ g:expr_list + AssertEqual [3, 7], getpos('.')[1:2] + AssertEqual {}, ale#definition#GetMap() + +Execute(tsserver definition requests should be sent): + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + ALEGoToDefinition + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'definition', g:capability_checked + AssertEqual + \ 'function(''ale#definition#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@definition', {'file': expand('%:p'), 'line': 2, 'offset': 5}] + \ ], + \ g:message_list + AssertEqual {'42': {'open_in': 'current-buffer'}}, ale#definition#GetMap() + +Execute(tsserver type definition requests should be sent): + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + ALEGoToTypeDefinition + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'typeDefinition', g:capability_checked + AssertEqual + \ 'function(''ale#definition#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@typeDefinition', {'file': expand('%:p'), 'line': 2, 'offset': 5}] + \ ], + \ g:message_list + AssertEqual {'42': {'open_in': 'current-buffer'}}, ale#definition#GetMap() + +Execute(tsserver tab definition requests should be sent): + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + ALEGoToDefinition -tab + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'definition', g:capability_checked + AssertEqual + \ 'function(''ale#definition#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@definition', {'file': expand('%:p'), 'line': 2, 'offset': 5}] + \ ], + \ g:message_list + AssertEqual {'42': {'open_in': 'tab'}}, ale#definition#GetMap() + +Execute(The default navigation type should be used): + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + let g:ale_default_navigation = 'tab' + ALEGoToDefinition + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'definition', g:capability_checked + AssertEqual + \ 'function(''ale#definition#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@definition', {'file': expand('%:p'), 'line': 2, 'offset': 5}] + \ ], + \ g:message_list + AssertEqual {'42': {'open_in': 'tab'}}, ale#definition#GetMap() + +Given python(Some Python file): + foo + somelongerline + bazxyzxyzxyz + +Execute(Other files should be jumped to for LSP definition responses): + call ale#definition#SetMap({3: {'open_in': 'current-buffer'}}) + call ale#definition#HandleLSPResponse( + \ 1, + \ { + \ 'id': 3, + \ 'result': { + \ 'uri': ale#path#ToURI(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ 'range': { + \ 'start': {'line': 2, 'character': 7}, + \ }, + \ }, + \ } + \) + + AssertEqual + \ [ + \ 'edit +3 ' . fnameescape(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ ], + \ g:expr_list + AssertEqual [3, 8], getpos('.')[1:2] + AssertEqual {}, ale#definition#GetMap() + +Execute(Newer LocationLink items should be supported): + call ale#definition#SetMap({3: {'open_in': 'current-buffer'}}) + call ale#definition#HandleLSPResponse( + \ 1, + \ { + \ 'id': 3, + \ 'result': { + \ 'targetUri': ale#path#ToURI(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ 'targetRange': { + \ 'start': {'line': 2, 'character': 7}, + \ }, + \ }, + \ } + \) + + AssertEqual + \ [ + \ 'edit +3 ' . fnameescape(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ ], + \ g:expr_list + AssertEqual [3, 8], getpos('.')[1:2] + AssertEqual {}, ale#definition#GetMap() + +Execute(Locations inside the same file should be jumped to without using :edit): + call ale#definition#SetMap({3: {'open_in': 'current-buffer'}}) + call ale#definition#HandleLSPResponse( + \ 1, + \ { + \ 'id': 3, + \ 'result': { + \ 'uri': ale#path#ToURI(ale#path#Simplify(expand('%:p'))), + \ 'range': { + \ 'start': {'line': 2, 'character': 7}, + \ }, + \ }, + \ } + \) + + AssertEqual + \ [ + \ ], + \ g:expr_list + AssertEqual [3, 8], getpos('.')[1:2] + AssertEqual {}, ale#definition#GetMap() + +Execute(Other files should be jumped to in tabs for LSP definition responses): + call ale#definition#SetMap({3: {'open_in': 'tab'}}) + call ale#definition#HandleLSPResponse( + \ 1, + \ { + \ 'id': 3, + \ 'result': { + \ 'uri': ale#path#ToURI(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ 'range': { + \ 'start': {'line': 2, 'character': 7}, + \ }, + \ }, + \ } + \) + + AssertEqual + \ [ + \ 'tabedit +3 ' . fnameescape(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ ], + \ g:expr_list + AssertEqual [3, 8], getpos('.')[1:2] + AssertEqual {}, ale#definition#GetMap() + +Execute(Definition responses with lists should be handled): + call ale#definition#SetMap({3: {'open_in': 'current-buffer'}}) + call ale#definition#HandleLSPResponse( + \ 1, + \ { + \ 'id': 3, + \ 'result': [ + \ { + \ 'uri': ale#path#ToURI(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ 'range': { + \ 'start': {'line': 2, 'character': 7}, + \ }, + \ }, + \ { + \ 'uri': ale#path#ToURI(ale#path#Simplify(g:dir . '/other_file')), + \ 'range': { + \ 'start': {'line': 20, 'character': 3}, + \ }, + \ }, + \ ], + \ } + \) + + AssertEqual + \ [ + \ 'edit +3 ' . fnameescape(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ ], + \ g:expr_list + AssertEqual [3, 8], getpos('.')[1:2] + AssertEqual {}, ale#definition#GetMap() + +Execute(Definition responses with null response should be handled): + call ale#definition#SetMap({3: {'open_in': 'current-buffer'}}) + call ale#definition#HandleLSPResponse(1, {'id': 3, 'result': v:null}) + + AssertEqual [], g:expr_list + +Execute(LSP definition requests should be sent): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + call setpos('.', [bufnr(''), 1, 5, 0]) + + ALEGoToDefinition + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'definition', g:capability_checked + AssertEqual + \ 'function(''ale#definition#HandleLSPResponse'')', + \ string(g:Callback) + + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}] + \ }], + \ [0, 'textDocument/definition', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'line': 0, 'character': 2}, + \ }], + \ ], + \ g:message_list + + AssertEqual {'42': {'open_in': 'current-buffer'}}, ale#definition#GetMap() + +Execute(LSP type definition requests should be sent): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + call setpos('.', [bufnr(''), 1, 5, 0]) + + ALEGoToTypeDefinition + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'typeDefinition', g:capability_checked + AssertEqual + \ 'function(''ale#definition#HandleLSPResponse'')', + \ string(g:Callback) + + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}] + \ }], + \ [0, 'textDocument/typeDefinition', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'line': 0, 'character': 2}, + \ }], + \ ], + \ g:message_list + + AssertEqual {'42': {'open_in': 'current-buffer'}}, ale#definition#GetMap() + +Execute(LSP tab definition requests should be sent): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + call setpos('.', [bufnr(''), 1, 5, 0]) + + ALEGoToDefinition -tab + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'definition', g:capability_checked + AssertEqual + \ 'function(''ale#definition#HandleLSPResponse'')', + \ string(g:Callback) + + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}] + \ }], + \ [0, 'textDocument/definition', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'line': 0, 'character': 2}, + \ }], + \ ], + \ g:message_list + + AssertEqual {'42': {'open_in': 'tab'}}, ale#definition#GetMap() + +Execute(LSP tab type definition requests should be sent): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + call setpos('.', [bufnr(''), 1, 5, 0]) + + ALEGoToTypeDefinition -tab + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'typeDefinition', g:capability_checked + AssertEqual + \ 'function(''ale#definition#HandleLSPResponse'')', + \ string(g:Callback) + + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}] + \ }], + \ [0, 'textDocument/typeDefinition', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'line': 0, 'character': 2}, + \ }], + \ ], + \ g:message_list + + AssertEqual {'42': {'open_in': 'tab'}}, ale#definition#GetMap() diff --git a/vim-config/plugins/ale/test/test_gradle_build_classpath_command.vader b/vim-config/plugins/ale/test/test_gradle_build_classpath_command.vader new file mode 100644 index 00000000..9557aa0d --- /dev/null +++ b/vim-config/plugins/ale/test/test_gradle_build_classpath_command.vader @@ -0,0 +1,52 @@ +Before: + Save $PATH + Save $PATHEXT + + let $PATHEXT = '.' + + call ale#test#SetDirectory('/testplugin/test') + runtime ale_linters/kotlin/kotlinc.vim + + let g:command_tail = ' -I ' . ale#Escape(ale#gradle#GetInitPath()) + \ . ' -q printClasspath' + + let g:gradle_init_path = ale#path#Simplify(g:dir . '../../autoload/ale/gradle/init.gradle') + +After: + Restore + + unlet! g:gradle_init_path + unlet! g:command_tail + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Should return 'gradlew' command if project includes gradle wapper): + call ale#test#SetFilename('test-files/gradle/wrapped-project/src/main/kotlin/dummy.kt') + + AssertEqual + \ [ + \ ale#path#Simplify(g:dir . '/test-files/gradle/wrapped-project'), + \ ale#Escape(ale#path#Simplify(g:dir . '/test-files/gradle/wrapped-project/gradlew')) + \ . g:command_tail, + \ ], + \ ale#gradle#BuildClasspathCommand(bufnr('')) + +Execute(Should return 'gradle' command if project does not include gradle wapper): + call ale#test#SetFilename('test-files/gradle/unwrapped-project/src/main/kotlin/dummy.kt') + let $PATH .= (has('win32') ? ';' : ':') + \ . ale#path#Simplify(g:dir . '/test-files/gradle') + + AssertEqual + \ [ + \ ale#path#Simplify(g:dir . '/test-files/gradle/unwrapped-project'), + \ ale#Escape('gradle') . g:command_tail + \ ], + \ ale#gradle#BuildClasspathCommand(bufnr('')) + +Execute(Should return empty string if gradle cannot be executed): + call ale#test#SetFilename('test-files/gradle/non-gradle-project/src/main/kotlin/dummy.kt') + + AssertEqual + \ ['', ''], + \ ale#gradle#BuildClasspathCommand(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_gradle_find_executable.vader b/vim-config/plugins/ale/test/test_gradle_find_executable.vader new file mode 100644 index 00000000..f874748c --- /dev/null +++ b/vim-config/plugins/ale/test/test_gradle_find_executable.vader @@ -0,0 +1,37 @@ +Before: + Save $PATH + Save $PATHEXT + + " Count the gradle executable without .exe as executable on Windows + let $PATHEXT = '.' + + call ale#test#SetDirectory('/testplugin/test') + runtime ale_linters/kotlin/kotlinc.vim + +After: + Restore + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Should return 'gradlew' if found in parent directory): + call ale#test#SetFilename('test-files/gradle/wrapped-project/src/main/kotlin/dummy.kt') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/gradle/wrapped-project/gradlew'), + \ ale#gradle#FindExecutable(bufnr('')) + +Execute(Should return 'gradle' if 'gradlew' not found in parent directory): + call ale#test#SetFilename('test-files/gradle/unwrapped-project/src/main/kotlin/dummy.kt') + let $PATH .= (has('win32') ? ';': ':') . ale#path#Simplify(g:dir . '/test-files/gradle') + + AssertEqual + \ 'gradle', + \ ale#gradle#FindExecutable(bufnr('')) + +Execute(Should return empty string if 'gradlew' not in parent directory and gradle not in path): + call ale#test#SetFilename('test-files/gradle/unwrapped-project/src/main/kotlin/dummy.kt') + + AssertEqual + \ '', + \ ale#gradle#FindExecutable(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_gradle_find_project_root.vader b/vim-config/plugins/ale/test/test_gradle_find_project_root.vader new file mode 100644 index 00000000..b6159188 --- /dev/null +++ b/vim-config/plugins/ale/test/test_gradle_find_project_root.vader @@ -0,0 +1,35 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + runtime ale_linters/kotlin/kotlinc.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Should return directory for 'gradlew' if found in parent directory): + call ale#test#SetFilename('test-files/gradle/wrapped-project/src/main/kotlin/dummy.kt') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/gradle/wrapped-project'), + \ ale#gradle#FindProjectRoot(bufnr('')) + +Execute(Should return directory for 'settings.gradle' if found in parent directory): + call ale#test#SetFilename('test-files/gradle/settings-gradle-project/src/main/kotlin/dummy.kt') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/gradle/settings-gradle-project'), + \ ale#gradle#FindProjectRoot(bufnr('')) + +Execute(Should return directory for 'build.gradle' if found in parent directory): + call ale#test#SetFilename('test-files/gradle/build-gradle-project/src/main/kotlin/dummy.kt') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/gradle/build-gradle-project'), + \ ale#gradle#FindProjectRoot(bufnr('')) + +Execute(Should return empty string if gradle files are not found in parent directory): + call ale#test#SetFilename('test-files/gradle/non-gradle-project/src/main/kotlin/dummy.kt') + + AssertEqual + \ '', + \ ale#gradle#FindProjectRoot(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_highlight_placement.vader b/vim-config/plugins/ale/test/test_highlight_placement.vader new file mode 100644 index 00000000..dab73073 --- /dev/null +++ b/vim-config/plugins/ale/test/test_highlight_placement.vader @@ -0,0 +1,448 @@ +Before: + Save g:ale_buffer_info + Save g:ale_echo_cursor + Save g:ale_enabled + Save g:ale_run_synchronously + Save g:ale_set_highlights + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_set_signs + Save g:ale_exclude_highlights + Save b:ale_exclude_highlights + + runtime autoload/ale/highlight.vim + + let g:ale_run_synchronously = 1 + unlet! g:ale_run_synchronously_callbacks + let g:ale_set_highlights = 1 + let g:ale_set_signs = 1 + let g:ale_buffer_info = {} + + " Disable features we don't need for these tests. + let g:ale_set_quickfix = 0 + let g:ale_set_loclist = 0 + let g:ale_echo_cursor = 0 + let g:ale_exclude_highlights = [] + let b:ale_exclude_highlights = [] + + function! GenerateResults(buffer, output) + return [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'E', + \ 'text': 'foo', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'type': 'W', + \ 'text': 'bar', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 5, + \ 'type': 'E', + \ 'text': 'wat', + \ }, + \] + endfunction + + let g:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace') + let g:nvim_highlight_matches = {} + + function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort + if a:line_end != -1 + throw 'nvim api behavior not supported' + endif + + let l:matches = get(g:nvim_highlight_matches, a:buffer, []) + call filter( + \ l:matches, + \ {_, val -> val.pos1[0] < (a:line_start + 1) }, + \) + endfunction + + function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort + if a:col_end == -1 + throw 'nvim api behavior not supported' + endif + + let l:matches = get(g:nvim_highlight_matches, a:buffer, []) + let g:nvim_highlight_matches[a:buffer] = l:matches + + let l:new_match = { + \ 'group': a:hl_group, + \ 'priority': 10, + \ 'pos1': [a:line + 1, a:col_start + 1, a:col_end - a:col_start], + \} + + call add(l:matches, l:new_match) + " sort by line number to emulate getmatches faithfully + call sort(l:matches, {m1, m2 -> m1.pos1[0] - m2.pos1[0]}) + endfunction + + " We don't care what the IDs are, just that we have some matches. + " The IDs are generated. + function! GetMatchesWithoutIDs() abort + if g:has_nvim_highlight + return get(g:nvim_highlight_matches, bufnr(''), []) + else + let l:list = getmatches() + + for l:item in l:list + call remove(l:item, 'id') + endfor + + return l:list + endif + endfunction + + call ale#linter#Define('testft', { + \ 'name': 'x', + \ 'executable': has('win32') ? 'cmd': 'echo', + \ 'command': has('win32') ? 'echo' : '/bin/sh -c ''echo''', + \ 'callback': 'GenerateResults', + \}) + highlight link SomeOtherGroup SpellBad + +After: + Restore + + unlet! g:ale_run_synchronously_callbacks + unlet! g:items + unlet! b:ale_enabled + unlet! g:has_nvim_highlight + unlet! g:nvim_highlight_matches + + delfunction GenerateResults + call ale#linter#Reset() + call clearmatches() + call ale#sign#Clear() + highlight clear SomeOtherGroup + + runtime autoload/ale/highlight.vim + +Given testft(A Javscript file with warnings/errors): + foo + bar + baz wat + line four + +Execute(Highlights should be set when a linter runs): + ALELint + call ale#test#FlushJobs() + + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]}, + \ {'group': 'ALEWarning', 'priority': 10, 'pos1': [2, 1, 1]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 5, 1]} + \ ], + \ GetMatchesWithoutIDs() + +" This test is important for preventing ALE from showing highlights for +" the wrong files. +Execute(Highlights set by ALE should be removed when buffer cleanup is done): + call ale#engine#InitBufferInfo(bufnr('%')) + + call ale#highlight#SetHighlights(bufnr('%'), [ + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 2}, + \]) + + if !g:has_nvim_highlight + " This check doesn't work with the new API, for some reason. + AssertEqual + \ [{'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]}], + \ GetMatchesWithoutIDs() + endif + + call ale#engine#Cleanup(bufnr('%')) + + AssertEqual [], GetMatchesWithoutIDs() + +Execute(Highlights should be cleared when buffers are hidden): + call ale#engine#InitBufferInfo(bufnr('%')) + " The second item should be ignored, as it has no column infomration. + let g:ale_buffer_info[bufnr('%')].loclist = [ + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 2}, + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 4, 'col': 0}, + \] + call ale#highlight#SetHighlights( + \ bufnr('%'), + \ g:ale_buffer_info[bufnr('%')].loclist + \) + + AssertEqual 1, len(GetMatchesWithoutIDs()), 'The highlights weren''t initially set!' + + call ale#highlight#BufferHidden(bufnr('%')) + + AssertEqual 0, len(GetMatchesWithoutIDs()), 'The highlights weren''t cleared!' + + call ale#highlight#UpdateHighlights() + + AssertEqual 1, len(GetMatchesWithoutIDs()), 'The highlights weren''t set again!' + +Execute(Only ALE highlights should be restored when buffers are restored): + call ale#engine#InitBufferInfo(bufnr('%')) + let g:ale_buffer_info[bufnr('%')].loclist = [ + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 2}, + \] + call ale#highlight#SetHighlights( + \ bufnr('%'), + \ g:ale_buffer_info[bufnr('%')].loclist + \) + + call matchaddpos('SomeOtherGroup', [[1, 1, 1]]) + + " We should have both highlights. + if g:has_nvim_highlight + " When the newer NeoVim API is used, we don't have to worry about + " other highlights, namespacing is available. + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]}, + \ ], + \ GetMatchesWithoutIDs() + else + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]}, + \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]}, + \ ], + \ sort(GetMatchesWithoutIDs(), {m1, m2 -> m1.group < m2.group ? -1 : 1}) + endif + + call ale#highlight#BufferHidden(bufnr('%')) + + " We should remove our highlight, but not the other one. + if g:has_nvim_highlight + AssertEqual [], GetMatchesWithoutIDs() + else + AssertEqual + \ [ + \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]} + \ ], + \ GetMatchesWithoutIDs() + endif + + call ale#highlight#UpdateHighlights() + + " Our highlight should apper again. + if g:has_nvim_highlight + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]}, + \ ], + \ GetMatchesWithoutIDs() + else + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 1]}, + \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]}, + \ ], + \ sort(GetMatchesWithoutIDs(), {m1, m2 -> m1.group < m2.group ? -1 : 1}) + endif + +Execute(Higlight end columns should set an appropriate size): + call ale#highlight#SetHighlights(bufnr('%'), [ + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 2, 'end_col': 5}, + \ {'bufnr': bufnr('%'), 'type': 'W', 'lnum': 4, 'col': 1, 'end_col': 5}, + \]) + + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 2, 4]}, + \ {'group': 'ALEWarning', 'priority': 10, 'pos1': [4, 1, 5]}, + \ ], + \ GetMatchesWithoutIDs() + +Execute(Higlight end columns should set an appropriate size): + call ale#highlight#SetHighlights(bufnr('%'), [ + \ {'bufnr': bufnr('%') - 1, 'type': 'E', 'lnum': 1, 'col': 1}, + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 1, 'col': 1}, + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 2, 'col': 1}, + \ {'bufnr': bufnr('%'), 'type': 'E', 'sub_type': 'style', 'lnum': 3, 'col': 1}, + \ {'bufnr': bufnr('%'), 'type': 'W', 'lnum': 4, 'col': 1}, + \ {'bufnr': bufnr('%'), 'type': 'W', 'lnum': 5, 'col': 1}, + \ {'bufnr': bufnr('%'), 'type': 'W', 'sub_type': 'style', 'lnum': 6, 'col': 1}, + \ {'bufnr': bufnr('%'), 'type': 'I', 'lnum': 7, 'col': 1}, + \ {'bufnr': bufnr('%') + 1, 'type': 'E', 'lnum': 1, 'col': 1}, + \]) + + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [2, 1, 1]}, + \ {'group': 'ALEStyleError', 'priority': 10, 'pos1': [3, 1, 1]}, + \ {'group': 'ALEWarning', 'priority': 10, 'pos1': [4, 1, 1]}, + \ {'group': 'ALEWarning', 'priority': 10, 'pos1': [5, 1, 1]}, + \ {'group': 'ALEStyleWarning', 'priority': 10, 'pos1': [6, 1, 1]}, + \ {'group': 'ALEInfo', 'priority': 10, 'pos1': [7, 1, 1]}, + \ ], + \ GetMatchesWithoutIDs() + +Execute(Highlighting should support errors spanning many lines): + let g:items = [ + \ {'bufnr': bufnr(''), 'type': 'E', 'lnum': 1, 'col': 1, 'end_lnum': 10, 'end_col': 3}, + \] + + call ale#highlight#SetHighlights(bufnr(''), g:items) + + if g:has_nvim_highlight + " The newer NeoVim highlight API produces different output. + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1073741824]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [2, 1, 1073741824]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [3, 1, 1073741824]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [4, 1, 1073741824]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [5, 1, 1073741824]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [6, 1, 1073741824]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [7, 1, 1073741824]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [8, 1, 1073741824]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [9, 1, 1073741824]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [10, 1, 3]}, + \ ], + \ GetMatchesWithoutIDs() + else + " We should set 2 highlights for the item, as we can only add 8 at a time. + AssertEqual + \ [ + \ { + \ 'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1073741824], + \ 'pos2': [2], 'pos3': [3], 'pos4': [4], 'pos5': [5], 'pos6': [6], + \ 'pos7': [7], 'pos8': [8], + \ }, + \ { + \ 'group': 'ALEError', 'priority': 10, + \ 'pos1': [9], 'pos2': [10, 1, 3] + \ }, + \ ], + \ GetMatchesWithoutIDs() + endif + +Execute(Highlights should always be cleared when the buffer highlight list is empty): + if g:has_nvim_highlight + " The newer API uses namespacing. We'll emulate it here. + call ale#highlight#nvim_buf_add_highlight( + \ bufnr(''), + \ 1, + \ 'ALEError', + \ 0, + \ 0, + \ 1, + \) + + AssertEqual + \ [{'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]}], + \ GetMatchesWithoutIDs() + else + " Add our highlights and something else. + call matchaddpos('ALEError', [[1, 1, 1]]) + call matchaddpos('SomeOtherGroup', [[1, 1, 1]]) + + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]}, + \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]}, + \ ], + \ GetMatchesWithoutIDs() + endif + + + " Set the List we use for holding highlights for buffers. + let b:ale_highlight_items = [] + + " Call the function for updating the highlights called when buffers + " are entered, or when problems are presented. + call ale#highlight#UpdateHighlights() + + " Check that we remove our highlights. + if g:has_nvim_highlight + AssertEqual [], GetMatchesWithoutIDs() + else + AssertEqual + \ [{'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]}], + \ GetMatchesWithoutIDs() + endif + +Execute(Highlights should be hidden when excluded): + let b:ale_exclude_highlights = ['ig.*ore', 'nope'] + + call ale#highlight#SetHighlights(bufnr('%'), [ + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 1, 'col': 1, 'text': 'hello'}, + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 2, 'col': 1, 'text': 'ignore'}, + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 1, 'text': 'nope'}, + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 4, 'col': 1, 'text': 'world'}, + \]) + + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]}, + \ {'group': 'ALEError', 'priority': 10, 'pos1': [4, 1, 1]}, + \ ], + \ GetMatchesWithoutIDs() + +Execute(Highlights should be cleared when ALE is disabled): + let g:ale_enabled = 1 + call ale#highlight#SetHighlights(bufnr(''), [ + \ {'bufnr': bufnr(''), 'type': 'E', 'lnum': 1, 'col': 1, 'end_lnum': 10, 'end_col': 3}, + \]) + + let g:ale_enabled = 0 + call ale#highlight#UpdateHighlights() + + AssertEqual [], GetMatchesWithoutIDs() + + let g:ale_enabled = 1 + call ale#highlight#SetHighlights(bufnr(''), [ + \ {'bufnr': bufnr(''), 'type': 'E', 'lnum': 1, 'col': 1, 'end_lnum': 10, 'end_col': 3}, + \]) + + let b:ale_enabled = 0 + call ale#highlight#UpdateHighlights() + + AssertEqual [], GetMatchesWithoutIDs() + +Execute(Line highlights should be set when signs are disabled): + " This will mess with your settings, but it needs to be tested. + " We need to match highlights case-insenstive when removing them. + hi link aleerrorline spellbad + + let g:ale_set_signs = 0 + + call ale#highlight#SetHighlights(bufnr(''), [ + \ {'bufnr': bufnr(''), 'type': 'E', 'lnum': 1, 'col': 1}, + \ {'bufnr': bufnr(''), 'type': 'W', 'lnum': 2, 'col': 1}, + \ {'bufnr': bufnr(''), 'type': 'I', 'lnum': 3, 'col': 1}, + \]) + + if g:has_nvim_highlight + " The output is different with the newer NeoVIM highlight API. + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]}, + \ {'group': 'ALEErrorLine', 'priority': 10, 'pos1': [1, 1, 1073741824]}, + \ {'group': 'ALEWarning', 'priority': 10, 'pos1': [2, 1, 1]}, + \ {'group': 'ALEWarningLine', 'priority': 10, 'pos1': [2, 1, 1073741824]}, + \ {'group': 'ALEInfo', 'priority': 10, 'pos1': [3, 1, 1]}, + \ {'group': 'ALEInfoLine', 'priority': 10, 'pos1': [3, 1, 1073741824]} + \ ], + \ GetMatchesWithoutIDs() + else + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]}, + \ {'group': 'ALEWarning', 'priority': 10, 'pos1': [2, 1, 1]}, + \ {'group': 'ALEInfo', 'priority': 10, 'pos1': [3, 1, 1]}, + \ {'group': 'aleerrorline', 'priority': 10, 'pos1': [1]}, + \ {'group': 'ALEWarningLine', 'priority': 10, 'pos1': [2]}, + \ {'group': 'ALEInfoLine', 'priority': 10, 'pos1': [3]}, + \ ], + \ GetMatchesWithoutIDs() + endif + + " All of the highlights should be removed. + call ale#highlight#RemoveHighlights() + AssertEqual [], GetMatchesWithoutIDs() diff --git a/vim-config/plugins/ale/test/test_highlight_position_chunking.vader b/vim-config/plugins/ale/test/test_highlight_position_chunking.vader new file mode 100644 index 00000000..cd9161b5 --- /dev/null +++ b/vim-config/plugins/ale/test/test_highlight_position_chunking.vader @@ -0,0 +1,76 @@ +Execute(CreatePositions() should support single character matches): + AssertEqual [[[1, 5, 1]]], ale#highlight#CreatePositions(1, 5, 1, 5) + " When the end column is behind the start column, ignore it. + AssertEqual [[[2, 5, 1]]], ale#highlight#CreatePositions(2, 5, 1, 5) + +Execute(CreatePositions() should support multiple character matches on a single line): + AssertEqual [[[1, 5, 6]]], ale#highlight#CreatePositions(1, 5, 1, 10) + " When the end column is behind the start column, ignore it. + AssertEqual [[[2, 5, 6]]], ale#highlight#CreatePositions(2, 5, 1, 10) + +Execute(CreatePositions() should support character matches two lines): + AssertEqual [[[1, 5, 1073741824], [2, 1, 10]]], ale#highlight#CreatePositions(1, 5, 2, 10) + +Execute(CreatePositions() should support character matches across many lines): + " Test chunks from 1,3 to 1,17 + AssertEqual [ + \ [[1, 5, 1073741824], 2, [3, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 3, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, [4, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 4, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, [5, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 5, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, [6, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 6, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, [7, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 7, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, [8, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 8, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], + \ [[9, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 9, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], + \ [9, [10, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 10, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], + \ [9, 10, [11, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 11, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], + \ [9, 10, 11, [12, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 12, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], + \ [9, 10, 11, 12, [13, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 13, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], + \ [9, 10, 11, 12, 13, [14, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 14, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], + \ [9, 10, 11, 12, 13, 14, [15, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 15, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], + \ [9, 10, 11, 12, 13, 14, 15, [16, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 16, 10) + AssertEqual [ + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], + \ [9, 10, 11, 12, 13, 14, 15, 16], + \ [[17, 1, 10]], + \], ale#highlight#CreatePositions(1, 5, 17, 10) + " Test another random sample at higher lines. + AssertEqual [ + \ [[21, 8, 1073741824], 22, 23, 24, 25, 26, 27, 28], + \ [29, 30, 31, 32, 33, 34, 35, 36], + \ [[37, 1, 2]], + \], ale#highlight#CreatePositions(21, 8, 37, 2) diff --git a/vim-config/plugins/ale/test/test_history_saving.vader b/vim-config/plugins/ale/test/test_history_saving.vader new file mode 100644 index 00000000..5d81c2a3 --- /dev/null +++ b/vim-config/plugins/ale/test/test_history_saving.vader @@ -0,0 +1,177 @@ +Before: + Save g:ale_max_buffer_history_size + Save g:ale_history_enabled + Save g:ale_history_log_output + Save g:ale_run_synchronously + Save g:ale_enabled + + let g:ale_enabled = 1 + let g:ale_run_synchronously = 1 + + unlet! b:ale_fixers + unlet! b:ale_enabled + unlet! b:ale_history + + " Temporarily set the shell to /bin/sh, if it isn't already set that way. + " This will make it so the test works when running it directly. + let g:current_shell = &shell + + if !has('win32') + let &shell = '/bin/sh' + endif + + let g:history = [] + let g:ale_buffer_info = {} + let g:ale_max_buffer_history_size = 20 + let g:ale_history_log_output = 0 + + function! TestFixer(buffer) + return {'command': 'echo foo'} + endfunction + + function! CollectResults(buffer, output) + return [] + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'CollectResults', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': has('win32') + \ ? 'echo command history test' + \ : '/bin/sh -c ''echo command history test''', + \ 'read_buffer': 0, + \}) + +After: + Restore + + unlet! g:expected_results + unlet! b:ale_fixers + unlet! b:ale_enabled + " Clear the history we changed. + unlet! b:ale_history + + " Reset the shell back to what it was before. + let &shell = g:current_shell + unlet g:current_shell + unlet g:history + + call ale#engine#Cleanup(bufnr('')) + call ale#linter#Reset() + + let g:ale_buffer_info = {} + let g:ale_max_buffer_history_size = 20 + delfunction TestFixer + delfunction CollectResults + +Given foobar (Some imaginary filetype): + anything + +Execute(History should be set when commands are run): + AssertEqual 'foobar', &filetype + + let b:ale_history = [] + ALELint + call ale#test#FlushJobs() + + let g:history = filter( + \ copy(ale#history#Get(bufnr(''))), + \ 'v:val.job_id isnot# ''executable''', + \) + + AssertEqual 1, len(g:history) + AssertEqual + \ ['command', 'exit_code', 'job_id', 'status'], + \ sort(keys(g:history[0])) + + if has('win32') + AssertEqual 'cmd /s/c "echo command history test"', g:history[0].command + else + AssertEqual ['/bin/sh', '-c', '/bin/sh -c ''echo command history test'''], g:history[0].command + endif + + AssertEqual 'finished', g:history[0].status + AssertEqual 0, g:history[0].exit_code + " The Job ID will change each time, but we can check the type. + AssertEqual type(1), type(g:history[0].job_id) + +Execute(History should be not set when disabled): + AssertEqual 'foobar', &filetype + + let g:ale_history_enabled = 0 + + ALELint + call ale#test#FlushJobs() + + AssertEqual [], ale#history#Get(bufnr('')) + +Execute(History should include command output if logging is enabled): + AssertEqual 'foobar', &filetype + + let g:ale_history_log_output = 1 + + " Retry this test until it works. This one can randomly fail. + let b:ale_history = [] + ALELint + call ale#test#FlushJobs() + + let g:history = ale#history#Get(bufnr('')) + + AssertEqual 1, len(g:history) + AssertEqual + \ ['command history test'], + \ map( + \ copy(get(g:history[0], 'output', [])), + \ 'substitute(v:val, ''[\r ]*$'', '''', ''g'')' + \ ) + +Execute(History items should be popped after going over the max): + let b:ale_history = map(range(20), '{''status'': ''started'', ''job_id'': v:val, ''command'': ''foobar''}') + + call ale#history#Add(bufnr(''), 'started', 347, 'last command') + + AssertEqual + \ ( + \ map(range(1, 19), '{''status'': ''started'', ''job_id'': v:val, ''command'': ''foobar''}') + \ + [{'status': 'started', 'job_id': 347, 'command': 'last command'}] + \ ), + \ ale#history#Get(bufnr('')) + +Execute(Nothing should be added to history if the size is too low): + let g:ale_max_buffer_history_size = 0 + + call ale#history#Add(bufnr(''), 'started', 347, 'last command') + + AssertEqual [], ale#history#Get(bufnr('')) + + let g:ale_max_buffer_history_size = -2 + + call ale#history#Add(1, 'started', 347, 'last command') + + AssertEqual [], ale#history#Get(bufnr('')) + +Given foobar(Some file with an imaginary filetype): + a + b + c + +Execute(The history should be updated when fixers are run): + call ale#test#SetFilename('dummy.txt') + + let b:ale_fixers = {'foobar': ['TestFixer']} + let b:ale_enabled = 0 + + ALEFix + + AssertEqual ['started'], map(copy(b:ale_history), 'v:val.status') + + call ale#test#FlushJobs() + + AssertEqual ['finished'], map(copy(b:ale_history), 'v:val.status') + + if has('win32') + AssertEqual 'cmd /s/c "echo foo ', split(b:ale_history[0].command, '<')[0] + else + AssertEqual '/bin/sh -c echo foo ', split(join(b:ale_history[0].command), '<')[0] + endif diff --git a/vim-config/plugins/ale/test/test_hover.vader b/vim-config/plugins/ale/test/test_hover.vader new file mode 100644 index 00000000..7a9c8d91 --- /dev/null +++ b/vim-config/plugins/ale/test/test_hover.vader @@ -0,0 +1,272 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('dummy.txt') + + let g:Callback = 0 + let g:message_list = [] + let g:item_list = [] + let g:show_message_arg_list = [] + + let g:ale_floating_preview = 0 + let g:ale_hover_to_floating_preview = 0 + let g:ale_detail_to_floating_preview = 0 + + runtime autoload/ale/linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/util.vim + runtime autoload/ale/floating_preview.vim + runtime autoload/ale/hover.vim + + let g:floated_lines = [] + let g:floating_preview_show_called = 0 + + " Stub out so we can track the call + function! ale#floating_preview#Show(lines, ...) abort + let g:floating_preview_show_called = 1 + let g:floated_lines = a:lines + endfunction + + function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort + let g:Callback = a:callback + + return { + \ 'command': 'foobar', + \ 'connection_id': 347, + \ 'project_root': '/foo/bar', + \} + endfunction + + function! ale#lsp#Send(conn_id, message, root) abort + call add(g:message_list, a:message) + + return 42 + endfunction + + function! ale#util#ShowMessage(string, ...) abort + call add(g:show_message_arg_list, [a:string] + a:000) + endfunction + + function! HandleValidLSPResult(result) abort + " The cursor is beyond the length of the line. + " We will clamp the cursor position with the line length. + call setpos('.', [bufnr(''), 1, 5, 0]) + + call ale#hover#SetMap({3: { + \ 'buffer': bufnr(''), + \ 'line': 1, + \ 'column': 5, + \}}) + call ale#hover#HandleLSPResponse( + \ 1, + \ { + \ 'id': 3, + \ 'result': a:result, + \ } + \) + endfunction + + +After: + call ale#hover#SetMap({}) + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + unlet! g:Callback + unlet! g:message_list + unlet! b:ale_linters + unlet! g:show_message_arg_list + + delfunction HandleValidLSPResult + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/floating_preview.vim + +Given python(Some Python file): + foo + somelongerline + bazxyzxyzxyz + +Execute(Other messages for the tsserver handler should be ignored): + call ale#hover#HandleTSServerResponse(1, {'command': 'foo'}) + +Execute(Failed hover responses should be handled correctly): + call ale#hover#SetMap({3: {}}) + call ale#hover#HandleTSServerResponse( + \ 1, + \ {'command': 'quickinfo', 'request_seq': 3} + \) + AssertEqual {}, ale#hover#GetMap() + +Given typescript(Some typescript file): + foo + somelongerline + bazxyzxyzxyz + +Execute(tsserver quickinfo responses will null missing bodies should be handled): + call ale#hover#SetMap({3: {}}) + call ale#hover#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'quickinfo', + \ 'request_seq': 3, + \ 'success': v:true, + \ } + \) + + AssertEqual {}, ale#hover#GetMap() + +Execute(tsserver quickinfo displayString values should be displayed): + call ale#hover#SetMap({3: {'buffer': bufnr('')}}) + call ale#hover#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'quickinfo', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': {'displayString': 'foo bar'}, + \ } + \) + + AssertEqual [['foo bar']], g:show_message_arg_list + AssertEqual {}, ale#hover#GetMap() + +Execute(LSP hover responses with just a string should be handled): + call HandleValidLSPResult({'contents': 'foobar'}) + + AssertEqual [['foobar', {'commands': []}]], g:show_message_arg_list + AssertEqual {}, ale#hover#GetMap() + +Execute(LSP hover null responses should be handled): + call HandleValidLSPResult(v:null) + + AssertEqual [], g:show_message_arg_list + AssertEqual {}, ale#hover#GetMap() + +Execute(LSP hover responses with markup content should be handled): + call HandleValidLSPResult({'contents': {'kind': 'markdown', 'value': 'markup'}}) + + AssertEqual [['markup', {'commands': []}]], g:show_message_arg_list + AssertEqual {}, ale#hover#GetMap() + +Execute(LSP hover responses with markup content missing values should be handled): + call HandleValidLSPResult({'contents': {'kind': 'markdown'}}) + + AssertEqual [], g:show_message_arg_list + AssertEqual {}, ale#hover#GetMap() + +Execute(LSP hover response with lists of strings should be handled): + call HandleValidLSPResult({'contents': [ + \ "foo\n", + \ "bar\n", + \]}) + + AssertEqual [["foo\n\nbar", {'commands': []}]], g:show_message_arg_list + AssertEqual {}, ale#hover#GetMap() + +Execute(LSP hover response with lists of strings and marked strings should be handled): + call HandleValidLSPResult({'contents': [ + \ {'language': 'rust', 'value': 'foo'}, + \ "bar\n", + \]}) + + AssertEqual [ + \ [ + \ "foo\n\nbar", + \ { + \ 'commands': [ + \ 'unlet! b:current_syntax', + \ 'syntax include @ALE_hover_rust syntax/rust.vim', + \ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%2l/ contains=@ALE_hover_rust', + \ ], + \ }, + \ ], + \], g:show_message_arg_list + AssertEqual {}, ale#hover#GetMap() + +Execute(LSP hover with ale_floating_preview should float): + let g:ale_floating_preview = 1 + + call HandleValidLSPResult({'contents': "the message\ncontinuing"}) + + AssertEqual 1, g:floating_preview_show_called + AssertEqual ["the message", "continuing"], g:floated_lines + +Execute(LSP hover ale_hover_to_floating_preview should float): + let g:ale_hover_to_floating_preview = 1 + + call HandleValidLSPResult({'contents': "the message\ncontinuing"}) + + AssertEqual 1, g:floating_preview_show_called + AssertEqual ["the message", "continuing"], g:floated_lines + + +Execute(LSP hover by default should not float): + call HandleValidLSPResult({'contents': "the message\ncontinuing"}) + + AssertEqual 0, g:floating_preview_show_called + +Execute(tsserver responses for documentation requests should be handled): + call ale#hover#SetMap({3: {'show_documentation': 1, 'buffer': bufnr('')}}) + + call ale#hover#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'quickinfo', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'documentation': 'foo is a very good method', + \ 'displayString': 'foo bar', + \ }, + \ } + \) + + " The preview window should show the text. + AssertEqual ['foo is a very good method'], ale#test#GetPreviewWindowText() + silent! pclose + +Execute(hover with show_documentation should be in the preview window, not floating): + let g:ale_hover_to_floating_preview = 1 + let g:ale_floating_preview = 1 + + call ale#hover#SetMap({3: {'show_documentation': 1, 'buffer': bufnr('')}}) + + call ale#hover#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'quickinfo', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'documentation': 'foo is a very good method', + \ 'displayString': 'foo bar ', + \ }, + \ } + \) + + let expected = ["Every statement should end with a semicolon", "second line"] + + AssertEqual 0, g:floating_preview_show_called + +Execute(TSServer hover without show_documentation and ale_floating_preview should float): + let g:ale_floating_preview = 1 + + call ale#hover#SetMap({3: {'buffer': bufnr('')}}) + + call ale#hover#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'quickinfo', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'displayString': "the message\ncontinuing", + \ }, + \ } + \) + + AssertEqual 1, g:floating_preview_show_called + AssertEqual ["the message", "continuing"], g:floated_lines diff --git a/vim-config/plugins/ale/test/test_hover_parsing.vader b/vim-config/plugins/ale/test/test_hover_parsing.vader new file mode 100644 index 00000000..4129c26a --- /dev/null +++ b/vim-config/plugins/ale/test/test_hover_parsing.vader @@ -0,0 +1,173 @@ +Execute(Invalid results should be handled): + AssertEqual [[], []], ale#hover#ParseLSPResult(0) + AssertEqual [[], []], ale#hover#ParseLSPResult([0]) + AssertEqual [[], []], ale#hover#ParseLSPResult('') + AssertEqual [[], []], ale#hover#ParseLSPResult({}) + AssertEqual [[], []], ale#hover#ParseLSPResult([{}]) + AssertEqual [[], []], ale#hover#ParseLSPResult(['']) + AssertEqual [[], []], ale#hover#ParseLSPResult({'value': ''}) + AssertEqual [[], []], ale#hover#ParseLSPResult([{'value': ''}]) + AssertEqual [[], []], ale#hover#ParseLSPResult({'kind': 'markdown'}) + AssertEqual [[], []], ale#hover#ParseLSPResult({'kind': 'plaintext'}) + AssertEqual [[], []], ale#hover#ParseLSPResult({'kind': 'x', 'value': 'xxx'}) + +Execute(A string with a code fence should be handled): + AssertEqual + \ [ + \ [ + \ 'unlet! b:current_syntax', + \ 'syntax include @ALE_hover_python syntax/python.vim', + \ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python', + \ ], + \ [ + \ 'def foo():', + \ ' pass', + \ ], + \ ], + \ ale#hover#ParseLSPResult(join([ + \ '```python', + \ 'def foo():', + \ ' pass', + \ '```', + \ ], "\n")) + + AssertEqual + \ [ + \ [ + \ 'unlet! b:current_syntax', + \ 'syntax include @ALE_hover_python syntax/python.vim', + \ 'unlet! b:current_syntax', + \ 'syntax include @ALE_hover_typescript syntax/typescript.vim', + \ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python', + \ 'syntax region ALE_hover_2 start=/\%5l/ end=/\%8l/ contains=@ALE_hover_python', + \ 'syntax region ALE_hover_3 start=/\%8l/ end=/\%10l/ contains=@ALE_hover_typescript', + \ ], + \ [ + \ 'def foo():', + \ ' pass', + \ '', + \ 'middle line', + \ '', + \ 'def bar():', + \ ' pass', + \ '', + \ 'const baz = () => undefined', + \ ], + \ ], + \ ale#hover#ParseLSPResult(join([ + \ '```python', + \ 'def foo():', + \ ' pass', + \ '```', + \ 'middle line', + \ '```python', + \ 'def bar():', + \ ' pass', + \ '```', + \ '```typescript', + \ 'const baz = () => undefined', + \ '```', + \ ], "\n")) + +Execute(Multiple strings with fences should be handled): + AssertEqual + \ [ + \ [ + \ 'unlet! b:current_syntax', + \ 'syntax include @ALE_hover_python syntax/python.vim', + \ 'unlet! b:current_syntax', + \ 'syntax include @ALE_hover_typescript syntax/typescript.vim', + \ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python', + \ 'syntax region ALE_hover_2 start=/\%5l/ end=/\%8l/ contains=@ALE_hover_python', + \ 'syntax region ALE_hover_3 start=/\%8l/ end=/\%10l/ contains=@ALE_hover_typescript', + \ ], + \ [ + \ 'def foo():', + \ ' pass', + \ '', + \ 'middle line', + \ '', + \ 'def bar():', + \ ' pass', + \ '', + \ 'const baz = () => undefined', + \ ], + \ ], + \ ale#hover#ParseLSPResult([ + \ join([ + \ '```python', + \ 'def foo():', + \ ' pass', + \ '```', + \ ], "\n"), + \ join([ + \ 'middle line', + \ '```python', + \ 'def bar():', + \ ' pass', + \ '```', + \ '```typescript', + \ 'const baz = () => undefined', + \ '```', + \ ], "\n"), + \ ]) + +Execute(Objects with kinds should be handled): + AssertEqual + \ [ + \ [ + \ 'unlet! b:current_syntax', + \ 'syntax include @ALE_hover_python syntax/python.vim', + \ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python', + \ ], + \ [ + \ 'def foo():', + \ ' pass', + \ '', + \ '```typescript', + \ 'const baz = () => undefined', + \ '```', + \ ], + \ ], + \ ale#hover#ParseLSPResult([ + \ { + \ 'kind': 'markdown', + \ 'value': join([ + \ '```python', + \ 'def foo():', + \ ' pass', + \ '```', + \ ], "\n"), + \ }, + \ { + \ 'kind': 'plaintext', + \ 'value': join([ + \ '```typescript', + \ 'const baz = () => undefined', + \ '```', + \ ], "\n"), + \ }, + \ ]) + +Execute(Simple markdown formatting should be handled): + AssertEqual + \ [ + \ [ + \ 'unlet! b:current_syntax', + \ 'syntax include @ALE_hover_python syntax/python.vim', + \ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python', + \ ], + \ [ + \ 'def foo():', + \ ' pass', + \ '', + \ 'formatted _ line _', + \ ], + \ ], + \ ale#hover#ParseLSPResult(join([ + \ '```python', + \ 'def foo():', + \ ' pass', + \ '```', + \ 'formatted \_ line \_', + \ ], "\n")) diff --git a/vim-config/plugins/ale/test/test_ignoring_linters.vader b/vim-config/plugins/ale/test/test_ignoring_linters.vader new file mode 100644 index 00000000..19f45add --- /dev/null +++ b/vim-config/plugins/ale/test/test_ignoring_linters.vader @@ -0,0 +1,403 @@ +Before: + Save g:ale_disable_lsp + +After: + Restore + + unlet! b:ale_disable_lsp + +Execute(GetList should ignore some invalid values): + AssertEqual [], ale#engine#ignore#GetList('', 'foo') + AssertEqual [], ale#engine#ignore#GetList('', 0) + AssertEqual [], ale#engine#ignore#GetList('', v:null) + +Execute(GetList should handle Lists): + AssertEqual ['foo', 'bar'], ale#engine#ignore#GetList('', ['foo', 'bar']) + +Execute(GetList should handle Dictionaries): + AssertEqual + \ ['linter1', 'linter2'], + \ uniq(sort(ale#engine#ignore#GetList('x.y.z', { + \ 'x': ['linter1'], + \ 'abc': ['linter3'], + \ 'z': ['linter2'], + \ }))) + +Execute(Exclude should ignore some invalid values): + AssertEqual + \ [ + \ {'name': 'linter1', 'aliases': []}, + \ {'name': 'linter2', 'aliases': ['alias1']}, + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ ale#engine#ignore#Exclude( + \ 'foo.bar', + \ [ + \ {'name': 'linter1', 'aliases': []}, + \ {'name': 'linter2', 'aliases': ['alias1']}, + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ 'foo', + \ 0, + \ ) + AssertEqual + \ [ + \ {'name': 'linter1', 'aliases': []}, + \ {'name': 'linter2', 'aliases': ['alias1']}, + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ ale#engine#ignore#Exclude( + \ 'foo.bar', + \ [ + \ {'name': 'linter1', 'aliases': []}, + \ {'name': 'linter2', 'aliases': ['alias1']}, + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ 0, + \ 0, + \ ) + AssertEqual + \ [ + \ {'name': 'linter1', 'aliases': []}, + \ {'name': 'linter2', 'aliases': ['alias1']}, + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ ale#engine#ignore#Exclude( + \ 'foo.bar', + \ [ + \ {'name': 'linter1', 'aliases': []}, + \ {'name': 'linter2', 'aliases': ['alias1']}, + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ v:null, + \ 0, + \ ) + +Execute(Exclude should handle Lists): + AssertEqual + \ [ + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ ale#engine#ignore#Exclude( + \ 'foo.bar', + \ [ + \ {'name': 'linter1', 'aliases': []}, + \ {'name': 'linter2', 'aliases': ['alias1']}, + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ ['linter1', 'alias1'], + \ 0, + \ ) + +Execute(Exclude should handle Dictionaries): + AssertEqual + \ [ + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ ale#engine#ignore#Exclude( + \ 'foo.bar', + \ [ + \ {'name': 'linter1', 'aliases': []}, + \ {'name': 'linter2', 'aliases': ['alias1']}, + \ {'name': 'linter3', 'aliases': []}, + \ ], + \ {'foo': ['linter1'], 'bar': ['alias1']}, + \ 0, + \ ) + +Execute(Exclude should filter LSP linters when g:ale_disable_lsp is set to 1): + AssertEqual + \ [ + \ {'name': 'linter1', 'aliases': [], 'lsp': ''}, + \ {'name': 'linter2', 'aliases': []}, + \ ], + \ ale#engine#ignore#Exclude( + \ 'foo', + \ [ + \ {'name': 'linter1', 'aliases': [], 'lsp': ''}, + \ {'name': 'linter2', 'aliases': []}, + \ {'name': 'linter3', 'aliases': [], 'lsp': 'stdio'}, + \ ], + \ [], + \ 1, + \ ) + +Execute(Exclude should filter LSP linters when b:ale_disable_lsp is set to 1): + AssertEqual + \ [ + \ {'name': 'linter1', 'aliases': [], 'lsp': ''}, + \ {'name': 'linter2', 'aliases': []}, + \ ], + \ ale#engine#ignore#Exclude( + \ 'foo', + \ [ + \ {'name': 'linter1', 'aliases': [], 'lsp': ''}, + \ {'name': 'linter2', 'aliases': []}, + \ {'name': 'linter3', 'aliases': [], 'lsp': 'stdio'}, + \ ], + \ [], + \ 1, + \ ) + +Before: + Save g:ale_linters_ignore + Save g:ale_buffer_info + Save g:ale_disable_lsp + + let g:ale_disable_lsp = 0 + + let g:linters = [] + let g:loclist = [] + let g:run_linters_called = 0 + + runtime autoload/ale/engine.vim + + " Mock the engine function so we can set it up. + function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort + let g:linters = a:linters + let g:run_linters_called = 1 + endfunction + + function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort + let g:loclist = a:loclist + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'true', + \ 'command': has('win32') ? 'echo' : 'true', + \}) + call ale#test#SetDirectory('/testplugin/test') + +After: + Restore + + unlet! b:ale_linted + unlet! b:ale_linters_ignore + unlet! b:ale_quitting + unlet! b:ale_save_event_fired + unlet! b:ale_disable_lsp + unlet! g:linters + unlet! g:loclist + unlet! g:lsp_message + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + call ale#lsp_linter#ClearLSPData() + runtime autoload/ale/engine.vim + +Given foobar(An empty file): +Execute(Global ignore lists should be applied for linters): + " We have to set up buffer info so RunLinters is called. + let g:ale_buffer_info = {bufnr(''): {}} + + ALELint + Assert g:run_linters_called, "The mock callback wasn't called" + AssertEqual ['testlinter'], map(g:linters, 'v:val.name') + + let g:ale_linters_ignore = ['testlinter'] + ALELint + AssertEqual [], g:linters + +Execute(buffer ignore lists should be applied for linters): + " We have to set up buffer info so RunLinters is called. + let g:ale_buffer_info = {bufnr(''): {}} + + ALELint + Assert g:run_linters_called, "The mock callback wasn't called" + AssertEqual ['testlinter'], map(g:linters, 'v:val.name') + + let b:ale_linters_ignore = ['testlinter'] + ALELint + AssertEqual [], g:linters + +Execute(Buffer ignore lists should be applied for tsserver): + call ale#test#SetFilename('filename.ts') + call ale#engine#InitBufferInfo(bufnr('')) + + let g:lsp_message = { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'syntaxDiag', + \ 'body': { + \ 'file': g:dir . '/filename.ts', + \ 'diagnostics':[ + \ { + \ 'start': { + \ 'line':2, + \ 'offset':14, + \ }, + \ 'end': { + \ 'line':2, + \ 'offset':15, + \ }, + \ 'text': ''','' expected.', + \ "code":1005 + \ }, + \ ], + \ }, + \} + + call ale#lsp_linter#HandleLSPResponse(347, g:lsp_message) + + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 14, + \ 'nr': 1005, + \ 'code': '1005', + \ 'type': 'E', + \ 'end_col': 14, + \ 'end_lnum': 2, + \ 'text': ''','' expected.', + \ }, + \ ], + \ g:loclist + + let g:loclist = [] + let b:ale_linters_ignore = ['tsserver'] + call ale#lsp_linter#HandleLSPResponse(347, g:lsp_message) + + AssertEqual [], g:loclist + +Execute(Buffer ignore lists should be applied for LSP linters): + call ale#test#SetFilename('filename.py') + call ale#engine#InitBufferInfo(bufnr('')) + call ale#lsp_linter#SetLSPLinterMap({'347': 'lsplinter'}) + + let g:lsp_message = { + \ 'jsonrpc': '2.0', + \ 'method': 'textDocument/publishDiagnostics', + \ 'params': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'diagnostics': [ + \ { + \ 'severity': 1, + \ 'message': 'x', + \ 'range': { + \ 'start': {'line': 0, 'character': 9}, + \ 'end': {'line': 0, 'character': 9}, + \ }, + \ } + \ ], + \ }, + \} + + call ale#lsp_linter#HandleLSPResponse(347, g:lsp_message) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'type': 'E', + \ 'end_col': 9, + \ 'end_lnum': 1, + \ 'text': 'x', + \ } + \ ], + \ g:loclist + + let b:ale_linters_ignore = ['lsplinter'] + let g:loclist = [] + + call ale#lsp_linter#HandleLSPResponse(347, g:lsp_message) + + AssertEqual [], g:loclist + +Execute(ale_disable_lsp should be applied for tsserver): + call ale#test#SetFilename('filename.ts') + call ale#engine#InitBufferInfo(bufnr('')) + + let g:lsp_message = { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': 'syntaxDiag', + \ 'body': { + \ 'file': g:dir . '/filename.ts', + \ 'diagnostics':[ + \ { + \ 'start': { + \ 'line':2, + \ 'offset':14, + \ }, + \ 'end': { + \ 'line':2, + \ 'offset':15, + \ }, + \ 'text': ''','' expected.', + \ "code":1005 + \ }, + \ ], + \ }, + \} + + call ale#lsp_linter#HandleLSPResponse(347, g:lsp_message) + + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 14, + \ 'nr': 1005, + \ 'code': '1005', + \ 'type': 'E', + \ 'end_col': 14, + \ 'end_lnum': 2, + \ 'text': ''','' expected.', + \ }, + \ ], + \ g:loclist + + let g:loclist = [] + let b:ale_disable_lsp = 1 + call ale#lsp_linter#HandleLSPResponse(347, g:lsp_message) + + AssertEqual [], g:loclist + +Execute(ale_disable_lsp should be applied for LSP linters): + call ale#test#SetFilename('filename.py') + call ale#engine#InitBufferInfo(bufnr('')) + call ale#lsp_linter#SetLSPLinterMap({'347': 'lsplinter'}) + + let g:lsp_message = { + \ 'jsonrpc': '2.0', + \ 'method': 'textDocument/publishDiagnostics', + \ 'params': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'diagnostics': [ + \ { + \ 'severity': 1, + \ 'message': 'x', + \ 'range': { + \ 'start': {'line': 0, 'character': 9}, + \ 'end': {'line': 0, 'character': 9}, + \ }, + \ } + \ ], + \ }, + \} + + call ale#lsp_linter#HandleLSPResponse(347, g:lsp_message) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'type': 'E', + \ 'end_col': 9, + \ 'end_lnum': 1, + \ 'text': 'x', + \ } + \ ], + \ g:loclist + + let b:ale_disable_lsp = 1 + let g:loclist = [] + + call ale#lsp_linter#HandleLSPResponse(347, g:lsp_message) + + AssertEqual [], g:loclist diff --git a/vim-config/plugins/ale/test/test_jq_linter.vader b/vim-config/plugins/ale/test/test_jq_linter.vader new file mode 100644 index 00000000..cbe23b96 --- /dev/null +++ b/vim-config/plugins/ale/test/test_jq_linter.vader @@ -0,0 +1,18 @@ +Before: + runtime ale_linters/json/jq.vim + +After: + call ale#linter#Reset() + +Execute (Should parse error correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 9, + \ 'text': 'Expected another array element', + \ } + \ ], + \ ale_linters#json#jq#Handle(0, [ + \ 'parse error: Expected another array element at line 1, column 9' + \ ]) diff --git a/vim-config/plugins/ale/test/test_jsonlint_executable_detection.vader b/vim-config/plugins/ale/test/test_jsonlint_executable_detection.vader new file mode 100644 index 00000000..60bc6d75 --- /dev/null +++ b/vim-config/plugins/ale/test/test_jsonlint_executable_detection.vader @@ -0,0 +1,45 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + + runtime ale_linters/json/jsonlint.vim + +After: + let g:ale_json_jsonlint_executable = 'jsonlint' + let g:ale_json_jsonlint_use_global = 0 + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(local executable should be detected correctly): + call ale#test#SetFilename('test-files/jsonlint/app/src/app.json') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/jsonlint/app/node_modules/.bin/jsonlint'), + \ ale_linters#json#jsonlint#GetExecutable(bufnr('')) + +Execute(recursively executable should be detected correctly): + call ale#test#SetFilename('test-files/jsonlint/app-without-jsonlint/src/app.json') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/jsonlint/node_modules/jsonlint/lib/cli.js'), + \ ale_linters#json#jsonlint#GetExecutable(bufnr('')) + +Execute(use_global should override project executable): + let g:ale_json_jsonlint_use_global = 1 + + call ale#test#SetFilename('test-files/jsonlint/app/src/app.json') + + AssertEqual + \ 'jsonlint', + \ ale_linters#json#jsonlint#GetExecutable(bufnr('')) + +Execute(manually defined should override default executable): + let g:ale_json_jsonlint_use_global = 1 + let g:ale_json_jsonlint_executable = 'custom_jsonlint' + + call ale#test#SetFilename('test-files/jsonlint/app/src/app.json') + + AssertEqual + \ 'custom_jsonlint', + \ ale_linters#json#jsonlint#GetExecutable(bufnr('')) + diff --git a/vim-config/plugins/ale/test/test_line_join.vader b/vim-config/plugins/ale/test/test_line_join.vader new file mode 100644 index 00000000..9356a2b7 --- /dev/null +++ b/vim-config/plugins/ale/test/test_line_join.vader @@ -0,0 +1,84 @@ +Before: + let g:lines = [] + let g:data = '' + + function! LineCallback(job_id, line) abort + call add(g:lines, a:line) + endfunction + + function! RawCallback(job_id, some_data) abort + let g:data .= a:some_data + endfunction + +After: + unlet! g:last_line + unlet! g:lines + unlet! g:data + delfunction LineCallback + delfunction RawCallback + +Execute (ALE should handle empty Lists for the lines): + let g:last_line = ale#util#JoinNeovimOutput(1, '', [], 'nl', function('LineCallback')) + + AssertEqual [], g:lines + AssertEqual '', g:last_line + +Execute (ALE should pass on full lines for NeoVim): + let g:last_line = ale#util#JoinNeovimOutput(1, '', ['x', 'y', ''], 'nl', function('LineCallback')) + + AssertEqual ['x', 'y'], g:lines + AssertEqual '', g:last_line + +Execute (ALE should pass on a single long line): + let g:last_line = ale#util#JoinNeovimOutput(1, '', ['x'], 'nl', function('LineCallback')) + + AssertEqual [], g:lines + AssertEqual 'x', g:last_line + +Execute (ALE should handle just a single line of output): + let g:last_line = ale#util#JoinNeovimOutput(1, '', ['x', ''], 'nl', function('LineCallback')) + + AssertEqual ['x'], g:lines + AssertEqual '', g:last_line + +Execute (ALE should join two incomplete pieces of large lines together): + let g:last_line = ale#util#JoinNeovimOutput(1, 'x', ['y'], 'nl', function('LineCallback')) + + AssertEqual [], g:lines + AssertEqual 'xy', g:last_line + +Execute (ALE join incomplete lines, and set new ones): + let g:last_line = ale#util#JoinNeovimOutput(1, 'x', ['y', 'z', 'a'], 'nl', function('LineCallback')) + + AssertEqual ['xy', 'z'], g:lines + AssertEqual 'a', g:last_line + +Execute (ALE join incomplete lines, and set new ones, with two elements): + let g:last_line = ale#util#JoinNeovimOutput(1, 'x', ['y', 'z'], 'nl', function('LineCallback')) + + AssertEqual ['xy'], g:lines + AssertEqual 'z', g:last_line + +Execute (ALE should pass on full lines for NeoVim for raw data): + let g:last_line = ale#util#JoinNeovimOutput(1, '', ['x', 'y', ''], 'raw', function('RawCallback')) + + AssertEqual "x\ny\n", g:data + AssertEqual '', g:last_line + +Execute (ALE should pass on a single long line): + let g:last_line = ale#util#JoinNeovimOutput(1, '', ['x'], 'raw', function('RawCallback')) + + AssertEqual 'x', g:data + AssertEqual '', g:last_line + +Execute (ALE should handle just a single line of output): + let g:last_line = ale#util#JoinNeovimOutput(1, '', ['x', ''], 'raw', function('RawCallback')) + + AssertEqual "x\n", g:data + AssertEqual '', g:last_line + +Execute (ALE should pass on two lines and one incomplete one): + let g:last_line = ale#util#JoinNeovimOutput(1, '', ['y', 'z', 'a'], 'raw', function('RawCallback')) + + AssertEqual "y\nz\na", g:data + AssertEqual '', g:last_line diff --git a/vim-config/plugins/ale/test/test_lint_file_linters.vader b/vim-config/plugins/ale/test/test_lint_file_linters.vader new file mode 100644 index 00000000..d16f4aa1 --- /dev/null +++ b/vim-config/plugins/ale/test/test_lint_file_linters.vader @@ -0,0 +1,317 @@ +Before: + Save g:ale_fix_on_save + Save g:ale_enabled + Save g:ale_run_synchronously + Save g:ale_set_lists_synchronously + Save g:ale_buffer_info + Save g:ale_linters + + let g:ale_buffer_info = {} + let g:ale_run_synchronously = 1 + unlet! g:ale_run_synchronously_callbacks + let g:ale_set_lists_synchronously = 1 + let b:ale_save_event_fired = 0 + + let g:buffer_result = [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'buffer error', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'buffer warning', + \ 'type': 'W', + \ }, + \] + + function! LintFileCallback(buffer, output) + return [ + \ { + \ 'lnum': 1, + \ 'col': 3, + \ 'text': 'file warning', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 3, + \ 'text': 'file error', + \ 'type': 'E', + \ }, + \] + endfunction + + function! BufferCallback(buffer, output) + return deepcopy(g:buffer_result) + endfunction + + function! GetSimplerLoclist() + let l:loclist = [] + + for l:item in ale#test#GetLoclistWithoutModule() + call add(l:loclist, { + \ 'lnum': l:item.lnum, + \ 'col': l:item.col, + \ 'text': l:item.text, + \ 'type': l:item.type, + \}) + endfor + + return l:loclist + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'lint_file_linter', + \ 'callback': 'LintFileCallback', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': 'echo', + \ 'lint_file': 1, + \}) + + call ale#linter#Define('foobar', { + \ 'name': 'buffer_linter', + \ 'callback': 'BufferCallback', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': 'echo', + \ 'read_buffer': 0, + \}) + + let g:filename = tempname() + call writefile([], g:filename) + call ale#test#SetFilename(g:filename) + +After: + if !g:ale_run_synchronously + call ale#engine#Cleanup(bufnr('')) + endif + + Restore + + unlet! g:ale_run_synchronously_callbacks + unlet! b:ale_save_event_fired + unlet! b:ale_enabled + unlet g:buffer_result + let g:ale_buffer_info = {} + call ale#linter#Reset() + call setloclist(0, []) + delfunction LintFileCallback + delfunction BufferCallback + + if filereadable(g:filename) + call delete(g:filename) + endif + + unlet g:filename + +Given foobar (Some imaginary filetype): + foo + bar + baz + +Execute(Running linters without 'lint_file' should run only buffer linters): + call ale#Queue(0) + call ale#test#FlushJobs() + + AssertEqual [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'buffer error', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'buffer warning', + \ 'type': 'W', + \ }, + \], GetSimplerLoclist() + +Execute(Running linters with 'lint_file' should run all linters): + Assert filereadable(expand('%:p')), 'The file was not readable' + + call ale#Queue(0, 'lint_file') + call ale#test#FlushJobs() + + AssertEqual [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'buffer error', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 3, + \ 'text': 'file warning', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'buffer warning', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 3, + \ 'text': 'file error', + \ 'type': 'E', + \ }, + \], GetSimplerLoclist() + +Execute(Linter errors from files should be kept): + Assert filereadable(expand('%:p')), 'The file was not readable' + + call ale#Queue(0, 'lint_file') + call ale#test#FlushJobs() + + " Change the results for the buffer callback. + let g:buffer_result = [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'new buffer error', + \ 'type': 'E', + \ }, + \] + + call ale#Queue(0) + call ale#test#FlushJobs() + + AssertEqual [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'new buffer error', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 3, + \ 'text': 'file warning', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 3, + \ 'text': 'file error', + \ 'type': 'E', + \ }, + \], GetSimplerLoclist() + +Execute(Linter errors from files should be kept when no other linters are run): + let g:ale_linters = {'foobar': ['lint_file_linter']} + Assert filereadable(expand('%:p')), 'The file was not readable' + + call ale#Queue(0, 'lint_file') + call ale#test#FlushJobs() + + AssertEqual [ + \ { + \ 'lnum': 1, + \ 'col': 3, + \ 'text': 'file warning', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 3, + \ 'text': 'file error', + \ 'type': 'E', + \ }, + \], GetSimplerLoclist() + + call ale#Queue(0) + + AssertEqual [ + \ { + \ 'lnum': 1, + \ 'col': 3, + \ 'text': 'file warning', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 3, + \ 'text': 'file error', + \ 'type': 'E', + \ }, + \], GetSimplerLoclist() + +Execute(The Save event should respect the buffer number): + let g:ale_linters = {'foobar': ['lint_file_linter']} + Assert filereadable(expand('%:p')), 'The file was not readable' + + call ale#events#SaveEvent(bufnr('') + 1) + call ale#test#FlushJobs() + + " We shouldn't get any prblems yet. + AssertEqual [], GetSimplerLoclist() + + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + " We should get them now we used the right buffer number. + AssertEqual [ + \ { + \ 'lnum': 1, + \ 'col': 3, + \ 'text': 'file warning', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 3, + \ 'text': 'file error', + \ 'type': 'E', + \ }, + \], GetSimplerLoclist() + +Execute(The Save event should set b:ale_save_event_fired to 1): + let g:ale_lint_on_save = 1 + let b:ale_enabled = 1 + + call ale#linter#Reset() + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + " This flag needs to be set so windows can be opened, etc. + AssertEqual 1, b:ale_save_event_fired + +Execute(b:ale_save_event_fired should be set to 0 when results are set): + let b:ale_save_event_fired = 1 + + call ale#engine#SetResults(bufnr(''), []) + call ale#test#FlushJobs() + + AssertEqual 0, b:ale_save_event_fired + +Execute(lint_file linters should stay running after checking without them): + let g:ale_run_synchronously = 0 + + " Run all linters, then just the buffer linters. + call ale#Queue(0, 'lint_file') + call ale#Queue(0) + + " The lint_file linter should still be running. + AssertEqual + \ ['lint_file_linter', 'buffer_linter'], + \ map(copy(g:ale_buffer_info[bufnr('')].active_linter_list), 'v:val.name') + " We should have 1 job for each linter. + AssertEqual + \ 2, + \ len(keys(get(get(ale#command#GetData(), bufnr(''), {}), 'jobs', {}))) + + call ale#test#WaitForJobs(2000) + +Execute(The save event should not lint the buffer when ALE is disabled): + let g:ale_enabled = 0 + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + AssertEqual [], GetSimplerLoclist() + AssertEqual 0, b:ale_save_event_fired diff --git a/vim-config/plugins/ale/test/test_lint_on_enter_when_file_changed.vader b/vim-config/plugins/ale/test/test_lint_on_enter_when_file_changed.vader new file mode 100644 index 00000000..0d4c4af8 --- /dev/null +++ b/vim-config/plugins/ale/test/test_lint_on_enter_when_file_changed.vader @@ -0,0 +1,84 @@ +Before: + Save &filetype + Save g:ale_buffer_info + Save g:ale_lint_on_enter + Save g:ale_set_lists_synchronously + + let g:buf = bufnr('') + let g:ale_lint_on_enter = 1 + let g:ale_run_synchronously = 1 + let g:ale_set_lists_synchronously = 1 + + function! TestCallback(buffer, output) + return [{ + \ 'lnum': 1, + \ 'col': 3, + \ 'text': 'baz boz', + \}] + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'true', + \ 'command': has('win32') ? 'echo' : 'true', + \}) + +After: + Restore + unlet! g:buf + let g:ale_run_synchronously = 0 + delfunction TestCallback + call ale#linter#Reset() + call setloclist(0, []) + +Execute(The file changed event function should set b:ale_file_changed): + let g:ale_lint_on_enter = 0 + + if has('gui_running') + new + else + e test + endif + + call ale#events#FileChangedEvent(g:buf) + close + + " We should set the flag in the other buffer + AssertEqual 1, getbufvar(g:buf, 'ale_file_changed') + +Execute(The file changed event function should lint the current buffer when it has changed): + set filetype=foobar + call ale#events#FileChangedEvent(bufnr('')) + call ale#test#FlushJobs() + + AssertEqual [{ + \ 'bufnr': bufnr(''), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'baz boz', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }], ale#test#GetLoclistWithoutModule() + +Execute(The buffer should be checked after entering it after the file has changed): + let b:ale_file_changed = 1 + + set filetype=foobar + call ale#events#ReadOrEnterEvent(bufnr('')) + call ale#test#FlushJobs() + + AssertEqual [{ + \ 'bufnr': bufnr(''), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'baz boz', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }], ale#test#GetLoclistWithoutModule() diff --git a/vim-config/plugins/ale/test/test_lint_on_filetype_changed.vader b/vim-config/plugins/ale/test/test_lint_on_filetype_changed.vader new file mode 100644 index 00000000..cfc99d58 --- /dev/null +++ b/vim-config/plugins/ale/test/test_lint_on_filetype_changed.vader @@ -0,0 +1,77 @@ +Before: + Save &filetype + Save g:ale_lint_on_filetype_changed + + let g:ale_lint_on_filetype_changed = 1 + let g:queue_calls = [] + + function! ale#Queue(...) + call add(g:queue_calls, a:000) + endfunction + +After: + Restore + + unlet! g:queue_calls + + " Reload the ALE code to load the real function again. + runtime autoload/ale.vim + + unlet! b:ale_original_filetype + +Execute(The original filetype should be set on BufEnter): + let &filetype = 'foobar' + + call ale#events#ReadOrEnterEvent(bufnr('')) + + AssertEqual 'foobar', b:ale_original_filetype + + let &filetype = 'bazboz' + + call ale#events#ReadOrEnterEvent(bufnr('')) + + AssertEqual 'bazboz', b:ale_original_filetype + +Execute(Linting should not be queued when the filetype is the same): + let b:ale_original_filetype = 'foobar' + let g:queue_calls = [] + + call ale#events#FileTypeEvent(bufnr(''), 'foobar') + + AssertEqual [], g:queue_calls + +Execute(Linting should be queued when the filetype changes): + let b:ale_original_filetype = 'foobar' + let g:queue_calls = [] + + call ale#events#FileTypeEvent(bufnr(''), 'bazboz') + + AssertEqual [[300, 'lint_file', bufnr('')]], g:queue_calls + " The original filetype should be updated, so we don't trigger linting + " by setting a filetype equal to what it already is. + AssertEqual 'bazboz', b:ale_original_filetype + +Execute(Linting should be done when the original filetype was blank): + let b:ale_original_filetype = '' + + call ale#events#FileTypeEvent(bufnr(''), 'bazboz') + + AssertEqual [[300, 'lint_file', bufnr('')]], g:queue_calls + AssertEqual 'bazboz', b:ale_original_filetype + +Execute(Linting should not be done when the setting is off): + let b:ale_original_filetype = 'foobar' + let g:ale_lint_on_filetype_changed = 0 + + call ale#events#FileTypeEvent(bufnr(''), 'bazboz') + + AssertEqual [], g:queue_calls + " We should still update the old filetype + AssertEqual 'bazboz', b:ale_original_filetype + +Execute(Linting should be done when the original filetype was not set): + unlet! b:ale_original_filetype + + call ale#events#FileTypeEvent(bufnr(''), 'bazboz') + + AssertEqual [], g:queue_calls diff --git a/vim-config/plugins/ale/test/test_linter_defintion_processing.vader b/vim-config/plugins/ale/test/test_linter_defintion_processing.vader new file mode 100644 index 00000000..4c096a5e --- /dev/null +++ b/vim-config/plugins/ale/test/test_linter_defintion_processing.vader @@ -0,0 +1,501 @@ +Before: + Save g:ale_root + Save b:ale_root + + let g:ale_root = {} + unlet! b:ale_root + + let g:linter = {} + +After: + unlet g:linter + +Execute (PreProcess should throw when the linter object is not a Dictionary): + AssertThrows call ale#linter#PreProcess('testft', '') + AssertEqual 'The linter object must be a Dictionary', g:vader_exception + +Execute (PreProcess should throw when there is no name): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'command': 'echo', + \}) + AssertEqual '`name` must be defined to name the linter', g:vader_exception + +Execute (PreProcess should throw when there is no callback): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'executable': 'echo', + \ 'command': 'echo', + \}) + AssertEqual '`callback` must be defined with a callback to accept output', g:vader_exception + +Execute (PreProcess should throw when then callback is not a function): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 1, + \ 'executable': 'echo', + \ 'command': 'echo', + \}) + AssertEqual '`callback` must be defined with a callback to accept output', g:vader_exception + +Execute (PreProcess should throw when there is no executable): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'command': 'echo', + \}) + AssertEqual '`executable` must be defined', g:vader_exception + +Execute (PreProcess should throw when executable is not a string): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 123, + \ 'command': 'echo', + \}) + AssertEqual '`executable` must be a String or Function if defined', g:vader_exception + +Execute (PreProcess should allow executable to be a callback): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': function('type'), + \ 'command': 'echo', + \}) + +Execute (PreProcess should throw when there is no command): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \}) + AssertEqual '`command` must be defined', g:vader_exception + +Execute (PreProcess should throw when command is not a string): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'command': [], + \}) + AssertEqual '`command` must be a String or Function if defined', g:vader_exception + +Execute (PreProcess should allow command to be a callback): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'command': function('type'), + \}) + +Execute (PreProcess should throw when cwd is not a string): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'cwd': [], + \ 'command': 'echo', + \}) + AssertEqual '`cwd` must be a String or Function if defined', g:vader_exception + +Execute (PreProcess should allow cwd to be a callback): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'cwd': function('type'), + \ 'command': 'echo', + \}) + +Execute (PreProcess should allow cwd to be a string): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'cwd': '/foo/bar', + \ 'command': 'echo', + \}) + +Execute (PreProcess should when the output stream isn't a valid string): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'command': 'echo', + \ 'output_stream': 'xxx', + \}) + AssertEqual "`output_stream` must be 'stdout', 'stderr', or 'both'", g:vader_exception + +Execute (PreProcess should not throw when everything is correct): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'command': 'echo', + \}) + +Execute (PreProcess should accept an stdout output_stream): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'command': 'echo', + \ 'output_stream': 'stdout', + \}) + +Execute (PreProcess should accept an stderr output_stream): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'command': 'echo', + \ 'output_stream': 'stderr', + \}) + +Execute (PreProcess should accept a 'both' output_stream): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'command': 'echo', + \ 'output_stream': 'both', + \}) + +Execute(PreProcess should process the read_buffer option correctly): + let g:linter = { + \ 'name': 'x', + \ 'callback': 'x', + \ 'executable': 'x', + \ 'command': 'x', + \ 'read_buffer': '0', + \} + + AssertThrows call ale#linter#PreProcess('testft', g:linter) + AssertEqual '`read_buffer` must be `0` or `1`', g:vader_exception + + let g:linter.read_buffer = 0 + + call ale#linter#PreProcess('testft', g:linter) + + let g:linter.read_buffer = 1 + + call ale#linter#PreProcess('testft', g:linter) + +Execute(PreProcess should set a default value for read_buffer): + let g:linter = { + \ 'name': 'x', + \ 'callback': 'x', + \ 'executable': 'x', + \ 'command': 'x', + \} + + AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer + +Execute(PreProcess should process the lint_file option correctly): + let g:linter = { + \ 'name': 'x', + \ 'callback': 'x', + \ 'executable': 'x', + \ 'command': 'x', + \ 'lint_file': 'x', + \} + + AssertThrows call ale#linter#PreProcess('testft', g:linter) + AssertEqual '`lint_file` must be `0`, `1`, or a Function', g:vader_exception + + let g:linter.lint_file = 0 + + AssertEqual 0, ale#linter#PreProcess('testft', g:linter).lint_file + " The default for read_buffer should be 1 when lint_file is 0 + AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer + + let g:linter.lint_file = 1 + + AssertEqual 1, ale#linter#PreProcess('testft', g:linter).lint_file + " The default for read_buffer should still be 1 + AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer + + let g:linter.read_buffer = 1 + + " We should be able to set `read_buffer` and `lint_file` at the same time. + AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer + + let g:linter.lint_file = function('type') + + Assert type(ale#linter#PreProcess('testft', g:linter).lint_file) is v:t_func + +Execute(PreProcess should set a default value for lint_file): + let g:linter = { + \ 'name': 'x', + \ 'callback': 'x', + \ 'executable': 'x', + \ 'command': 'x', + \} + + AssertEqual 0, ale#linter#PreProcess('testft', g:linter).lint_file + +Execute(PreProcess should set a default value for aliases): + let g:linter = { + \ 'name': 'x', + \ 'callback': 'x', + \ 'executable': 'x', + \ 'command': 'x', + \} + + AssertEqual [], ale#linter#PreProcess('testft', g:linter).aliases + +Execute(PreProcess should complain about invalid `aliases` values): + let g:linter = { + \ 'name': 'x', + \ 'callback': 'x', + \ 'executable': 'x', + \ 'command': 'x', + \ 'aliases': 'foo', + \} + + AssertThrows call ale#linter#PreProcess('testft', g:linter) + AssertEqual '`aliases` must be a List of String values', g:vader_exception + + let g:linter.aliases = [1] + + AssertThrows call ale#linter#PreProcess('testft', g:linter) + AssertEqual '`aliases` must be a List of String values', g:vader_exception + +Execute(PreProcess should accept `aliases` lists): + let g:linter = { + \ 'name': 'x', + \ 'callback': 'x', + \ 'executable': 'x', + \ 'command': 'x', + \ 'aliases': [], + \} + + AssertEqual [], ale#linter#PreProcess('testft', g:linter).aliases + + let g:linter.aliases = ['foo', 'bar'] + + AssertEqual ['foo', 'bar'], ale#linter#PreProcess('testft', g:linter).aliases + +Execute(PreProcess should accept tsserver LSP configuration): + let g:linter = { + \ 'name': 'x', + \ 'executable': 'x', + \ 'command': 'x', + \ 'lsp': 'tsserver', + \ 'language': 'x', + \ 'project_root': 'x', + \} + + AssertEqual 'tsserver', ale#linter#PreProcess('testft', g:linter).lsp + +Execute(PreProcess should accept stdio LSP configuration): + let g:linter = { + \ 'name': 'x', + \ 'executable': 'x', + \ 'command': 'x', + \ 'lsp': 'stdio', + \ 'language': 'x', + \ 'project_root': 'x', + \} + + AssertEqual 'stdio', ale#linter#PreProcess('testft', g:linter).lsp + +Execute(PreProcess should accept LSP server configurations): + let g:linter = { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'language': 'foobar', + \ 'project_root': 'x', + \} + + AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp + +Execute(PreProcess should accept let you specify the `language` as a Function): + let g:linter = { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'language': {-> 'foobar'}, + \ 'project_root': 'x', + \} + + AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language(bufnr('')) + +Execute(PreProcess should complain about invalid language values): + let g:linter = { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'language': 0, + \ 'project_root': 'x', + \} + + AssertThrows call ale#linter#PreProcess('testft', g:linter) + AssertEqual '`language` must be a String or Function if defined', g:vader_exception + +Execute(PreProcess should use the filetype as the language string by default): + let g:linter = { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'project_root': 'x', + \} + + AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language + +Execute(PreProcess should require an `address` for LSP socket configurations): + let g:linter = { + \ 'name': 'x', + \ 'lsp': 'socket', + \} + + AssertThrows call ale#linter#PreProcess('testft', g:linter) + AssertEqual '`address` must be defined for getting the LSP address', g:vader_exception + +Execute(PreProcess should complain about `address` for non-LSP linters): + let g:linter = { + \ 'name': 'x', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'command': 'echo', + \ 'address': 'X', + \} + + AssertThrows call ale#linter#PreProcess('testft', g:linter) + AssertEqual '`address` cannot be used when lsp != ''socket''', g:vader_exception + +Execute(PreProcess accept `address` as a String): + let g:linter = ale#linter#PreProcess('testft', { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'foo:123', + \ 'language': 'x', + \ 'project_root': 'x', + \}) + + AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter) + +Execute(PreProcess accept address as a Function): + let g:linter = ale#linter#PreProcess('testft', { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': {-> 'foo:123'}, + \ 'language': 'x', + \ 'project_root': 'x', + \}) + + AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter) + +Execute(PreProcess should complain about invalid address values): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 0, + \ 'language': 'x', + \ 'project_root': 'x', + \}) + AssertEqual '`address` must be a String or Function if defined', g:vader_exception + +Execute(PreProcess should allow the `project_root` to be set as a String): + let g:linter = ale#linter#PreProcess('testft', { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'foo:123', + \ 'language': 'x', + \ 'project_root': '/foo/bar', + \}) + + AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter) + +Execute(PreProcess should `project_root` be set as a Function): + let g:linter = ale#linter#PreProcess('testft', { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'foo:123', + \ 'language': 'x', + \ 'project_root': {-> '/foo/bar'}, + \}) + + AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter) + +Execute(PreProcess should complain when `project_root` is invalid): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'foo:123', + \ 'language': 'x', + \ 'project_root': 0, + \}) + AssertEqual '`project_root` must be a String or Function', g:vader_exception + +Execute(PreProcess should throw when `initialization_options` is not a Dictionary or callback): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'language': 'x', + \ 'project_root': 'x', + \ 'initialization_options': 0, + \}) + AssertEqual '`initialization_options` must be a Dictionary or Function if defined', g:vader_exception + +Execute(PreProcess should accept `initialization_options` as a Dictionary): + let g:linter = ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'language': 'x', + \ 'project_root': 'x', + \ 'initialization_options': {'foo': v:true}, + \}) + + AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter) + +Execute(PreProcess should accept `initialization_options` as a Function): + let g:linter = ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'language': 'x', + \ 'project_root': 'x', + \ 'initialization_options': {-> {'foo': v:true}}, + \}) + + AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter) + +Execute(PreProcess should accept `lsp_config` as a Dictionary): + let g:linter = { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'language': 'x', + \ 'project_root': 'x', + \ 'lsp_config': {'foo': 'bar'}, + \} + + AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter) + +Execute(PreProcess should accept `lsp_config` as a Function): + let g:linter = { + \ 'name': 'x', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'language': 'x', + \ 'project_root': 'x', + \ 'lsp_config': {-> {'foo': 'bar'}}, + \} + + AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter) + +Execute(PreProcess should throw when `lsp_config` is not a Dictionary or Function): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'lsp': 'socket', + \ 'address': 'X', + \ 'language': 'x', + \ 'project_root': 'x', + \ 'lsp_config': 'x', + \}) + AssertEqual '`lsp_config` must be a Dictionary or Function if defined', g:vader_exception diff --git a/vim-config/plugins/ale/test/test_linter_retrieval.vader b/vim-config/plugins/ale/test/test_linter_retrieval.vader new file mode 100644 index 00000000..88885b71 --- /dev/null +++ b/vim-config/plugins/ale/test/test_linter_retrieval.vader @@ -0,0 +1,190 @@ +Before: + Save g:ale_linters + Save g:ale_linter_aliases + + let g:testlinter1 = {'name': 'testlinter1', 'executable': 'testlinter1', 'command': 'testlinter1', 'callback': 'testCB1', 'output_stream': 'stdout', 'read_buffer': 1, 'lint_file': 0, 'aliases': [], 'lsp': ''} + let g:testlinter2 = {'name': 'testlinter2', 'executable': 'testlinter2', 'command': 'testlinter2', 'callback': 'testCB2', 'output_stream': 'stdout', 'read_buffer': 0, 'lint_file': 1, 'aliases': [], 'lsp': ''} + call ale#linter#Reset() + call ale#linter#PreventLoading('testft') + call ale#linter#PreventLoading('javascript') + call ale#linter#PreventLoading('typescript') + +After: + Restore + + unlet! g:testlinter1 + unlet! g:testlinter2 + unlet! b:ale_linters + unlet! b:ale_linter_aliases + call ale#linter#Reset() + +Execute (You should be able to get a defined linter): + call ale#linter#Define('testft', g:testlinter1) + AssertEqual [g:testlinter1], ale#linter#Get('testft') + +Execute (You should be able get select a single linter): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + let g:ale_linters = {'testft': ['testlinter1']} + + AssertEqual [g:testlinter1], ale#linter#Get('testft') + +Execute (You should be able to select a linter by an alias): + let g:testlinter1.aliases = ['foo', 'linter1alias'] + + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + let g:ale_linters = {'testft': ['linter1alias']} + + AssertEqual [g:testlinter1], ale#linter#Get('testft') + +Execute (You should be able to select linters with a buffer option): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + let g:ale_linters = {'testft': ['testlinter1', 'testlinter2']} + let b:ale_linters = {'testft': ['testlinter1']} + + AssertEqual [g:testlinter1], ale#linter#Get('testft') + +Execute (b:ale_linters should work when set to a List): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + let g:ale_linters = {'testft': ['testlinter1', 'testlinter2']} + let b:ale_linters = ['testlinter1'] + + AssertEqual [g:testlinter1], ale#linter#Get('testft') + +Execute (b:ale_linters should disable all linters when set to an empty List): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + let g:ale_linters = {'testft': ['testlinter1', 'testlinter2']} + let b:ale_linters = [] + + AssertEqual [], ale#linter#Get('testft') + +Execute (b:ale_linters should enable all available linters when set to 'all'): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + let g:ale_linters = {'testft': ['testlinter1']} + let b:ale_linters = 'all' + + AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft') + +Execute (Buffer settings shouldn't completely replace global settings): + call ale#linter#Define('testft', g:testlinter1) + call ale#linter#Define('testft', g:testlinter2) + let g:ale_linters = {'testft': ['testlinter1']} + let b:ale_linters = {'testft2': ['testlinter1', 'testlinter2']} + + AssertEqual [g:testlinter1], ale#linter#Get('testft') + +Execute (You should be able to alias linters from one filetype to another): + call ale#linter#Define('testft1', g:testlinter1) + let g:ale_linter_aliases = {'testft2': 'testft1'} + + AssertEqual [g:testlinter1], ale#linter#Get('testft2') + +Execute (You should be able to filter aliased linters): + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft1', g:testlinter2) + let g:ale_linters = {'testft1': ['testlinter1'], 'testft2': ['testlinter2']} + let g:ale_linter_aliases = {'testft2': 'testft1'} + + AssertEqual [g:testlinter1], ale#linter#Get('testft1') + AssertEqual [g:testlinter2], ale#linter#Get('testft2') + +Execute (Dot-separated filetypes should be handled correctly): + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + + AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1.testft2') + +Execute (Linters for multiple aliases should be loaded): + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + let ale_linter_aliases = {'testft3': ['testft1', 'testft2']} + + AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft3') + +Execute (You should be able to alias filetypes to themselves and another): + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + let ale_linter_aliases = {'testft1': ['testft1', 'testft2']} + + AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1') + +Execute (Buffer-local overrides for aliases should be used): + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + let g:ale_linter_aliases = {'testft1': ['testft2']} + let b:ale_linter_aliases = {'testft1': ['testft1', 'testft2']} + + AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1') + +Execute (The local alias option shouldn't completely replace the global one): + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + let g:ale_linter_aliases = {'testft1': ['testft1', 'testft2']} + " This is a key set for a different filetype. + " We should look for a key in this Dictionary first, and then check the + " global Dictionary. + let b:ale_linter_aliases = {'testft3': ['testft1']} + + AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1') + +Execute (Lists should be accepted for local aliases): + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + let g:ale_linter_aliases = {'testft1': ['testft1', 'testft2']} + " We should load the testft2 linters for this buffer, with no duplicates. + let b:ale_linter_aliases = ['testft2'] + + AssertEqual [g:testlinter2], ale#linter#Get('anything.else') + +Execute (Strings should be accepted for local aliases): + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + let g:ale_linter_aliases = {'testft1': ['testft1', 'testft2']} + " We should load the testft2 linters for this buffer, with no duplicates. + let b:ale_linter_aliases = 'testft2' + + AssertEqual [g:testlinter2], ale#linter#Get('anything.else') + +Execute (Buffer-local overrides for aliases should be used): + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft2', g:testlinter2) + let g:ale_linter_aliases = {'testft1': ['testft2']} + let b:ale_linter_aliases = {'testft1': ['testft1', 'testft2']} + + AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1') + +Execute (Linters new linters with the same name should replace old ones): + let g:testlinter1.name = g:testlinter2.name + + call ale#linter#Define('testft1', g:testlinter1) + call ale#linter#Define('testft1', g:testlinter2) + + AssertEqual [g:testlinter2], ale#linter#GetAll(['testft1']) + +Execute (Linters should be loaded from disk appropriately): + call ale#linter#Reset() + AssertEqual [{'name': 'testlinter', 'output_stream': 'stdout', 'executable': 'testlinter', 'command': 'testlinter', 'callback': 'testCB', 'read_buffer': 1, 'lint_file': 0, 'aliases': [], 'lsp': ''}], ale#linter#Get('testft') + + +Execute (Linters for later filetypes should replace the former ones): + call ale#linter#Define('javascript', { + \ 'name': 'eslint', + \ 'executable': 'y', + \ 'command': 'y', + \ 'callback': 'y', + \}) + call ale#linter#Define('typescript', { + \ 'name': 'eslint', + \ 'executable': 'x', + \ 'command': 'x', + \ 'callback': 'x', + \}) + + AssertEqual [ + \ {'output_stream': 'stdout', 'lint_file': 0, 'read_buffer': 1, 'name': 'eslint', 'executable': 'x', 'lsp': '', 'aliases': [], 'command': 'x', 'callback': 'x'} + \], ale#linter#Get('javascript.typescript') diff --git a/vim-config/plugins/ale/test/test_linter_type_mapping.vader b/vim-config/plugins/ale/test/test_linter_type_mapping.vader new file mode 100644 index 00000000..0ec22a56 --- /dev/null +++ b/vim-config/plugins/ale/test/test_linter_type_mapping.vader @@ -0,0 +1,120 @@ +Before: + Save g:ale_type_map + +After: + Restore + unlet! b:ale_type_map + +Execute(It should be possible to remap errors to style errors): + let g:ale_type_map = {'foo': {'E': 'ES'}} + + AssertEqual + \ [ + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ ], + \ ale#engine#FixLocList(bufnr(''), 'foo', 0, [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ ]) + +Execute(It should be possible to remap errors to style errors with buffer-local variables): + let b:ale_type_map = {'foo': {'E': 'ES'}} + + AssertEqual + \ [ + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ ], + \ ale#engine#FixLocList(bufnr(''), 'foo', 0, [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ ]) + +Execute(It should be possible to remap warnings to style warnings): + let g:ale_type_map = {'foo': {'W': 'WS'}} + + AssertEqual + \ [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ ], + \ ale#engine#FixLocList(bufnr(''), 'foo', 0, [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ ]) + +Execute(It should be possible to remap style errors to errors): + let g:ale_type_map = {'foo': {'ES': 'E'}} + + AssertEqual + \ [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ ], + \ ale#engine#FixLocList(bufnr(''), 'foo', 0, [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ ]) + +Execute(It should be possible to remap style warnings to warnings): + let g:ale_type_map = {'foo': {'WS': 'W'}} + + AssertEqual + \ [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ ], + \ ale#engine#FixLocList(bufnr(''), 'foo', 0, [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ ]) + +Execute(It should be possible to info problems to warnings): + let g:ale_type_map = {'foo': {'I': 'W'}} + + AssertEqual + \ [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'}, + \ ], + \ ale#engine#FixLocList(bufnr(''), 'foo', 0, [ + \ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1}, + \ ]) diff --git a/vim-config/plugins/ale/test/test_linting_blacklist.vader b/vim-config/plugins/ale/test/test_linting_blacklist.vader new file mode 100644 index 00000000..2bcc9576 --- /dev/null +++ b/vim-config/plugins/ale/test/test_linting_blacklist.vader @@ -0,0 +1,16 @@ +Before: + let g:ale_buffer_info = {} + +After: + call ale#engine#Cleanup(bufnr('')) + + let g:ale_buffer_info = {} + +Given unite (A Unite.vim file): + anything + +Execute(Running ALE on a blacklisted file shouldn't change anything): + call ale#Queue(0) + call ale#test#WaitForJobs(2000) + + AssertEqual {}, g:ale_buffer_info diff --git a/vim-config/plugins/ale/test/test_linting_updates_loclist.vader b/vim-config/plugins/ale/test/test_linting_updates_loclist.vader new file mode 100644 index 00000000..41c86522 --- /dev/null +++ b/vim-config/plugins/ale/test/test_linting_updates_loclist.vader @@ -0,0 +1,96 @@ +Before: + Save g:ale_echo_cursor + Save g:ale_set_highlights + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_set_signs + Save g:ale_run_synchronously + Save g:ale_set_lists_synchronously + Save g:ale_buffer_info + Save g:ale_sign_offset + + " We want to check that sign IDs are set for this test. + let g:ale_set_signs = 1 + let g:ale_set_loclist = 1 + let g:ale_sign_offset = 2000000 + " Disable features we don't need for these tests. + let g:ale_set_quickfix = 0 + let g:ale_set_highlights = 0 + let g:ale_echo_cursor = 0 + + let g:ale_run_synchronously = 1 + let g:ale_set_lists_synchronously = 1 + let g:ale_buffer_info = {} + + function! TestCallback(buffer, output) + return [ + \ { + \ 'lnum': 1, + \ 'type': 'W', + \ 'col': 10, + \ 'text': 'Infix operators must be spaced. [Warning/space-infix-ops]', + \ }, + \ { + \ 'lnum': 2, + \ 'type': 'E', + \ 'col': 10, + \ 'text': 'Missing semicolon. [Error/semi]', + \ } + \] + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd': 'true', + \ 'command': 'true', + \ 'read_buffer': 0, + \}) + + sign unplace * + + call ale#engine#Cleanup(bufnr('')) + +After: + Restore + + delfunction TestCallback + + call ale#linter#Reset() + + sign unplace * + +Given foobar (Some JavaScript with problems): + var y = 3+3; + var y = 3 + +Execute(The loclist should be updated after linting is done): + ALELint + call ale#test#FlushJobs() + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'testlinter', + \ 'nr': -1, + \ 'type': 'W', + \ 'col': 10, + \ 'text': 'Infix operators must be spaced. [Warning/space-infix-ops]', + \ 'sign_id': 2000001, + \ }, + \ { + \ 'lnum': 2, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'testlinter', + \ 'nr': -1, + \ 'type': 'E', + \ 'col': 10, + \ 'text': 'Missing semicolon. [Error/semi]', + \ 'sign_id': 2000002, + \ } + \ ], + \ get(get(g:ale_buffer_info, bufnr('%'), {}), 'loclist', []) diff --git a/vim-config/plugins/ale/test/test_list_formatting.vader b/vim-config/plugins/ale/test/test_list_formatting.vader new file mode 100644 index 00000000..d79a664b --- /dev/null +++ b/vim-config/plugins/ale/test/test_list_formatting.vader @@ -0,0 +1,188 @@ +Before: + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_loclist_msg_format + Save g:ale_open_list + Save g:ale_buffer_info + Save g:ale_set_lists_synchronously + + let g:ale_set_lists_synchronously = 1 + let g:ale_loclist_msg_format = '%code: %%s' + let g:ale_open_list = 0 + let g:loclist = [] + let g:ale_buffer_info = {bufnr(''): {'loclist': g:loclist}} + + function! AddItem(data) abort + let l:item = { + \ 'bufnr': bufnr(''), + \ 'lnum': 1, + \ 'col': 1, + \ 'type': 'E', + \ 'linter_name': 'some_linter', + \} + + call add(g:loclist, extend(l:item, a:data)) + endfunction + +After: + Restore + + unlet! g:loclist + unlet! b:ale_loclist_msg_format + + delfunction AddItem + + call setloclist(0, []) + call setqflist([]) + +Execute(Formatting with codes should work for the loclist): + call AddItem({'text': "nocode\r"}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'nocode', + \ }, + \ ], + \ ale#test#GetLoclistWithoutModule() + + call remove(g:loclist, 0) + call AddItem({'text': 'withcode', 'code': 'E123'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'E123: withcode', + \ }, + \ ], + \ ale#test#GetLoclistWithoutModule() + +Execute(Formatting with codes should work for the quickfix list): + let g:ale_set_loclist = 0 + let g:ale_set_quickfix = 1 + + call AddItem({'text': "nocode\r"}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'nocode', + \ }, + \ ], + \ ale#test#GetQflistWithoutModule() + + call remove(g:loclist, 0) + call AddItem({'text': 'withcode', 'code': 'E123'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'E123: withcode', + \ }, + \ ], + \ ale#test#GetQflistWithoutModule() + +Execute(Formatting with the linter name should work for the loclist): + let g:ale_loclist_msg_format = '(%linter%) %s' + + call AddItem({'text': 'whatever'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': '(some_linter) whatever', + \ }, + \ ], + \ ale#test#GetLoclistWithoutModule() + +Execute(Formatting with the linter name should work for the quickfix list): + let g:ale_loclist_msg_format = '(%linter%) %s' + let g:ale_set_loclist = 0 + let g:ale_set_quickfix = 1 + + call AddItem({'text': 'whatever'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': '(some_linter) whatever', + \ }, + \ ], + \ ale#test#GetQflistWithoutModule() + +Execute(The buffer loclist format option should take precedence): + let g:ale_loclist_msg_format = '(%linter%) %s' + let b:ale_loclist_msg_format = 'FOO %s' + + call AddItem({'text': 'whatever'}) + call ale#list#SetLists(bufnr(''), g:loclist) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 1, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'FOO whatever', + \ }, + \ ], + \ ale#test#GetLoclistWithoutModule() diff --git a/vim-config/plugins/ale/test/test_list_opening.vader b/vim-config/plugins/ale/test/test_list_opening.vader new file mode 100644 index 00000000..8f0b2fd5 --- /dev/null +++ b/vim-config/plugins/ale/test/test_list_opening.vader @@ -0,0 +1,262 @@ +" Author: Yann Fery +Before: + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_open_list + Save g:ale_keep_list_window_open + Save g:ale_list_window_size + Save g:ale_list_vertical + Save g:ale_buffer_info + Save g:ale_set_lists_synchronously + + let g:ale_set_loclist = 1 + let g:ale_set_quickfix = 0 + let g:ale_open_list = 0 + let g:ale_keep_list_window_open = 0 + let g:ale_list_window_size = 10 + let g:ale_list_vertical = 0 + let g:ale_set_lists_synchronously = 1 + + let g:loclist = [ + \ {'bufnr': bufnr(''), 'lnum': 5, 'col': 5, 'text': 'x'}, + \ {'bufnr': bufnr(''), 'lnum': 5, 'col': 4, 'text': 'x'}, + \ {'bufnr': bufnr(''), 'lnum': 2, 'col': 10, 'text': 'x'}, + \ {'bufnr': bufnr(''), 'lnum': 3, 'col': 2, 'text': 'x'}, + \] + let g:ale_buffer_info = {bufnr(''): {'loclist': g:loclist}} + + function GetQuickfixHeight() abort + for l:win in range(1, winnr('$')) + if getwinvar(l:win, '&buftype') ==# 'quickfix' + return winheight(l:win) + endif + endfor + + return 0 + endfunction + + " If the window is vertical, window size should match column size/width + function GetQuickfixIsVertical(cols) abort + for l:win in range(1, winnr('$')) + if getwinvar(l:win, '&buftype') is# 'quickfix' + return winwidth(l:win) == a:cols + endif + endfor + + return 0 + endfunction + +After: + Restore + + unlet! g:loclist + unlet! b:ale_list_vertical + unlet! b:ale_list_window_size + unlet! b:ale_open_list + unlet! b:ale_keep_list_window_open + unlet! b:ale_save_event_fired + + delfunction GetQuickfixHeight + delfunction GetQuickfixIsVertical + + " Close quickfix window after every execute block + lcl + ccl + call setloclist(0, []) + call setqflist([]) + +Execute(IsQuickfixOpen should return the right output): + AssertEqual 0, ale#list#IsQuickfixOpen() + call setloclist(0, g:loclist) + lopen + AssertEqual 1, ale#list#IsQuickfixOpen() + lcl + AssertEqual 0, ale#list#IsQuickfixOpen() + call setqflist(g:loclist) + copen + AssertEqual 1, ale#list#IsQuickfixOpen() + ccl + AssertEqual 0, ale#list#IsQuickfixOpen() + +Execute(The quickfix window should not open by default for the loclist): + call ale#list#SetLists(bufnr('%'), g:loclist) + Assert !ale#list#IsQuickfixOpen() + +Execute(The quickfix window should open for just the loclist): + let g:ale_open_list = 1 + + " It should not open for an empty list. + call ale#list#SetLists(bufnr('%'), []) + Assert !ale#list#IsQuickfixOpen() + + " With a non-empty loclist, the window must open. + call ale#list#SetLists(bufnr('%'), g:loclist) + Assert ale#list#IsQuickfixOpen() + + " Clear the list and it should close again. + call ale#list#SetLists(bufnr('%'), []) + Assert !ale#list#IsQuickfixOpen() + +Execute(The quickfix window height should be correct for the loclist): + let g:ale_open_list = 1 + let g:ale_list_window_size = 7 + + call ale#list#SetLists(bufnr('%'), g:loclist) + + AssertEqual 7, GetQuickfixHeight() + +Execute(The quickfix window height should be correct for the loclist with buffer variables): + let g:ale_open_list = 1 + let b:ale_list_window_size = 8 + + call ale#list#SetLists(bufnr('%'), g:loclist) + + AssertEqual 8, GetQuickfixHeight() + +Execute(The quickfix window should be vertical for the loclist with appropriate variables): + let g:ale_open_list = 1 + let b:ale_list_window_size = 8 + let b:ale_list_vertical = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + + AssertEqual 1, GetQuickfixIsVertical(8) + +Execute(The quickfix window should be horizontal for the loclist with appropriate variables): + let g:ale_open_list = 1 + let b:ale_list_window_size = 8 + let b:ale_list_vertical = 0 + + call ale#list#SetLists(bufnr('%'), g:loclist) + + AssertEqual 0, GetQuickfixIsVertical(8) + +Execute(The quickfix window should stay open for just the loclist): + let g:ale_open_list = 1 + let g:ale_keep_list_window_open = 1 + + " The window should stay open after even after it is made blank again. + call ale#list#SetLists(bufnr('%'), g:loclist) + call ale#list#SetLists(bufnr('%'), []) + Assert ale#list#IsQuickfixOpen() + +Execute(The quickfix window should not open by default when quickfix is on): + let g:ale_set_quickfix = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + Assert !ale#list#IsQuickfixOpen() + +Execute(The quickfix window should open for the quickfix list): + let g:ale_set_quickfix = 1 + let g:ale_open_list = 1 + + let g:ale_buffer_info[bufnr('') + 1] = { + \ 'loclist': [{'bufnr': -1, 'filename': '/foo/bar', 'lnum': 5, 'col': 5, 'text': 'x'}], + \} + + " It should not open for an empty list. + call ale#list#SetLists(bufnr('%'), []) + Assert !ale#list#IsQuickfixOpen(), 'The quickfix window was opened when the list was empty' + + " With a non-empty quickfix list, the window must open. + call ale#list#SetLists(bufnr('%'), g:loclist) + Assert ale#list#IsQuickfixOpen(), 'The quickfix window was closed when the list was not empty' + + " Clear this List. The window should stay open, as there are other items. + let g:ale_buffer_info[bufnr('')].loclist = [] + call ale#list#SetLists(bufnr('%'), []) + Assert ale#list#IsQuickfixOpen(), 'The quickfix window closed even though there are items in another buffer' + + " Clear the other List now. Now the window should close. + call remove(g:ale_buffer_info, bufnr('') + 1) + call ale#list#SetLists(bufnr('%'), []) + Assert !ale#list#IsQuickfixOpen(), 'The quickfix window was not closed' + +Execute(The quickfix window should stay open for the quickfix list): + let g:ale_set_quickfix = 1 + let g:ale_open_list = 1 + let g:ale_keep_list_window_open = 1 + + " The window should stay open after even after it is made blank again. + call ale#list#SetLists(bufnr('%'), g:loclist) + call ale#list#SetLists(bufnr('%'), []) + Assert ale#list#IsQuickfixOpen() + +Execute(The quickfix window height should be correct for the quickfix list): + let g:ale_set_quickfix = 1 + let g:ale_open_list = 1 + let g:ale_list_window_size = 7 + + call ale#list#SetLists(bufnr('%'), g:loclist) + + AssertEqual 7, GetQuickfixHeight() + +Execute(The quickfix window height should be correct for the quickfix list with buffer variables): + let g:ale_set_quickfix = 1 + let g:ale_open_list = 1 + let b:ale_list_window_size = 8 + + call ale#list#SetLists(bufnr('%'), g:loclist) + + AssertEqual 8, GetQuickfixHeight() + +Execute(The quickfix window should be vertical for the quickfix with appropriate variables): + let g:ale_open_list = 1 + let b:ale_list_window_size = 8 + let b:ale_list_vertical = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + + AssertEqual 1, GetQuickfixIsVertical(8) + +Execute(The quickfix window should be horizontal for the quickfix with appropriate variables): + let g:ale_open_list = 1 + let b:ale_list_window_size = 8 + let b:ale_list_vertical = 0 + + call ale#list#SetLists(bufnr('%'), g:loclist) + + AssertEqual 0, GetQuickfixIsVertical(8) + +Execute(The buffer ale_open_list option should be respected): + let b:ale_open_list = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + Assert ale#list#IsQuickfixOpen() + +Execute(The buffer ale_keep_list_window_open option should be respected): + let b:ale_open_list = 1 + let b:ale_keep_list_window_open = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + call ale#list#SetLists(bufnr('%'), []) + + Assert ale#list#IsQuickfixOpen() + +Execute(The ale_open_list='on_save' option should work): + let b:ale_open_list = 'on_save' + + call ale#list#SetLists(bufnr('%'), g:loclist) + " The list shouldn't open yet, the event wasn't fired. + Assert !ale#list#IsQuickfixOpen() + + " Turn this option off, to ensure that we update lists immediately when we + " save buffers. + let g:ale_set_lists_synchronously = 0 + let b:ale_save_event_fired = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + " Now the list should have opened. + Assert ale#list#IsQuickfixOpen() + + call ale#list#SetLists(bufnr('%'), []) + " The window should close again when the loclist is empty. + Assert !ale#list#IsQuickfixOpen() + +Execute(The window shouldn't open on save when ale_open_list=0): + let b:ale_open_list = 0 + let b:ale_save_event_fired = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + " Now the list should have opened. + Assert !ale#list#IsQuickfixOpen() diff --git a/vim-config/plugins/ale/test/test_list_titles.vader b/vim-config/plugins/ale/test/test_list_titles.vader new file mode 100644 index 00000000..1f0b2308 --- /dev/null +++ b/vim-config/plugins/ale/test/test_list_titles.vader @@ -0,0 +1,77 @@ +Before: + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_buffer_info + Save g:ale_set_lists_synchronously + + let g:ale_buffer_info = {} + let g:ale_set_loclist = 0 + let g:ale_set_quickfix = 0 + let g:ale_set_lists_synchronously = 1 + + call ale#test#SetDirectory('/testplugin/test') + +After: + Restore + + call setloclist(0, []) + call setqflist([]) + + call ale#test#RestoreDirectory() + +Execute(The loclist titles should be set appropriately): + silent noautocmd file foo + + let g:ale_set_loclist = 1 + + call ale#list#SetLists(bufnr(''), [ + \ {'bufnr': bufnr(''), 'lnum': 5, 'col': 5, 'text': 'x', 'type': 'E'}, + \]) + + AssertEqual [{ + \ 'lnum': 5, + \ 'bufnr': bufnr(''), + \ 'col': 5, + \ 'text': 'x', + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \}], ale#test#GetLoclistWithoutModule() + + if !has('nvim') + AssertEqual + \ {'title': ale#path#Simplify(getcwd() . '/foo')}, + \ getloclist(0, {'title': ''}) + endif + +Execute(The quickfix titles should be set appropriately): + silent noautocmd file foo + + let g:ale_set_quickfix = 1 + + let g:ale_buffer_info[bufnr('')] = { + \ 'loclist': [{'bufnr': bufnr(''), 'lnum': 5, 'col': 5, 'text': 'x', 'type': 'E'}], + \} + + call ale#list#SetLists(bufnr(''), [ + \ {'bufnr': bufnr(''), 'lnum': 5, 'col': 5, 'text': 'x', 'type': 'E'}, + \]) + AssertEqual [{ + \ 'lnum': 5, + \ 'bufnr': bufnr(''), + \ 'col': 5, + \ 'text': 'x', + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \}], ale#test#GetQflistWithoutModule() + + if !has('nvim') + AssertEqual + \ {'title': ale#path#Simplify(getcwd() . '/foo')}, + \ getqflist({'title': ''}) + endif diff --git a/vim-config/plugins/ale/test/test_load_all_linters.vader b/vim-config/plugins/ale/test/test_load_all_linters.vader new file mode 100644 index 00000000..6806719a --- /dev/null +++ b/vim-config/plugins/ale/test/test_load_all_linters.vader @@ -0,0 +1,6 @@ +Execute(Exceptions shouldn't be thrown when loading all linters): + " This test will look for errors when loading any of the linter files. + runtime! ale_linters/*/*.vim + +After: + call ale#linter#Reset() diff --git a/vim-config/plugins/ale/test/test_loclist_binary_search.vader b/vim-config/plugins/ale/test/test_loclist_binary_search.vader new file mode 100644 index 00000000..219fb314 --- /dev/null +++ b/vim-config/plugins/ale/test/test_loclist_binary_search.vader @@ -0,0 +1,66 @@ +Before: + let g:loclist = [ + \ {'bufnr': 1, 'lnum': 2, 'col': 10}, + \ {'bufnr': 1, 'lnum': 3, 'col': 2}, + \ {'bufnr': 1, 'lnum': 3, 'col': 10}, + \ {'bufnr': 1, 'lnum': 3, 'col': 12}, + \ {'bufnr': 1, 'lnum': 3, 'col': 25}, + \ {'bufnr': 1, 'lnum': 5, 'col': 4}, + \ {'bufnr': 1, 'lnum': 5, 'col': 5}, + \ {'bufnr': 1, 'lnum': 9, 'col': 5}, + \ {'bufnr': 1, 'lnum': 10, 'col': 1}, + \ {'bufnr': 2, 'lnum': 7, 'col': 10}, + \ {'bufnr': 2, 'lnum': 9, 'col': 2}, + \ {'bufnr': 2, 'lnum': 10, 'col': 2}, + \ {'bufnr': 2, 'lnum': 11, 'col': 2}, + \] + +After: + unlet g:loclist + +Execute(Exact column matches should be correct): + AssertEqual 1, ale#util#BinarySearch(g:loclist, 1, 3, 2) + +Execute(Off lines, there should be no match): + AssertEqual -1, ale#util#BinarySearch(g:loclist, 1, 4, 2) + +Execute(Near column matches should be taken): + AssertEqual 2, ale#util#BinarySearch(g:loclist, 1, 3, 11) + AssertEqual 3, ale#util#BinarySearch(g:loclist, 1, 3, 13) + +Execute(Columns before should be taken when the cursor is far ahead): + AssertEqual 4, ale#util#BinarySearch(g:loclist, 1, 3, 300) + +Execute(The only problems on lines in later columns should be matched): + AssertEqual 7, ale#util#BinarySearch(g:loclist, 1, 9, 1) + +Execute(The only problems on lines in earlier columns should be matched): + AssertEqual 8, ale#util#BinarySearch(g:loclist, 1, 10, 30) + +Execute(Lines for other buffers should not be matched): + AssertEqual -1, ale#util#BinarySearch(g:loclist, 1, 7, 10) + +Execute(Searches for buffers later in the list should work): + AssertEqual 10, ale#util#BinarySearch(g:loclist, 2, 9, 10) + +Execute(Searches should work with just one item): + let g:loclist = [{'bufnr': 1, 'lnum': 3, 'col': 10}] + + AssertEqual 0, ale#util#BinarySearch(g:loclist, 1, 3, 2) + +Execute(Searches should return the last item on a single column): + let g:loclist = [ + \ {'bufnr': 1, 'lnum': 1, 'col': 10, 'type': 'W'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 10, 'type': 'E'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 11, 'type': 'W'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 11, 'type': 'E'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 20, 'type': 'W'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 20, 'type': 'E'}, + \] + + " We should return the index for the last item at some column to the right. + AssertEqual 1, ale#util#BinarySearch(g:loclist, 1, 1, 1) + " We should return the index for the last item at the column we are on. + AssertEqual 3, ale#util#BinarySearch(g:loclist, 1, 1, 11) + " We should prefer items to the left of the cursor, over the right. + AssertEqual 3, ale#util#BinarySearch(g:loclist, 1, 1, 19) diff --git a/vim-config/plugins/ale/test/test_loclist_corrections.vader b/vim-config/plugins/ale/test/test_loclist_corrections.vader new file mode 100644 index 00000000..d53b1411 --- /dev/null +++ b/vim-config/plugins/ale/test/test_loclist_corrections.vader @@ -0,0 +1,468 @@ +Before: + Save g:ale_filename_mappings + + let g:ale_filename_mappings = {} + +After: + unlet! b:temp_name + unlet! b:other_bufnr + + Restore + + +Execute(FixLocList should map filenames): + " Paths converted back into temporary filenames shouldn't be included. + let g:ale_filename_mappings = { + \ 'linter2': [['/xxx/', '/data/']], + \ 'linter1': [ + \ ['/bar/', '/data/special/'], + \ ['/foo/', '/data/'], + \ [ + \ ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h:h')) . '/', + \ '/x-tmp/', + \ ], + \ ], + \} + + AssertEqual + \ [ + \ '/foo/file.txt', + \ v:null, + \ '/bar/file.txt', + \ ], + \ map( + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'linter1', + \ 0, + \ [ + \ {'text': 'x', 'lnum': 1, 'filename': '/data/file.txt'}, + \ {'text': 'x', 'lnum': 1, 'filename': '/x-tmp/file.txt'}, + \ {'text': 'x', 'lnum': 1, 'filename': '/data/special/file.txt'}, + \ ], + \ ), + \ 'get(v:val, ''filename'', v:null)', + \ ) + + +Given foo (Some file with lines to count): + foo12345678 + bar12345678 + baz12345678 + four12345678 + five12345678 + six12345678 + seven12345678 + eight12345678 + nine12345678 + ten12345678 + +Execute(FixLocList should set all the default values correctly): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 2, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ { + \ 'text': 'b', + \ 'lnum': 2, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [{'text': 'a', 'lnum': 2}, {'text': 'b', 'lnum': 2}], + \ ) + +Execute(FixLocList should use the values we supply): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 3, + \ 'col': 4, + \ 'bufnr': 10000, + \ 'vcol': 0, + \ 'type': 'W', + \ 'nr': 42, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [{ + \ 'text': 'a', + \ 'lnum': 3, + \ 'col': 4, + \ 'bufnr': 10000, + \ 'vcol': 1, + \ 'type': 'W', + \ 'nr': 42, + \ }], + \ ) + +Execute(FixLocList should set items with lines beyond the end to the last line): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [{'text': 'a', 'lnum': 11}], + \ ) + +Execute(FixLocList should move line 0 to line 1): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 1, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [{'text': 'a', 'lnum': 0}], + \ ) + +Execute(FixLocList should convert line and column numbers correctly): + " The numbers should be 10, not 8 as octals. + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 10, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [{'text': 'a', 'lnum': '010', 'col': '010'}], + \ ) + +Execute(FixLocList should pass on end_col values): + " The numbers should be 10, not 8 as octals. + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 10, + \ 'end_col': 12, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 11, + \ 'end_col': 12, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [ + \ {'text': 'a', 'lnum': '010', 'col': '010', 'end_col': '012'}, + \ {'text': 'a', 'lnum': '010', 'col': '011', 'end_col': 12}, + \ ], + \ ) + +Execute(FixLocList should pass on end_lnum values): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 10, + \ 'end_lnum': 13, + \ 'end_col': 12, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 11, + \ 'end_lnum': 13, + \ 'end_col': 12, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [ + \ {'text': 'a', 'lnum': '010', 'col': '010', 'end_col': '012', 'end_lnum': '013'}, + \ {'text': 'a', 'lnum': '010', 'col': '011', 'end_col': 12, 'end_lnum': 13}, + \ ], + \ ) + +Execute(FixLocList should allow subtypes to be set): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'sub_type': 'style', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [{'text': 'a', 'lnum': 11, 'sub_type': 'style'}], + \ ) + +Execute(FixLocList should accept filenames): + let b:other_bufnr = bufnr('/foo/bar/baz', 1) + + " Make sure we actually get another buffer number, or the test is invalid. + AssertNotEqual -1, b:other_bufnr + + call ale#test#SetFilename('test.txt') + + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 2, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'filename': expand('%:p'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ { + \ 'text': 'a', + \ 'lnum': 3, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'filename': expand('%:p'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ { + \ 'text': 'a', + \ 'lnum': 4, + \ 'col': 0, + \ 'bufnr': b:other_bufnr, + \ 'filename': '/foo/bar/baz', + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ { + \ 'text': 'a', + \ 'lnum': 5, + \ 'col': 0, + \ 'bufnr': b:other_bufnr, + \ 'filename': '/foo/bar/baz', + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [ + \ {'text': 'a', 'lnum': 2, 'filename': expand('%:p')}, + \ {'text': 'a', 'lnum': 3, 'filename': expand('%:p')}, + \ {'text': 'a', 'lnum': 4, 'filename': '/foo/bar/baz'}, + \ {'text': 'a', 'lnum': 5, 'filename': '/foo/bar/baz'}, + \ ], + \ ) + +Execute(FixLocList should interpret temporary filenames as being the current buffer): + let b:temp_name = tempname() + + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 2, + \ 'col': 0, + \ 'bufnr': bufnr(''), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ { + \ 'text': 'a', + \ 'lnum': 3, + \ 'col': 0, + \ 'bufnr': bufnr(''), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr(''), + \ 'foobar', + \ 0, + \ [ + \ {'text': 'a', 'lnum': 2, 'filename': b:temp_name}, + \ {'text': 'a', 'lnum': 3, 'filename': substitute(b:temp_name, '\\', '/', 'g')}, + \ ], + \ ) + +Execute(The error code should be passed on): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ 'code': 'some-code' + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [{'text': 'a', 'lnum': 11, 'code': 'some-code'}], + \ ) + +Execute(FixLocList should mark problems as coming from other sources if requested): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 2, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ 'from_other_source': 1, + \ }, + \ { + \ 'text': 'b', + \ 'lnum': 2, + \ 'col': 0, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ 'from_other_source': 1, + \ }, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 1, + \ [{'text': 'a', 'lnum': 2}, {'text': 'b', 'lnum': 2}], + \ ) + +Given(A file with Japanese multi-byte text): + はじめまして! + -私はワープです。 +Execute(character positions should be converted to byte positions): + AssertEqual + \ [ + \ {'lnum': 1, 'bufnr': bufnr(''), 'col': 0, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'}, + \ {'lnum': 1, 'bufnr': bufnr(''), 'col': 1, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'}, + \ {'lnum': 1, 'bufnr': bufnr(''), 'col': 4, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'}, + \ {'lnum': 1, 'bufnr': bufnr(''), 'col': 7, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'}, + \ {'lnum': 1, 'bufnr': bufnr(''), 'col': 7, 'end_col': 13, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'}, + \ {'lnum': 1, 'bufnr': bufnr(''), 'col': 7, 'end_col': 13, 'end_lnum': 1, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'}, + \ {'lnum': 1, 'bufnr': bufnr(''), 'col': 7, 'end_col': 17, 'end_lnum': 2, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'}, + \ {'lnum': 2, 'bufnr': bufnr(''), 'col': 17, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'}, + \ ], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ 'foobar', + \ 0, + \ [ + \ {'text': 'a', 'lnum': 1, 'col': 0, 'vcol': 1}, + \ {'text': 'a', 'lnum': 1, 'col': 1, 'vcol': 1}, + \ {'text': 'a', 'lnum': 1, 'col': 2, 'vcol': 1}, + \ {'text': 'a', 'lnum': 1, 'col': 3, 'vcol': 1}, + \ {'text': 'a', 'lnum': 1, 'col': 3, 'end_col': 5, 'vcol': 1}, + \ {'text': 'a', 'lnum': 1, 'col': 3, 'end_col': 5, 'end_lnum': 1, 'vcol': 1}, + \ {'text': 'a', 'lnum': 1, 'col': 3, 'end_col': 7, 'end_lnum': 2, 'vcol': 1}, + \ {'text': 'a', 'lnum': 2, 'col': 7, 'vcol': 1}, + \ ], + \ ) diff --git a/vim-config/plugins/ale/test/test_loclist_jumping.vader b/vim-config/plugins/ale/test/test_loclist_jumping.vader new file mode 100644 index 00000000..8ec4e583 --- /dev/null +++ b/vim-config/plugins/ale/test/test_loclist_jumping.vader @@ -0,0 +1,121 @@ +Before: + let g:ale_buffer_info = { + \ bufnr(''): { + \ 'loclist': [ + \ {'type': 'E', 'bufnr': bufnr('') - 1, 'lnum': 3, 'col': 2}, + \ {'type': 'E', 'bufnr': bufnr(''), 'lnum': 1, 'col': 2}, + \ {'type': 'E', 'bufnr': bufnr(''), 'lnum': 1, 'col': 3}, + \ {'type': 'W', 'sub_type': 'style', 'bufnr': bufnr(''), 'lnum': 2, 'col': 1}, + \ {'type': 'E', 'bufnr': bufnr(''), 'lnum': 2, 'col': 2}, + \ {'type': 'W', 'sub_type': 'style', 'bufnr': bufnr(''), 'lnum': 2, 'col': 3}, + \ {'type': 'W', 'bufnr': bufnr(''), 'lnum': 2, 'col': 6}, + \ {'type': 'E', 'bufnr': bufnr(''), 'lnum': 2, 'col': 700}, + \ {'type': 'E', 'bufnr': bufnr('') + 1, 'lnum': 3, 'col': 2}, + \ ], + \ }, + \} + + function! TestJump(position, wrap, filter, subtype_filter, pos) + call cursor(a:pos) + + if type(a:position) == type(0) + call ale#loclist_jumping#JumpToIndex(a:position) + else + call ale#loclist_jumping#Jump(a:position, a:wrap, a:filter, + \ a:subtype_filter) + endif + + return getcurpos()[1:2] + endfunction + +After: + let g:ale_buffer_info = {} + delfunction TestJump + +Given foobar (Some imaginary filetype): + 12345678 + 12345678 + +Execute(loclist jumping should jump correctly when not wrapping): + AssertEqual [2, 1], TestJump('before', 0, 'any', 'any', [2, 2]) + AssertEqual [1, 3], TestJump('before', 0, 'any', 'any', [2, 1]) + AssertEqual [2, 3], TestJump('after', 0, 'any', 'any', [2, 2]) + AssertEqual [2, 1], TestJump('after', 0, 'any', 'any', [1, 3]) + AssertEqual [2, 6], TestJump('after', 0, 'any', 'any', [2, 4]) + AssertEqual [2, 8], TestJump('after', 0, 'any', 'any', [2, 6]) + +Execute(loclist jumping should jump correctly when wrapping): + AssertEqual [2, 1], TestJump('before', 1, 'any', 'any', [2, 2]) + AssertEqual [1, 3], TestJump('before', 1, 'any', 'any', [2, 1]) + AssertEqual [2, 3], TestJump('after', 1, 'any', 'any', [2, 2]) + AssertEqual [2, 1], TestJump('after', 1, 'any', 'any', [1, 3]) + AssertEqual [2, 6], TestJump('after', 1, 'any', 'any', [2, 4]) + + AssertEqual [1, 2], TestJump('after', 1, 'any', 'any', [2, 8]) + AssertEqual [2, 8], TestJump('before', 1, 'any', 'any', [1, 2]) + +Execute(loclist jumping should jump correctly with warning filters): + AssertEqual [2, 1], TestJump('after', 0, 'W', 'any', [1, 2]) + AssertEqual [2, 6], TestJump('after', 0, 'W', 'any', [2, 3]) + AssertEqual [2, 1], TestJump('after', 1, 'W', 'any', [2, 6]) + +Execute(loclist jumping should jump correctly with error filters): + AssertEqual [1, 2], TestJump('after', 1, 'E', 'any', [2, 700]) + AssertEqual [2, 2], TestJump('before', 0, 'E', 'any', [2, 700]) + AssertEqual [2, 2], TestJump('after', 1, 'E', 'any', [1, 3]) + +Execute(loclist jumping should jump correctly with sub type filters): + AssertEqual [2, 3], TestJump('after', 0, 'any', 'style', [2, 1]) + AssertEqual [2, 2], TestJump('after', 0, 'any', '', [1, 3]) + AssertEqual [2, 1], TestJump('after', 1, 'any', 'style', [2, 6]) + +Execute(loclist jumping not jump when the loclist is empty): + let g:ale_buffer_info[bufnr('%')].loclist = [] + + AssertEqual [1, 6], TestJump('before', 0, 'any', 'any', [1, 6]) + AssertEqual [1, 6], TestJump('before', 1, 'any', 'any', [1, 6]) + AssertEqual [1, 6], TestJump('after', 0, 'any', 'any', [1, 6]) + AssertEqual [1, 6], TestJump('after', 1, 'any', 'any', [1, 6]) + +Execute(We should be able to jump to the last item): + AssertEqual [2, 8], TestJump(-1, 0, 'any', 'any', [1, 6]) + +Execute(We shouldn't move when jumping to the last item where there are none): + let g:ale_buffer_info[bufnr('%')].loclist = [] + + AssertEqual [1, 6], TestJump(-1, 0, 'any', 'any', [1, 6]) + +Execute(We should be able to jump to the first item): + AssertEqual [1, 2], TestJump(0, 0, 'any', 'any', [1, 6]) + +Execute(We shouldn't move when jumping to the first item where there are none): + let g:ale_buffer_info[bufnr('%')].loclist = [] + + AssertEqual [1, 6], TestJump(0, 0, 'any', 'any', [1, 6]) + +Execute(We should be able to jump when the error line is blank): + " Add a blank line at the end. + call setline(1, getline('.', '$') + ['']) + " Add a problem on the blank line. + call add(g:ale_buffer_info[bufnr('%')].loclist, {'type': 'E', 'bufnr': bufnr(''), 'lnum': 3, 'col': 1}) + + AssertEqual 0, len(getline(3)) + AssertEqual [2, 8], TestJump('before', 0, 'any', 'any', [3, 1]) + AssertEqual [2, 8], TestJump('before', 1, 'any', 'any', [3, 1]) + AssertEqual [3, 1], TestJump('after', 0, 'any', 'any', [3, 1]) + AssertEqual [1, 2], TestJump('after', 1, 'any', 'any', [3, 1]) + +Execute(ALE should jump to column 1 instead of 0): + let g:ale_buffer_info = { + \ bufnr(''): { + \ 'loclist': [ + \ {'type': 'E', 'bufnr': bufnr(''), 'lnum': 1, 'col': 5}, + \ {'type': 'E', 'bufnr': bufnr(''), 'lnum': 2, 'col': 0}, + \ ], + \ }, + \} + + AssertEqual [2, 1], TestJump('after', 1, 'any', 'any', [1, 5]) + AssertEqual [1, 5], TestJump('after', 1, 'any', 'any', [2, 1]) + AssertEqual [2, 1], TestJump('before', 1, 'any', 'any', [1, 5]) + AssertEqual [1, 5], TestJump('before', 1, 'any', 'any', [2, 1]) diff --git a/vim-config/plugins/ale/test/test_loclist_sorting.vader b/vim-config/plugins/ale/test/test_loclist_sorting.vader new file mode 100644 index 00000000..376e743a --- /dev/null +++ b/vim-config/plugins/ale/test/test_loclist_sorting.vader @@ -0,0 +1,43 @@ +Execute(loclist item should be sorted): + AssertEqual [ + \ {'bufnr': -1, 'filename': 'b', 'lnum': 4, 'col': 2}, + \ {'bufnr': -1, 'filename': 'b', 'lnum': 5, 'col': 2}, + \ {'bufnr': -1, 'filename': 'c', 'lnum': 3, 'col': 2}, + \ {'bufnr': 1, 'lnum': 2, 'col': 10}, + \ {'bufnr': 1, 'lnum': 3, 'col': 2}, + \ {'bufnr': 1, 'lnum': 5, 'col': 4}, + \ {'bufnr': 1, 'lnum': 5, 'col': 5}, + \ {'bufnr': 2, 'lnum': 1, 'col': 2}, + \ {'bufnr': 2, 'lnum': 1, 'col': 5}, + \ {'bufnr': 2, 'lnum': 5, 'col': 5}, + \ {'bufnr': 3, 'lnum': 1, 'col': 1}, + \ ], + \ sort([ + \ {'bufnr': 3, 'lnum': 1, 'col': 1}, + \ {'bufnr': -1, 'filename': 'b', 'lnum': 5, 'col': 2}, + \ {'bufnr': 1, 'lnum': 5, 'col': 5}, + \ {'bufnr': 2, 'lnum': 5, 'col': 5}, + \ {'bufnr': -1, 'filename': 'b', 'lnum': 4, 'col': 2}, + \ {'bufnr': 1, 'lnum': 5, 'col': 4}, + \ {'bufnr': 1, 'lnum': 2, 'col': 10}, + \ {'bufnr': 2, 'lnum': 1, 'col': 5}, + \ {'bufnr': 1, 'lnum': 3, 'col': 2}, + \ {'bufnr': 2, 'lnum': 1, 'col': 2}, + \ {'bufnr': -1, 'filename': 'c', 'lnum': 3, 'col': 2}, + \], 'ale#util#LocItemCompare') + +Execute(Items should be sorted in by their problem priority when they lie on the same column): + AssertEqual [ + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'W', 'sub_type': 'style'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'E', 'sub_type': 'style'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'I'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'W'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'E'}, + \ ], + \ sort([ + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'E'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'I'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'W'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'E', 'sub_type': 'style'}, + \ {'bufnr': 1, 'lnum': 1, 'col': 1, 'type': 'W', 'sub_type': 'style'}, + \], 'ale#util#LocItemCompare') diff --git a/vim-config/plugins/ale/test/test_maven_build_classpath_command.vader b/vim-config/plugins/ale/test/test_maven_build_classpath_command.vader new file mode 100644 index 00000000..c10f457b --- /dev/null +++ b/vim-config/plugins/ale/test/test_maven_build_classpath_command.vader @@ -0,0 +1,53 @@ +Before: + Save $PATH + Save $PATHEXT + + let $PATHEXT = '.' + + call ale#test#SetDirectory('/testplugin/test') + runtime ale_linters/java/javac.vim + let g:expected_wrapper = '' + if has('unix') + let g:expected_wrapper = 'mvnw' + else + let g:expected_wrapper = 'mvnw.cmd' + endif + +After: + Restore + + unlet! g:expected_wrapper + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Should use 'mvnw' in classpath command if available): + call ale#test#SetFilename('test-files/maven/maven-java-project/module1/src/main/java/dummy1.java') + + AssertEqual + \ [ + \ ale#path#Simplify(g:dir . '/test-files/maven/maven-java-project/module1'), + \ ale#Escape(ale#path#Simplify(g:dir . '/test-files/maven/maven-java-project/module1/' . g:expected_wrapper)) + \ . ' dependency:build-classpath', + \ ], + \ ale#maven#BuildClasspathCommand(bufnr('')) + +Execute(Should use 'mvn' in classpath command if it is executable and 'mvnw' is unavailable): + call ale#test#SetFilename('test-files/maven/maven-java-project/module2/src/main/java/dummy2.java') + let $PATH .= (has('win32') ? ';' : ':') + \ . ale#path#Simplify(g:dir . '/test-files/maven') + + AssertEqual + \ [ + \ ale#path#Simplify(g:dir . '/test-files/maven/maven-java-project/module2'), + \ ale#Escape('mvn') + \ . ' dependency:build-classpath', + \ ], + \ ale#maven#BuildClasspathCommand(bufnr('')) + +Execute(Should return empty string if maven cannot be executed): + call ale#test#SetFilename('test-files/maven/non-maven-project/src/main/java/dummy.java') + + AssertEqual + \ ['', ''], + \ ale#maven#BuildClasspathCommand(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_maven_find_executable.vader b/vim-config/plugins/ale/test/test_maven_find_executable.vader new file mode 100644 index 00000000..f0f06b12 --- /dev/null +++ b/vim-config/plugins/ale/test/test_maven_find_executable.vader @@ -0,0 +1,46 @@ +Before: + Save $PATH + Save $PATHEXT + + " Count the maven executable without .exe as executable on Windows + let $PATHEXT = '.' + + call ale#test#SetDirectory('/testplugin/test') + runtime ale_linters/java/javac.vim + let g:expected_wrapper = '' + if has('unix') + let g:expected_wrapper = 'mvnw' + else + let g:expected_wrapper = 'mvnw.cmd' + endif + +After: + Restore + + unlet! g:expected_wrapper + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Should return 'mvnw' if found in parent directory): + call ale#test#SetFilename('test-files/maven/maven-java-project/module1/src/main/java/dummy1.java') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/maven/maven-java-project/module1/' . g:expected_wrapper), + \ ale#maven#FindExecutable(bufnr('')) + +Execute(Should return 'mvn' if 'mvnw' not found in parent directory): + call ale#test#SetFilename('test-files/maven/maven-java-project/module2/src/main/java/dummy2.java') + let $PATH .= (has('win32') ? ';' : ':') + \ . ale#path#Simplify(g:dir . '/test-files/maven') + + AssertEqual + \ 'mvn', + \ ale#maven#FindExecutable(bufnr('')) + +Execute(Should return empty string if 'mvnw' not in parent directory and mvn not in path): + call ale#test#SetFilename('mvn-test-files/java-maven-project/module2/src/main/java/dummy2.java') + + AssertEqual + \ '', + \ ale#gradle#FindExecutable(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_maven_find_project_root.vader b/vim-config/plugins/ale/test/test_maven_find_project_root.vader new file mode 100644 index 00000000..f761b2ef --- /dev/null +++ b/vim-config/plugins/ale/test/test_maven_find_project_root.vader @@ -0,0 +1,28 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + runtime ale_linters/kotlin/javac.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Should return directory for 'mvnw' if found in parent directory): + call ale#test#SetFilename('test-files/maven/maven-java-project/module1/src/main/java/dummy1.java') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/maven/maven-java-project/module1'), + \ ale#maven#FindProjectRoot(bufnr('')) + +Execute(Should return directory for 'pom.xml' if found in parent directory): + call ale#test#SetFilename('test-files/maven/maven-java-project/module2/src/main/java/dummy2.java') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/maven/maven-java-project/module2'), + \ ale#maven#FindProjectRoot(bufnr('')) + +Execute(Should return empty string if maven files are not found in parent directory): + call ale#test#SetFilename('test-files/maven/non-maven-project/src/main/java/dummy.java') + + AssertEqual + \ '', + \ ale#maven#FindProjectRoot(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_nearest_file_search.vader b/vim-config/plugins/ale/test/test_nearest_file_search.vader new file mode 100644 index 00000000..f5c12de4 --- /dev/null +++ b/vim-config/plugins/ale/test/test_nearest_file_search.vader @@ -0,0 +1,15 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + +After: + call ale#test#RestoreDirectory() + +Execute(We should be able to find a configuration file further up): + call ale#test#SetFilename('test-files/top/middle/bottom/dummy.txt') + + AssertEqual + \ ale#path#Simplify(expand('%:p:h:h:h:h:h') . '/test-files/top/example.ini'), + \ ale#path#FindNearestFile(bufnr('%'), 'example.ini') + +Execute(We shouldn't find anything for files which don't match): + AssertEqual '', ale#path#FindNearestFile(bufnr('%'), 'cantfindthis') diff --git a/vim-config/plugins/ale/test/test_nimlsp_project_root.vader b/vim-config/plugins/ale/test/test_nimlsp_project_root.vader new file mode 100644 index 00000000..d10989b3 --- /dev/null +++ b/vim-config/plugins/ale/test/test_nimlsp_project_root.vader @@ -0,0 +1,19 @@ +Before: + runtime ale_linters/nim/nimlsp.vim + call ale#test#SetDirectory('/testplugin/test') + +After: + if isdirectory(g:dir . '/.git') + call delete(g:dir . '/.git', 'd') + endif + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + +Execute(Detect root of nim project with .git/ correctly): + call ale#test#SetFilename('test-files/nim/with-git/src/source.nim') + call mkdir(g:dir . '/.git') + AssertEqual + \ ale#path#Simplify(g:dir), + \ ale_linters#nim#nimlsp#GetProjectRoot(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_no_linting_on_write_quit.vader b/vim-config/plugins/ale/test/test_no_linting_on_write_quit.vader new file mode 100644 index 00000000..3e49b506 --- /dev/null +++ b/vim-config/plugins/ale/test/test_no_linting_on_write_quit.vader @@ -0,0 +1,118 @@ +Before: + Save g:ale_echo_cursor + Save g:ale_fix_on_save + Save g:ale_fixers + Save g:ale_lint_on_save + Save g:ale_set_highlights + Save g:ale_set_lists_synchronously + Save g:ale_set_loclist + Save g:ale_set_quickfix + Save g:ale_set_signs + + let g:ale_run_synchronously = 1 + let g:ale_set_lists_synchronously = 1 + " Disable the things we don't need, but leave enabled what we do. + let g:ale_echo_cursor = 0 + let g:ale_set_signs = 0 + let g:ale_set_quickfix = 0 + let g:ale_set_loclist = 1 + let g:ale_set_highlights = 0 + let g:ale_echo_cursor = 0 + + function! TestCallback(buffer, output) + return [{'lnum': 1, 'col': 1, 'text': 'xxx'}] + endfunction + + function AddLine(buffer, lines) abort + return a:lines + ['x'] + endfunction + + let g:ale_fixers = { + \ 'testft': ['AddLine'], + \} + + call ale#linter#PreventLoading('testft') + call ale#linter#Define('testft', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'true', + \ 'command': 'true', + \}) + +Given testft (An empty file): + +After: + Restore + + unlet! g:ale_run_synchronously + unlet! b:ale_quitting + delfunction TestCallback + delfunction AddLine + + call ale#linter#Reset() + call setloclist(0, []) + +Execute(No linting should be done on :wq or :x): + let g:ale_lint_on_save = 1 + let g:ale_fix_on_save = 0 + + " First try just the SaveEvent, to be sure that we set errors in the test. + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()) + + " Now try doing it again, but where we run the quit event first. + call setloclist(0, []) + call ale#events#QuitEvent(bufnr('')) + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + AssertEqual [], ale#test#GetLoclistWithoutModule() + +Execute(No linting should be for :w after :q fails): + let g:ale_lint_on_save = 1 + let g:ale_fix_on_save = 0 + + call ale#events#QuitEvent(bufnr('')) + call ale#test#FlushJobs() + + " Simulate 2 seconds passing. + let b:ale_quitting -= 1000 + + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()) + +Execute(No linting should be done on :wq or :x after fixing files): + let g:ale_lint_on_save = 1 + let g:ale_fix_on_save = 1 + + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()) + + " Now try doing it again, but where we run the quit event first. + call setloclist(0, []) + call ale#events#QuitEvent(bufnr('')) + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + AssertEqual [], ale#test#GetLoclistWithoutModule() + +Execute(Linting should be done after :q fails and fixing files): + let g:ale_lint_on_save = 1 + let g:ale_fix_on_save = 1 + + call ale#events#QuitEvent(bufnr('')) + call ale#test#FlushJobs() + + " Simulate 2 seconds passing. + let b:ale_quitting -= 1000 + + call ale#events#SaveEvent(bufnr('')) + call ale#test#FlushJobs() + + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()) diff --git a/vim-config/plugins/ale/test/test_organize_imports.vader b/vim-config/plugins/ale/test/test_organize_imports.vader new file mode 100644 index 00000000..63973a54 --- /dev/null +++ b/vim-config/plugins/ale/test/test_organize_imports.vader @@ -0,0 +1,172 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('dummy.txt') + + let g:old_filename = expand('%:p') + let g:Callback = '' + let g:expr_list = [] + let g:message_list = [] + let g:handle_code_action_called = 0 + let g:code_actions = [] + let g:options = {} + let g:capability_checked = '' + let g:conn_id = v:null + let g:InitCallback = v:null + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/organize_imports.vim + runtime autoload/ale/code_action.vim + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {}) + call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer) + + if a:linter.lsp is# 'tsserver' + call ale#lsp#MarkConnectionAsTsserver(g:conn_id) + endif + + let l:details = { + \ 'command': 'foobar', + \ 'buffer': a:buffer, + \ 'connection_id': g:conn_id, + \ 'project_root': '/foo/bar', + \} + + let g:InitCallback = {-> ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)} + endfunction + + function! ale#lsp#HasCapability(conn_id, capability) abort + let g:capability_checked = a:capability + + return 1 + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + + return 42 + endfunction + + function! ale#util#Execute(expr) abort + call add(g:expr_list, a:expr) + endfunction + + function! ale#code_action#HandleCodeAction(code_action, options) abort + let g:handle_code_action_called = 1 + Assert !get(a:options, 'should_save') + call add(g:code_actions, a:code_action) + endfunction + +After: + if g:conn_id isnot v:null + call ale#lsp#RemoveConnectionWithID(g:conn_id) + endif + + call ale#references#SetMap({}) + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + unlet! g:capability_checked + unlet! g:InitCallback + unlet! g:old_filename + unlet! g:conn_id + unlet! g:Callback + unlet! g:message_list + unlet! g:expr_list + unlet! b:ale_linters + unlet! g:options + unlet! g:code_actions + unlet! g:handle_code_action_called + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/organize_imports.vim + runtime autoload/ale/code_action.vim + +Execute(Other messages for the tsserver handler should be ignored): + call ale#organize_imports#HandleTSServerResponse(1, {'command': 'foo'}) + AssertEqual g:handle_code_action_called, 0 + +Execute(Failed organizeImports responses should be handled correctly): + call ale#organize_imports#HandleTSServerResponse( + \ 1, + \ {'command': 'organizeImports', 'request_seq': 3} + \) + AssertEqual g:handle_code_action_called, 0 + +Execute(Code actions from tsserver should be handled): + call ale#organize_imports#HandleTSServerResponse(1, { + \ 'command': 'organizeImports', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': [], + \}) + AssertEqual g:handle_code_action_called, 1 + AssertEqual [{ + \ 'description': 'Organize Imports', + \ 'changes': [], + \}], g:code_actions + +Given typescript(Some typescript file): + foo + somelongerline + bazxyzxyzxyz + +Execute(tsserver organize imports requests should be sent): + call ale#linter#Reset() + runtime ale_linters/typescript/tsserver.vim + + ALEOrganizeImports + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual + \ 'function(''ale#organize_imports#HandleTSServerResponse'')', + \ string(g:Callback) + + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@organizeImports', { + \ 'scope': { + \ 'type': 'file', + \ 'args': { + \ 'file': expand('%:p'), + \ }, + \ }, + \ }] + \ ], + \ g:message_list + +Given python(Some Python file): + foo + somelongerline + bazxyzxyzxyz + +Execute(Should result in error message): + call ale#linter#Reset() + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + + ALEOrganizeImports + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual [ + \ 'echom ''OrganizeImports currently only works with tsserver''', + \], g:expr_list diff --git a/vim-config/plugins/ale/test/test_other_sources.vader b/vim-config/plugins/ale/test/test_other_sources.vader new file mode 100644 index 00000000..e6f9911c --- /dev/null +++ b/vim-config/plugins/ale/test/test_other_sources.vader @@ -0,0 +1,153 @@ +Before: + Save g:ale_buffer_info + Save g:ale_set_signs + Save g:ale_set_quickfix + Save g:ale_set_loclist + Save g:ale_set_highlights + Save g:ale_echo_cursor + + let g:ale_buffer_info = {} + let g:ale_run_synchronously = 1 + let g:ale_set_lists_synchronously = 1 + let g:ale_set_signs = 0 + let g:ale_set_quickfix = 0 + let g:ale_set_loclist = 1 + let g:ale_set_highlights = 0 + let g:ale_echo_cursor = 0 + + function! TestCallback(buffer, output) + return [] + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''', + \}) + +After: + Restore + + unlet! b:ale_linters + unlet! g:want_results_signaled + unlet! g:want_results_buffer_value + unlet! g:lint_pre_signaled + unlet! g:ale_run_synchronously + unlet! g:ale_set_lists_synchronously + + delfunction TestCallback + + augroup VaderTest + autocmd! + augroup END + + augroup! VaderTest + + call ale#linter#Reset() + call setloclist(0, []) + +Given foobar (Some imaginary filetype): +Execute(StartChecking should mark a buffer as being actively checked): + Assert !ale#engine#IsCheckingBuffer(bufnr('')) + + call ale#other_source#StartChecking(bufnr(''), 'other-source-linter') + + Assert ale#engine#IsCheckingBuffer(bufnr('')) + +Execute(ShowResults sould make a buffer inactive): + call ale#other_source#StartChecking(bufnr(''), 'other-source-linter') + call ale#other_source#StartChecking(bufnr(''), 'second-other-source-linter') + + call ale#other_source#ShowResults(bufnr(''), 'other-source-linter', []) + + Assert ale#engine#IsCheckingBuffer(bufnr('')) + + call ale#other_source#ShowResults(bufnr(''), 'second-other-source-linter', []) + + Assert !ale#engine#IsCheckingBuffer(bufnr('')) + +Execute(ShowResults should show results at any time): + call ale#other_source#ShowResults(bufnr(''), 'other-source-linter', [ + \ {'text': 'xyz', 'lnum': 1}, + \]) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 0, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': -1, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'xyz', + \ }, + \ ], + \ ale#test#GetLoclistWithoutModule() + + call ale#other_source#ShowResults(bufnr(''), 'other-source-linter', []) + + AssertEqual [], ale#test#GetLoclistWithoutModule() + +Execute(A regular lint cycle shouldn't clear results from other sources): + call ale#other_source#ShowResults(bufnr(''), 'other-source-linter', [ + \ {'text': 'xyz', 'lnum': 1}, + \]) + ALELint + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 0, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': -1, + \ 'type': 'E', + \ 'pattern': '', + \ 'text': 'xyz', + \ }, + \ ], + \ ale#test#GetLoclistWithoutModule() + +Execute(ALEWantResults should be signaled when a buffer is checked): + augroup VaderTest + autocmd! + autocmd User ALEWantResults let g:want_results_signaled = 1 + autocmd User ALELintPre let g:lint_pre_signaled = 1 + augroup END + + " Even when all linters are disabled, we should send the signal. + let b:ale_linters = [] + ALELint + + Assert get(g:, 'want_results_signaled') + Assert !get(g:, 'lint_pre_signaled') + +Execute(ALEWantResults should set a variable indicating which buffer is being checked): + augroup VaderTest + autocmd! + autocmd User ALEWantResults let g:want_results_buffer_value = g:ale_want_results_buffer + augroup END + + let b:ale_linters = [] + ALELint + + AssertEqual bufnr(''), g:want_results_buffer_value + +Execute(ALEWantResults should lead to an ALELintPre signal if another source responds): + augroup VaderTest + autocmd! + autocmd User ALEWantResults call ale#other_source#StartChecking(bufnr(''), 'other-source-linter') + autocmd User ALELintPre let g:lint_pre_signaled = 1 + augroup END + + " Even when all linters are disabled, we should send the signal. + let b:ale_linters = [] + ALELint + + Assert get(g:, 'lint_pre_signaled') diff --git a/vim-config/plugins/ale/test/test_parse_command_args.vader b/vim-config/plugins/ale/test/test_parse_command_args.vader new file mode 100644 index 00000000..0103b967 --- /dev/null +++ b/vim-config/plugins/ale/test/test_parse_command_args.vader @@ -0,0 +1,52 @@ +After: + unlet! b:parse_result + + if exists(':ParseTest') + delcommand ParseTest + endif + +Execute(ale#args#Parse should handle empty input): + AssertEqual + \ [{}, ''], + \ ale#args#Parse([], '') + AssertEqual + \ [{}, ''], + \ ale#args#Parse(['foo', 'bar'], '') + +Execute(ale#args#Parse should parse commands correctly): + AssertEqual + \ [{'foo': '', 'bar': ''}, 'leave these alone'], + \ ale#args#Parse(['foo', 'bar'], '-foo -bar leave these alone') + AssertEqual + \ [{'foo': ''}, 'leave these alone'], + \ ale#args#Parse(['foo', 'bar'], '-foo leave these alone') + +Execute(ale#args#Parse should raise errors for unknown arguments): + AssertThrows call ale#args#Parse(['foo', 'bar'], '-nope leave these alone') + AssertEqual 'Invalid argument: -nope', g:vader_exception + +Execute(ale#args#Parse should stop parsing arguments after --): + AssertEqual + \ [{'foo': ''}, ' --nope leave these alone'], + \ ale#args#Parse(['foo', 'bar'], '-foo -- --nope leave these alone') + AssertEqual + \ [{}, '--'], + \ ale#args#Parse(['foo', 'bar'], '-- --') + AssertEqual + \ [{}, ''], + \ ale#args#Parse(['foo', 'bar'], '--') + +Execute(ale#args#Parse should work for an example command): + command! -nargs=* ParseTest let b:parse_result = ale#args#Parse(['foo', 'bar'], ) + + ParseTest + AssertEqual [{}, ''], b:parse_result + + ParseTest -foo + AssertEqual [{'foo': ''}, ''], b:parse_result + + ParseTest -foo -bar + AssertEqual [{'foo': '', 'bar': ''}, ''], b:parse_result + + ParseTest -foo -bar leave these alone + AssertEqual [{'foo': '', 'bar': ''}, 'leave these alone'], b:parse_result diff --git a/vim-config/plugins/ale/test/test_path_dirname.vader b/vim-config/plugins/ale/test/test_path_dirname.vader new file mode 100644 index 00000000..818a62a8 --- /dev/null +++ b/vim-config/plugins/ale/test/test_path_dirname.vader @@ -0,0 +1,13 @@ +Execute(ale#path#Dirname should return empty strings should be returned for empty values): + AssertEqual '', ale#path#Dirname('') + AssertEqual '', ale#path#Dirname(0) + AssertEqual '', ale#path#Dirname(v:null) + +Execute(ale#path#Dirname should return the dirname of paths): + AssertEqual '/foo', ale#path#Dirname('/foo/bar') + AssertEqual '/foo', ale#path#Dirname('/foo/bar/') + + if has('win32') + AssertEqual 'C:\foo', ale#path#Dirname('C:\foo\bar') + AssertEqual 'C:\foo', ale#path#Dirname('C:\foo\bar\') + endif diff --git a/vim-config/plugins/ale/test/test_path_equality.vader b/vim-config/plugins/ale/test/test_path_equality.vader new file mode 100644 index 00000000..ee6ae2c5 --- /dev/null +++ b/vim-config/plugins/ale/test/test_path_equality.vader @@ -0,0 +1,82 @@ +Before: + function! CheckPath(path) abort + return ale#path#IsBufferPath(bufnr(''), ale#path#Simplify(a:path)) + endfunction + +After: + delfunction CheckPath + +Execute(ale#path#Simplify should adjust paths correctly): + if has('unix') + " Multiple slashes should be removed correctly. + AssertEqual '/foo/bar/baz', ale#path#Simplify('////foo///bar///baz') + " Back slashes should be converted to forward slashes. + " This means some valid filenames are adjusted incorrectly, but in practice + " no filenames for code should contain back slashes, and adjusting slashes + " like this makes ALE work in MSYS. + AssertEqual 'foo/bar/baz', ale#path#Simplify('foo\bar\baz') + else + " Multiple slashes should be removed correctly. + AssertEqual '\foo\bar\baz', ale#path#Simplify('\\\foo\bar\baz') + " Forward slashes should be replaced with back slashes. + AssertEqual 'foo\bar\baz', ale#path#Simplify('foo/bar/baz') + endif + +Execute(ale#path#IsBufferPath should match simple relative paths): + call ale#test#SetFilename('app/foo.txt') + + Assert CheckPath('app/foo.txt'), 'No match for foo.txt' + Assert !CheckPath('app/bar.txt'), 'Bad match for bar.txt' + +Execute(ale#path#IsBufferPath should match relative paths with dots): + call ale#test#SetFilename('app/foo.txt') + + " Skip these checks on Windows. + if !has('win32') + Assert CheckPath('../../app/foo.txt'), 'No match for ../../app/foo.txt' + endif + +Execute(ale#path#IsBufferPath should match absolute paths): + silent file! foo.txt + + Assert CheckPath(getcwd() . '/foo.txt'), 'No match for foo.txt' + Assert !CheckPath(getcwd() . '/bar.txt'), 'Bad match for bar.txt' + +Execute(ale#path#IsBufferPath should match paths beginning with ./): + silent file! foo.txt + + if !has('win32') + Assert ale#path#IsBufferPath(bufnr(''), './foo.txt'), 'No match for ./foo.txt' + endif + +Execute(ale#path#IsBufferPath should match if our path ends with the test path): + silent file! foo/bar/baz.txt + + Assert CheckPath('bar/baz.txt'), 'No match for bar/baz.txt' + +Execute(ale#path#IsBufferPath should match paths with redundant slashes): + silent file! foo.txt + + Assert CheckPath(getcwd() . '////foo.txt'), 'No match for foo.txt' + +Execute(ale#path#IsBufferPath should accept various names for stdin): + Assert ale#path#IsBufferPath(bufnr(''), '-') + Assert ale#path#IsBufferPath(bufnr(''), 'stdin') + Assert ale#path#IsBufferPath(bufnr(''), '') + Assert ale#path#IsBufferPath(bufnr(''), '') + +Execute(ale#path#IsBufferPath should match files in /tmp): + call ale#test#SetFilename('app/test.ts') + + Assert ale#path#IsBufferPath(bufnr(''), tempname() . '/test.ts') + +Execute(ale#path#IsBufferPath should match Windows paths on Unix): + " This test should pass Unix. + " + " Back slashes in paths should be replaced with forward slashes, even though + " back slashes are valid in filenames on Unix. + if has('unix') + call ale#test#SetFilename('app/foo/test.ts') + + Assert ale#path#IsBufferPath(bufnr(''), 'foo\test.ts') + endif diff --git a/vim-config/plugins/ale/test/test_path_upwards.vader b/vim-config/plugins/ale/test/test_path_upwards.vader new file mode 100644 index 00000000..cd461a28 --- /dev/null +++ b/vim-config/plugins/ale/test/test_path_upwards.vader @@ -0,0 +1,48 @@ +Execute(ale#path#Upwards should return the correct path components): + if has('unix') + " Absolute paths should include / on the end. + AssertEqual + \ ['/foo/bar/baz', '/foo/bar', '/foo', '/'], + \ ale#path#Upwards('/foo/bar/baz') + AssertEqual + \ ['/foo/bar/baz', '/foo/bar', '/foo', '/'], + \ ale#path#Upwards('/foo/bar/baz///') + " Relative paths do not. + AssertEqual + \ ['foo/bar/baz', 'foo/bar', 'foo'], + \ ale#path#Upwards('foo/bar/baz') + AssertEqual + \ ['foo2/bar', 'foo2'], + \ ale#path#Upwards('foo//..////foo2////bar') + " Expect an empty List for empty strings. + AssertEqual [], ale#path#Upwards('') + endif + + if has('win32') + AssertEqual + \ ['C:\foo\bar\baz', 'C:\foo\bar', 'C:\foo', 'C:\'], + \ ale#path#Upwards('C:\foo\bar\baz') + AssertEqual + \ ['C:\foo\bar\baz', 'C:\foo\bar', 'C:\foo', 'C:\'], + \ ale#path#Upwards('C:\foo\bar\baz\\\') + AssertEqual + \ ['/foo\bar\baz', '/foo\bar', '/foo', '/'], + \ ale#path#Upwards('/foo/bar/baz') + AssertEqual + \ ['foo\bar\baz', 'foo\bar', 'foo'], + \ ale#path#Upwards('foo/bar/baz') + AssertEqual + \ ['foo\bar\baz', 'foo\bar', 'foo'], + \ ale#path#Upwards('foo\bar\baz') + " simplify() is used internally, and should sort out \ paths when actually + " running Windows, which we can't test here. + AssertEqual + \ ['foo2\bar', 'foo2'], + \ ale#path#Upwards('foo//..///foo2////bar') + " Expect an empty List for empty strings. + AssertEqual [], ale#path#Upwards('') + " Paths starting with // return / + AssertEqual + \ ['/foo2\bar', '/foo2', '/'], + \ ale#path#Upwards('//foo//..///foo2////bar') + endif diff --git a/vim-config/plugins/ale/test/test_path_uri.vader b/vim-config/plugins/ale/test/test_path_uri.vader new file mode 100644 index 00000000..0f2cba7e --- /dev/null +++ b/vim-config/plugins/ale/test/test_path_uri.vader @@ -0,0 +1,73 @@ +Before: + scriptencoding utf-8 + +Execute(ale#path#ToURI should work for Windows paths): + AssertEqual 'file:///C:/foo/bar/baz.tst', ale#path#ToURI('C:\foo\bar\baz.tst') + AssertEqual 'foo/bar/baz.tst', ale#path#ToURI('foo\bar\baz.tst') + +Execute(ale#path#FromURI should work for Unix paths): + AssertEqual '/foo/bar/baz.tst', ale#path#FromURI('file:///foo/bar/baz.tst') + AssertEqual '/foo/bar/baz.tst', ale#path#FromURI('file:/foo/bar/baz.tst') + AssertEqual '/foo/bar/baz.tst', ale#path#FromURI('FILE:///foo/bar/baz.tst') + AssertEqual '/foo/bar/baz.tst', ale#path#FromURI('FILE:/foo/bar/baz.tst') + +Execute(ale#path#FromURI should work for Windows paths): + if has('win32') + AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('file:///C:/foo/bar/baz.tst') + AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('file:/C:/foo/bar/baz.tst') + AssertEqual 'c:\foo\bar\baz.tst', ale#path#FromURI('file:///c:/foo/bar/baz.tst') + AssertEqual 'c:\foo\bar\baz.tst', ale#path#FromURI('file:/c:/foo/bar/baz.tst') + AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('FILE:///C:/foo/bar/baz.tst') + AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('FILE:/C:/foo/bar/baz.tst') + else + AssertEqual '/C:/foo/bar/baz.tst', ale#path#FromURI('file:///C:/foo/bar/baz.tst') + AssertEqual '/C:/foo/bar/baz.tst', ale#path#FromURI('file:/C:/foo/bar/baz.tst') + AssertEqual '/c:/foo/bar/baz.tst', ale#path#FromURI('file:///c:/foo/bar/baz.tst') + AssertEqual '/c:/foo/bar/baz.tst', ale#path#FromURI('file:/c:/foo/bar/baz.tst') + AssertEqual '/C:/foo/bar/baz.tst', ale#path#FromURI('FILE:///C:/foo/bar/baz.tst') + AssertEqual '/C:/foo/bar/baz.tst', ale#path#FromURI('FILE:/C:/foo/bar/baz.tst') + endif + +Execute(ale#path#FromURI parse Windows paths with a pipe): + if has('win32') + AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('file:///C|/foo/bar/baz.tst') + AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('file:/C|/foo/bar/baz.tst') + AssertEqual 'c:\foo\bar\baz.tst', ale#path#FromURI('file:///c|/foo/bar/baz.tst') + AssertEqual 'c:\foo\bar\baz.tst', ale#path#FromURI('file:/c|/foo/bar/baz.tst') + AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('FILE:///C|/foo/bar/baz.tst') + AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('FILE:/C|/foo/bar/baz.tst') + else + AssertEqual '/C|/foo/bar/baz.tst', ale#path#FromURI('file:///C|/foo/bar/baz.tst') + AssertEqual '/C|/foo/bar/baz.tst', ale#path#FromURI('file:/C|/foo/bar/baz.tst') + AssertEqual '/c|/foo/bar/baz.tst', ale#path#FromURI('file:///c|/foo/bar/baz.tst') + AssertEqual '/c|/foo/bar/baz.tst', ale#path#FromURI('file:/c|/foo/bar/baz.tst') + AssertEqual '/C|/foo/bar/baz.tst', ale#path#FromURI('FILE:///C|/foo/bar/baz.tst') + AssertEqual '/C|/foo/bar/baz.tst', ale#path#FromURI('FILE:/C|/foo/bar/baz.tst') + endif + +Execute(ale#path#FromURI should handle the colon for the drive letter being encoded): + " These URIs shouldn't be created, but we'll handle them anyway. + if has('win32') + AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('file:///C%3A/foo/bar/baz.tst') + else + AssertEqual '/C:/foo/bar/baz.tst', ale#path#FromURI('file:///C%3A/foo/bar/baz.tst') + endif + +Execute(ale#path#ToURI should work for Unix paths): + AssertEqual 'file:///foo/bar/baz.tst', ale#path#ToURI('/foo/bar/baz.tst') + AssertEqual 'foo/bar/baz.tst', ale#path#ToURI('foo/bar/baz.tst') + +Execute(ale#path#ToURI should keep safe characters): + AssertEqual '//a-zA-Z0-9$-_.!*''(),', ale#path#ToURI('\/a-zA-Z0-9$-_.!*''(),') + +Execute(ale#path#ToURI should percent encode unsafe characters): + AssertEqual '%20%2b%3a%3f%26%3d', ale#path#ToURI(' +:?&=') + +Execute(ale#path#FromURI should decode percent encodings): + AssertEqual ' +:?&=', ale#path#FromURI('%20%2b%3a%3f%26%3d') + +Execute(ale#path#ToURI should handle UTF-8): + AssertEqual 'file:///T%c3%a9l%c3%a9chargement', ale#path#ToURI('/Téléchargement') + +Execute(ale#path#FromURI should handle UTF-8): + AssertEqual '/Téléchargement', ale#path#FromURI('file:///T%C3%A9l%C3%A9chargement') diff --git a/vim-config/plugins/ale/test/test_pattern_options.vader b/vim-config/plugins/ale/test/test_pattern_options.vader new file mode 100644 index 00000000..3b6500e5 --- /dev/null +++ b/vim-config/plugins/ale/test/test_pattern_options.vader @@ -0,0 +1,107 @@ +Before: + Save g:ale_pattern_options + Save g:ale_pattern_options_enabled + Save b:ale_quitting + Save b:ale_original_filetype + Save &filetype + + unlet! b:ale_file_changed + + let g:ale_pattern_options_enabled = 1 + let g:ale_pattern_options = {} + + let b:ale_enabled = 0 + let b:some_option = 0 + + call ale#test#SetDirectory('/testplugin/test') + +After: + Restore + + unlet! b:ale_enabled + unlet! b:some_option + + call ale#test#RestoreDirectory() + +Execute(The pattern options function should work when there are no patterns): + call ale#test#SetFilename('foobar.js') + call ale#events#ReadOrEnterEvent(bufnr('')) + +Execute(Buffer variables should be set when filename patterns match): + let g:ale_pattern_options = { + \ 'baz.*\.js': { + \ 'ale_enabled': 1, + \ 'some_option': 347, + \ '&filetype': 'pattern_option_set_filetype', + \ }, + \} + + call ale#test#SetFilename('foobar.js') + call ale#events#ReadOrEnterEvent(bufnr('')) + + AssertEqual 0, b:ale_enabled + AssertEqual 0, b:some_option + + call ale#test#SetFilename('bazboz.js') + call ale#events#ReadOrEnterEvent(bufnr('')) + + AssertEqual 1, b:ale_enabled + AssertEqual 347, b:some_option + AssertEqual 'pattern_option_set_filetype', &filetype + +Execute(Multiple pattern matches should be applied): + let g:ale_pattern_options = { + \ 'foo': { + \ 'some_option': 666, + \ }, + \ 'bar': { + \ 'ale_enabled': 1, + \ 'some_option': 123, + \ }, + \ 'notmatched': { + \ 'some_option': 489, + \ 'ale_enabled': 0, + \ }, + \} + + call ale#test#SetFilename('foobar.js') + call ale#events#ReadOrEnterEvent(bufnr('')) + + AssertEqual 1, b:ale_enabled + AssertEqual 666, b:some_option + +Execute(Patterns should not be applied when the setting is disabled): + let g:ale_pattern_options_enabled = 0 + let g:ale_pattern_options = {'foo': {'some_option': 666}} + + call ale#test#SetFilename('foobar.js') + call ale#events#ReadOrEnterEvent(bufnr('')) + + AssertEqual 0, b:some_option + +" This test is important for making sure we update the sorted items. +Execute(Patterns should be applied after the Dictionary changes): + call ale#test#SetFilename('foobar.js') + + let g:ale_pattern_options = {} + + call ale#events#ReadOrEnterEvent(bufnr('')) + + AssertEqual 0, b:some_option + + let g:ale_pattern_options['foo'] = {'some_option': 666} + + call ale#events#ReadOrEnterEvent(bufnr('')) + + AssertEqual 666, b:some_option + +Execute(SetOptions should tolerate settings being unset): + " This might happen if ALE is loaded in a weird way, so tolerate it. + unlet! g:ale_pattern_options + unlet! g:ale_pattern_options_enabled + + call ale#events#ReadOrEnterEvent(bufnr('')) + + let g:ale_pattern_options_enabled = 1 + + call ale#events#ReadOrEnterEvent(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_prepare_command.vader b/vim-config/plugins/ale/test/test_prepare_command.vader new file mode 100644 index 00000000..6a71eaed --- /dev/null +++ b/vim-config/plugins/ale/test/test_prepare_command.vader @@ -0,0 +1,75 @@ +Before: + Save &shell + Save &shellcmdflag + Save g:ale_shell + Save g:ale_shell_arguments + + unlet! g:ale_shell + unlet! g:ale_shell_arguments + +After: + Restore + +Execute(sh should be used when the shell is fish): + if !has('win32') + " Set something else, so we will replace that too. + let &shellcmdflag = '-f' + let &shell = 'fish' + + AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar') + + let &shell = '/usr/bin/fish' + + AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar') + + let &shell = '/usr/local/bin/fish' + + AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar') + endif + +Execute(sh should be used when the shell is powershell): + if !has('win32') + " Set something else, so we will replace that too. + let &shellcmdflag = '-f' + let &shell = 'pwsh' + + AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar') + + let &shell = '/usr/bin/pwsh' + + AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar') + + let &shell = '/usr/local/bin/pwsh' + + AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar') + endif + +Execute(Other shells should be used when set): + if !has('win32') + let &shell = '/bin/bash' + let &shellcmdflag = '-c' + let g:ale_shell = &shell + + AssertEqual ['/bin/bash', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar') + endif + +Execute(cmd /s/c as a string should be used on Windows): + if has('win32') + let &shell = 'who cares' + let &shellcmdflag = 'whatever' + + AssertEqual 'cmd /s/c "foobar"', ale#job#PrepareCommand(bufnr(''), 'foobar') + endif + +Execute(Setting ale_shell should cause ale#job#PrepareCommand to use set shell): + let g:ale_shell = '/foo/bar' + + if has('win32') + AssertEqual ['/foo/bar', '/c', 'foobar'], ale#job#PrepareCommand(bufnr(''), "foobar") + else + AssertEqual ['/foo/bar', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), "foobar") + endif + + let g:ale_shell_arguments = '-x' + + AssertEqual ['/foo/bar', '-x', 'foobar'], ale#job#PrepareCommand(bufnr(''), "foobar") diff --git a/vim-config/plugins/ale/test/test_puppet_path_detection.vader b/vim-config/plugins/ale/test/test_puppet_path_detection.vader new file mode 100644 index 00000000..e918e916 --- /dev/null +++ b/vim-config/plugins/ale/test/test_puppet_path_detection.vader @@ -0,0 +1,22 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + + runtime ale_linters/puppet/languageserver.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(old-style module should find its root correctly): + call ale#test#SetFilename('test-files/puppet/old-style-module/manifests/init.pp') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/puppet/old-style-module'), + \ ale_linters#puppet#languageserver#GetProjectRoot(bufnr('')) + +Execute(new-style module should find its root correctly): + call ale#test#SetFilename('test-files/puppet/new-style-module/lib/puppet/types/exampletype.rb') + + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/puppet/new-style-module'), + \ ale_linters#puppet#languageserver#GetProjectRoot(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_python_find_project_root.vader b/vim-config/plugins/ale/test/test_python_find_project_root.vader new file mode 100644 index 00000000..e323c866 --- /dev/null +++ b/vim-config/plugins/ale/test/test_python_find_project_root.vader @@ -0,0 +1,11 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + +After: + call ale#test#RestoreDirectory() + +Execute(Detect root of Python project with .flake8 correctly): + call ale#test#SetFilename('test-files/python/python-package-project/package-name/module.py') + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/python/python-package-project'), + \ ale#python#FindProjectRoot(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_python_pipenv.vader b/vim-config/plugins/ale/test/test_python_pipenv.vader new file mode 100644 index 00000000..041e2874 --- /dev/null +++ b/vim-config/plugins/ale/test/test_python_pipenv.vader @@ -0,0 +1,19 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + +After: + call ale#test#RestoreDirectory() + +Execute(ale#python#PipenvPresent is true when a pipenv environment is present): + call ale#test#SetFilename('test-files/python/pipenv/whatever.py') + + AssertEqual + \ ale#python#PipenvPresent(bufnr('%')), + \ 1 + +Execute(ale#python#PipenvPresent is false when no pipenv environment is present): + call ale#test#SetFilename('test-files/python/no_pipenv/whatever.py') + + AssertEqual + \ ale#python#PipenvPresent(bufnr('%')), + \ 0 diff --git a/vim-config/plugins/ale/test/test_python_poetry.vader b/vim-config/plugins/ale/test/test_python_poetry.vader new file mode 100644 index 00000000..8197b786 --- /dev/null +++ b/vim-config/plugins/ale/test/test_python_poetry.vader @@ -0,0 +1,19 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + +After: + call ale#test#RestoreDirectory() + +Execute(ale#python#poetryPresent is true when a poetry environment is present): + call ale#test#SetFilename('test-files/python/poetry/whatever.py') + + AssertEqual + \ ale#python#PoetryPresent(bufnr('%')), + \ 1 + +Execute(ale#python#poetryPresent is false when no poetry environment is present): + call ale#test#SetFilename('test-files/python/no_poetry/whatever.py') + + AssertEqual + \ ale#python#PoetryPresent(bufnr('%')), + \ 0 diff --git a/vim-config/plugins/ale/test/test_python_traceback.vader b/vim-config/plugins/ale/test/test_python_traceback.vader new file mode 100644 index 00000000..6a659986 --- /dev/null +++ b/vim-config/plugins/ale/test/test_python_traceback.vader @@ -0,0 +1,79 @@ +Execute(ale#python#HandleTraceback returns empty List for empty lines): + AssertEqual + \ [], + \ ale#python#HandleTraceback([], 10) + +Execute(ale#python#HandleTraceback returns traceback, when present): + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'Exception: Example error (See :ALEDetail)', + \ 'detail': join([ + \ 'Traceback (most recent call last):', + \ ' File "./example.py", line 5, in ', + \ ' raise Exception(''Example message'')', + \ 'Exception: Example error', + \ ], "\n"), + \ }], + \ ale#python#HandleTraceback([ + \ 'Traceback (most recent call last):', + \ ' File "./example.py", line 5, in ', + \ ' raise Exception(''Example message'')', + \ 'Exception: Example error', + \ ], 1) + +" SyntaxError has extra output lines about the source +Execute(ale#python#HandleTraceback returns SyntaxError traceback): + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'SyntaxError: invalid syntax (See :ALEDetail)', + \ 'detail': join([ + \ 'Traceback (most recent call last):', + \ ' File "", line 1, in ', + \ ' File "example.py", line 5', + \ ' +', + \ ' ^', + \ 'SyntaxError: invalid syntax', + \ ], "\n"), + \ }], + \ ale#python#HandleTraceback([ + \ 'Traceback (most recent call last):', + \ ' File "", line 1, in ', + \ ' File "example.py", line 5', + \ ' +', + \ ' ^', + \ 'SyntaxError: invalid syntax', + \ ], 1) + +Execute(ale#python#HandleTraceback ignores traceback after line limit): + AssertEqual + \ [], + \ ale#python#HandleTraceback([ + \ '', + \ 'Traceback (most recent call last):', + \ ' File "./example.py", line 5, in ', + \ ' raise Exception(''Example message'')', + \ 'Exception: Example error', + \ ], 1) + +Execute(ale#python#HandleTraceback doesn't include later lines in detail): + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'Exception: Example error (See :ALEDetail)', + \ 'detail': join([ + \ 'Traceback (most recent call last):', + \ ' File "./example.py", line 5, in ', + \ ' raise Exception(''Example message'')', + \ 'Exception: Example error', + \ ], "\n"), + \ }], + \ ale#python#HandleTraceback([ + \ 'Traceback (most recent call last):', + \ ' File "./example.py", line 5, in ', + \ ' raise Exception(''Example message'')', + \ 'Exception: Example error', + \ 'file:1:2: Style issue', + \ 'file:3:4: Non-style issue', + \ ], 1) diff --git a/vim-config/plugins/ale/test/test_python_virtualenv.vader b/vim-config/plugins/ale/test/test_python_virtualenv.vader new file mode 100644 index 00000000..b44c5fa2 --- /dev/null +++ b/vim-config/plugins/ale/test/test_python_virtualenv.vader @@ -0,0 +1,12 @@ +Before: + Save $VIRTUAL_ENV + let $VIRTUAL_ENV = "/opt/example/" + +After: + Restore + +Execute(ale#python#FindVirtualenv falls back to $VIRTUAL_ENV when no directories match): + AssertEqual + \ ale#python#FindVirtualenv(bufnr('%')), + \ '/opt/example/', + \ 'Expected VIRTUAL_ENV environment variable to be used, but it was not' diff --git a/vim-config/plugins/ale/test/test_quickfix_deduplication.vader b/vim-config/plugins/ale/test/test_quickfix_deduplication.vader new file mode 100644 index 00000000..9cb8b931 --- /dev/null +++ b/vim-config/plugins/ale/test/test_quickfix_deduplication.vader @@ -0,0 +1,50 @@ +Before: + Save g:ale_buffer_info + +After: + Restore + +Execute: + " Results from multiple buffers should be gathered together. + " Equal problems should be de-duplicated. + let g:ale_buffer_info = { + \ '1': {'loclist': [ + \ {'type': 'E', 'bufnr': 2, 'lnum': 1, 'col': 2, 'text': 'foo'}, + \ {'type': 'E', 'bufnr': 2, 'lnum': 1, 'col': 5, 'text': 'bar'}, + \ {'type': 'E', 'bufnr': -1, 'filename': 'c', 'lnum': 3, 'col': 2, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 5, 'col': 4, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 2, 'lnum': 5, 'col': 5, 'text': 'foo'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 2, 'col': 10, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 3, 'col': 2, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 5, 'col': 5, 'text': 'x'}, + \ {'type': 'E', 'bufnr': -1, 'filename': 'b', 'lnum': 4, 'col': 2, 'text': 'x'}, + \ {'type': 'E', 'bufnr': -1, 'filename': 'b', 'lnum': 5, 'col': 2, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 3, 'lnum': 1, 'col': 1, 'text': 'foo'}, + \ ]}, + \ '2': {'loclist': [ + \ {'type': 'E', 'bufnr': 1, 'lnum': 2, 'col': 10, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 5, 'col': 5, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 2, 'lnum': 1, 'col': 2, 'text': 'foo'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 3, 'col': 2, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 5, 'col': 4, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 2, 'lnum': 1, 'col': 5, 'text': 'bar'}, + \ {'type': 'E', 'bufnr': 2, 'lnum': 5, 'col': 5, 'text': 'another error'}, + \ ]}, + \} + + AssertEqual + \ [ + \ {'type': 'E', 'bufnr': -1, 'filename': 'b', 'lnum': 4, 'col': 2, 'text': 'x'}, + \ {'type': 'E', 'bufnr': -1, 'filename': 'b', 'lnum': 5, 'col': 2, 'text': 'x'}, + \ {'type': 'E', 'bufnr': -1, 'filename': 'c', 'lnum': 3, 'col': 2, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 2, 'col': 10, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 3, 'col': 2, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 5, 'col': 4, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 1, 'lnum': 5, 'col': 5, 'text': 'x'}, + \ {'type': 'E', 'bufnr': 2, 'lnum': 1, 'col': 2, 'text': 'foo'}, + \ {'type': 'E', 'bufnr': 2, 'lnum': 1, 'col': 5, 'text': 'bar'}, + \ {'type': 'E', 'bufnr': 2, 'lnum': 5, 'col': 5, 'text': 'another error'}, + \ {'type': 'E', 'bufnr': 2, 'lnum': 5, 'col': 5, 'text': 'foo'}, + \ {'type': 'E', 'bufnr': 3, 'lnum': 1, 'col': 1, 'text': 'foo'}, + \ ], + \ ale#list#GetCombinedList() diff --git a/vim-config/plugins/ale/test/test_quitting_variable.vader b/vim-config/plugins/ale/test/test_quitting_variable.vader new file mode 100644 index 00000000..32eb0c36 --- /dev/null +++ b/vim-config/plugins/ale/test/test_quitting_variable.vader @@ -0,0 +1,39 @@ +Before: + Save g:ale_enabled + + unlet! b:ale_quitting + let g:ale_enabled = 0 + +After: + Restore + + unlet! b:ale_quitting + unlet! b:time_before + +Execute(QuitEvent should set b:ale_quitting some time from the clock): + let b:time_before = ale#events#ClockMilliseconds() + + call ale#events#QuitEvent(bufnr('')) + + Assert b:ale_quitting >= b:time_before + Assert b:ale_quitting <= ale#events#ClockMilliseconds() + +Execute(ReadOrEnterEvent should set b:ale_quitting to 0): + let b:ale_quitting = 1 + + call ale#events#ReadOrEnterEvent(bufnr('')) + + AssertEqual 0, b:ale_quitting + +Execute(The QuitRecently function should work when the variable isn't set): + AssertEqual 0, ale#events#QuitRecently(bufnr('')) + +Execute(The QuitRecently function should return 1 when ALE quit recently): + let b:ale_quitting = ale#events#ClockMilliseconds() + + AssertEqual 1, ale#events#QuitRecently(bufnr('')) + +Execute(The QuitRecently function should return 0 when a second has passed): + let b:ale_quitting = ale#events#ClockMilliseconds() - 1001 + + AssertEqual 0, ale#events#QuitRecently(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_redundant_tsserver_rendering_avoided.vader b/vim-config/plugins/ale/test/test_redundant_tsserver_rendering_avoided.vader new file mode 100644 index 00000000..05660d4e --- /dev/null +++ b/vim-config/plugins/ale/test/test_redundant_tsserver_rendering_avoided.vader @@ -0,0 +1,178 @@ +Before: + Save g:ale_buffer_info + Save g:ale_disable_lsp + Save g:ale_lsp_suggestions + + let g:ale_disable_lsp = 0 + let g:ale_lsp_suggestions = 1 + unlet! b:ale_disable_lsp + + function! CreateError(type, message) abort + let l:diagnostics = [] + + if !empty(a:message) + let l:diagnostics = [{ + \ 'start': {'line': 1, 'offset': 1}, + \ 'end': {'line': 1, 'offset':1}, + \ 'text': a:message, + \ 'code': 1005, + \}] + endif + + return { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': a:type, + \ 'body': {'file': expand('%:p'), 'diagnostics': l:diagnostics}, + \} + endfunction + + function! CreateLoclist(message) abort + let l:list = [] + + if !empty(a:message) + let l:list = [{ + \ 'lnum': 1, + \ 'col': 1, + \ 'end_lnum': 1, + \ 'end_col': 1, + \ 'text': a:message, + \}] + endif + + return l:list + endfunction + + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('filename.ts') + + runtime autoload/ale/engine.vim + + let g:ale_buffer_info = {bufnr(''): {'loclist': [], 'active_linter_list': []}} + let g:ale_handle_loclist_called = 0 + + function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort + let g:ale_handle_loclist_called = 1 + endfunction + +After: + Restore + + delfunction CreateError + delfunction CreateLoclist + + call ale#test#RestoreDirectory() + + runtime autoload/ale/engine.vim + +Execute(An initial empty list of syntax errors should be ignored): + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(An initial list of syntax errors should be handled): + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Subsequent empty lists should be ignored): + let g:ale_buffer_info[bufnr('')].syntax_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(Empty then non-empty syntax errors should be handled): + let g:ale_buffer_info[bufnr('')].syntax_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then empty syntax errors should be handled): + let g:ale_buffer_info[bufnr('')].syntax_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', '')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then non-empty syntax errors should be handled): + let g:ale_buffer_info[bufnr('')].syntax_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(An initial empty list of semantic errors should be ignored): + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(An initial list of semantic errors should be handled): + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Subsequent empty lists should be ignored - semantic): + let g:ale_buffer_info[bufnr('')].semantic_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(Empty then non-empty semantic errors should be handled): + let g:ale_buffer_info[bufnr('')].semantic_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then empty semantic errors should be handled): + let g:ale_buffer_info[bufnr('')].semantic_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', '')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then non-empty semantic errors should be handled): + let g:ale_buffer_info[bufnr('')].semantic_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Subsequent empty lists should be ignored - suggestion): + let g:ale_buffer_info[bufnr('')].suggestion_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(You should be able to disable suggestions): + let g:ale_lsp_suggestions = 0 + let g:ale_buffer_info[bufnr('')].suggestion_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', 'x')) + + Assert !g:ale_handle_loclist_called + +Execute(Empty then non-empty suggestion messages should be handled): + let g:ale_buffer_info[bufnr('')].suggestion_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then empt suggestion messages should be handled): + let g:ale_buffer_info[bufnr('')].suggestion_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', '')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then non-empty suggestion messages should be handled): + let g:ale_buffer_info[bufnr('')].suggestion_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', 'x')) + + Assert g:ale_handle_loclist_called diff --git a/vim-config/plugins/ale/test/test_regex_escaping.vader b/vim-config/plugins/ale/test/test_regex_escaping.vader new file mode 100644 index 00000000..b79b8c56 --- /dev/null +++ b/vim-config/plugins/ale/test/test_regex_escaping.vader @@ -0,0 +1,4 @@ +Execute(ale#util#EscapePCRE should escape strings for PCRE or RE2 appropriately): + AssertEqual '\\\^\$\*\+\?\.\(\)\|\{\}\[\]', ale#util#EscapePCRE('\^$*+?.()|{}[]') + AssertEqual 'abcABC09', ale#util#EscapePCRE('abcABC09') + AssertEqual '/', ale#util#EscapePCRE('/') diff --git a/vim-config/plugins/ale/test/test_rename.vader b/vim-config/plugins/ale/test/test_rename.vader new file mode 100644 index 00000000..42bcfd95 --- /dev/null +++ b/vim-config/plugins/ale/test/test_rename.vader @@ -0,0 +1,504 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('dummy.txt') + + let g:old_filename = expand('%:p') + let g:Callback = '' + let g:expr_list = [] + let g:message_list = [] + let g:handle_code_action_called = 0 + let g:code_actions = [] + let g:options = {} + let g:capability_checked = '' + let g:conn_id = v:null + let g:InitCallback = v:null + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/rename.vim + runtime autoload/ale/code_action.vim + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {}) + call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer) + + if a:linter.lsp is# 'tsserver' + call ale#lsp#MarkConnectionAsTsserver(g:conn_id) + endif + + let l:details = { + \ 'command': 'foobar', + \ 'buffer': a:buffer, + \ 'connection_id': g:conn_id, + \ 'project_root': '/foo/bar', + \} + + let g:InitCallback = {-> ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)} + endfunction + + function! ale#lsp#HasCapability(conn_id, capability) abort + let g:capability_checked = a:capability + + return 1 + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + + return 42 + endfunction + + function! ale#util#Execute(expr) abort + call add(g:expr_list, a:expr) + endfunction + + function! ale#code_action#HandleCodeAction(code_action, options) abort + let g:handle_code_action_called = 1 + Assert get(a:options, 'should_save') + call add(g:code_actions, a:code_action) + endfunction + + function! ale#util#Input(message, value) abort + return 'a-new-name' + endfunction + + call ale#rename#SetMap({ + \ 3: { + \ 'old_name': 'oldName', + \ 'new_name': 'aNewName', + \ }, + \}) + +After: + if g:conn_id isnot v:null + call ale#lsp#RemoveConnectionWithID(g:conn_id) + endif + + call ale#rename#SetMap({}) + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + unlet! g:capability_checked + unlet! g:InitCallback + unlet! g:old_filename + unlet! g:conn_id + unlet! g:Callback + unlet! g:message_list + unlet! g:expr_list + unlet! b:ale_linters + unlet! g:options + unlet! g:code_actions + unlet! g:handle_code_action_called + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/rename.vim + runtime autoload/ale/code_action.vim + +Execute(Other messages for the tsserver handler should be ignored): + call ale#rename#HandleTSServerResponse(1, {'command': 'foo'}) + AssertEqual g:handle_code_action_called, 0 + +Execute(Failed rename responses should be handled correctly): + call ale#rename#SetMap({3: {'old_name': 'oldName', 'new_name': 'a-test'}}) + call ale#rename#HandleTSServerResponse( + \ 1, + \ {'command': 'rename', 'request_seq': 3} + \) + AssertEqual g:handle_code_action_called, 0 + +Given typescript(Some typescript file): + foo + somelongerline + bazxyzxyzxyz + +Execute(Code actions from tsserver should be handled): + call ale#rename#HandleTSServerResponse(1, { + \ 'command': 'rename', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'locs': [ + \ { + \ 'file': '/foo/bar/file1.ts', + \ 'locs': [ + \ { + \ 'start': { + \ 'line': 1, + \ 'offset': 2, + \ }, + \ 'end': { + \ 'line': 3, + \ 'offset': 4, + \ }, + \ }, + \ ], + \ }, + \ { + \ 'file': '/foo/bar/file2.ts', + \ 'locs': [ + \ { + \ 'start': { + \ 'line': 10, + \ 'offset': 20, + \ }, + \ 'end': { + \ 'line': 30, + \ 'offset': 40, + \ }, + \ }, + \ ], + \ }, + \ ] + \ }, + \}) + + AssertEqual + \ [ + \ { + \ 'description': 'rename', + \ 'changes': [ + \ { + \ 'fileName': '/foo/bar/file1.ts', + \ 'textChanges': [ + \ { + \ 'start': { + \ 'line': 1, + \ 'offset': 2, + \ }, + \ 'end': { + \ 'line': 3, + \ 'offset': 4, + \ }, + \ 'newText': 'aNewName', + \ }, + \ ], + \ }, + \ { + \ 'fileName': '/foo/bar/file2.ts', + \ 'textChanges': [ + \ { + \ 'start': { + \ 'line': 10, + \ 'offset': 20, + \ }, + \ 'end': { + \ 'line': 30, + \ 'offset': 40, + \ }, + \ 'newText': 'aNewName', + \ }, + \ ], + \ }, + \ ], + \ } + \ ], + \ g:code_actions + +Execute(HandleTSServerResponse does nothing when no data in rename_map): + call ale#rename#HandleTSServerResponse(1, { + \ 'command': 'rename', + \ 'request_seq': -9, + \ 'success': v:true, + \ 'body': {} + \}) + + AssertEqual g:handle_code_action_called, 0 + +Execute(Prints a tsserver error message when unsuccessful): + call ale#rename#HandleTSServerResponse(1, { + \ 'command': 'rename', + \ 'request_seq': 3, + \ 'success': v:false, + \ 'message': 'This symbol cannot be renamed', + \}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''Error renaming "oldName" to: "aNewName". ' . + \ 'Reason: This symbol cannot be renamed'''], g:expr_list + +Execute(Does nothing when no changes): + call ale#rename#HandleTSServerResponse(1, { + \ 'command': 'rename', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'locs': [] + \ } + \}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''Error renaming "oldName" to: "aNewName"'''], g:expr_list + +Execute(tsserver rename requests should be sent): + call ale#rename#SetMap({}) + call ale#linter#Reset() + + runtime ale_linters/typescript/tsserver.vim + call setpos('.', [bufnr(''), 2, 5, 0]) + + ALERename + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'rename', g:capability_checked + AssertEqual + \ 'function(''ale#rename#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@rename', { + \ 'file': expand('%:p'), + \ 'line': 2, + \ 'offset': 5, + \ 'arguments': { + \ 'findInComments': g:ale_rename_tsserver_find_in_comments, + \ 'findInStrings': g:ale_rename_tsserver_find_in_strings, + \ }, + \ }] + \ ], + \ g:message_list + AssertEqual {'42': {'old_name': 'somelongerline', 'new_name': 'a-new-name'}}, + \ ale#rename#GetMap() + +Given python(Some Python file): + foo + somelongerline + bazxyzxyzxyz + +Execute(Code actions from LSP should be handled): + call ale#rename#HandleLSPResponse(1, { + \ 'id': 3, + \ 'result': { + \ 'changes': { + \ 'file:///foo/bar/file1.ts': [ + \ { + \ 'range': { + \ 'start': { + \ 'line': 1, + \ 'character': 2, + \ }, + \ 'end': { + \ 'line': 3, + \ 'character': 4, + \ }, + \ }, + \ 'newText': 'bla123' + \ }, + \ ], + \ }, + \ }, + \}) + + AssertEqual + \ [ + \ { + \ 'description': 'rename', + \ 'changes': [ + \ { + \ 'fileName': '/foo/bar/file1.ts', + \ 'textChanges': [ + \ { + \ 'start': { + \ 'line': 2, + \ 'offset': 3, + \ }, + \ 'end': { + \ 'line': 4, + \ 'offset': 5, + \ }, + \ 'newText': 'bla123', + \ }, + \ ], + \ }, + \ ], + \ } + \ ], + \ g:code_actions + +Execute(DocumentChanges from LSP should be handled): + call ale#rename#HandleLSPResponse(1, { + \ 'id': 3, + \ 'result': { + \ 'documentChanges': [ + \ { + \ 'textDocument': { + \ 'version': 1.0, + \ 'uri': 'file:///foo/bar/file1.ts', + \ }, + \ 'edits': [ + \ { + \ 'range': { + \ 'start': { + \ 'line': 1, + \ 'character': 2, + \ }, + \ 'end': { + \ 'line': 3, + \ 'character': 4, + \ }, + \ }, + \ 'newText': 'bla123', + \ }, + \ ], + \ }, + \ ], + \ }, + \}) + + AssertEqual + \ [ + \ { + \ 'description': 'rename', + \ 'changes': [ + \ { + \ 'fileName': '/foo/bar/file1.ts', + \ 'textChanges': [ + \ { + \ 'start': { + \ 'line': 2, + \ 'offset': 3, + \ }, + \ 'end': { + \ 'line': 4, + \ 'offset': 5, + \ }, + \ 'newText': 'bla123', + \ }, + \ ], + \ }, + \ ], + \ } + \ ], + \ g:code_actions + +Execute(Single DocumentChange from LSP should be handled): + call ale#rename#HandleLSPResponse(1, { + \ 'id': 3, + \ 'result': { + \ 'documentChanges': { + \ 'textDocument': { + \ 'version': 1.0, + \ 'uri': 'file:///foo/bar/file1.ts', + \ }, + \ 'edits': [ + \ { + \ 'range': { + \ 'start': { + \ 'line': 1, + \ 'character': 2, + \ }, + \ 'end': { + \ 'line': 3, + \ 'character': 4, + \ }, + \ }, + \ 'newText': 'bla123', + \ }, + \ ], + \ }, + \ }, + \}) + + AssertEqual + \ [ + \ { + \ 'description': 'rename', + \ 'changes': [ + \ { + \ 'fileName': '/foo/bar/file1.ts', + \ 'textChanges': [ + \ { + \ 'start': { + \ 'line': 2, + \ 'offset': 3, + \ }, + \ 'end': { + \ 'line': 4, + \ 'offset': 5, + \ }, + \ 'newText': 'bla123', + \ }, + \ ], + \ }, + \ ], + \ } + \ ], + \ g:code_actions +Execute(LSP should perform no action when no result): + call ale#rename#HandleLSPResponse(1, { + \ 'id': 3, + \}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''No rename result received from server'''], g:expr_list + +Execute(LSP should perform no action when no changes): + call ale#rename#HandleLSPResponse(1, { + \ 'id': 3, + \ 'result': {}, + \}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''No changes received from server'''], g:expr_list + +Execute(LSP should perform no action when changes is empty): + call ale#rename#HandleLSPResponse(1, { + \ 'id': 3, + \ 'result': { + \ 'changes': [], + \ }, + \}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''No changes received from server'''], g:expr_list + +Execute(LSP rename requests should be sent): + call ale#rename#SetMap({}) + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + call setpos('.', [bufnr(''), 1, 5, 0]) + + ALERename + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'rename', g:capability_checked + AssertEqual + \ 'function(''ale#rename#HandleLSPResponse'')', + \ string(g:Callback) + + AssertEqual + \ [ + \ [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}] + \ }], + \ [0, 'textDocument/rename', { + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}, + \ 'position': {'line': 0, 'character': 2}, + \ 'newName': 'a-new-name', + \ }], + \ ], + \ g:message_list + + AssertEqual {'42': {'old_name': 'foo', 'new_name': 'a-new-name'}}, + \ ale#rename#GetMap() diff --git a/vim-config/plugins/ale/test/test_resolve_local_path.vader b/vim-config/plugins/ale/test/test_resolve_local_path.vader new file mode 100644 index 00000000..d8a8ec52 --- /dev/null +++ b/vim-config/plugins/ale/test/test_resolve_local_path.vader @@ -0,0 +1,17 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + +After: + call ale#test#RestoreDirectory() + +Execute(We should be able to find the local version of a file): + call ale#test#SetFilename('test-files/top/middle/bottom/dummy.txt') + + AssertEqual + \ ale#path#Simplify(expand('%:p:h:h:h:h:h') . '/test-files/top/example.ini'), + \ ale#path#ResolveLocalPath(bufnr('%'), 'example.ini', '/global/config.ini') + +Execute(We shouldn't find anything for files which don't match): + AssertEqual + \ '/global/config.ini', + \ ale#path#ResolveLocalPath(bufnr('%'), 'missing.ini', '/global/config.ini') diff --git a/vim-config/plugins/ale/test/test_results_not_cleared_when_opening_loclist.vader b/vim-config/plugins/ale/test/test_results_not_cleared_when_opening_loclist.vader new file mode 100644 index 00000000..5621eb35 --- /dev/null +++ b/vim-config/plugins/ale/test/test_results_not_cleared_when_opening_loclist.vader @@ -0,0 +1,30 @@ +Before: + Save g:ale_buffer_info + + call ale#linter#Reset() + +After: + Restore + + call setloclist(0, []) + call clearmatches() + call ale#sign#Clear() + +Given foobar (Some file): + abc + +Execute(The loclist shouldn't be cleared when opening the loclist): + call ale#engine#InitBufferInfo(bufnr('')) + let g:ale_buffer_info[bufnr('')].loclist = [ + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 2}, + \] + call setloclist(0, g:ale_buffer_info[bufnr('')].loclist) + + " The cleanup function is called when the loclist window is closed. + " If some cleanup is done for this buffer, for which nothing is wrong, + " then the loclist for the window, which is the same window as the window + " we are checking, will be cleared. + :lopen + :q + + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()), 'The loclist was cleared' diff --git a/vim-config/plugins/ale/test/test_sandbox_execution.vader b/vim-config/plugins/ale/test/test_sandbox_execution.vader new file mode 100644 index 00000000..cf994ce8 --- /dev/null +++ b/vim-config/plugins/ale/test/test_sandbox_execution.vader @@ -0,0 +1,103 @@ +Before: + function! TestCallback(buffer, output) + return [ + \ { + \ 'lnum': 1, + \ 'bufnr': 1, + \ 'vcol': 0, + \ 'linter_name': 'testlinter', + \ 'nr': -1, + \ 'type': 'E', + \ 'col': 1, + \ 'text': 'Test Error', + \ }, + \] + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': 'echo', + \ 'command': 'echo', + \}) + + let g:ale_buffer_info = {} + +After: + unlet! b:in_sandbox + unlet! b:result + + delfunction TestCallback + call ale#linter#Reset() + let g:ale_buffer_info = {} + + +Given foobar (Some imaginary filetype): + foo + bar + baz + +Execute(ale#util#InSandbox should return 1 when in a sandbox): + sandbox let b:in_sandbox = ale#util#InSandbox() + + Assert b:in_sandbox, 'ale#util#InSandbox() returned 0 for a sandbox command' + +Execute(ALE shouldn't blow up when run from a sandbox): + AssertEqual 'foobar', &filetype + + sandbox call ale#Queue(0) + sandbox call ale#Queue(1) + +Execute(ALE shouldn't blow up if file cleanup happens in a sandbox): + " Make a call to an engine function first, so the function will be defined + " before we make the sandbox call. + " + " You are not allowed to define any functions in the sandbox. + call ale#engine#InitBufferInfo(3) + + let g:ale_buffer_info[3] = { + \ 'temporary_file_list': ['/tmp/foo'], + \ 'temporary_directory_list': ['/tmp/bar'], + \} + sandbox call ale#command#RemoveManagedFiles(3) + + AssertEqual ['/tmp/foo'], g:ale_buffer_info[3].temporary_file_list + AssertEqual ['/tmp/bar'], g:ale_buffer_info[3].temporary_directory_list + +Execute(You shouldn't be able to define linters from the sandbox): + call ale#linter#Reset() + call ale#linter#PreventLoading('testft') + + AssertThrows sandbox call ale#linter#Define('testft', { + \ 'name': 'testlinter', + \ 'output_stream': 'stdout', + \ 'executable': 'testlinter', + \ 'command': 'testlinter', + \ 'callback': 'testCB', + \}) + AssertEqual 'Vim(let):E48: Not allowed in sandbox', g:vader_exception + AssertEqual [], ale#linter#GetAll(['testft']) + +Execute(You shouldn't be able to register fixers from the sandbox): + call ale#fix#registry#Clear() + AssertThrows sandbox call ale#fix#registry#Add('prettier', '', ['javascript'], 'prettier') + AssertEqual 'Vim(let):E48: Not allowed in sandbox', g:vader_exception + AssertEqual [], ale#fix#registry#CompleteFixers('', 'ALEFix ', 7) + +Execute(You shouldn't be able to get linters from the sandbox, to prevent tampering): + AssertThrows sandbox call ale#linter#GetLintersLoaded() + AssertEqual 'Vim(let):E48: Not allowed in sandbox', g:vader_exception + + call ale#linter#Reset() + + sandbox let b:result = ale#linter#GetAll(['testft']) + + AssertEqual 0, len(b:result) + + let b:result = ale#linter#GetAll(['testft']) + + AssertEqual 1, len(b:result) + + sandbox let b:result = ale#linter#GetAll(['testft']) + + AssertEqual 0, len(b:result) diff --git a/vim-config/plugins/ale/test/test_semver_utils.vader b/vim-config/plugins/ale/test/test_semver_utils.vader new file mode 100644 index 00000000..b38feb06 --- /dev/null +++ b/vim-config/plugins/ale/test/test_semver_utils.vader @@ -0,0 +1,43 @@ +After: + call ale#semver#ResetVersionCache() + +Execute(ParseVersion should return the version from the lines of output): + " We should be able to parse the semver string from flake8 + AssertEqual [3, 0, 4], ale#semver#ParseVersion([ + \ '3.0.4 (mccabe: 0.5.2, pyflakes: 1.2.3, pycodestyle: 2.0.0) CPython 2.7.12 on Linux', + \ '1.2.3', + \]) + +Execute(ParseVersion should return an empty list when no vesrion can be found): + AssertEqual [], ale#semver#ParseVersion(['x']) + AssertEqual [], ale#semver#ParseVersion([]) + +Execute(ParseVersion should tolerate missing patch numbers): + " This goes against the semver spec, but we handle it anyway. + AssertEqual [3, 4, 0], ale#semver#ParseVersion(['Version 3.4']) + +Execute(GTE should compare triples correctly): + Assert ale#semver#GTE([3, 0, 4], [3, 0, 0]) + Assert ale#semver#GTE([3, 0, 0], [3, 0, 0]) + Assert ale#semver#GTE([3, 0, 0], [2, 0, 0]) + Assert ale#semver#GTE([3, 1, 0], [3, 1, 0]) + Assert ale#semver#GTE([3, 2, 0], [3, 1, 0]) + Assert ale#semver#GTE([3, 2, 2], [3, 1, 6]) + Assert ale#semver#GTE([3, 2, 5], [3, 2, 5]) + Assert ale#semver#GTE([3, 2, 6], [3, 2, 5]) + Assert !ale#semver#GTE([2, 9, 1], [3, 0, 0]) + Assert !ale#semver#GTE([3, 2, 3], [3, 3, 3]) + Assert !ale#semver#GTE([3, 3, 2], [3, 3, 3]) + +Execute(GTE should compare pairs correctly): + Assert ale#semver#GTE([3, 0], [3, 0, 0]) + Assert ale#semver#GTE([3, 0], [3, 0]) + Assert ale#semver#GTE([3, 1], [3, 0]) + Assert ale#semver#GTE([3, 1], [3, 0, 0]) + Assert ale#semver#GTE([3, 0, 1], [3, 0]) + Assert !ale#semver#GTE([3, 0], [3, 0, 1]) + Assert !ale#semver#GTE([3, 0], [3, 1]) + Assert !ale#semver#GTE([2, 9, 11], [3, 0]) + +Execute(GTE should permit the LHS to be an empty List): + Assert !ale#semver#GTE([], [0, 0, 0]) diff --git a/vim-config/plugins/ale/test/test_set_list_timers.vader b/vim-config/plugins/ale/test/test_set_list_timers.vader new file mode 100644 index 00000000..e53b97a4 --- /dev/null +++ b/vim-config/plugins/ale/test/test_set_list_timers.vader @@ -0,0 +1,29 @@ +Before: + Save g:ale_set_lists_synchronously + Save g:ale_open_list + + let g:ale_set_lists_synchronously = 0 + +After: + Restore + + sleep 1ms + call setloclist(0, []) + lclose + +Execute(The SetLists function should work when run in a timer): + call ale#list#SetLists(bufnr(''), [ + \ {'bufnr': bufnr(''), 'lnum': 5, 'col': 5, 'text': 'x', 'type': 'E'}, + \]) + sleep 1ms + AssertEqual [{ + \ 'lnum': 5, + \ 'bufnr': bufnr(''), + \ 'col': 5, + \ 'text': 'x', + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': 0, + \ 'type': 'E', + \ 'pattern': '', + \}], ale#test#GetLoclistWithoutModule() diff --git a/vim-config/plugins/ale/test/test_setting_loclist_from_another_buffer.vader b/vim-config/plugins/ale/test/test_setting_loclist_from_another_buffer.vader new file mode 100644 index 00000000..028ffb1e --- /dev/null +++ b/vim-config/plugins/ale/test/test_setting_loclist_from_another_buffer.vader @@ -0,0 +1,26 @@ +Before: + Save g:ale_buffer_info + + let g:ale_buffer_info = { + \ bufnr(''): { + \ 'loclist': [{'bufnr': bufnr(''), 'lnum': 4, 'col': 1, 'text': 'foo'}] + \ }, + \} + + let g:original_buffer = bufnr('%') + noautocmd new + +After: + Restore + + unlet! g:original_buffer + +Execute(Errors should be set in the loclist for the original buffer, not the new one): + call ale#list#SetLists( + \ g:original_buffer, + \ g:ale_buffer_info[(g:original_buffer)].loclist, + \ ) + + AssertEqual [], ale#test#GetLoclistWithoutModule() + AssertEqual 1, len(getloclist(bufwinid(g:original_buffer))) + AssertEqual 'foo', getloclist(bufwinid(g:original_buffer))[0].text diff --git a/vim-config/plugins/ale/test/test_setting_problems_found_in_previous_buffers.vader b/vim-config/plugins/ale/test/test_setting_problems_found_in_previous_buffers.vader new file mode 100644 index 00000000..a5c8e0d3 --- /dev/null +++ b/vim-config/plugins/ale/test/test_setting_problems_found_in_previous_buffers.vader @@ -0,0 +1,98 @@ +Before: + Save g:ale_buffer_info + Save &filetype + Save g:ale_set_lists_synchronously + + let g:ale_set_lists_synchronously = 1 + + " Set up items in other buffers which should set in this one. + let g:ale_buffer_info = {} + call ale#engine#InitBufferInfo(bufnr('') + 1) + let g:ale_buffer_info[bufnr('') + 1].loclist = + \ ale#engine#FixLocList(bufnr('') + 1, 'linter_one', 0, [ + \ {'lnum': 1, 'filename': expand('%:p'), 'text': 'foo'}, + \ {'lnum': 2, 'filename': expand('%:p'), 'text': 'bar'}, + \ {'lnum': 2, 'text': 'ignore this one'}, + \ ]) + call ale#engine#InitBufferInfo(bufnr('') + 2) + let g:ale_buffer_info[bufnr('') + 2].loclist = + \ ale#engine#FixLocList(bufnr('') + 2, 'linter_one', 0, [ + \ {'lnum': 1, 'filename': expand('%:p'), 'text': 'foo'}, + \ {'lnum': 3, 'filename': expand('%:p'), 'text': 'baz'}, + \ {'lnum': 5, 'text': 'ignore this one'}, + \ ]) + + call ale#linter#Define('foobar', { + \ 'name': 'linter_one', + \ 'callback': 'WhoCares', + \ 'executable': 'echo', + \ 'command': 'sleep 1000', + \ 'lint_file': 1, + \}) + +After: + call ale#engine#Cleanup(bufnr('')) + Restore + call ale#linter#Reset() + + " Items and markers, etc. + call setloclist(0, []) + call clearmatches() + call ale#sign#Clear() + +Given foobar(A file with some lines): + foo + bar + baz + +Execute(Problems found from previously opened buffers should be set when linting for the first time): + call ale#engine#RunLinters(bufnr(''), ale#linter#Get(&filetype), 0) + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'bufnr': bufnr(''), + \ 'col': 0, + \ 'filename': expand('%:p'), + \ 'linter_name': 'linter_one', + \ 'nr': -1, + \ 'type': 'E', + \ 'vcol': 0, + \ 'text': 'foo', + \ 'sign_id': 1000001, + \ }, + \ { + \ 'lnum': 2, + \ 'bufnr': bufnr(''), + \ 'col': 0, + \ 'filename': expand('%:p'), + \ 'linter_name': 'linter_one', + \ 'nr': -1, + \ 'type': 'E', + \ 'vcol': 0, + \ 'text': 'bar', + \ 'sign_id': 1000002, + \ }, + \ { + \ 'lnum': 3, + \ 'bufnr': bufnr(''), + \ 'col': 0, + \ 'filename': expand('%:p'), + \ 'linter_name': 'linter_one', + \ 'nr': -1, + \ 'type': 'E', + \ 'vcol': 0, + \ 'text': 'baz', + \ 'sign_id': 1000003, + \ }, + \ ], + \ g:ale_buffer_info[bufnr('')].loclist + + AssertEqual + \ [ + \ {'lnum': 1, 'bufnr': bufnr(''), 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'E', 'pattern': '', 'text': 'foo'}, + \ {'lnum': 2, 'bufnr': bufnr(''), 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'E', 'pattern': '', 'text': 'bar'}, + \ {'lnum': 3, 'bufnr': bufnr(''), 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'E', 'pattern': '', 'text': 'baz'}, + \ ], + \ ale#test#GetLoclistWithoutModule() diff --git a/vim-config/plugins/ale/test/test_shell_detection.vader b/vim-config/plugins/ale/test/test_shell_detection.vader new file mode 100644 index 00000000..11d801c3 --- /dev/null +++ b/vim-config/plugins/ale/test/test_shell_detection.vader @@ -0,0 +1,177 @@ +Before: + runtime ale_linters/sh/shell.vim + runtime ale_linters/sh/shellcheck.vim + +After: + call ale#linter#Reset() + + unlet! b:is_bash + unlet! b:is_sh + unlet! b:is_kornshell + +Given(A file with a Bash hashbang): + #!/bin/bash + +Execute(/bin/bash should be detected appropriately): + AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr('')) + AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with /bin/sh): + #!/usr/bin/env sh -eu --foobar + +Execute(/bin/sh should be detected appropriately): + AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr('')) + AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with bash as an argument to env): + #!/usr/bin/env bash + +Execute(/usr/bin/env bash should be detected appropriately): + AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr('')) + AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a tcsh hash bang and arguments): + #!/usr/bin/env tcsh -eu --foobar + +Execute(tcsh should be detected appropriately): + AssertEqual 'tcsh', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'tcsh', ale_linters#sh#shell#GetExecutable(bufnr('')) + AssertEqual 'tcsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a zsh hash bang and arguments): + #!/usr/bin/env zsh -eu --foobar + +Execute(zsh should be detected appropriately): + AssertEqual 'zsh', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'zsh', ale_linters#sh#shell#GetExecutable(bufnr('')) + AssertEqual 'zsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a csh hash bang and arguments): + #!/usr/bin/env csh -eu --foobar + +Execute(csh should be detected appropriately): + AssertEqual 'csh', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'csh', ale_linters#sh#shell#GetExecutable(bufnr('')) + AssertEqual 'csh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a ksh hashbang): + #!/bin/ksh + +Execute(/bin/ksh should be detected appropriately): + AssertEqual 'ksh', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'ksh', ale_linters#sh#shell#GetExecutable(bufnr('')) + AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a ksh as an argument to env): + #!/usr/bin/env ksh + +Execute(ksh should be detected appropriately): + AssertEqual 'ksh', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'ksh', ale_linters#sh#shell#GetExecutable(bufnr('')) + AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a sh hash bang and arguments): + #!/usr/bin/env sh -eu --foobar + +Execute(sh should be detected appropriately): + AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr('')) + AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file without a hashbang): + +Execute(The bash dialect should be used for shellcheck if b:is_bash is 1): + let b:is_bash = 1 + + AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Execute(The sh dialect should be used for shellcheck if b:is_sh is 1): + let b:is_sh = 1 + + AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Execute(The ksh dialect should be used for shellcheck if b:is_kornshell is 1): + let b:is_kornshell = 1 + + AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Execute(The filetype should be used as the default shell type when there is no hashbang line): + set filetype=zsh + AssertEqual 'zsh', ale#handlers#sh#GetShellType(bufnr('')) + + set filetype=tcsh + AssertEqual 'tcsh', ale#handlers#sh#GetShellType(bufnr('')) + + set filetype=python + AssertEqual '', ale#handlers#sh#GetShellType(bufnr('')) + +Given(A file with /bin/ash): + #!/bin/ash + +Execute(The ash dialect should be used for the shell and the base function): + AssertEqual 'ash', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'ash', ale_linters#sh#shell#GetExecutable(bufnr('')) + +Execute(dash should be used for shellcheck, which has no ash dialect): + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with /bin/dash): + #!/bin/dash + +Execute(The dash dialect should be used for the shell and the base function): + AssertEqual 'dash', ale#handlers#sh#GetShellType(bufnr('')) + AssertEqual 'dash', ale_linters#sh#shell#GetExecutable(bufnr('')) + +Execute(dash should be used for shellcheck): + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a Bash shellcheck shell directive): + # shellcheck shell=bash + +Execute(bash dialect should be detected appropriately): + AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a sh shellcheck shell directive): + #shellcheck shell=sh + +Execute(sh dialect should be detected appropriately): + AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a tcsh shellcheck shell directive): + # shellcheck shell=tcsh + +Execute(tcsh dialect should be detected appropriately): + AssertEqual 'tcsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a zsh shellcheck shell directive): + # shellcheck shell=zsh + +Execute(zsh dialect should be detected appropriately): + AssertEqual 'zsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a csh shellcheck shell directive): + # shellcheck shell=csh + +Execute(zsh dialect should be detected appropriately): + AssertEqual 'csh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a ksh shellcheck shell directive): + # shellcheck shell=ksh + +Execute(ksh dialect should be detected appropriately): + AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a dash shellcheck shell directive): + # shellcheck shell=dash + +Execute(dash dialect should be detected appropriately): + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a ash shellcheck shell directive): + # shellcheck shell=ash + +Execute(dash dialect should be detected for ash that shellcheck does not support): + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_should_do_nothing_conditions.vader b/vim-config/plugins/ale/test/test_should_do_nothing_conditions.vader new file mode 100644 index 00000000..6dfed555 --- /dev/null +++ b/vim-config/plugins/ale/test/test_should_do_nothing_conditions.vader @@ -0,0 +1,88 @@ +Before: + Save g:ale_filetype_blacklist + Save g:ale_maximum_file_size + Save g:ale_enabled + Save &l:statusline + + let b:fake_mode = 'n' + + call ale#test#SetDirectory('/testplugin/test') + + let b:funky_command_created = 0 + + runtime autoload/ale/util.vim + + function! ale#util#Mode(...) abort + return b:fake_mode + endfunction + + " We will test for the existence of this command, so create one if needed. + if !exists(':CtrlPFunky') + command CtrlPFunky echo + let b:funky_command_created = 1 + endif + +After: + Restore + + call ale#test#RestoreDirectory() + + if b:funky_command_created + delcommand CtrlPFunky + let b:funky_command_created = 0 + endif + + unlet! b:funky_command_created + unlet! b:fake_mode + + if &diff is 1 + let &diff = 0 + endif + + runtime autoload/ale/util.vim + +Given foobar(An empty file): +Execute(ALE shouldn't do much of anything for ctrlp-funky buffers): + Assert !ale#ShouldDoNothing(bufnr('')), 'The preliminary check failed' + + let &l:statusline = '%#CtrlPMode2# prt %*%#CtrlPMode1# line %* ={%#CtrlPMode1# funky %*}= <-> %=%<%#CtrlPMode2# %{getcwd()} %*' + + Assert ale#ShouldDoNothing(bufnr('')) + +Execute(ALE shouldn't try to check buffers with '.' as the filename): + AssertEqual + \ 0, + \ ale#ShouldDoNothing(bufnr('')), + \ 'ShouldDoNothing() was 1 for some other reason' + + silent! noautocmd file . + + Assert ale#ShouldDoNothing(bufnr('')) + +Execute(DoNothing should return 1 when the filetype is empty): + AssertEqual + \ 0, + \ ale#ShouldDoNothing(bufnr('')), + \ 'ShouldDoNothing() was 1 for some other reason' + + set filetype= + + AssertEqual 1, ale#ShouldDoNothing(bufnr('')) + +Execute(DoNothing should return 1 when an operator is pending): + let b:fake_mode = 'no' + + AssertEqual 1, ale#ShouldDoNothing(bufnr('')) + +Execute(DoNothing should return 1 for diff buffers): + let &diff = 1 + + AssertEqual 1, ale#ShouldDoNothing(bufnr('')) + +Execute(The DoNothing check should work if the ALE globals aren't defined): + unlet! g:ale_filetype_blacklist + unlet! g:ale_maximum_file_size + unlet! g:ale_enabled + + " This shouldn't throw exceptions. + call ale#ShouldDoNothing(bufnr('')) diff --git a/vim-config/plugins/ale/test/test_sml_command.vader b/vim-config/plugins/ale/test/test_sml_command.vader new file mode 100644 index 00000000..e89486c4 --- /dev/null +++ b/vim-config/plugins/ale/test/test_sml_command.vader @@ -0,0 +1,45 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(smlnj finds CM file if it exists): + call ale#test#SetFilename('test-files/smlnj/cm/foo.sml') + + AssertEqual + \ ale#test#GetFilename('test-files/smlnj/cm/sources.cm'), + \ ale#handlers#sml#GetCmFile(bufnr('%')) + +Execute(smlnj finds CM file by searching upwards): + call ale#test#SetFilename('test-files/smlnj/cm/path/to/bar.sml') + + AssertEqual + \ ale#test#GetFilename('test-files/smlnj/cm/sources.cm'), + \ ale#handlers#sml#GetCmFile(bufnr('%')) + +Execute(smlnj returns '' when no CM file found): + call ale#test#SetFilename('test-files/smlnj/file/qux.sml') + + AssertEqual '', ale#handlers#sml#GetCmFile(bufnr('%')) + +Execute(CM-project mode enabled when CM file found): + call ale#test#SetFilename('test-files/smlnj/cm/foo.sml') + + AssertEqual 'sml', ale#handlers#sml#GetExecutableSmlnjCm(bufnr('%')) + +Execute(single-file mode disabled when CM file found): + call ale#test#SetFilename('test-files/smlnj/cm/foo.sml') + + AssertEqual '', ale#handlers#sml#GetExecutableSmlnjFile(bufnr('%')) + +Execute(CM-project mode disabled when CM file not found): + call ale#test#SetFilename('test-files/smlnj/file/qux.sml') + + AssertEqual '', ale#handlers#sml#GetExecutableSmlnjCm(bufnr('%')) + +Execute(single-file mode enabled when CM file found): + call ale#test#SetFilename('test-files/smlnj/file/qux.sml') + + AssertEqual 'sml', ale#handlers#sml#GetExecutableSmlnjFile(bufnr('%')) diff --git a/vim-config/plugins/ale/test/test_socket_connections.vader b/vim-config/plugins/ale/test/test_socket_connections.vader new file mode 100644 index 00000000..c59b942d --- /dev/null +++ b/vim-config/plugins/ale/test/test_socket_connections.vader @@ -0,0 +1,139 @@ +Before: + let g:can_run_socket_tests = !has('win32') + \ && (exists('*ch_close') || exists('*chanclose')) + + if g:can_run_socket_tests + call ale#test#SetDirectory('/testplugin/test') + + let g:channel_id_received = 0 + let g:data_received = '' + + function! WaitForData(expected_data, timeout) abort + let l:ticks = 0 + + while l:ticks < a:timeout + " Sleep first, so we can switch to the callback. + let l:ticks += 10 + sleep 10ms + + if g:data_received is# a:expected_data + break + endif + endwhile + endfunction + + function! TestCallback(channel_id, data) abort + let g:channel_id_received = a:channel_id + let g:data_received .= a:data + endfunction + + let g:port = 10347 + let g:pid_tcp = str2nr(system( + \ 'python' + \ . ' ' . ale#Escape(g:dir . '/script/dumb_tcp_server.py') + \ . ' ' . g:port + \)) + let g:pipe_path = tempname() + let g:pid_pipe = str2nr(system( + \ 'python' + \ . ' ' . ale#Escape(g:dir . '/script/dumb_named_pipe_server.py') + \ . ' ' . g:pipe_path + \)) + endif + +After: + if g:can_run_socket_tests + call ale#test#RestoreDirectory() + + unlet! g:channel_id_received + unlet! g:data_received + unlet! g:channel_id + + delfunction WaitForData + delfunction TestCallback + + if has_key(g:, 'pid_tcp') + call system('kill ' . g:pid_tcp) + endif + + if has_key(g:, 'pid_pipe') + call system('kill ' . g:pid_pipe) + endif + + unlet! g:pid_tcp + unlet! g:port + unlet! g:pid_pipe + unlet! g:pipe_path + endif + + unlet! g:can_run_socket_tests + +Execute(Sending and receiving connections to tcp sockets should work): + if g:can_run_socket_tests + let g:channel_id = ale#socket#Open( + \ '127.0.0.1:' . g:port, + \ {'callback': function('TestCallback')} + \) + + Assert g:channel_id >= 0, 'The socket was not opened!' + + call ale#socket#Send(g:channel_id, 'hello') + call ale#socket#Send(g:channel_id, ' world') + + AssertEqual 1, ale#socket#IsOpen(g:channel_id) + + " Wait up to 1 second for the expected data to arrive. + call WaitForData('hello world', 1000) + + AssertEqual g:channel_id, g:channel_id_received + AssertEqual 'hello world', g:data_received + AssertEqual '127.0.0.1:' . g:port, ale#socket#GetAddress(g:channel_id) + + call ale#socket#Close(g:channel_id) + + AssertEqual 0, ale#socket#IsOpen(g:channel_id) + AssertEqual '', ale#socket#GetAddress(g:channel_id) + endif + + " NeoVim versions which can't connect to sockets should just fail. + if has('nvim') && !exists('*chanclose') + AssertEqual -1, ale#socket#Open( + \ '127.0.0.1:1111', + \ {'callback': function('function')} + \) + endif + +Execute(Sending and receiving connections to named pipe sockets should work): + if g:can_run_socket_tests && has('nvim-0.4') + let g:channel_id = ale#socket#Open( + \ g:pipe_path, + \ {'callback': function('TestCallback')} + \) + + Assert g:channel_id >= 0, 'The socket was not opened!' + + call ale#socket#Send(g:channel_id, 'hello') + call ale#socket#Send(g:channel_id, ' world') + + AssertEqual 1, ale#socket#IsOpen(g:channel_id) + + " Wait up to 1 second for the expected data to arrive. + call WaitForData('hello world', 1000) + + AssertEqual g:channel_id, g:channel_id_received + AssertEqual 'hello world', g:data_received + AssertEqual g:pipe_path, ale#socket#GetAddress(g:channel_id) + + call ale#socket#Close(g:channel_id) + + AssertEqual 0, ale#socket#IsOpen(g:channel_id) + AssertEqual '', ale#socket#GetAddress(g:channel_id) + endif + + " NeoVim versions which can't connect to sockets should just fail. + if has('nvim-0.4') && !exists('*chanclose') + AssertEqual -1, ale#socket#Open( + \ g:pipe_path, + \ {'callback': function('function')} + \) + endif diff --git a/vim-config/plugins/ale/test/test_statusline.vader b/vim-config/plugins/ale/test/test_statusline.vader new file mode 100644 index 00000000..f76cbfa9 --- /dev/null +++ b/vim-config/plugins/ale/test/test_statusline.vader @@ -0,0 +1,157 @@ +Before: + Save g:ale_statusline_format + Save g:ale_buffer_info + + let g:ale_buffer_info = {} + + " A function for conveniently creating expected count objects. + function! Counts(data) abort + let l:res = { + \ '0': 0, + \ '1': 0, + \ 'error': 0, + \ 'warning': 0, + \ 'info': 0, + \ 'style_error': 0, + \ 'style_warning': 0, + \ 'total': 0, + \} + + for l:key in keys(a:data) + let l:res[l:key] = a:data[l:key] + endfor + + let l:res[0] = l:res.error + l:res.style_error + let l:res[1] = l:res.warning + l:res.style_warning + l:res.info + let l:res.total = l:res[0] + l:res[1] + + return l:res + endfunction + + " A test simplified loclist that will be used for some of the + " tests in this module. + let g:test_buffer_info = { + \ bufnr(''): { + \ 'loclist': [ + \ {'bufnr': bufnr('') - 1, 'type': 'E'}, + \ {'bufnr': bufnr('') - 1, 'type': 'E', 'sub_type': 'style'}, + \ {'bufnr': bufnr('') - 1, 'type': 'W'}, + \ {'bufnr': bufnr('') - 1, 'type': 'W', 'sub_type': 'style'}, + \ {'bufnr': bufnr('') - 1, 'type': 'I'}, + \ {'bufnr': bufnr(''), 'type': 'E'}, + \ {'bufnr': bufnr(''), 'type': 'E', 'sub_type': 'style'}, + \ {'bufnr': bufnr(''), 'type': 'E', 'sub_type': 'style'}, + \ {'bufnr': bufnr(''), 'type': 'W'}, + \ {'bufnr': bufnr(''), 'type': 'W'}, + \ {'bufnr': bufnr(''), 'type': 'W'}, + \ {'bufnr': bufnr(''), 'type': 'W', 'sub_type': 'style'}, + \ {'bufnr': bufnr(''), 'type': 'W', 'sub_type': 'style'}, + \ {'bufnr': bufnr(''), 'type': 'W', 'sub_type': 'style'}, + \ {'bufnr': bufnr(''), 'type': 'W', 'sub_type': 'style'}, + \ {'bufnr': bufnr(''), 'type': 'I'}, + \ {'bufnr': bufnr(''), 'type': 'I'}, + \ {'bufnr': bufnr(''), 'type': 'I'}, + \ {'bufnr': bufnr(''), 'type': 'I'}, + \ {'bufnr': bufnr(''), 'type': 'I'}, + \ {'bufnr': bufnr('') + 1, 'type': 'E'}, + \ {'bufnr': bufnr('') + 1, 'type': 'E', 'sub_type': 'style'}, + \ {'bufnr': bufnr('') + 1, 'type': 'W'}, + \ {'bufnr': bufnr('') + 1, 'type': 'W', 'sub_type': 'style'}, + \ {'bufnr': bufnr('') + 1, 'type': 'I'}, + \ ], + \ }, + \} +After: + Restore + + delfunction Counts + unlet g:test_buffer_info + +Execute (Count should be 0 when data is empty): + AssertEqual Counts({}), ale#statusline#Count(bufnr('')) + +Execute (FirstProblem should be 0 when data is empty): + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'error') + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'warning') + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'style_error') + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'style_warning') + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'info') + +Execute (Count should read data from the cache): + let g:ale_buffer_info = {'44': {'count': Counts({'error': 1, 'warning': 2})}} + AssertEqual Counts({'error': 1, 'warning': 2}), ale#statusline#Count(44) + +Execute (FirstProblem should read data from the cache): + let g:ale_buffer_info = + \{"44": + \{'count': 0, + \'first_problems': + \{'error': {'lnum': 3}, + \'warning': {'lnum': 44}, + \'style_error': {'lnum': 22}, + \'style_warning': {'lnum': 223}, + \'info': {'lnum': 2} + \} + \} + \} + AssertEqual {'lnum': 3}, ale#statusline#FirstProblem(44, 'error') + AssertEqual {'lnum': 44}, ale#statusline#FirstProblem(44, 'warning') + AssertEqual {'lnum': 223}, ale#statusline#FirstProblem(44, 'style_warning') + AssertEqual {'lnum': 22}, ale#statusline#FirstProblem(44, 'style_error') + AssertEqual {'lnum': 2}, ale#statusline#FirstProblem(44, 'info') + +Execute (The count should be correct after an update): + let g:ale_buffer_info = {'44': {}} + call ale#statusline#Update(44, []) + AssertEqual Counts({}), ale#statusline#Count(44) + +Execute (FirstProblem should be correct after an update): + let g:ale_buffer_info = {'44': {}} + call ale#statusline#Update(44, []) + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'error') + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'warning') + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'style_error') + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'style_warning') + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'info') + +Execute (Count should match the loclist): + let g:ale_buffer_info = g:test_buffer_info + AssertEqual { + \ 'error': 1, + \ 'style_error': 2, + \ 'warning': 3, + \ 'style_warning': 4, + \ 'info': 5, + \ '0': 3, + \ '1': 12, + \ 'total': 15, + \}, ale#statusline#Count(bufnr('')) + +Execute (FirstProblem should pull the first matching value from the loclist): + let g:ale_buffer_info = g:test_buffer_info + AssertEqual {'bufnr': bufnr(''), 'type': 'E'}, ale#statusline#FirstProblem(bufnr(''), 'error') + AssertEqual {'bufnr': bufnr(''), 'type': 'W'}, ale#statusline#FirstProblem(bufnr(''), 'warning') + AssertEqual {'bufnr': bufnr(''), 'type': 'E', 'sub_type': 'style'}, ale#statusline#FirstProblem(bufnr(''), 'style_error') + AssertEqual {'bufnr': bufnr(''), 'type': 'W', 'sub_type': 'style'}, ale#statusline#FirstProblem(bufnr(''), 'style_warning') + AssertEqual {'bufnr': bufnr(''), 'type': 'I'}, ale#statusline#FirstProblem(bufnr(''), 'info') + +Execute (Output should be empty for non-existent buffer): + let g:ale_buffer_info = g:test_buffer_info + AssertEqual Counts({}), ale#statusline#Count(9001) + AssertEqual {}, ale#statusline#FirstProblem(9001, 'error') + AssertEqual {}, ale#statusline#FirstProblem(9001, 'warning') + AssertEqual {}, ale#statusline#FirstProblem(9001, 'style_error') + AssertEqual {}, ale#statusline#FirstProblem(9001, 'style_warning') + AssertEqual {}, ale#statusline#FirstProblem(9001, 'info') + +Execute(ale#statusline#Update shouldn't blow up when globals are undefined): + unlet! g:ale_statusline_format + call ale#statusline#Update(1, []) + +Execute(ale#statusline#Count should return 0 counts when globals are undefined): + unlet! g:ale_statusline_format + AssertEqual Counts({}), ale#statusline#Count(1) + +Execute(FirstProblem should return an empty dict when globals are undefined): + unlet! g:ale_statusline_format + AssertEqual {}, ale#statusline#FirstProblem(bufnr(''), 'info') diff --git a/vim-config/plugins/ale/test/test_swift_find_project_root.vader b/vim-config/plugins/ale/test/test_swift_find_project_root.vader new file mode 100644 index 00000000..88a26021 --- /dev/null +++ b/vim-config/plugins/ale/test/test_swift_find_project_root.vader @@ -0,0 +1,18 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + +After: + call ale#test#RestoreDirectory() + +Execute(Detect root of Swift project with Package.swift correctly): + call ale#test#SetFilename('test-files/swift/swift-package-project/src/folder/dummy.swift') + AssertEqual + \ ale#path#Simplify(g:dir . '/test-files/swift/swift-package-project'), + \ ale#swift#FindProjectRoot(bufnr('')) + +Execute(Detect no root in case of non-Package.swift project): + call ale#test#SetFilename('test-files/swift/non-swift-package-project/src/folder/dummy.swift') + AssertEqual + \ '', + \ ale#swift#FindProjectRoot(bufnr('')) + diff --git a/vim-config/plugins/ale/test/test_symbol_search.vader b/vim-config/plugins/ale/test/test_symbol_search.vader new file mode 100644 index 00000000..382b2b40 --- /dev/null +++ b/vim-config/plugins/ale/test/test_symbol_search.vader @@ -0,0 +1,189 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('dummy.txt') + + let g:Callback = '' + let g:expr_list = [] + let g:message_list = [] + let g:preview_called = 0 + let g:item_list = [] + let g:options = {} + let g:capability_checked = '' + let g:conn_id = v:null + let g:InitCallback = v:null + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/preview.vim + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {}) + call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer) + let l:details = { + \ 'buffer': a:buffer, + \ 'connection_id': g:conn_id, + \ 'project_root': '/foo/bar', + \ 'language_id': 'python', + \} + + let g:InitCallback = {-> a:Callback(a:linter, l:details)} + endfunction + + function! ale#lsp#HasCapability(conn_id, capability) abort + let g:capability_checked = a:capability + + return 1 + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + + return 42 + endfunction + + function! ale#util#Execute(expr) abort + call add(g:expr_list, a:expr) + endfunction + + function! ale#preview#ShowSelection(item_list, options) abort + let g:preview_called = 1 + let g:item_list = a:item_list + let g:options = a:options + endfunction + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + unlet! g:capability_checked + unlet! g:InitCallback + unlet! g:conn_id + unlet! g:Callback + unlet! g:message_list + unlet! g:expr_list + unlet! b:ale_linters + unlet! g:options + unlet! g:item_list + unlet! g:preview_called + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/preview.vim + +Execute(Other messages for the LSP handler should be ignored): + call ale#symbol#HandleLSPResponse(1, {'command': 'foo'}) + +Execute(Failed symbol responses should be handled correctly): + call ale#symbol#SetMap({3: {}}) + call ale#symbol#HandleLSPResponse(1, {'id': 3}) + AssertEqual {}, ale#symbol#GetMap() + +Execute(LSP symbol responses should be handled): + call ale#symbol#SetMap({3: {}}) + call ale#symbol#HandleLSPResponse( + \ 1, + \ { + \ 'id': 3, + \ 'result': [ + \ { + \ 'name': 'foo', + \ 'location': { + \ 'uri': ale#path#ToURI(ale#path#Simplify(g:dir . '/completion_dummy_file')), + \ 'range': { + \ 'start': {'line': 2, 'character': 7}, + \ }, + \ }, + \ }, + \ { + \ 'name': 'foobar', + \ 'location': { + \ 'uri': ale#path#ToURI(ale#path#Simplify(g:dir . '/other_file')), + \ 'range': { + \ 'start': {'line': 7, 'character': 15}, + \ }, + \ }, + \ }, + \ ], + \ } + \) + + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Simplify(g:dir . '/completion_dummy_file'), + \ 'line': 3, + \ 'column': 8, + \ 'match': 'foo', + \ }, + \ { + \ 'filename': ale#path#Simplify(g:dir . '/other_file'), + \ 'line': 8, + \ 'column': 16, + \ 'match': 'foobar', + \ }, + \ ], + \ g:item_list + AssertEqual {}, ale#symbol#GetMap() + +Execute(Preview windows should not be opened for empty LSP symbol responses): + call ale#symbol#SetMap({3: {}}) + call ale#symbol#HandleLSPResponse( + \ 1, + \ { + \ 'id': 3, + \ 'result': [ + \ ], + \ } + \) + + Assert !g:preview_called + AssertEqual {}, ale#symbol#GetMap() + AssertEqual ['echom ''No symbols found.'''], g:expr_list + +Given python(Some Python file): + foo + somelongerline + bazxyzxyzxyz + +Execute(LSP symbol requests should be sent): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + call setpos('.', [bufnr(''), 1, 5, 0]) + + ALESymbolSearch foo bar + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'symbol_search', g:capability_checked + AssertEqual + \ 'function(''ale#symbol#HandleLSPResponse'')', + \ string(g:Callback) + + AssertEqual + \ [ + \ [0, 'workspace/symbol', {'query': 'foo bar'}], + \ ], + \ g:message_list + + AssertEqual {'42': {'buffer': bufnr(''), 'use_relative_paths': 0}}, ale#symbol#GetMap() + +Execute('-relative' argument should enable 'use_relative_paths' in HandleLSPResponse): + runtime ale_linters/python/pylsp.vim + let b:ale_linters = ['pylsp'] + call setpos('.', [bufnr(''), 1, 5, 0]) + + ALESymbolSearch -relative foo bar + + call g:InitCallback() + + AssertEqual {'42': {'buffer': bufnr(''), 'use_relative_paths': 1}}, ale#symbol#GetMap() diff --git a/vim-config/plugins/ale/test/test_temporary_file_management.vader b/vim-config/plugins/ale/test/test_temporary_file_management.vader new file mode 100644 index 00000000..bb735886 --- /dev/null +++ b/vim-config/plugins/ale/test/test_temporary_file_management.vader @@ -0,0 +1,146 @@ +Before: + Save g:ale_buffer_info + + let g:ale_buffer_info = {} + let g:ale_run_synchronously = 1 + + let g:command = 'echo test' + let g:filename = '' + let g:directory = '' + let g:preserved_directory = '' + + function! TestCommandCallback(buffer) abort + " We are registering a temporary file, so we should delete it. + let g:filename = tempname() + call writefile(['foo'], g:filename) + call ale#command#ManageFile(a:buffer, g:filename) + + " We are registering this directory appropriately, so we should delete + " the whole thing. + let g:directory = tempname() + call mkdir(g:directory) + call writefile(['foo'], g:directory . '/bar') + call ale#command#ManageDirectory(a:buffer, g:directory) + + " We are registering this directory as temporary file, so we + " shouldn't delete it. + let g:preserved_directory = tempname() + call mkdir(g:preserved_directory) + call writefile(['foo'], g:preserved_directory . '/bar') + call ale#command#ManageFile(a:buffer, g:preserved_directory) + + return g:command + endfunction + + function! TestCallback(buffer, output) abort + return [] + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'executable': has('win32') ? 'cmd' : 'echo', + \ 'callback': 'TestCallback', + \ 'command': function('TestCommandCallback'), + \}) + call ale#command#ClearData() + +After: + Restore + + if !empty(g:preserved_directory) + call delete(g:preserved_directory, 'rf') + endif + + unlet! g:ale_run_synchronously + unlet! g:command + unlet! g:filename + unlet! g:directory + unlet! g:preserved_directory + delfunction TestCommandCallback + delfunction TestCallback + call ale#linter#Reset() + call ale#command#ClearData() + +Given foobar (Some imaginary filetype): + foo + bar + baz + +Execute(ALE should delete managed files/directories appropriately after linting): + AssertEqual 'foobar', &filetype + + call ale#Queue(0) + call ale#test#FlushJobs() + + Assert !filereadable(g:filename), 'The temporary file was not deleted' + Assert !isdirectory(g:directory), 'The temporary directory was not deleted' + Assert isdirectory(g:preserved_directory), 'The temporary directory was not kept' + +Execute(ALE should delete managed files even if no command is run): + AssertEqual 'foobar', &filetype + + let g:command = '' + + call ale#Queue(0) + call ale#test#WaitForJobs(2000) + + Assert !filereadable(g:filename), 'The temporary file was not deleted' + Assert !isdirectory(g:directory), 'The temporary directory was not deleted' + Assert isdirectory(g:preserved_directory), 'The temporary directory was not kept' + +Execute(ALE should delete managed files when the buffer is removed): + call ale#engine#InitBufferInfo(bufnr('%')) + call TestCommandCallback(bufnr('%')) + call ale#engine#Cleanup(bufnr('%')) + + Assert !filereadable(g:filename), 'The temporary file was not deleted' + Assert !isdirectory(g:directory), 'The temporary directory was not deleted' + Assert isdirectory(g:preserved_directory), 'The tempoary directory was not kept' + +Execute(ALE should create and delete directories for ale#command#CreateDirectory()): + call ale#engine#InitBufferInfo(bufnr('%')) + + let b:dir = ale#command#CreateDirectory(bufnr('%')) + let b:dir2 = ale#command#CreateDirectory(bufnr('%')) + + Assert isdirectory(b:dir), 'The directory was not created' + + " We should get the correct file permissions. + " We want to ensure that the directory is not readable by 'other' + if has('unix') + AssertEqual 'rwxr-x---', getfperm(b:dir) + endif + + " The two directories shouldn't be the same. + AssertNotEqual b:dir2, b:dir + + call ale#engine#Cleanup(bufnr('%')) + + Assert !isdirectory(b:dir), 'The directory was not deleted' + Assert !isdirectory(b:dir2), 'The second directory was not deleted' + +Execute(ale#command#ManageFile should add the file even if the buffer info hasn't been set yet): + call ale#command#ManageFile(bufnr(''), '/foo/bar') + + AssertEqual + \ { + \ bufnr(''): { + \ 'jobs': {}, + \ 'file_list': ['/foo/bar'], + \ 'directory_list': [], + \ }, + \ }, + \ ale#command#GetData() + +Execute(ale#command#ManageDirectory should add the directory even if the buffer info hasn't been set yet): + call ale#command#ManageDirectory(bufnr(''), '/foo/bar') + + AssertEqual + \ { + \ bufnr(''): { + \ 'jobs': {}, + \ 'file_list': [], + \ 'directory_list': ['/foo/bar'], + \ }, + \ }, + \ ale#command#GetData() diff --git a/vim-config/plugins/ale/test/test_tmpdir_wrapper.vader b/vim-config/plugins/ale/test/test_tmpdir_wrapper.vader new file mode 100644 index 00000000..151b8943 --- /dev/null +++ b/vim-config/plugins/ale/test/test_tmpdir_wrapper.vader @@ -0,0 +1,32 @@ +Before: + let g:exists = exists('$TMPDIR') + let g:old_value = $TMPDIR + +After: + if g:exists + let $TMPDIR = g:old_value + else + silent! unlet! $TMPDIR + endif + + unlet! g:exists + unlet! g:old_value + +Execute(ale#util#Tempname shouldn't set $TMPDIR to an empty string if it isn't set): + " You can't run this test twice on old Vim versions. + if has('unix') + Assert ale#util#Tempname() =~# '^/tmp' + Assert !exists('$TMPDIR'), '$TMPDIR exists where it shouldn''t' + endif + +Execute(ale#util#Tempname shouldn't replace $TMPDIR and reset them to an empty string.): + if has('unix') + let $TMPDIR = '' + Assert ale#util#Tempname() =~# '^/tmp' + + if !has('nvim') + Assert exists('$TMPDIR'), '$TMPDIR doesn''t exist where it should' + endif + + AssertEqual '', $TMPDIR + endif diff --git a/vim-config/plugins/ale/test/test_vim8_processid_parsing.vader b/vim-config/plugins/ale/test/test_vim8_processid_parsing.vader new file mode 100644 index 00000000..26416b15 --- /dev/null +++ b/vim-config/plugins/ale/test/test_vim8_processid_parsing.vader @@ -0,0 +1,5 @@ +Execute(Vim8 Process ID parsing should work): + AssertEqual 123, ale#job#ParseVim8ProcessID('process 123 run') + AssertEqual 347, ale#job#ParseVim8ProcessID('process 347 failed') + AssertEqual 789, ale#job#ParseVim8ProcessID('process 789 dead') + AssertEqual 0, ale#job#ParseVim8ProcessID('no process') diff --git a/vim-config/plugins/ale/test/test_windows_escaping.vader b/vim-config/plugins/ale/test/test_windows_escaping.vader new file mode 100644 index 00000000..22cad888 --- /dev/null +++ b/vim-config/plugins/ale/test/test_windows_escaping.vader @@ -0,0 +1,42 @@ +Before: + Save &shell + let &shell = 'cmd.exe' + +After: + Restore + +Execute(ale#Escape for cmd.exe should allow not escape paths without special characters): + AssertEqual 'C:', ale#Escape('C:') + AssertEqual 'C:\', ale#Escape('C:\') + AssertEqual 'python', ale#Escape('python') + AssertEqual 'C:\foo\bar', ale#Escape('C:\foo\bar') + AssertEqual '/bar/baz', ale#Escape('/bar/baz') + AssertEqual 'nul', ale#Escape('nul') + AssertEqual '''foo''', ale#Escape('''foo''') + +Execute(ale#Escape for cmd.exe should escape Windows paths with spaces appropriately): + AssertEqual '"C:\foo bar\baz"', ale#Escape('C:\foo bar\baz') + AssertEqual '"^foo bar^"', ale#Escape('^foo bar^') + AssertEqual '"&foo bar&"', ale#Escape('&foo bar&') + AssertEqual '"|foo bar|"', ale#Escape('|foo bar|') + AssertEqual '"foo bar>"', ale#Escape('>foo bar>') + AssertEqual '"^foo bar^"', ale#Escape('^foo bar^') + AssertEqual '"''foo'' ''bar''"', ale#Escape('''foo'' ''bar''') + +Execute(ale#Escape for cmd.exe should use caret escapes on special characters): + AssertEqual '^^foo^^', ale#Escape('^foo^') + AssertEqual '^&foo^&', ale#Escape('&foo&') + AssertEqual '^|foo^|', ale#Escape('|foo|') + AssertEqual '^foo^>', ale#Escape('>foo>') + AssertEqual '^^foo^^', ale#Escape('^foo^') + AssertEqual '''foo''^^''bar''', ale#Escape('''foo''^''bar''') + +Execute(ale#Escape for cmd.exe should escape percent characters): + AssertEqual '%%foo%%', ale#Escape('%foo%') + AssertEqual 'C:\foo%%\bar\baz%%', ale#Escape('C:\foo%\bar\baz%') + AssertEqual '"C:\foo bar%%\baz%%"', ale#Escape('C:\foo bar%\baz%') + AssertEqual '^^%%foo%%', ale#Escape('^%foo%') + AssertEqual '"^%%foo%% %%bar%%"', ale#Escape('^%foo% %bar%') + AssertEqual '"^%%foo%% %%bar%% """""', ale#Escape('^%foo% %bar% ""') diff --git a/vim-config/plugins/ale/test/test_wrap_comand.vader b/vim-config/plugins/ale/test/test_wrap_comand.vader new file mode 100644 index 00000000..7ddb06a1 --- /dev/null +++ b/vim-config/plugins/ale/test/test_wrap_comand.vader @@ -0,0 +1,48 @@ +Before: + Save g:ale_command_wrapper + + let g:ale_command_wrapper = '' + + function! TestCommand(expected_part, input) abort + let l:expected = has('win32') + \ ? 'cmd /s/c "' . a:expected_part . '"' + \ : split(&shell) + split(&shellcmdflag) + [a:expected_part] + + AssertEqual l:expected, ale#job#PrepareCommand(bufnr(''), a:input) + endfunction + +After: + Restore + + unlet! b:ale_command_wrapper + + delfunction TestCommand + +Execute(The command wrapper should work with a nice command): + let b:ale_command_wrapper = 'nice -n 5' + + call TestCommand('nice -n 5 foo bar', 'foo bar') + +Execute(The command wrapper should work with a nice command with an explicit marker): + let b:ale_command_wrapper = 'nice -n 5 %*' + + call TestCommand('nice -n 5 foo bar', 'foo bar') + +Execute(Wrappers with spread arguments in the middle should be suppported): + let b:ale_command_wrapper = 'wrap %* --' + + call TestCommand('wrap foo bar --', 'foo bar') + +Execute(Wrappers with the command as one argument should be supported): + let b:ale_command_wrapper = 'wrap -c %@ -x' + + call TestCommand('wrap -c ' . ale#Escape('foo bar') . ' -x', 'foo bar') + +Execute(&& and ; should be moved to the front): + let b:ale_command_wrapper = 'wrap -c %@ -x' + + call TestCommand('foo && bar; wrap -c ' . ale#Escape('baz') . ' -x', 'foo && bar;baz') + + let b:ale_command_wrapper = 'nice -n 5' + + call TestCommand('foo && bar; nice -n 5 baz -z', 'foo && bar;baz -z') diff --git a/vim-config/plugins/ale/test/test_writefile_function.vader b/vim-config/plugins/ale/test/test_writefile_function.vader new file mode 100644 index 00000000..53a88331 --- /dev/null +++ b/vim-config/plugins/ale/test/test_writefile_function.vader @@ -0,0 +1,117 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + + let g:new_line_test_file = tempname() + +After: + noautocmd :e! ++ff=unix + setlocal buftype=nofile + + if filereadable(g:new_line_test_file) + call delete(g:new_line_test_file) + endif + + unlet! g:new_line_test_file + + call ale#test#RestoreDirectory() + +Given(A file with Windows line ending characters): + first + second + third + +Execute(Carriage returns should be included for ale#util#Writefile): + call ale#test#SetFilename(g:new_line_test_file) + + setlocal buftype= + noautocmd :w + noautocmd :e! ++ff=dos + + call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file) + + AssertEqual + \ ["first\r", "second\r", "third\r", ''], + \ readfile(g:new_line_test_file, 'b') + +Given(A file with extra carriage returns): + first + second + third + fourth + +Execute(Carriage returns should be de-depulicated): + call ale#test#SetFilename(g:new_line_test_file) + + setlocal buftype= + noautocmd :w + noautocmd :e! ++ff=dos + + call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file) + + AssertEqual + \ ["first\r", "second\r", "third\r", "fourth\r", ''], + \ readfile(g:new_line_test_file, 'b') + +Given(A file with Unix line ending characters): + first + second + third + +Execute(Unix file lines should be written as normal): + call ale#test#SetFilename(g:new_line_test_file) + + setlocal buftype= + noautocmd :w + noautocmd :e! ++ff=unix + + call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file) + + AssertEqual + \ ['first', 'second', 'third', ''], + \ readfile(g:new_line_test_file, 'b') + +Execute(Newline at end of file should be preserved even when nofixeol): + call ale#test#SetFilename(g:new_line_test_file) + + setlocal buftype= + noautocmd :w + noautocmd :e! ++ff=unix + set eol + set nofixeol + + call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file) + + AssertEqual + \ ['first', 'second', 'third', ''], + \ readfile(g:new_line_test_file, 'b') + +Execute(Newline should not be appended on write when noeol and nofixeol): + call ale#test#SetFilename(g:new_line_test_file) + + setlocal buftype= + noautocmd :w + noautocmd :e! ++ff=unix + set noeol + set nofixeol + + call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file) + + AssertEqual + \ ['first', 'second', 'third'], + \ readfile(g:new_line_test_file, 'b') + +Execute(Newline should be appended on write when noeol and fixeol): + call ale#test#SetFilename(g:new_line_test_file) + + setlocal buftype= + noautocmd :w + noautocmd :e! ++ff=unix + set noeol + set fixeol + + call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file) + + AssertEqual + \ ['first', 'second', 'third', ''], + \ readfile(g:new_line_test_file, 'b') + diff --git a/vim-config/plugins/ale/test/util/test_cd_string_commands.vader b/vim-config/plugins/ale/test/util/test_cd_string_commands.vader new file mode 100644 index 00000000..d854214a --- /dev/null +++ b/vim-config/plugins/ale/test/util/test_cd_string_commands.vader @@ -0,0 +1,20 @@ +Before: + silent! cd /testplugin/test/util + let g:dir = getcwd() + +After: + silent execute 'cd ' . fnameescape(g:dir) + unlet! g:dir + +Execute(CdString should output the correct command string): + " We will check that escaping is done correctly for each platform. + AssertEqual + \ has('unix') ? 'cd ''/foo bar/baz'' && ' : 'cd /d "/foo bar/baz" && ', + \ ale#command#CdString('/foo bar/baz') + +Execute(CdString handle substitution and formatting): + call ale#test#SetFilename('foo.txt') + + AssertEqual + \ has('unix') ? 'cd %s:h && ' : 'cd /d %s:h && ', + \ ale#command#CdString('%s:h') diff --git a/vim-config/plugins/ale/test/v_files/testfile.v b/vim-config/plugins/ale/test/v_files/testfile.v new file mode 100644 index 00000000..e69de29b diff --git a/vim-config/plugins/ale/test/vimrc b/vim-config/plugins/ale/test/vimrc new file mode 100644 index 00000000..3f80c636 --- /dev/null +++ b/vim-config/plugins/ale/test/vimrc @@ -0,0 +1,42 @@ +" vint: -ProhibitSetNoCompatible + +" Make most tests just set lists synchronously when run in Docker, etc. +let g:ale_set_lists_synchronously = 1 + +" This lowercase highlight definition is needed for highlight tests. +hi link aleerrorline spellbad + +" Load builtin plugins +" We need this because run_vim.sh sets -i NONE +if has('win32') + set runtimepath=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,C:\vader,C:\testplugin +else + set runtimepath=/home/vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,/testplugin,/vader +endif + +" The following is just an example +filetype plugin indent on +syntax on + +if !has('win32') + set shell=/bin/sh + set shellcmdflag=-c +endif + +set nocompatible +set tabstop=4 +set softtabstop=4 +set shiftwidth=4 +set expandtab +set backspace=2 +set nofoldenable +set foldmethod=syntax +set foldlevelstart=10 +set foldnestmax=10 +set ttimeoutlen=0 +" The encoding must be explicitly set for tests for Windows. +execute 'set encoding=utf-8' + +let g:mapleader=',' + +let g:ale_ignore_2_4_warnings = 1