From dfa38ff0ddeb1b330309cc55e5af24714d0d567a Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 19 Jul 2018 17:00:23 +0100 Subject: Make LSP support more prominent in the README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 26baf76c..1bf5cc69 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ ![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true) ALE (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim -0.2.0+ and Vim 8 while you edit your text files. +0.2.0+ and Vim 8 while you edit your text files, and acts as a Vim +[language server protocol](https://langserver.org/) client. ![linting example](img/example.gif?raw=true) -- cgit v1.2.3 From 27f1915745d22a2d3831b3431a498d3ef674648c Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 19 Jul 2018 17:06:39 +0100 Subject: Capitalize Language Server Protocol --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1bf5cc69..dea58fd9 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ALE (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim 0.2.0+ and Vim 8 while you edit your text files, and acts as a Vim -[language server protocol](https://langserver.org/) client. +[Language Server Protocol](https://langserver.org/) client. ![linting example](img/example.gif?raw=true) -- cgit v1.2.3 From 324838adae32f4062c2099c297530588fb80a1a3 Mon Sep 17 00:00:00 2001 From: Ben Spiers Date: Thu, 19 Jul 2018 18:25:45 +0100 Subject: Add support for Fortran language server by @hansec --- README.md | 2 +- ale_linters/fortran/language_server.vim | 23 +++++++++++++++++++++++ doc/ale.txt | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 ale_linters/fortran/language_server.vim diff --git a/README.md b/README.md index dea58fd9..6196512d 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ formatting. | Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) | | Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) | | Fish | fish [-n flag](https://linux.die.net/man/1/fish) -| Fortran | [gcc](https://gcc.gnu.org/) | +| 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) | diff --git a/ale_linters/fortran/language_server.vim b/ale_linters/fortran/language_server.vim new file mode 100644 index 00000000..c0dd51bf --- /dev/null +++ b/ale_linters/fortran/language_server.vim @@ -0,0 +1,23 @@ +" Author: unpairedbracket ben.spiers22@gmail.com +" Description: A language server for fortran + +call ale#Set('fortran_language_server_executable', 'fortls') +call ale#Set('fortran_language_server_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#fortran#language_server#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'fortran_language_server_executable') +endfunction + +function! ale_linters#fortran#language_server#GetProjectRoot(buffer) abort + let l:fortls_file = ale#path#FindNearestFile(a:buffer, '.fortls') + + return !empty(l:fortls_file) ? fnamemodify(l:fortls_file, ':h') : '' +endfunction + +call ale#linter#Define('fortran', { +\ 'name': 'language_server', +\ 'lsp': 'stdio', +\ 'executable_callback': 'ale_linters#fortran#language_server#GetExecutable', +\ 'command_callback': 'ale_linters#fortran#language_server#GetExecutable', +\ 'project_root_callback': 'ale_linters#fortran#language_server#GetProjectRoot', +\}) diff --git a/doc/ale.txt b/doc/ale.txt index 2b25091e..2862057b 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -355,7 +355,7 @@ Notes: * Erb: `erb`, `erubi`, `erubis` * Erlang: `erlc`, `SyntaxErl` * Fish: `fish` (-n flag) -* Fortran: `gcc` +* Fortran: `gcc`, `language_server` * Fountain: `proselint` * FusionScript: `fusion-lint` * Git Commit Messages: `gitlint` -- cgit v1.2.3 From 61a5880747128dbf988a076e190ccb346500b5ff Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 19 Jul 2018 21:15:05 +0100 Subject: Capture server capabilities from LSP servers --- autoload/ale/lsp.vim | 48 +++++++++ .../test_other_initialize_message_handling.vader | 111 +++++++++++++++++++++ 2 files changed, 159 insertions(+) diff --git a/autoload/ale/lsp.vim b/autoload/ale/lsp.vim index e44b5bc3..1dac3ab1 100644 --- a/autoload/ale/lsp.vim +++ b/autoload/ale/lsp.vim @@ -15,6 +15,8 @@ function! ale#lsp#NewConnection(initialization_options) abort " open_documents: A Dictionary mapping buffers to b:changedtick, keeping " track of when documents were opened, and when we last changed them. " callback_list: A list of callbacks for handling LSP responses. + " initialization_options: Options to send to the server. + " capabilities: Features the server supports. let l:conn = { \ 'id': '', \ 'data': '', @@ -22,6 +24,13 @@ function! ale#lsp#NewConnection(initialization_options) abort \ 'open_documents': {}, \ 'callback_list': [], \ 'initialization_options': a:initialization_options, + \ 'capabilities': { + \ 'hover': 0, + \ 'references': 0, + \ 'completion': 0, + \ 'completion_trigger_characters': [], + \ 'definition': 0, + \ }, \} call add(s:connections, l:conn) @@ -44,6 +53,11 @@ function! s:FindConnection(key, value) abort return {} endfunction +" Get the capabilities for a connection, or an empty Dictionary. +function! ale#lsp#GetConnectionCapabilities(id) abort + return get(s:FindConnection('id', a:id), 'capabilities', {}) +endfunction + function! ale#lsp#GetNextMessageID() abort " Use the current ID let l:id = g:ale_lsp_next_message_id @@ -185,6 +199,38 @@ function! s:HandleInitializeResponse(conn, response) abort endif endfunction +" Update capabilities from the server, so we know which features the server +" supports. +function! s:UpdateCapabilities(conn, capabilities) abort + if type(a:capabilities) != type({}) + return + endif + + if get(a:capabilities, 'hoverProvider') is v:true + let a:conn.capabilities.hover = 1 + endif + + if get(a:capabilities, 'referencesProvider') is v:true + let a:conn.capabilities.references = 1 + endif + + if !empty(get(a:capabilities, 'completionProvider')) + let a:conn.capabilities.completion = 1 + endif + + if type(get(a:capabilities, 'completionProvider')) is type({}) + let l:chars = get(a:capabilities.completionProvider, 'triggerCharacters') + + if type(l:chars) is type([]) + let a:conn.capabilities.completion_trigger_characters = l:chars + endif + endif + + if get(a:capabilities, 'definitionProvider') is v:true + let a:conn.capabilities.definition = 1 + endif +endfunction + function! ale#lsp#HandleOtherInitializeResponses(conn, response) abort let l:uninitialized_projects = [] @@ -200,6 +246,8 @@ function! ale#lsp#HandleOtherInitializeResponses(conn, response) abort if get(a:response, 'method', '') is# '' if has_key(get(a:response, 'result', {}), 'capabilities') + call s:UpdateCapabilities(a:conn, a:response.result.capabilities) + for [l:dir, l:project] in l:uninitialized_projects call s:MarkProjectAsInitialized(a:conn, l:project) endfor diff --git a/test/lsp/test_other_initialize_message_handling.vader b/test/lsp/test_other_initialize_message_handling.vader index 3a7c7f62..f9567ee0 100644 --- a/test/lsp/test_other_initialize_message_handling.vader +++ b/test/lsp/test_other_initialize_message_handling.vader @@ -9,6 +9,13 @@ Before: \ 'projects': { \ '/foo/bar': b:project, \ }, + \ 'capabilities': { + \ 'hover': 0, + \ 'references': 0, + \ 'completion': 0, + \ 'completion_trigger_characters': [], + \ 'definition': 0, + \ }, \} After: @@ -64,3 +71,107 @@ Execute(Other messages should not initialize projects): call ale#lsp#HandleOtherInitializeResponses(b:conn, {'result': {'x': {}}}) AssertEqual 0, b:project.initialized + +Execute(Capabilities should bet set up correctly): + call ale#lsp#HandleOtherInitializeResponses(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 + \ }, + \ }, + \}) + + AssertEqual + \ { + \ 'capabilities': { + \ 'completion_trigger_characters': ['.'], + \ 'completion': 1, + \ 'references': 1, + \ 'hover': 1, + \ 'definition': 1, + \ }, + \ 'message_queue': [], + \ 'projects': { + \ '/foo/bar': { + \ 'initialized': 1, + \ 'message_queue': [], + \ 'init_request_id': 3, + \ }, + \ }, + \ }, + \ b:conn + +Execute(Disabled capabilities should be recognised correctly): + call ale#lsp#HandleOtherInitializeResponses(b:conn, { + \ 'jsonrpc': '2.0', + \ 'id': 1, + \ 'result': { + \ 'capabilities': { + \ 'renameProvider': v:true, + \ '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:true, + \ 'signatureHelpProvider': { + \ 'triggerCharacters': ['(', ','], + \ }, + \ 'definitionProvider': v:false, + \ 'experimental': {}, + \ 'documentHighlightProvider': v:true + \ }, + \ }, + \}) + + AssertEqual + \ { + \ 'capabilities': { + \ 'completion_trigger_characters': [], + \ 'completion': 0, + \ 'references': 0, + \ 'hover': 0, + \ 'definition': 0, + \ }, + \ 'message_queue': [], + \ 'projects': { + \ '/foo/bar': { + \ 'initialized': 1, + \ 'message_queue': [], + \ 'init_request_id': 3, + \ }, + \ }, + \ }, + \ b:conn -- cgit v1.2.3 From e8bea510df1ce952ef877aec3c58b3c39d98b7ae Mon Sep 17 00:00:00 2001 From: Ben Spiers Date: Thu, 19 Jul 2018 22:27:47 +0100 Subject: Add documentation and testing for fortls --- ale_linters/fortran/language_server.vim | 6 +++++- doc/ale-fortran.txt | 19 +++++++++++++++++++ doc/ale.txt | 1 + .../test_fortran_fortls_callback.vader | 18 ++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/command_callback/test_fortran_fortls_callback.vader diff --git a/ale_linters/fortran/language_server.vim b/ale_linters/fortran/language_server.vim index c0dd51bf..fd763fcf 100644 --- a/ale_linters/fortran/language_server.vim +++ b/ale_linters/fortran/language_server.vim @@ -8,6 +8,10 @@ function! ale_linters#fortran#language_server#GetExecutable(buffer) abort return ale#Var(a:buffer, 'fortran_language_server_executable') endfunction +function! ale_linters#fortran#language_server#GetCommand(buffer) abort + return ale#Escape(ale_linters#fortran#language_server#GetExecutable(a:buffer)) +endfunction + function! ale_linters#fortran#language_server#GetProjectRoot(buffer) abort let l:fortls_file = ale#path#FindNearestFile(a:buffer, '.fortls') @@ -18,6 +22,6 @@ call ale#linter#Define('fortran', { \ 'name': 'language_server', \ 'lsp': 'stdio', \ 'executable_callback': 'ale_linters#fortran#language_server#GetExecutable', -\ 'command_callback': 'ale_linters#fortran#language_server#GetExecutable', +\ 'command_callback': 'ale_linters#fortran#language_server#GetCommand', \ 'project_root_callback': 'ale_linters#fortran#language_server#GetProjectRoot', \}) diff --git a/doc/ale-fortran.txt b/doc/ale-fortran.txt index ed6bc724..c9b7e8e2 100644 --- a/doc/ale-fortran.txt +++ b/doc/ale-fortran.txt @@ -32,5 +32,24 @@ g:ale_fortran_gcc_use_free_form *g:ale_fortran_gcc_use_free_form* instead, for checking files with fixed form layouts. +=============================================================================== +language_server *ale-fortran-language-server* + +g:ale_fortran_language_server_executable *g:ale_fortran_language_server_executable* + *b:ale_fortran_language_server_executable* + Type: |String| + Default: `'fortls'` + + This variable can be changed to modify the executable used for the Fortran + Language Server. + +g:ale_fortran_language_server_use_global *g:ale_fortran_language_server_use_global* + *b:ale_fortran_language_server_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index 2862057b..068ee16d 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -76,6 +76,7 @@ CONTENTS *ale-contents* 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| diff --git a/test/command_callback/test_fortran_fortls_callback.vader b/test/command_callback/test_fortran_fortls_callback.vader new file mode 100644 index 00000000..3be7ff4f --- /dev/null +++ b/test/command_callback/test_fortran_fortls_callback.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('fortran-fortls-project/test.F90') + + AssertLSPProject ale#path#Simplify(g:dir . '/fortran-fortls-project') + +Execute(The language should be correct): + AssertLSPLanguage 'fortran' -- cgit v1.2.3 From ad986a8d821c343cafa363ebb4399fe589a373e1 Mon Sep 17 00:00:00 2001 From: Ben Spiers Date: Thu, 19 Jul 2018 22:37:06 +0100 Subject: Add the .fortls file necessary for tests to work (defying .gitignore) --- test/command_callback/fortran-fortls-project/.fortls | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/command_callback/fortran-fortls-project/.fortls diff --git a/test/command_callback/fortran-fortls-project/.fortls b/test/command_callback/fortran-fortls-project/.fortls new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/test/command_callback/fortran-fortls-project/.fortls @@ -0,0 +1,2 @@ +{ +} -- cgit v1.2.3 From ac6bc6d0ae279c70081cba4225de2df54688757d Mon Sep 17 00:00:00 2001 From: Eric Wolf Date: Fri, 20 Jul 2018 16:30:16 +0200 Subject: Add cabal-ghc linter cabal-ghc calls ghc via cabal exec and so ghc has access to packages in cabal sandboxes for example --- README.md | 2 +- ale_linters/haskell/cabal_ghc.vim | 18 +++++++++++++++++ doc/ale-haskell.txt | 11 +++++++++++ doc/ale.txt | 3 ++- .../test_haskell_cabal_ghc_command_callbacks.vader | 23 ++++++++++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 ale_linters/haskell/cabal_ghc.vim create mode 100644 test/command_callback/test_haskell_cabal_ghc_command_callbacks.vader diff --git a/README.md b/README.md index dea58fd9..be237a65 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ formatting. | GraphQL | [eslint](http://eslint.org/), [gqlint](https://github.com/happylinks/gqlint), [prettier](https://github.com/prettier/prettier) | | Haml | [haml-lint](https://github.com/brigade/haml-lint) | | Handlebars | [ember-template-lint](https://github.com/rwjblue/ember-template-lint) | -| Haskell | [brittany](https://github.com/lspitzner/brittany), [ghc](https://www.haskell.org/ghc/), [stack-ghc](https://haskellstack.org/), [stack-build](https://haskellstack.org/) !!, [ghc-mod](https://github.com/DanielG/ghc-mod), [stack-ghc-mod](https://github.com/DanielG/ghc-mod), [hlint](https://hackage.haskell.org/package/hlint), [hdevtools](https://hackage.haskell.org/package/hdevtools), [hfmt](https://github.com/danstiner/hfmt) | +| Haskell | [brittany](https://github.com/lspitzner/brittany), [ghc](https://www.haskell.org/ghc/), [cabal-ghc](https://www.haskell.org/cabal/), [stack-ghc](https://haskellstack.org/), [stack-build](https://haskellstack.org/) !!, [ghc-mod](https://github.com/DanielG/ghc-mod), [stack-ghc-mod](https://github.com/DanielG/ghc-mod), [hlint](https://hackage.haskell.org/package/hlint), [hdevtools](https://hackage.haskell.org/package/hdevtools), [hfmt](https://github.com/danstiner/hfmt) | | HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [write-good](https://github.com/btford/write-good) | | Idris | [idris](http://www.idris-lang.org/) | | Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/) | diff --git a/ale_linters/haskell/cabal_ghc.vim b/ale_linters/haskell/cabal_ghc.vim new file mode 100644 index 00000000..79fd8ff9 --- /dev/null +++ b/ale_linters/haskell/cabal_ghc.vim @@ -0,0 +1,18 @@ +" Author: Eric Wolf +" Description: ghc for Haskell files called with cabal exec + +call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0') + +function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort + return 'cabal exec -- ghc ' + \ . ale#Var(a:buffer, 'haskell_cabal_ghc_options') + \ . ' %t' +endfunction + +call ale#linter#Define('haskell', { +\ 'name': 'cabal-ghc', +\ 'output_stream': 'stderr', +\ 'executable': 'cabal', +\ 'command_callback': 'ale_linters#haskell#cabal_ghc#GetCommand', +\ 'callback': 'ale#handlers#haskell#HandleGHCFormat', +\}) diff --git a/doc/ale-haskell.txt b/doc/ale-haskell.txt index 09ecd92d..15d3ce48 100644 --- a/doc/ale-haskell.txt +++ b/doc/ale-haskell.txt @@ -22,6 +22,17 @@ g:ale_haskell_ghc_options *g:ale_haskell_ghc_options* This variable can be changed to modify flags given to ghc. +=============================================================================== +cabal-ghc *ale-haskell-cabal-ghc* + +g:ale_haskell_cabal_ghc_options *g:ale_haskell_cabal_ghc_options* + *b:ale_haskell_cabal_ghc_options* + Type: |String| + Default: `'-fno-code -v0'` + + This variable can be changed to modify flags given to ghc through cabal + exec. + =============================================================================== hdevtools *ale-haskell-hdevtools* diff --git a/doc/ale.txt b/doc/ale.txt index 2b25091e..bfef2bed 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -98,6 +98,7 @@ CONTENTS *ale-contents* haskell...............................|ale-haskell-options| brittany............................|ale-haskell-brittany| ghc.................................|ale-haskell-ghc| + cabal-ghc...........................|ale-haskell-cabal-ghc| hdevtools...........................|ale-haskell-hdevtools| hfmt................................|ale-haskell-hfmt| stack-build.........................|ale-haskell-stack-build| @@ -364,7 +365,7 @@ Notes: * GraphQL: `eslint`, `gqlint`, `prettier` * Haml: `haml-lint` * Handlebars: `ember-template-lint` -* Haskell: `brittany`, `ghc`, `stack-ghc`, `stack-build`!!, `ghc-mod`, `stack-ghc-mod`, `hlint`, `hdevtools`, `hfmt` +* Haskell: `brittany`, `ghc`, `cabal-ghc`, `stack-ghc`, `stack-build`!!, `ghc-mod`, `stack-ghc-mod`, `hlint`, `hdevtools`, `hfmt` * HTML: `alex`!!, `HTMLHint`, `proselint`, `tidy`, `write-good` * Idris: `idris` * Java: `checkstyle`, `javac`, `google-java-format`, `PMD` diff --git a/test/command_callback/test_haskell_cabal_ghc_command_callbacks.vader b/test/command_callback/test_haskell_cabal_ghc_command_callbacks.vader new file mode 100644 index 00000000..650aefa3 --- /dev/null +++ b/test/command_callback/test_haskell_cabal_ghc_command_callbacks.vader @@ -0,0 +1,23 @@ +Before: + Save g:ale_haskell_cabal_ghc_options + + unlet! g:ale_haskell_cabal_ghc_options + unlet! b:ale_haskell_cabal_ghc_options + + runtime ale_linters/haskell/cabal_ghc.vim + +After: + Restore + unlet! b:ale_haskell_cabal_ghc_options + call ale#linter#Reset() + +Execute(The options should be used in the command): + AssertEqual + \ 'cabal exec -- ghc -fno-code -v0 %t', + \ ale_linters#haskell#cabal_ghc#GetCommand(bufnr('')) + + let b:ale_haskell_cabal_ghc_options = 'foobar' + + AssertEqual + \ 'cabal exec -- ghc foobar %t', + \ ale_linters#haskell#cabal_ghc#GetCommand(bufnr('')) -- cgit v1.2.3 From 0d37aaac7a6f2a6291d7db1032fe08196164fc73 Mon Sep 17 00:00:00 2001 From: w0rp Date: Fri, 20 Jul 2018 16:10:25 +0100 Subject: Fix #1631 - Disable balloon support for terminals by default --- doc/ale.txt | 9 +++++++-- plugin/ale.vim | 5 +---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/ale.txt b/doc/ale.txt index 2b25091e..96bbc89b 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1413,8 +1413,7 @@ g:ale_set_balloons *g:ale_set_balloons* *b:ale_set_balloons* Type: |Number| - Default: `(has('balloon_eval') && has('gui_running'))` - `|| (has('balloon_eval_term') && !has('gui_running'))` + Default: `has('balloon_eval') && has('gui_running')` When this option is set to `1`, balloon messages will be displayed for problems or hover information if available. @@ -1424,6 +1423,12 @@ 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. + Balloons can be enabled for terminal versions of Vim that support balloons, + but some versions of Vim will produce strange mouse behavior when balloons + are enabled. To configure balloons for your terminal, you should first + configure your |ttymouse| setting, and then consider setting + `g:ale_set_balloons` to `1` before ALE is loaded. + `b:ale_set_balloons` can be set to `0` to disable balloons for a buffer. Balloons cannot be enabled for a specific buffer when not initially enabled globally. diff --git a/plugin/ale.vim b/plugin/ale.vim index ad2639bb..f0f90b6b 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -110,10 +110,7 @@ let g:ale_set_highlights = get(g:, 'ale_set_highlights', has('syntax')) let g:ale_echo_cursor = get(g:, 'ale_echo_cursor', 1) " 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')) -\ || (has('balloon_eval_term') && !has('gui_running')) -\) +let g:ale_set_balloons = get(g:, 'ale_set_balloons', has('balloon_eval') && has('gui_running')) " This flag can be set to 0 to disable warnings for trailing whitespace let g:ale_warn_about_trailing_whitespace = get(g:, 'ale_warn_about_trailing_whitespace', 1) -- cgit v1.2.3 From 014c924630c38afcc402902ed712b54ff232d861 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 22 Jul 2018 12:10:35 +0100 Subject: Move GitHub files to the .github directory --- .github/CODE_OF_CONDUCT.md | 3 + .github/CONTRIBUTING.md | 25 ++ .github/PULL_REQUEST_TEMPLATE.md | 8 + .github/README.md | 818 +++++++++++++++++++++++++++++++++++++++ CODE_OF_CONDUCT.md | 3 - CONTRIBUTING.md | 25 -- PULL_REQUEST_TEMPLATE.md | 8 - README.md | 818 --------------------------------------- 8 files changed, 854 insertions(+), 854 deletions(-) create mode 100644 .github/CODE_OF_CONDUCT.md create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/README.md delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.md delete mode 100644 PULL_REQUEST_TEMPLATE.md delete mode 100644 README.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..587bb372 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +Codes of conduct are totally unnecessary and dumb. + +Just don't be a jerk and have fun. diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..e59f8326 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,25 @@ +## Guidelines + +Have fun, and work on whatever floats your boat. Take It Easy :tm:. + +For help with contributing to ALE, see `:help ale-development` in Vim, or view +the help file online [here](/w0rp/ale/blob/master/doc/ale-development.txt). + +## Creating Issues + +Before creating any issues, please look through the current list of issues and +pull requests, and ensure that the issue hasn't already been reported. If an +issue has already been reported, but you have some new insight, please add +a comment to the existing issue. + +Please read the FAQ in the README before creating any issues. A feature +you desire may already exist and be documented, or the FAQ might explain +how to solve a problem you have already. + +Please try and describe any issues reported with as much detail as you can +provide about your Vim version, the linter you were trying to run, your +operating system, or any other information you think might be helpful. + +Please describe your issue in clear, grammatically correct, and easy to +understand English. You are more likely to see an issue resolved if others +can understand you. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..8e1b5c57 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ + diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 00000000..6196512d --- /dev/null +++ b/.github/README.md @@ -0,0 +1,818 @@ +# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) + + +![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true) + +ALE (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim +0.2.0+ and Vim 8 while you edit your text files, and acts as a Vim +[Language Server Protocol](https://langserver.org/) client. + +![linting example](img/example.gif?raw=true) + +ALE makes use of NeoVim and Vim 8 job control functions and timers to +run linters on the contents of text buffers and return errors as +text is changed in Vim. This allows for displaying warnings and +errors in files being edited in Vim before files have been saved +back to a filesystem. + +In other words, this plugin allows you to lint while you type. + +ALE offers support for fixing code with command line tools in a non-blocking +manner with the `:ALEFix` feature, supporting tools in many languages, like +`prettier`, `eslint`, `autopep8`, and more. + +ALE acts as a "language client" to support a variety of Language Server Protocol +features, including: + +* Diagnostics (via Language Server Protocol linters) +* Go To Definition (`:ALEGoToDefinition`) +* Completion (`let g:ale_completion_enabled = 1`) +* Finding references (`:ALEFindReferences`) +* Hover information (`:ALEHover`) + +If you don't care about Language Server Protocol, ALE won't load any of the code +for working with it unless needed. One of ALE's general missions is that you +won't pay for the features that you don't use. + +## Table of Contents + +1. [Supported Languages and Tools](#supported-languages) +2. [Usage](#usage) + 1. [Linting](#usage-linting) + 2. [Fixing](#usage-fixing) + 3. [Completion](#usage-completion) + 4. [Go To Definition](#usage-go-to-definition) + 5. [Find References](#usage-find-references) + 6. [Hovering](#usage-hover) +3. [Installation](#installation) + 1. [Installation with Vim package management](#standard-installation) + 2. [Installation with Pathogen](#installation-with-pathogen) + 3. [Installation with Vundle](#installation-with-vundle) +4. [Contributing](#contributing) +5. [FAQ](#faq) + 1. [How do I disable particular linters?](#faq-disable-linters) + 2. [How can I keep the sign gutter open?](#faq-keep-signs) + 3. [How can I change the signs ALE uses?](#faq-change-signs) + 4. [How can I change or disable the highlights ALE uses?](#faq-change-highlights) + 5. [How can I show errors or warnings in my statusline?](#faq-statusline) + 6. [How can I show errors or warnings in my lightline?](#faq-lightline) + 7. [How can I change the format for echo messages?](#faq-echo-format) + 8. [How can I execute some code when ALE starts or stops linting?](#faq-autocmd) + 9. [How can I navigate between errors quickly?](#faq-navigation) + 10. [How can I run linters only when I save files?](#faq-lint-on-save) + 11. [How can I use the quickfix list instead of the loclist?](#faq-quickfix) + 12. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint) + 13. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad) + 14. [How can I configure my C or C++ project?](#faq-c-configuration) + 15. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration) + 16. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height) + + + +## 1. 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. + + + +**Notes:** + +* *^ No linters for text or Vim help filetypes are enabled by default.* +* *!! These linters check only files on disk. See `:help ale-lint-file-linters`* + +| Language | Tools | +| -------- | ----- | +| ASM | [gcc](https://gcc.gnu.org) | +| Ansible | [ansible-lint](https://github.com/willthames/ansible-lint) | +| API Blueprint | [drafter](https://github.com/apiaryio/drafter) | +| AsciiDoc | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [write-good](https://github.com/btford/write-good) | +| Awk | [gawk](https://www.gnu.org/software/gawk/)| +| Bash | [language-server](https://github.com/mads-hartmann/bash-language-server), shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | +| Bourne Shell | shell [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | +| C | [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [clang](http://clang.llvm.org/), [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | +| C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) !!, [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) !!, [cquery](https://github.com/cquery-project/cquery), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | +| CUDA | [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) | +| C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) see:`help ale-cs-mcs` for details, [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) !! see:`help ale-cs-mcsc` for details and configuration| +| Chef | [foodcritic](http://www.foodcritic.io/) | +| Clojure | [joker](https://github.com/candid82/joker) | +| CloudFormation | [cfn-python-lint](https://github.com/awslabs/cfn-python-lint) | +| CMake | [cmakelint](https://github.com/richq/cmake-lint) | +| CoffeeScript | [coffee](http://coffeescript.org/), [coffeelint](https://www.npmjs.com/package/coffeelint) | +| Crystal | [crystal](https://crystal-lang.org/) !! | +| CSS | [csslint](http://csslint.net/), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) | +| Cucumber | [cucumber](https://cucumber.io/) | +| Cython (pyrex filetype) | [cython](http://cython.org/) | +| D | [dmd](https://dlang.org/dmd-linux.html) | +| Dafny | [dafny](https://rise4fun.com/Dafny) !! | +| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) | +| Dockerfile | [hadolint](https://github.com/hadolint/hadolint) | +| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!| +| Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) | +| Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) | +| Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) | +| Fish | fish [-n flag](https://linux.die.net/man/1/fish) +| 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 | [gofmt](https://golang.org/cmd/gofmt/), [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/) !!, [golint](https://godoc.org/github.com/golang/lint), [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) !!, [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !! | +| GraphQL | [eslint](http://eslint.org/), [gqlint](https://github.com/happylinks/gqlint), [prettier](https://github.com/prettier/prettier) | +| Haml | [haml-lint](https://github.com/brigade/haml-lint) | +| Handlebars | [ember-template-lint](https://github.com/rwjblue/ember-template-lint) | +| Haskell | [brittany](https://github.com/lspitzner/brittany), [ghc](https://www.haskell.org/ghc/), [stack-ghc](https://haskellstack.org/), [stack-build](https://haskellstack.org/) !!, [ghc-mod](https://github.com/DanielG/ghc-mod), [stack-ghc-mod](https://github.com/DanielG/ghc-mod), [hlint](https://hackage.haskell.org/package/hlint), [hdevtools](https://hackage.haskell.org/package/hdevtools), [hfmt](https://github.com/danstiner/hfmt) | +| HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [write-good](https://github.com/btford/write-good) | +| Idris | [idris](http://www.idris-lang.org/) | +| Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/) | +| JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint-cli), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo) +| JSON | [fixjson](https://github.com/rhysd/fixjson), [jsonlint](http://zaa.ch/jsonlint/), [jq](https://stedolan.github.io/jq/), [prettier](https://github.com/prettier/prettier) | +| Kotlin | [kotlinc](https://kotlinlang.org) !!, [ktlint](https://ktlint.github.io) !!, [languageserver](https://github.com/fwcd/KotlinLanguageServer) see `:help ale-integration-kotlin` for configuration instructions | +| LaTeX | [alex](https://github.com/wooorm/alex) !!, [chktex](http://www.nongnu.org/chktex/), [lacheck](https://www.ctan.org/pkg/lacheck), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | +| Less | [lessc](https://www.npmjs.com/package/less), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) | +| LLVM | [llc](https://llvm.org/docs/CommandGuide/llc.html) | +| Lua | [luac](https://www.lua.org/manual/5.1/luac.html), [luacheck](https://github.com/mpeterv/luacheck) | +| Mail | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [vale](https://github.com/ValeLint/vale) | +| Make | [checkmake](https://github.com/mrtazz/checkmake) | +| Markdown | [alex](https://github.com/wooorm/alex) !!, [markdownlint](https://github.com/DavidAnson/markdownlint) !!, [mdl](https://github.com/mivok/markdownlint), [prettier](https://github.com/prettier/prettier), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [remark-lint](https://github.com/wooorm/remark-lint), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | +| MATLAB | [mlint](https://www.mathworks.com/help/matlab/ref/mlint.html) | +| Mercury | [mmc](http://mercurylang.org) !! | +| NASM | [nasm](https://www.nasm.us/) !! | +| Nim | [nim check](https://nim-lang.org/docs/nimc.html) !! | +| nix | [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) | +| nroff | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)| +| Objective-C | [clang](http://clang.llvm.org/) | +| Objective-C++ | [clang](http://clang.llvm.org/) | +| OCaml | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-ocaml-merlin` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server) | +| Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic), [perltidy](https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy) | +| PHP | [hack](http://hacklang.org/), [hackfmt](https://github.com/facebook/flow/tree/master/hack/hackfmt), [langserver](https://github.com/felixfbecker/php-language-server), [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions, [php -l](https://secure.php.net/), [phpcs](https://github.com/squizlabs/PHP_CodeSniffer), [phpmd](https://phpmd.org), [phpstan](https://github.com/phpstan/phpstan), [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer), [php-cs-fixer](http://cs.sensiolabs.org/) | +| PO | [alex](https://github.com/wooorm/alex) !!, [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html), [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | +| Pod | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | +| Pony | [ponyc](https://github.com/ponylang/ponyc) | +| proto | [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) | +| Pug | [pug-lint](https://github.com/pugjs/pug-lint) | +| Puppet | [languageserver](https://github.com/lingua-pupuli/puppet-editor-services), [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) | +| Python | [autopep8](https://github.com/hhatto/autopep8), [black](https://github.com/ambv/black), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [prospector](http://github.com/landscapeio/prospector), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pyls](https://github.com/palantir/python-language-server), [pyre](https://github.com/facebook/pyre-check), [pylint](https://www.pylint.org/) !!, [yapf](https://github.com/google/yapf) | +| QML | [qmlfmt](https://github.com/jesperhh/qmlfmt), [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) | +| R | [lintr](https://github.com/jimhester/lintr) | +| ReasonML | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server), [refmt](https://github.com/reasonml/reason-cli) | +| reStructuredText | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [rstcheck](https://github.com/myint/rstcheck), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | +| Re:VIEW | [redpen](http://redpen.cc/) | +| RPM spec | [rpmlint](https://github.com/rpm-software-management/rpmlint) (disabled by default; see `:help ale-integration-spec`) | +| Ruby | [brakeman](http://brakemanscanner.org/) !!, [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) !!, [reek](https://github.com/troessner/reek), [rubocop](https://github.com/bbatsov/rubocop), [ruby](https://www.ruby-lang.org), [rufo](https://github.com/ruby-formatter/rufo) | +| Rust | cargo !! (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/), [rustfmt](https://github.com/rust-lang-nursery/rustfmt) | +| SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) | +| SCSS | [prettier](https://github.com/prettier/prettier), [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint), [stylelint](https://github.com/stylelint/stylelint) | +| Scala | [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html), [scalac](http://scala-lang.org), [scalafmt](https://scalameta.org/scalafmt/), [scalastyle](http://www.scalastyle.org) | +| Slim | [slim-lint](https://github.com/sds/slim-lint) | +| SML | [smlnj](http://www.smlnj.org/) | +| Solidity | [solhint](https://github.com/protofire/solhint), [solium](https://github.com/duaraghav8/Solium) | +| Stylus | [stylelint](https://github.com/stylelint/stylelint) | +| SQL | [sqlint](https://github.com/purcell/sqlint) | +| Swift | [swiftlint](https://github.com/realm/SwiftLint), [swiftformat](https://github.com/nicklockwood/SwiftFormat) | +| Tcl | [nagelfar](http://nagelfar.sourceforge.net) !! | +| Terraform | [tflint](https://github.com/wata727/tflint) | +| Texinfo | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)| +| Text^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | +| Thrift | [thrift](http://thrift.apache.org/) | +| TypeScript | [eslint](http://eslint.org/), [prettier](https://github.com/prettier/prettier), [tslint](https://github.com/palantir/tslint), tsserver, typecheck | +| Verilog | [iverilog](https://github.com/steveicarus/iverilog), [verilator](http://www.veripool.org/projects/verilator/wiki/Intro) | +| Vim | [vint](https://github.com/Kuniwak/vint) | +| Vim help^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | +| Vue | [prettier](https://github.com/prettier/prettier), [vls](https://github.com/vuejs/vetur/tree/master/server) | +| XHTML | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | +| XML | [xmllint](http://xmlsoft.org/xmllint.html) | +| YAML | [swaglint](https://github.com/byCedric/swaglint), [yamllint](https://yamllint.readthedocs.io/) | + + + +## 2. Usage + + + +### 2.i Linting + +Once this plugin is installed, while editing your files in supported +languages and tools which have been correctly installed, +this plugin will send the contents of your text buffers to a variety of +programs for checking the syntax and semantics of your programs. By default, +linters will be re-run in the background to check your syntax when you open +new buffers or as you make edits to your files. + +The behaviour of linting can be configured with a variety of options, +documented in [the Vim help file](doc/ale.txt). For more information on the +options ALE offers, consult `:help ale-options` for global options and `:help +ale-linter-options` for options specified to particular linters. + + + +### 2.ii Fixing + +ALE can fix files with the `ALEFix` command. Functions need to be configured +either in each buffer with a `b:ale_fixers`, or globally with `g:ale_fixers`. + +The recommended way to configure fixers is to define a List in an ftplugin file. + +```vim +" In ~/.vim/ftplugin/javascript.vim, or somewhere similar. + +" Fix files with prettier, and then ESLint. +let b:ale_fixers = ['prettier', 'eslint'] +" Equivalent to the above. +let b:ale_fixers = {'javascript': ['prettier', 'eslint']} +``` + +You can also configure your fixers from vimrc using `g:ale_fixers`, before +or after ALE has been loaded. + +```vim +" In ~/.vim/vimrc, or somewhere similar. +let g:ale_fixers = { +\ 'javascript': ['eslint'], +\} +``` + +If you want to automatically fix files when you save them, you need to turn +a setting on in vimrc. + +```vim +" Set this variable to 1 to fix files when you save them. +let g:ale_fix_on_save = 1 +``` + +The `:ALEFixSuggest` command will suggest some supported tools for fixing code. +Both `g:ale_fixers` and `b:ale_fixers` can also accept functions, including +lambda functions, as fixers, for fixing files with custom tools. + +See `:help ale-fix` for complete information on how to fix files with ALE. + + + +### 2.iii Completion + +ALE offers some support for completion via hijacking of omnicompletion while you +type. All of ALE's completion information must come from Language Server +Protocol linters, or from `tsserver` for TypeScript. + +```vim +" Enable completion where available. +let g:ale_completion_enabled = 1 +``` + +See `:help ale-completion` for more information. + + + +### 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. + +On vim/gvim with `balloon` support you can see the information in a tooltip +that appears under the mouse when you mouseover a symbol. + +See `:help ale-hover` for more information. + + + +## 3. Installation + +To install this plugin, you should use one of the following methods. +For Windows users, replace usage of the Unix `~/.vim` directory with +`%USERPROFILE%\vimfiles`, or another directory if you have configured +Vim differently. On Windows, your `~/.vimrc` file will be similarly +stored in `%USERPROFILE%\_vimrc`. + + + +### 3.i. Installation with Vim package management + +In Vim 8 and NeoVim, you can install plugins easily without needing to use +any other tools. Simply clone the plugin into your `pack` directory. + +#### Vim 8 on Unix + +```bash +mkdir -p ~/.vim/pack/git-plugins/start +git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale +``` + +#### NeoVim on Unix + +```bash +mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start +git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale +``` + +#### Vim 8 on Windows + +```bash +# Run these commands in the "Git for Windows" Bash terminal +mkdir -p ~/vimfiles/pack/git-plugins/start +git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale +``` + +#### Generating Vim help files + +You can add the following line to your vimrc files to generate documentation +tags automatically, if you don't have something similar already, so you can use +the `:help` command to consult ALE's online documentation: + +```vim +" Put these lines at the very end of your vimrc file. + +" Load all plugins now. +" Plugins need to be added to runtimepath before helptags can be generated. +packloadall +" Load all of the helptags now, after plugins have been loaded. +" All messages and errors will be ignored. +silent! helptags ALL +``` + + + +### 3.ii. Installation with Pathogen + +To install this module with [Pathogen](https://github.com/tpope/vim-pathogen), +you should clone this repository to your bundle directory, and ensure +you have the line `execute pathogen#infect()` in your `~/.vimrc` file. +You can run the following commands in your terminal to do so: + +```bash +cd ~/.vim/bundle +git clone https://github.com/w0rp/ale.git +``` + + + +### 3.iii. Installation with Vundle + +You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.vim) +by using the path on GitHub for this repository. + +```vim +Plugin 'w0rp/ale' +``` + +See the Vundle documentation for more information. + + + +## 4. Contributing + +If you would like to see support for more languages and tools, please +[create an issue](https://github.com/w0rp/ale/issues) +or [create a pull request](https://github.com/w0rp/ale/pulls). +If your tool can read from stdin or you have code to suggest which is good, +support can be happily added for it. + +If you are interested in the general direction of the project, check out the +[wiki home page](https://github.com/w0rp/ale/wiki). The wiki includes a +Roadmap for the future, and more. + +If you'd liked to discuss the project more directly, check out the `#vim-ale` channel +on Freenode. Web chat is available [here](https://webchat.freenode.net/?channels=vim-ale). + + + +## 5. FAQ + + + +### 5.i. How do I disable particular linters? + +By default, all available tools for all supported languages will be run. If you +want to only select a subset of the tools, 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 keep the sign gutter open? + +You can keep the sign gutter open at all times by setting the +`g:ale_sign_column_always` to 1 + +```vim +let g:ale_sign_column_always = 1 +``` + + + +### 5.iii. How can I change the signs ALE uses? + +Use these options to specify what text should be used for signs: + +```vim +let g:ale_sign_error = '>>' +let g:ale_sign_warning = '--' +``` + +ALE sets some background colors automatically for warnings and errors +in the sign gutter, with the names `ALEErrorSign` and `ALEWarningSign`. +These colors can be customised, or even removed completely: + +```vim +highlight clear ALEErrorSign +highlight clear ALEWarningSign +``` + + + +### 5.iv. How can I 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.v. How can I show errors or warnings in my statusline? + +[vim-airline](https://github.com/vim-airline/vim-airline) integrates with ALE +for displaying error information in the status bar. If you want to see the +status for ALE in a nice format, it is recommended to use vim-airline with ALE. +The airline extension can be enabled by adding the following to your vimrc: + +```vim +" Set this. Airline will handle the rest. +let g:airline#extensions#ale#enabled = 1 +``` + +If you don't want to use vim-airline, you can implement your own statusline +function without adding any other plugins. ALE provides a function for counting +the number of problems for this purpose, named `ale#statusline#Count`. + +Say you want to display all errors as one figure, and all non-errors as another +figure. You can do the following: + +```vim +function! LinterStatus() abort + let l:counts = ale#statusline#Count(bufnr('')) + + let l:all_errors = l:counts.error + l:counts.style_error + let l:all_non_errors = l:counts.total - l:all_errors + + return l:counts.total == 0 ? 'OK' : printf( + \ '%dW %dE', + \ all_non_errors, + \ all_errors + \) +endfunction + +set statusline=%{LinterStatus()} +``` + +See `:help ale#statusline#Count()` for more information. + + + +### 5.vi. How can I show errors or warnings in my lightline? + +[lightline](https://github.com/itchyny/lightline.vim) does not have built-in +support for ALE, nevertheless there is a plugin that adds this functionality: [maximbaz/lightline-ale](https://github.com/maximbaz/lightline-ale). + +For more information, check out the sources of that plugin, `:help ale#statusline#Count()` and [lightline documentation](https://github.com/itchyny/lightline.vim#advanced-configuration). + + + +### 5.vii. How can I change the format for echo messages? + +There are 3 global options that allow customizing the echoed message. + +- `g:ale_echo_msg_format` where: + * `%s` is the error message itself + * `%...code...%` is an optional error code, and most characters can be + written between the `%` characters. + * `%linter%` is the linter name + * `%severity` is the severity type +- `g:ale_echo_msg_error_str` is the string used for error severity. +- `g:ale_echo_msg_warning_str` is the string used for warning severity. + +So for example this: + +```vim +let g:ale_echo_msg_error_str = 'E' +let g:ale_echo_msg_warning_str = 'W' +let g:ale_echo_msg_format = '[%linter%] %s [%severity%]' +``` + +Will give you: + +![Echoed message](img/echo.png) + +See `:help g:ale_echo_msg_format` for more information. + + + +### 5.viii. How can I execute some code when ALE starts or stops linting? + +ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html) +events when a lint or fix cycle are started and stopped. There is also an event +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.ix. 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.x. How can I run linters only when I save files? + +ALE offers an option `g:ale_lint_on_save` for enabling running the linters +when files are saved. This option is enabled by default. If you only +wish to run linters when files are saved, you can turn the other +options off. + +```vim +" Write this in your vimrc file +let g:ale_lint_on_text_changed = 'never' +" You can disable this option too +" if you don't want linters to run on opening a file +let g:ale_lint_on_enter = 0 +``` + +If for whatever reason you don't wish to run linters again when you save +files, you can set `g:ale_lint_on_save` to `0`. + + + +### 5.xi. How can I use the quickfix list instead of the loclist? + +The quickfix list can be enabled by turning the `g:ale_set_quickfix` +option on. If you wish to also disable the loclist, you can disable +the `g:ale_set_loclist` option. + +```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.xii. How can I check JSX files with both stylelint and eslint? + +If you configure ALE options correctly in your vimrc file, and install +the right tools, you can check JSX files with stylelint and eslint. + +First, install eslint and install stylelint with +[stylelint-processor-styled-components](https://github.com/styled-components/stylelint-processor-styled-components). + +Supposing you have installed both tools correctly, configure your .jsx files so +`jsx` is included in the filetype. You can use an `autocmd` for this. + +```vim +augroup FiletypeGroup + autocmd! + au BufNewFile,BufRead *.jsx set filetype=javascript.jsx +augroup END +``` + +Supposing the filetype has been set correctly, you can set the following +options in a jsx.vim ftplugin file. + +```vim +" In ~/.vim/ftplugin/jsx.vim, or somewhere similar. +let b:ale_linters = ['stylelint', 'eslint'] +let b:ale_linter_aliases = ['css'] +``` + +Or if you want, you can configure the linters from your vimrc file. + +```vim +" In ~/.vim/vimrc, or somewhere similar. +let g:ale_linters = {'jsx': ['stylelint', 'eslint']} +let g:ale_linter_aliases = {'jsx': 'css'} +``` + +ALE will alias the `jsx` filetype so it uses the `css` filetype linters, and +use the original Array of selected linters for `jsx` from the `g:ale_linters` +object. All available linters will be used for the filetype `javascript`, and +no linter will be run twice for the same file. + + + +### 5.xiii. Will this plugin eat all of my laptop battery power? + +ALE takes advantage of the power of various tools to check your code. This of +course means that CPU time will be used to continuously check your code. If you +are concerned about the CPU time ALE will spend, which will of course imply +some cost to battery life, you can adjust your settings to make your CPU do +less work. + +First, consider increasing the delay before which ALE will run any linters +while you type. ALE uses a timeout which is cancelled and reset every time you +type, and this delay can be increased so linters are run less often. See +`:help g:ale_lint_delay` for more information. + +If you don't wish to run linters while you type, you can disable that +behaviour. Set `g:ale_lint_on_text_changed` to `never` or `normal`. You won't +get as frequent error checking, but ALE shouldn't block your ability to edit a +document after you save a file, so the asynchronous nature of the plugin will +still be an advantage. + +If you are still concerned, you can turn the automatic linting off altogether, +including the option `g:ale_lint_on_enter`, and you can run ALE manually with +`:ALELint`. + + + +### 5.xiv. How can I configure my C or C++ project? + +The structure of C and C++ projects varies wildly from project to project, with +many different build tools being used for building them, and many different +formats for project configuration files. ALE can run compilers easily, but +ALE cannot easily detect which compiler flags to use. + +Some tools and build configurations can generate +[compile_commands.json](https://clang.llvm.org/docs/JSONCompilationDatabase.html) +files. The `cppcheck`, `clangcheck`, `clangtidy` and `cquery` linters can read +these files for automatically determining the appropriate compiler flags to +use. + +For linting with compilers like `gcc` and `clang`, and with other tools, you +will need to tell ALE which compiler flags to use yourself. You can use +different options for different projects with the `g:ale_pattern_options` +setting. Consult the documentation for that setting for more information. +`b:ale_linters` can be used to select which tools you want to run, say if you +want to use only `gcc` for one project, and only `clang` for another. + +You may also configure buffer-local settings for linters with project-specific +vimrc files. [local_vimrc](https://github.com/LucHermitte/local_vimrc) can be +used for executing local vimrc files which can be shared in your project. + + + +### 5.xv. How can I configure ALE differently for different buffers? + +ALE offers various ways to configure which linters or fixers are run, and +other settings. For the majority of ALE's settings, they can either be +configured globally with a `g:` variable prefix, or for a specific buffer +with a `b:` variable prefix. For example, you can configure a Python ftplugin +file like so. + +```vim +" In ~/.vim/ftplugin/python.vim + +" Check Python files with flake8 and pylint. +let b:ale_linters = ['flake8', 'pylint'] +" Fix Python files with autopep8 and yapf. +let b:ale_fixers = ['autopep8', 'yapf'] +" Disable warnings about trailing whitespace for Python files. +let b:ale_warn_about_trailing_whitespace = 0 +``` + +For configuring files based on regular expression patterns matched against the +absolute path to a file, you can use `g:ale_pattern_options`. + +```vim +" Do not lint or fix minified files. +let g:ale_pattern_options = { +\ '\.min\.js$': {'ale_linters': [], 'ale_fixers': []}, +\ '\.min\.css$': {'ale_linters': [], 'ale_fixers': []}, +\} +" If you configure g:ale_pattern_options outside of vimrc, you need this. +let g:ale_pattern_options_enabled = 1 +``` + +Buffer-local variables for settings always override the global settings. + + + +### 5.xvi. How can I configure the height of the list in which ALE displays errors? + +To set a default height for the error list, use the `g:ale_list_window_size` variable. + +```vim +" Show 5 lines of errors (default: 10) +let g:ale_list_window_size = 5 +``` diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 587bb372..00000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,3 +0,0 @@ -Codes of conduct are totally unnecessary and dumb. - -Just don't be a jerk and have fun. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index e59f8326..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,25 +0,0 @@ -## Guidelines - -Have fun, and work on whatever floats your boat. Take It Easy :tm:. - -For help with contributing to ALE, see `:help ale-development` in Vim, or view -the help file online [here](/w0rp/ale/blob/master/doc/ale-development.txt). - -## Creating Issues - -Before creating any issues, please look through the current list of issues and -pull requests, and ensure that the issue hasn't already been reported. If an -issue has already been reported, but you have some new insight, please add -a comment to the existing issue. - -Please read the FAQ in the README before creating any issues. A feature -you desire may already exist and be documented, or the FAQ might explain -how to solve a problem you have already. - -Please try and describe any issues reported with as much detail as you can -provide about your Vim version, the linter you were trying to run, your -operating system, or any other information you think might be helpful. - -Please describe your issue in clear, grammatically correct, and easy to -understand English. You are more likely to see an issue resolved if others -can understand you. diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 8e1b5c57..00000000 --- a/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/README.md b/README.md deleted file mode 100644 index 6196512d..00000000 --- a/README.md +++ /dev/null @@ -1,818 +0,0 @@ -# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) - - -![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true) - -ALE (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim -0.2.0+ and Vim 8 while you edit your text files, and acts as a Vim -[Language Server Protocol](https://langserver.org/) client. - -![linting example](img/example.gif?raw=true) - -ALE makes use of NeoVim and Vim 8 job control functions and timers to -run linters on the contents of text buffers and return errors as -text is changed in Vim. This allows for displaying warnings and -errors in files being edited in Vim before files have been saved -back to a filesystem. - -In other words, this plugin allows you to lint while you type. - -ALE offers support for fixing code with command line tools in a non-blocking -manner with the `:ALEFix` feature, supporting tools in many languages, like -`prettier`, `eslint`, `autopep8`, and more. - -ALE acts as a "language client" to support a variety of Language Server Protocol -features, including: - -* Diagnostics (via Language Server Protocol linters) -* Go To Definition (`:ALEGoToDefinition`) -* Completion (`let g:ale_completion_enabled = 1`) -* Finding references (`:ALEFindReferences`) -* Hover information (`:ALEHover`) - -If you don't care about Language Server Protocol, ALE won't load any of the code -for working with it unless needed. One of ALE's general missions is that you -won't pay for the features that you don't use. - -## Table of Contents - -1. [Supported Languages and Tools](#supported-languages) -2. [Usage](#usage) - 1. [Linting](#usage-linting) - 2. [Fixing](#usage-fixing) - 3. [Completion](#usage-completion) - 4. [Go To Definition](#usage-go-to-definition) - 5. [Find References](#usage-find-references) - 6. [Hovering](#usage-hover) -3. [Installation](#installation) - 1. [Installation with Vim package management](#standard-installation) - 2. [Installation with Pathogen](#installation-with-pathogen) - 3. [Installation with Vundle](#installation-with-vundle) -4. [Contributing](#contributing) -5. [FAQ](#faq) - 1. [How do I disable particular linters?](#faq-disable-linters) - 2. [How can I keep the sign gutter open?](#faq-keep-signs) - 3. [How can I change the signs ALE uses?](#faq-change-signs) - 4. [How can I change or disable the highlights ALE uses?](#faq-change-highlights) - 5. [How can I show errors or warnings in my statusline?](#faq-statusline) - 6. [How can I show errors or warnings in my lightline?](#faq-lightline) - 7. [How can I change the format for echo messages?](#faq-echo-format) - 8. [How can I execute some code when ALE starts or stops linting?](#faq-autocmd) - 9. [How can I navigate between errors quickly?](#faq-navigation) - 10. [How can I run linters only when I save files?](#faq-lint-on-save) - 11. [How can I use the quickfix list instead of the loclist?](#faq-quickfix) - 12. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint) - 13. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad) - 14. [How can I configure my C or C++ project?](#faq-c-configuration) - 15. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration) - 16. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height) - - - -## 1. 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. - - - -**Notes:** - -* *^ No linters for text or Vim help filetypes are enabled by default.* -* *!! These linters check only files on disk. See `:help ale-lint-file-linters`* - -| Language | Tools | -| -------- | ----- | -| ASM | [gcc](https://gcc.gnu.org) | -| Ansible | [ansible-lint](https://github.com/willthames/ansible-lint) | -| API Blueprint | [drafter](https://github.com/apiaryio/drafter) | -| AsciiDoc | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [write-good](https://github.com/btford/write-good) | -| Awk | [gawk](https://www.gnu.org/software/gawk/)| -| Bash | [language-server](https://github.com/mads-hartmann/bash-language-server), shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | -| Bourne Shell | shell [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | -| C | [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [clang](http://clang.llvm.org/), [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | -| C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) !!, [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) !!, [cquery](https://github.com/cquery-project/cquery), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | -| CUDA | [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) | -| C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) see:`help ale-cs-mcs` for details, [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) !! see:`help ale-cs-mcsc` for details and configuration| -| Chef | [foodcritic](http://www.foodcritic.io/) | -| Clojure | [joker](https://github.com/candid82/joker) | -| CloudFormation | [cfn-python-lint](https://github.com/awslabs/cfn-python-lint) | -| CMake | [cmakelint](https://github.com/richq/cmake-lint) | -| CoffeeScript | [coffee](http://coffeescript.org/), [coffeelint](https://www.npmjs.com/package/coffeelint) | -| Crystal | [crystal](https://crystal-lang.org/) !! | -| CSS | [csslint](http://csslint.net/), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) | -| Cucumber | [cucumber](https://cucumber.io/) | -| Cython (pyrex filetype) | [cython](http://cython.org/) | -| D | [dmd](https://dlang.org/dmd-linux.html) | -| Dafny | [dafny](https://rise4fun.com/Dafny) !! | -| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) | -| Dockerfile | [hadolint](https://github.com/hadolint/hadolint) | -| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!| -| Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) | -| Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) | -| Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) | -| Fish | fish [-n flag](https://linux.die.net/man/1/fish) -| 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 | [gofmt](https://golang.org/cmd/gofmt/), [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/) !!, [golint](https://godoc.org/github.com/golang/lint), [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) !!, [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !! | -| GraphQL | [eslint](http://eslint.org/), [gqlint](https://github.com/happylinks/gqlint), [prettier](https://github.com/prettier/prettier) | -| Haml | [haml-lint](https://github.com/brigade/haml-lint) | -| Handlebars | [ember-template-lint](https://github.com/rwjblue/ember-template-lint) | -| Haskell | [brittany](https://github.com/lspitzner/brittany), [ghc](https://www.haskell.org/ghc/), [stack-ghc](https://haskellstack.org/), [stack-build](https://haskellstack.org/) !!, [ghc-mod](https://github.com/DanielG/ghc-mod), [stack-ghc-mod](https://github.com/DanielG/ghc-mod), [hlint](https://hackage.haskell.org/package/hlint), [hdevtools](https://hackage.haskell.org/package/hdevtools), [hfmt](https://github.com/danstiner/hfmt) | -| HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [write-good](https://github.com/btford/write-good) | -| Idris | [idris](http://www.idris-lang.org/) | -| Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/) | -| JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint-cli), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo) -| JSON | [fixjson](https://github.com/rhysd/fixjson), [jsonlint](http://zaa.ch/jsonlint/), [jq](https://stedolan.github.io/jq/), [prettier](https://github.com/prettier/prettier) | -| Kotlin | [kotlinc](https://kotlinlang.org) !!, [ktlint](https://ktlint.github.io) !!, [languageserver](https://github.com/fwcd/KotlinLanguageServer) see `:help ale-integration-kotlin` for configuration instructions | -| LaTeX | [alex](https://github.com/wooorm/alex) !!, [chktex](http://www.nongnu.org/chktex/), [lacheck](https://www.ctan.org/pkg/lacheck), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | -| Less | [lessc](https://www.npmjs.com/package/less), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) | -| LLVM | [llc](https://llvm.org/docs/CommandGuide/llc.html) | -| Lua | [luac](https://www.lua.org/manual/5.1/luac.html), [luacheck](https://github.com/mpeterv/luacheck) | -| Mail | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [vale](https://github.com/ValeLint/vale) | -| Make | [checkmake](https://github.com/mrtazz/checkmake) | -| Markdown | [alex](https://github.com/wooorm/alex) !!, [markdownlint](https://github.com/DavidAnson/markdownlint) !!, [mdl](https://github.com/mivok/markdownlint), [prettier](https://github.com/prettier/prettier), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [remark-lint](https://github.com/wooorm/remark-lint), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | -| MATLAB | [mlint](https://www.mathworks.com/help/matlab/ref/mlint.html) | -| Mercury | [mmc](http://mercurylang.org) !! | -| NASM | [nasm](https://www.nasm.us/) !! | -| Nim | [nim check](https://nim-lang.org/docs/nimc.html) !! | -| nix | [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) | -| nroff | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)| -| Objective-C | [clang](http://clang.llvm.org/) | -| Objective-C++ | [clang](http://clang.llvm.org/) | -| OCaml | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-ocaml-merlin` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server) | -| Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic), [perltidy](https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy) | -| PHP | [hack](http://hacklang.org/), [hackfmt](https://github.com/facebook/flow/tree/master/hack/hackfmt), [langserver](https://github.com/felixfbecker/php-language-server), [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions, [php -l](https://secure.php.net/), [phpcs](https://github.com/squizlabs/PHP_CodeSniffer), [phpmd](https://phpmd.org), [phpstan](https://github.com/phpstan/phpstan), [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer), [php-cs-fixer](http://cs.sensiolabs.org/) | -| PO | [alex](https://github.com/wooorm/alex) !!, [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html), [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | -| Pod | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | -| Pony | [ponyc](https://github.com/ponylang/ponyc) | -| proto | [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) | -| Pug | [pug-lint](https://github.com/pugjs/pug-lint) | -| Puppet | [languageserver](https://github.com/lingua-pupuli/puppet-editor-services), [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) | -| Python | [autopep8](https://github.com/hhatto/autopep8), [black](https://github.com/ambv/black), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [prospector](http://github.com/landscapeio/prospector), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pyls](https://github.com/palantir/python-language-server), [pyre](https://github.com/facebook/pyre-check), [pylint](https://www.pylint.org/) !!, [yapf](https://github.com/google/yapf) | -| QML | [qmlfmt](https://github.com/jesperhh/qmlfmt), [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) | -| R | [lintr](https://github.com/jimhester/lintr) | -| ReasonML | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server), [refmt](https://github.com/reasonml/reason-cli) | -| reStructuredText | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [rstcheck](https://github.com/myint/rstcheck), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | -| Re:VIEW | [redpen](http://redpen.cc/) | -| RPM spec | [rpmlint](https://github.com/rpm-software-management/rpmlint) (disabled by default; see `:help ale-integration-spec`) | -| Ruby | [brakeman](http://brakemanscanner.org/) !!, [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) !!, [reek](https://github.com/troessner/reek), [rubocop](https://github.com/bbatsov/rubocop), [ruby](https://www.ruby-lang.org), [rufo](https://github.com/ruby-formatter/rufo) | -| Rust | cargo !! (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/), [rustfmt](https://github.com/rust-lang-nursery/rustfmt) | -| SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) | -| SCSS | [prettier](https://github.com/prettier/prettier), [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint), [stylelint](https://github.com/stylelint/stylelint) | -| Scala | [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html), [scalac](http://scala-lang.org), [scalafmt](https://scalameta.org/scalafmt/), [scalastyle](http://www.scalastyle.org) | -| Slim | [slim-lint](https://github.com/sds/slim-lint) | -| SML | [smlnj](http://www.smlnj.org/) | -| Solidity | [solhint](https://github.com/protofire/solhint), [solium](https://github.com/duaraghav8/Solium) | -| Stylus | [stylelint](https://github.com/stylelint/stylelint) | -| SQL | [sqlint](https://github.com/purcell/sqlint) | -| Swift | [swiftlint](https://github.com/realm/SwiftLint), [swiftformat](https://github.com/nicklockwood/SwiftFormat) | -| Tcl | [nagelfar](http://nagelfar.sourceforge.net) !! | -| Terraform | [tflint](https://github.com/wata727/tflint) | -| Texinfo | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)| -| Text^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | -| Thrift | [thrift](http://thrift.apache.org/) | -| TypeScript | [eslint](http://eslint.org/), [prettier](https://github.com/prettier/prettier), [tslint](https://github.com/palantir/tslint), tsserver, typecheck | -| Verilog | [iverilog](https://github.com/steveicarus/iverilog), [verilator](http://www.veripool.org/projects/verilator/wiki/Intro) | -| Vim | [vint](https://github.com/Kuniwak/vint) | -| Vim help^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | -| Vue | [prettier](https://github.com/prettier/prettier), [vls](https://github.com/vuejs/vetur/tree/master/server) | -| XHTML | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | -| XML | [xmllint](http://xmlsoft.org/xmllint.html) | -| YAML | [swaglint](https://github.com/byCedric/swaglint), [yamllint](https://yamllint.readthedocs.io/) | - - - -## 2. Usage - - - -### 2.i Linting - -Once this plugin is installed, while editing your files in supported -languages and tools which have been correctly installed, -this plugin will send the contents of your text buffers to a variety of -programs for checking the syntax and semantics of your programs. By default, -linters will be re-run in the background to check your syntax when you open -new buffers or as you make edits to your files. - -The behaviour of linting can be configured with a variety of options, -documented in [the Vim help file](doc/ale.txt). For more information on the -options ALE offers, consult `:help ale-options` for global options and `:help -ale-linter-options` for options specified to particular linters. - - - -### 2.ii Fixing - -ALE can fix files with the `ALEFix` command. Functions need to be configured -either in each buffer with a `b:ale_fixers`, or globally with `g:ale_fixers`. - -The recommended way to configure fixers is to define a List in an ftplugin file. - -```vim -" In ~/.vim/ftplugin/javascript.vim, or somewhere similar. - -" Fix files with prettier, and then ESLint. -let b:ale_fixers = ['prettier', 'eslint'] -" Equivalent to the above. -let b:ale_fixers = {'javascript': ['prettier', 'eslint']} -``` - -You can also configure your fixers from vimrc using `g:ale_fixers`, before -or after ALE has been loaded. - -```vim -" In ~/.vim/vimrc, or somewhere similar. -let g:ale_fixers = { -\ 'javascript': ['eslint'], -\} -``` - -If you want to automatically fix files when you save them, you need to turn -a setting on in vimrc. - -```vim -" Set this variable to 1 to fix files when you save them. -let g:ale_fix_on_save = 1 -``` - -The `:ALEFixSuggest` command will suggest some supported tools for fixing code. -Both `g:ale_fixers` and `b:ale_fixers` can also accept functions, including -lambda functions, as fixers, for fixing files with custom tools. - -See `:help ale-fix` for complete information on how to fix files with ALE. - - - -### 2.iii Completion - -ALE offers some support for completion via hijacking of omnicompletion while you -type. All of ALE's completion information must come from Language Server -Protocol linters, or from `tsserver` for TypeScript. - -```vim -" Enable completion where available. -let g:ale_completion_enabled = 1 -``` - -See `:help ale-completion` for more information. - - - -### 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. - -On vim/gvim with `balloon` support you can see the information in a tooltip -that appears under the mouse when you mouseover a symbol. - -See `:help ale-hover` for more information. - - - -## 3. Installation - -To install this plugin, you should use one of the following methods. -For Windows users, replace usage of the Unix `~/.vim` directory with -`%USERPROFILE%\vimfiles`, or another directory if you have configured -Vim differently. On Windows, your `~/.vimrc` file will be similarly -stored in `%USERPROFILE%\_vimrc`. - - - -### 3.i. Installation with Vim package management - -In Vim 8 and NeoVim, you can install plugins easily without needing to use -any other tools. Simply clone the plugin into your `pack` directory. - -#### Vim 8 on Unix - -```bash -mkdir -p ~/.vim/pack/git-plugins/start -git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale -``` - -#### NeoVim on Unix - -```bash -mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start -git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale -``` - -#### Vim 8 on Windows - -```bash -# Run these commands in the "Git for Windows" Bash terminal -mkdir -p ~/vimfiles/pack/git-plugins/start -git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale -``` - -#### Generating Vim help files - -You can add the following line to your vimrc files to generate documentation -tags automatically, if you don't have something similar already, so you can use -the `:help` command to consult ALE's online documentation: - -```vim -" Put these lines at the very end of your vimrc file. - -" Load all plugins now. -" Plugins need to be added to runtimepath before helptags can be generated. -packloadall -" Load all of the helptags now, after plugins have been loaded. -" All messages and errors will be ignored. -silent! helptags ALL -``` - - - -### 3.ii. Installation with Pathogen - -To install this module with [Pathogen](https://github.com/tpope/vim-pathogen), -you should clone this repository to your bundle directory, and ensure -you have the line `execute pathogen#infect()` in your `~/.vimrc` file. -You can run the following commands in your terminal to do so: - -```bash -cd ~/.vim/bundle -git clone https://github.com/w0rp/ale.git -``` - - - -### 3.iii. Installation with Vundle - -You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.vim) -by using the path on GitHub for this repository. - -```vim -Plugin 'w0rp/ale' -``` - -See the Vundle documentation for more information. - - - -## 4. Contributing - -If you would like to see support for more languages and tools, please -[create an issue](https://github.com/w0rp/ale/issues) -or [create a pull request](https://github.com/w0rp/ale/pulls). -If your tool can read from stdin or you have code to suggest which is good, -support can be happily added for it. - -If you are interested in the general direction of the project, check out the -[wiki home page](https://github.com/w0rp/ale/wiki). The wiki includes a -Roadmap for the future, and more. - -If you'd liked to discuss the project more directly, check out the `#vim-ale` channel -on Freenode. Web chat is available [here](https://webchat.freenode.net/?channels=vim-ale). - - - -## 5. FAQ - - - -### 5.i. How do I disable particular linters? - -By default, all available tools for all supported languages will be run. If you -want to only select a subset of the tools, 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 keep the sign gutter open? - -You can keep the sign gutter open at all times by setting the -`g:ale_sign_column_always` to 1 - -```vim -let g:ale_sign_column_always = 1 -``` - - - -### 5.iii. How can I change the signs ALE uses? - -Use these options to specify what text should be used for signs: - -```vim -let g:ale_sign_error = '>>' -let g:ale_sign_warning = '--' -``` - -ALE sets some background colors automatically for warnings and errors -in the sign gutter, with the names `ALEErrorSign` and `ALEWarningSign`. -These colors can be customised, or even removed completely: - -```vim -highlight clear ALEErrorSign -highlight clear ALEWarningSign -``` - - - -### 5.iv. How can I 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.v. How can I show errors or warnings in my statusline? - -[vim-airline](https://github.com/vim-airline/vim-airline) integrates with ALE -for displaying error information in the status bar. If you want to see the -status for ALE in a nice format, it is recommended to use vim-airline with ALE. -The airline extension can be enabled by adding the following to your vimrc: - -```vim -" Set this. Airline will handle the rest. -let g:airline#extensions#ale#enabled = 1 -``` - -If you don't want to use vim-airline, you can implement your own statusline -function without adding any other plugins. ALE provides a function for counting -the number of problems for this purpose, named `ale#statusline#Count`. - -Say you want to display all errors as one figure, and all non-errors as another -figure. You can do the following: - -```vim -function! LinterStatus() abort - let l:counts = ale#statusline#Count(bufnr('')) - - let l:all_errors = l:counts.error + l:counts.style_error - let l:all_non_errors = l:counts.total - l:all_errors - - return l:counts.total == 0 ? 'OK' : printf( - \ '%dW %dE', - \ all_non_errors, - \ all_errors - \) -endfunction - -set statusline=%{LinterStatus()} -``` - -See `:help ale#statusline#Count()` for more information. - - - -### 5.vi. How can I show errors or warnings in my lightline? - -[lightline](https://github.com/itchyny/lightline.vim) does not have built-in -support for ALE, nevertheless there is a plugin that adds this functionality: [maximbaz/lightline-ale](https://github.com/maximbaz/lightline-ale). - -For more information, check out the sources of that plugin, `:help ale#statusline#Count()` and [lightline documentation](https://github.com/itchyny/lightline.vim#advanced-configuration). - - - -### 5.vii. How can I change the format for echo messages? - -There are 3 global options that allow customizing the echoed message. - -- `g:ale_echo_msg_format` where: - * `%s` is the error message itself - * `%...code...%` is an optional error code, and most characters can be - written between the `%` characters. - * `%linter%` is the linter name - * `%severity` is the severity type -- `g:ale_echo_msg_error_str` is the string used for error severity. -- `g:ale_echo_msg_warning_str` is the string used for warning severity. - -So for example this: - -```vim -let g:ale_echo_msg_error_str = 'E' -let g:ale_echo_msg_warning_str = 'W' -let g:ale_echo_msg_format = '[%linter%] %s [%severity%]' -``` - -Will give you: - -![Echoed message](img/echo.png) - -See `:help g:ale_echo_msg_format` for more information. - - - -### 5.viii. How can I execute some code when ALE starts or stops linting? - -ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html) -events when a lint or fix cycle are started and stopped. There is also an event -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.ix. 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.x. How can I run linters only when I save files? - -ALE offers an option `g:ale_lint_on_save` for enabling running the linters -when files are saved. This option is enabled by default. If you only -wish to run linters when files are saved, you can turn the other -options off. - -```vim -" Write this in your vimrc file -let g:ale_lint_on_text_changed = 'never' -" You can disable this option too -" if you don't want linters to run on opening a file -let g:ale_lint_on_enter = 0 -``` - -If for whatever reason you don't wish to run linters again when you save -files, you can set `g:ale_lint_on_save` to `0`. - - - -### 5.xi. How can I use the quickfix list instead of the loclist? - -The quickfix list can be enabled by turning the `g:ale_set_quickfix` -option on. If you wish to also disable the loclist, you can disable -the `g:ale_set_loclist` option. - -```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.xii. How can I check JSX files with both stylelint and eslint? - -If you configure ALE options correctly in your vimrc file, and install -the right tools, you can check JSX files with stylelint and eslint. - -First, install eslint and install stylelint with -[stylelint-processor-styled-components](https://github.com/styled-components/stylelint-processor-styled-components). - -Supposing you have installed both tools correctly, configure your .jsx files so -`jsx` is included in the filetype. You can use an `autocmd` for this. - -```vim -augroup FiletypeGroup - autocmd! - au BufNewFile,BufRead *.jsx set filetype=javascript.jsx -augroup END -``` - -Supposing the filetype has been set correctly, you can set the following -options in a jsx.vim ftplugin file. - -```vim -" In ~/.vim/ftplugin/jsx.vim, or somewhere similar. -let b:ale_linters = ['stylelint', 'eslint'] -let b:ale_linter_aliases = ['css'] -``` - -Or if you want, you can configure the linters from your vimrc file. - -```vim -" In ~/.vim/vimrc, or somewhere similar. -let g:ale_linters = {'jsx': ['stylelint', 'eslint']} -let g:ale_linter_aliases = {'jsx': 'css'} -``` - -ALE will alias the `jsx` filetype so it uses the `css` filetype linters, and -use the original Array of selected linters for `jsx` from the `g:ale_linters` -object. All available linters will be used for the filetype `javascript`, and -no linter will be run twice for the same file. - - - -### 5.xiii. Will this plugin eat all of my laptop battery power? - -ALE takes advantage of the power of various tools to check your code. This of -course means that CPU time will be used to continuously check your code. If you -are concerned about the CPU time ALE will spend, which will of course imply -some cost to battery life, you can adjust your settings to make your CPU do -less work. - -First, consider increasing the delay before which ALE will run any linters -while you type. ALE uses a timeout which is cancelled and reset every time you -type, and this delay can be increased so linters are run less often. See -`:help g:ale_lint_delay` for more information. - -If you don't wish to run linters while you type, you can disable that -behaviour. Set `g:ale_lint_on_text_changed` to `never` or `normal`. You won't -get as frequent error checking, but ALE shouldn't block your ability to edit a -document after you save a file, so the asynchronous nature of the plugin will -still be an advantage. - -If you are still concerned, you can turn the automatic linting off altogether, -including the option `g:ale_lint_on_enter`, and you can run ALE manually with -`:ALELint`. - - - -### 5.xiv. How can I configure my C or C++ project? - -The structure of C and C++ projects varies wildly from project to project, with -many different build tools being used for building them, and many different -formats for project configuration files. ALE can run compilers easily, but -ALE cannot easily detect which compiler flags to use. - -Some tools and build configurations can generate -[compile_commands.json](https://clang.llvm.org/docs/JSONCompilationDatabase.html) -files. The `cppcheck`, `clangcheck`, `clangtidy` and `cquery` linters can read -these files for automatically determining the appropriate compiler flags to -use. - -For linting with compilers like `gcc` and `clang`, and with other tools, you -will need to tell ALE which compiler flags to use yourself. You can use -different options for different projects with the `g:ale_pattern_options` -setting. Consult the documentation for that setting for more information. -`b:ale_linters` can be used to select which tools you want to run, say if you -want to use only `gcc` for one project, and only `clang` for another. - -You may also configure buffer-local settings for linters with project-specific -vimrc files. [local_vimrc](https://github.com/LucHermitte/local_vimrc) can be -used for executing local vimrc files which can be shared in your project. - - - -### 5.xv. How can I configure ALE differently for different buffers? - -ALE offers various ways to configure which linters or fixers are run, and -other settings. For the majority of ALE's settings, they can either be -configured globally with a `g:` variable prefix, or for a specific buffer -with a `b:` variable prefix. For example, you can configure a Python ftplugin -file like so. - -```vim -" In ~/.vim/ftplugin/python.vim - -" Check Python files with flake8 and pylint. -let b:ale_linters = ['flake8', 'pylint'] -" Fix Python files with autopep8 and yapf. -let b:ale_fixers = ['autopep8', 'yapf'] -" Disable warnings about trailing whitespace for Python files. -let b:ale_warn_about_trailing_whitespace = 0 -``` - -For configuring files based on regular expression patterns matched against the -absolute path to a file, you can use `g:ale_pattern_options`. - -```vim -" Do not lint or fix minified files. -let g:ale_pattern_options = { -\ '\.min\.js$': {'ale_linters': [], 'ale_fixers': []}, -\ '\.min\.css$': {'ale_linters': [], 'ale_fixers': []}, -\} -" If you configure g:ale_pattern_options outside of vimrc, you need this. -let g:ale_pattern_options_enabled = 1 -``` - -Buffer-local variables for settings always override the global settings. - - - -### 5.xvi. How can I configure the height of the list in which ALE displays errors? - -To set a default height for the error list, use the `g:ale_list_window_size` variable. - -```vim -" Show 5 lines of errors (default: 10) -let g:ale_list_window_size = 5 -``` -- cgit v1.2.3 From 6c10be8992b9a54e83bab58838c1553d36028c7e Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 22 Jul 2018 12:15:15 +0100 Subject: Update the tests to check README.md in the new location --- test/script/check-supported-tools-tables | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/script/check-supported-tools-tables b/test/script/check-supported-tools-tables index 220c7427..0666f0d1 100755 --- a/test/script/check-supported-tools-tables +++ b/test/script/check-supported-tools-tables @@ -22,11 +22,11 @@ ale_help_end_line="$(expr "$ale_help_start_line" + "$ale_help_section_size")" # Find the start and end lines for the same section in the README. readme_start_line="$( \ - grep -m1 -n '^.*[0-9][0-9]*\. *Supported Languages' README.md \ + grep -m1 -n '^.*[0-9][0-9]*\. *Supported Languages' .github/README.md \ | sed 's/\([0-9]*\).*/\1/' \ )" readme_section_size="$( \ - tail -n +"$readme_start_line" README.md \ + tail -n +"$readme_start_line" .github/README.md \ | grep -m1 -n '^##.*Usage' \ | sed 's/\([0-9]*\).*/\1/' \ )" @@ -46,7 +46,7 @@ sed -n "$ale_help_start_line,$ale_help_end_line"p doc/ale.txt \ | sed 's/^/ /' \ > "$doc_file" -sed -n "$readme_start_line,$readme_end_line"p README.md \ +sed -n "$readme_start_line,$readme_end_line"p .github/README.md \ | grep '| .* |' \ | sed '/^| Language/d;/^| ---/d' \ | sed 's/^|//' \ -- cgit v1.2.3 From 8062d6207edf71d1b1d0f02db965cf2bc2823d82 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 22 Jul 2018 12:16:42 +0100 Subject: Revert "Update the tests to check README.md in the new location" This reverts commit 6c10be8992b9a54e83bab58838c1553d36028c7e. --- test/script/check-supported-tools-tables | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/script/check-supported-tools-tables b/test/script/check-supported-tools-tables index 0666f0d1..220c7427 100755 --- a/test/script/check-supported-tools-tables +++ b/test/script/check-supported-tools-tables @@ -22,11 +22,11 @@ ale_help_end_line="$(expr "$ale_help_start_line" + "$ale_help_section_size")" # Find the start and end lines for the same section in the README. readme_start_line="$( \ - grep -m1 -n '^.*[0-9][0-9]*\. *Supported Languages' .github/README.md \ + grep -m1 -n '^.*[0-9][0-9]*\. *Supported Languages' README.md \ | sed 's/\([0-9]*\).*/\1/' \ )" readme_section_size="$( \ - tail -n +"$readme_start_line" .github/README.md \ + tail -n +"$readme_start_line" README.md \ | grep -m1 -n '^##.*Usage' \ | sed 's/\([0-9]*\).*/\1/' \ )" @@ -46,7 +46,7 @@ sed -n "$ale_help_start_line,$ale_help_end_line"p doc/ale.txt \ | sed 's/^/ /' \ > "$doc_file" -sed -n "$readme_start_line,$readme_end_line"p .github/README.md \ +sed -n "$readme_start_line,$readme_end_line"p README.md \ | grep '| .* |' \ | sed '/^| Language/d;/^| ---/d' \ | sed 's/^|//' \ -- cgit v1.2.3 From 89805919379645ae00dfe132e88b5db8e0601e17 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 22 Jul 2018 12:16:56 +0100 Subject: Move README.md back --- .github/README.md | 818 ------------------------------------------------------ README.md | 818 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 818 insertions(+), 818 deletions(-) delete mode 100644 .github/README.md create mode 100644 README.md diff --git a/.github/README.md b/.github/README.md deleted file mode 100644 index 6196512d..00000000 --- a/.github/README.md +++ /dev/null @@ -1,818 +0,0 @@ -# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) - - -![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true) - -ALE (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim -0.2.0+ and Vim 8 while you edit your text files, and acts as a Vim -[Language Server Protocol](https://langserver.org/) client. - -![linting example](img/example.gif?raw=true) - -ALE makes use of NeoVim and Vim 8 job control functions and timers to -run linters on the contents of text buffers and return errors as -text is changed in Vim. This allows for displaying warnings and -errors in files being edited in Vim before files have been saved -back to a filesystem. - -In other words, this plugin allows you to lint while you type. - -ALE offers support for fixing code with command line tools in a non-blocking -manner with the `:ALEFix` feature, supporting tools in many languages, like -`prettier`, `eslint`, `autopep8`, and more. - -ALE acts as a "language client" to support a variety of Language Server Protocol -features, including: - -* Diagnostics (via Language Server Protocol linters) -* Go To Definition (`:ALEGoToDefinition`) -* Completion (`let g:ale_completion_enabled = 1`) -* Finding references (`:ALEFindReferences`) -* Hover information (`:ALEHover`) - -If you don't care about Language Server Protocol, ALE won't load any of the code -for working with it unless needed. One of ALE's general missions is that you -won't pay for the features that you don't use. - -## Table of Contents - -1. [Supported Languages and Tools](#supported-languages) -2. [Usage](#usage) - 1. [Linting](#usage-linting) - 2. [Fixing](#usage-fixing) - 3. [Completion](#usage-completion) - 4. [Go To Definition](#usage-go-to-definition) - 5. [Find References](#usage-find-references) - 6. [Hovering](#usage-hover) -3. [Installation](#installation) - 1. [Installation with Vim package management](#standard-installation) - 2. [Installation with Pathogen](#installation-with-pathogen) - 3. [Installation with Vundle](#installation-with-vundle) -4. [Contributing](#contributing) -5. [FAQ](#faq) - 1. [How do I disable particular linters?](#faq-disable-linters) - 2. [How can I keep the sign gutter open?](#faq-keep-signs) - 3. [How can I change the signs ALE uses?](#faq-change-signs) - 4. [How can I change or disable the highlights ALE uses?](#faq-change-highlights) - 5. [How can I show errors or warnings in my statusline?](#faq-statusline) - 6. [How can I show errors or warnings in my lightline?](#faq-lightline) - 7. [How can I change the format for echo messages?](#faq-echo-format) - 8. [How can I execute some code when ALE starts or stops linting?](#faq-autocmd) - 9. [How can I navigate between errors quickly?](#faq-navigation) - 10. [How can I run linters only when I save files?](#faq-lint-on-save) - 11. [How can I use the quickfix list instead of the loclist?](#faq-quickfix) - 12. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint) - 13. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad) - 14. [How can I configure my C or C++ project?](#faq-c-configuration) - 15. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration) - 16. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height) - - - -## 1. 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. - - - -**Notes:** - -* *^ No linters for text or Vim help filetypes are enabled by default.* -* *!! These linters check only files on disk. See `:help ale-lint-file-linters`* - -| Language | Tools | -| -------- | ----- | -| ASM | [gcc](https://gcc.gnu.org) | -| Ansible | [ansible-lint](https://github.com/willthames/ansible-lint) | -| API Blueprint | [drafter](https://github.com/apiaryio/drafter) | -| AsciiDoc | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [write-good](https://github.com/btford/write-good) | -| Awk | [gawk](https://www.gnu.org/software/gawk/)| -| Bash | [language-server](https://github.com/mads-hartmann/bash-language-server), shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | -| Bourne Shell | shell [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | -| C | [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [clang](http://clang.llvm.org/), [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | -| C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) !!, [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) !!, [cquery](https://github.com/cquery-project/cquery), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | -| CUDA | [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) | -| C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) see:`help ale-cs-mcs` for details, [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) !! see:`help ale-cs-mcsc` for details and configuration| -| Chef | [foodcritic](http://www.foodcritic.io/) | -| Clojure | [joker](https://github.com/candid82/joker) | -| CloudFormation | [cfn-python-lint](https://github.com/awslabs/cfn-python-lint) | -| CMake | [cmakelint](https://github.com/richq/cmake-lint) | -| CoffeeScript | [coffee](http://coffeescript.org/), [coffeelint](https://www.npmjs.com/package/coffeelint) | -| Crystal | [crystal](https://crystal-lang.org/) !! | -| CSS | [csslint](http://csslint.net/), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) | -| Cucumber | [cucumber](https://cucumber.io/) | -| Cython (pyrex filetype) | [cython](http://cython.org/) | -| D | [dmd](https://dlang.org/dmd-linux.html) | -| Dafny | [dafny](https://rise4fun.com/Dafny) !! | -| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) | -| Dockerfile | [hadolint](https://github.com/hadolint/hadolint) | -| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!| -| Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) | -| Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) | -| Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) | -| Fish | fish [-n flag](https://linux.die.net/man/1/fish) -| 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 | [gofmt](https://golang.org/cmd/gofmt/), [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/) !!, [golint](https://godoc.org/github.com/golang/lint), [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) !!, [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !! | -| GraphQL | [eslint](http://eslint.org/), [gqlint](https://github.com/happylinks/gqlint), [prettier](https://github.com/prettier/prettier) | -| Haml | [haml-lint](https://github.com/brigade/haml-lint) | -| Handlebars | [ember-template-lint](https://github.com/rwjblue/ember-template-lint) | -| Haskell | [brittany](https://github.com/lspitzner/brittany), [ghc](https://www.haskell.org/ghc/), [stack-ghc](https://haskellstack.org/), [stack-build](https://haskellstack.org/) !!, [ghc-mod](https://github.com/DanielG/ghc-mod), [stack-ghc-mod](https://github.com/DanielG/ghc-mod), [hlint](https://hackage.haskell.org/package/hlint), [hdevtools](https://hackage.haskell.org/package/hdevtools), [hfmt](https://github.com/danstiner/hfmt) | -| HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [write-good](https://github.com/btford/write-good) | -| Idris | [idris](http://www.idris-lang.org/) | -| Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/) | -| JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint-cli), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo) -| JSON | [fixjson](https://github.com/rhysd/fixjson), [jsonlint](http://zaa.ch/jsonlint/), [jq](https://stedolan.github.io/jq/), [prettier](https://github.com/prettier/prettier) | -| Kotlin | [kotlinc](https://kotlinlang.org) !!, [ktlint](https://ktlint.github.io) !!, [languageserver](https://github.com/fwcd/KotlinLanguageServer) see `:help ale-integration-kotlin` for configuration instructions | -| LaTeX | [alex](https://github.com/wooorm/alex) !!, [chktex](http://www.nongnu.org/chktex/), [lacheck](https://www.ctan.org/pkg/lacheck), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | -| Less | [lessc](https://www.npmjs.com/package/less), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) | -| LLVM | [llc](https://llvm.org/docs/CommandGuide/llc.html) | -| Lua | [luac](https://www.lua.org/manual/5.1/luac.html), [luacheck](https://github.com/mpeterv/luacheck) | -| Mail | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [vale](https://github.com/ValeLint/vale) | -| Make | [checkmake](https://github.com/mrtazz/checkmake) | -| Markdown | [alex](https://github.com/wooorm/alex) !!, [markdownlint](https://github.com/DavidAnson/markdownlint) !!, [mdl](https://github.com/mivok/markdownlint), [prettier](https://github.com/prettier/prettier), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [remark-lint](https://github.com/wooorm/remark-lint), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | -| MATLAB | [mlint](https://www.mathworks.com/help/matlab/ref/mlint.html) | -| Mercury | [mmc](http://mercurylang.org) !! | -| NASM | [nasm](https://www.nasm.us/) !! | -| Nim | [nim check](https://nim-lang.org/docs/nimc.html) !! | -| nix | [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) | -| nroff | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)| -| Objective-C | [clang](http://clang.llvm.org/) | -| Objective-C++ | [clang](http://clang.llvm.org/) | -| OCaml | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-ocaml-merlin` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server) | -| Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic), [perltidy](https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy) | -| PHP | [hack](http://hacklang.org/), [hackfmt](https://github.com/facebook/flow/tree/master/hack/hackfmt), [langserver](https://github.com/felixfbecker/php-language-server), [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions, [php -l](https://secure.php.net/), [phpcs](https://github.com/squizlabs/PHP_CodeSniffer), [phpmd](https://phpmd.org), [phpstan](https://github.com/phpstan/phpstan), [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer), [php-cs-fixer](http://cs.sensiolabs.org/) | -| PO | [alex](https://github.com/wooorm/alex) !!, [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html), [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | -| Pod | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | -| Pony | [ponyc](https://github.com/ponylang/ponyc) | -| proto | [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) | -| Pug | [pug-lint](https://github.com/pugjs/pug-lint) | -| Puppet | [languageserver](https://github.com/lingua-pupuli/puppet-editor-services), [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) | -| Python | [autopep8](https://github.com/hhatto/autopep8), [black](https://github.com/ambv/black), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [prospector](http://github.com/landscapeio/prospector), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pyls](https://github.com/palantir/python-language-server), [pyre](https://github.com/facebook/pyre-check), [pylint](https://www.pylint.org/) !!, [yapf](https://github.com/google/yapf) | -| QML | [qmlfmt](https://github.com/jesperhh/qmlfmt), [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) | -| R | [lintr](https://github.com/jimhester/lintr) | -| ReasonML | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server), [refmt](https://github.com/reasonml/reason-cli) | -| reStructuredText | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [rstcheck](https://github.com/myint/rstcheck), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | -| Re:VIEW | [redpen](http://redpen.cc/) | -| RPM spec | [rpmlint](https://github.com/rpm-software-management/rpmlint) (disabled by default; see `:help ale-integration-spec`) | -| Ruby | [brakeman](http://brakemanscanner.org/) !!, [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) !!, [reek](https://github.com/troessner/reek), [rubocop](https://github.com/bbatsov/rubocop), [ruby](https://www.ruby-lang.org), [rufo](https://github.com/ruby-formatter/rufo) | -| Rust | cargo !! (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/), [rustfmt](https://github.com/rust-lang-nursery/rustfmt) | -| SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) | -| SCSS | [prettier](https://github.com/prettier/prettier), [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint), [stylelint](https://github.com/stylelint/stylelint) | -| Scala | [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html), [scalac](http://scala-lang.org), [scalafmt](https://scalameta.org/scalafmt/), [scalastyle](http://www.scalastyle.org) | -| Slim | [slim-lint](https://github.com/sds/slim-lint) | -| SML | [smlnj](http://www.smlnj.org/) | -| Solidity | [solhint](https://github.com/protofire/solhint), [solium](https://github.com/duaraghav8/Solium) | -| Stylus | [stylelint](https://github.com/stylelint/stylelint) | -| SQL | [sqlint](https://github.com/purcell/sqlint) | -| Swift | [swiftlint](https://github.com/realm/SwiftLint), [swiftformat](https://github.com/nicklockwood/SwiftFormat) | -| Tcl | [nagelfar](http://nagelfar.sourceforge.net) !! | -| Terraform | [tflint](https://github.com/wata727/tflint) | -| Texinfo | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)| -| Text^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | -| Thrift | [thrift](http://thrift.apache.org/) | -| TypeScript | [eslint](http://eslint.org/), [prettier](https://github.com/prettier/prettier), [tslint](https://github.com/palantir/tslint), tsserver, typecheck | -| Verilog | [iverilog](https://github.com/steveicarus/iverilog), [verilator](http://www.veripool.org/projects/verilator/wiki/Intro) | -| Vim | [vint](https://github.com/Kuniwak/vint) | -| Vim help^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | -| Vue | [prettier](https://github.com/prettier/prettier), [vls](https://github.com/vuejs/vetur/tree/master/server) | -| XHTML | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | -| XML | [xmllint](http://xmlsoft.org/xmllint.html) | -| YAML | [swaglint](https://github.com/byCedric/swaglint), [yamllint](https://yamllint.readthedocs.io/) | - - - -## 2. Usage - - - -### 2.i Linting - -Once this plugin is installed, while editing your files in supported -languages and tools which have been correctly installed, -this plugin will send the contents of your text buffers to a variety of -programs for checking the syntax and semantics of your programs. By default, -linters will be re-run in the background to check your syntax when you open -new buffers or as you make edits to your files. - -The behaviour of linting can be configured with a variety of options, -documented in [the Vim help file](doc/ale.txt). For more information on the -options ALE offers, consult `:help ale-options` for global options and `:help -ale-linter-options` for options specified to particular linters. - - - -### 2.ii Fixing - -ALE can fix files with the `ALEFix` command. Functions need to be configured -either in each buffer with a `b:ale_fixers`, or globally with `g:ale_fixers`. - -The recommended way to configure fixers is to define a List in an ftplugin file. - -```vim -" In ~/.vim/ftplugin/javascript.vim, or somewhere similar. - -" Fix files with prettier, and then ESLint. -let b:ale_fixers = ['prettier', 'eslint'] -" Equivalent to the above. -let b:ale_fixers = {'javascript': ['prettier', 'eslint']} -``` - -You can also configure your fixers from vimrc using `g:ale_fixers`, before -or after ALE has been loaded. - -```vim -" In ~/.vim/vimrc, or somewhere similar. -let g:ale_fixers = { -\ 'javascript': ['eslint'], -\} -``` - -If you want to automatically fix files when you save them, you need to turn -a setting on in vimrc. - -```vim -" Set this variable to 1 to fix files when you save them. -let g:ale_fix_on_save = 1 -``` - -The `:ALEFixSuggest` command will suggest some supported tools for fixing code. -Both `g:ale_fixers` and `b:ale_fixers` can also accept functions, including -lambda functions, as fixers, for fixing files with custom tools. - -See `:help ale-fix` for complete information on how to fix files with ALE. - - - -### 2.iii Completion - -ALE offers some support for completion via hijacking of omnicompletion while you -type. All of ALE's completion information must come from Language Server -Protocol linters, or from `tsserver` for TypeScript. - -```vim -" Enable completion where available. -let g:ale_completion_enabled = 1 -``` - -See `:help ale-completion` for more information. - - - -### 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. - -On vim/gvim with `balloon` support you can see the information in a tooltip -that appears under the mouse when you mouseover a symbol. - -See `:help ale-hover` for more information. - - - -## 3. Installation - -To install this plugin, you should use one of the following methods. -For Windows users, replace usage of the Unix `~/.vim` directory with -`%USERPROFILE%\vimfiles`, or another directory if you have configured -Vim differently. On Windows, your `~/.vimrc` file will be similarly -stored in `%USERPROFILE%\_vimrc`. - - - -### 3.i. Installation with Vim package management - -In Vim 8 and NeoVim, you can install plugins easily without needing to use -any other tools. Simply clone the plugin into your `pack` directory. - -#### Vim 8 on Unix - -```bash -mkdir -p ~/.vim/pack/git-plugins/start -git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale -``` - -#### NeoVim on Unix - -```bash -mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start -git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale -``` - -#### Vim 8 on Windows - -```bash -# Run these commands in the "Git for Windows" Bash terminal -mkdir -p ~/vimfiles/pack/git-plugins/start -git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale -``` - -#### Generating Vim help files - -You can add the following line to your vimrc files to generate documentation -tags automatically, if you don't have something similar already, so you can use -the `:help` command to consult ALE's online documentation: - -```vim -" Put these lines at the very end of your vimrc file. - -" Load all plugins now. -" Plugins need to be added to runtimepath before helptags can be generated. -packloadall -" Load all of the helptags now, after plugins have been loaded. -" All messages and errors will be ignored. -silent! helptags ALL -``` - - - -### 3.ii. Installation with Pathogen - -To install this module with [Pathogen](https://github.com/tpope/vim-pathogen), -you should clone this repository to your bundle directory, and ensure -you have the line `execute pathogen#infect()` in your `~/.vimrc` file. -You can run the following commands in your terminal to do so: - -```bash -cd ~/.vim/bundle -git clone https://github.com/w0rp/ale.git -``` - - - -### 3.iii. Installation with Vundle - -You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.vim) -by using the path on GitHub for this repository. - -```vim -Plugin 'w0rp/ale' -``` - -See the Vundle documentation for more information. - - - -## 4. Contributing - -If you would like to see support for more languages and tools, please -[create an issue](https://github.com/w0rp/ale/issues) -or [create a pull request](https://github.com/w0rp/ale/pulls). -If your tool can read from stdin or you have code to suggest which is good, -support can be happily added for it. - -If you are interested in the general direction of the project, check out the -[wiki home page](https://github.com/w0rp/ale/wiki). The wiki includes a -Roadmap for the future, and more. - -If you'd liked to discuss the project more directly, check out the `#vim-ale` channel -on Freenode. Web chat is available [here](https://webchat.freenode.net/?channels=vim-ale). - - - -## 5. FAQ - - - -### 5.i. How do I disable particular linters? - -By default, all available tools for all supported languages will be run. If you -want to only select a subset of the tools, 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 keep the sign gutter open? - -You can keep the sign gutter open at all times by setting the -`g:ale_sign_column_always` to 1 - -```vim -let g:ale_sign_column_always = 1 -``` - - - -### 5.iii. How can I change the signs ALE uses? - -Use these options to specify what text should be used for signs: - -```vim -let g:ale_sign_error = '>>' -let g:ale_sign_warning = '--' -``` - -ALE sets some background colors automatically for warnings and errors -in the sign gutter, with the names `ALEErrorSign` and `ALEWarningSign`. -These colors can be customised, or even removed completely: - -```vim -highlight clear ALEErrorSign -highlight clear ALEWarningSign -``` - - - -### 5.iv. How can I 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.v. How can I show errors or warnings in my statusline? - -[vim-airline](https://github.com/vim-airline/vim-airline) integrates with ALE -for displaying error information in the status bar. If you want to see the -status for ALE in a nice format, it is recommended to use vim-airline with ALE. -The airline extension can be enabled by adding the following to your vimrc: - -```vim -" Set this. Airline will handle the rest. -let g:airline#extensions#ale#enabled = 1 -``` - -If you don't want to use vim-airline, you can implement your own statusline -function without adding any other plugins. ALE provides a function for counting -the number of problems for this purpose, named `ale#statusline#Count`. - -Say you want to display all errors as one figure, and all non-errors as another -figure. You can do the following: - -```vim -function! LinterStatus() abort - let l:counts = ale#statusline#Count(bufnr('')) - - let l:all_errors = l:counts.error + l:counts.style_error - let l:all_non_errors = l:counts.total - l:all_errors - - return l:counts.total == 0 ? 'OK' : printf( - \ '%dW %dE', - \ all_non_errors, - \ all_errors - \) -endfunction - -set statusline=%{LinterStatus()} -``` - -See `:help ale#statusline#Count()` for more information. - - - -### 5.vi. How can I show errors or warnings in my lightline? - -[lightline](https://github.com/itchyny/lightline.vim) does not have built-in -support for ALE, nevertheless there is a plugin that adds this functionality: [maximbaz/lightline-ale](https://github.com/maximbaz/lightline-ale). - -For more information, check out the sources of that plugin, `:help ale#statusline#Count()` and [lightline documentation](https://github.com/itchyny/lightline.vim#advanced-configuration). - - - -### 5.vii. How can I change the format for echo messages? - -There are 3 global options that allow customizing the echoed message. - -- `g:ale_echo_msg_format` where: - * `%s` is the error message itself - * `%...code...%` is an optional error code, and most characters can be - written between the `%` characters. - * `%linter%` is the linter name - * `%severity` is the severity type -- `g:ale_echo_msg_error_str` is the string used for error severity. -- `g:ale_echo_msg_warning_str` is the string used for warning severity. - -So for example this: - -```vim -let g:ale_echo_msg_error_str = 'E' -let g:ale_echo_msg_warning_str = 'W' -let g:ale_echo_msg_format = '[%linter%] %s [%severity%]' -``` - -Will give you: - -![Echoed message](img/echo.png) - -See `:help g:ale_echo_msg_format` for more information. - - - -### 5.viii. How can I execute some code when ALE starts or stops linting? - -ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html) -events when a lint or fix cycle are started and stopped. There is also an event -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.ix. 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.x. How can I run linters only when I save files? - -ALE offers an option `g:ale_lint_on_save` for enabling running the linters -when files are saved. This option is enabled by default. If you only -wish to run linters when files are saved, you can turn the other -options off. - -```vim -" Write this in your vimrc file -let g:ale_lint_on_text_changed = 'never' -" You can disable this option too -" if you don't want linters to run on opening a file -let g:ale_lint_on_enter = 0 -``` - -If for whatever reason you don't wish to run linters again when you save -files, you can set `g:ale_lint_on_save` to `0`. - - - -### 5.xi. How can I use the quickfix list instead of the loclist? - -The quickfix list can be enabled by turning the `g:ale_set_quickfix` -option on. If you wish to also disable the loclist, you can disable -the `g:ale_set_loclist` option. - -```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.xii. How can I check JSX files with both stylelint and eslint? - -If you configure ALE options correctly in your vimrc file, and install -the right tools, you can check JSX files with stylelint and eslint. - -First, install eslint and install stylelint with -[stylelint-processor-styled-components](https://github.com/styled-components/stylelint-processor-styled-components). - -Supposing you have installed both tools correctly, configure your .jsx files so -`jsx` is included in the filetype. You can use an `autocmd` for this. - -```vim -augroup FiletypeGroup - autocmd! - au BufNewFile,BufRead *.jsx set filetype=javascript.jsx -augroup END -``` - -Supposing the filetype has been set correctly, you can set the following -options in a jsx.vim ftplugin file. - -```vim -" In ~/.vim/ftplugin/jsx.vim, or somewhere similar. -let b:ale_linters = ['stylelint', 'eslint'] -let b:ale_linter_aliases = ['css'] -``` - -Or if you want, you can configure the linters from your vimrc file. - -```vim -" In ~/.vim/vimrc, or somewhere similar. -let g:ale_linters = {'jsx': ['stylelint', 'eslint']} -let g:ale_linter_aliases = {'jsx': 'css'} -``` - -ALE will alias the `jsx` filetype so it uses the `css` filetype linters, and -use the original Array of selected linters for `jsx` from the `g:ale_linters` -object. All available linters will be used for the filetype `javascript`, and -no linter will be run twice for the same file. - - - -### 5.xiii. Will this plugin eat all of my laptop battery power? - -ALE takes advantage of the power of various tools to check your code. This of -course means that CPU time will be used to continuously check your code. If you -are concerned about the CPU time ALE will spend, which will of course imply -some cost to battery life, you can adjust your settings to make your CPU do -less work. - -First, consider increasing the delay before which ALE will run any linters -while you type. ALE uses a timeout which is cancelled and reset every time you -type, and this delay can be increased so linters are run less often. See -`:help g:ale_lint_delay` for more information. - -If you don't wish to run linters while you type, you can disable that -behaviour. Set `g:ale_lint_on_text_changed` to `never` or `normal`. You won't -get as frequent error checking, but ALE shouldn't block your ability to edit a -document after you save a file, so the asynchronous nature of the plugin will -still be an advantage. - -If you are still concerned, you can turn the automatic linting off altogether, -including the option `g:ale_lint_on_enter`, and you can run ALE manually with -`:ALELint`. - - - -### 5.xiv. How can I configure my C or C++ project? - -The structure of C and C++ projects varies wildly from project to project, with -many different build tools being used for building them, and many different -formats for project configuration files. ALE can run compilers easily, but -ALE cannot easily detect which compiler flags to use. - -Some tools and build configurations can generate -[compile_commands.json](https://clang.llvm.org/docs/JSONCompilationDatabase.html) -files. The `cppcheck`, `clangcheck`, `clangtidy` and `cquery` linters can read -these files for automatically determining the appropriate compiler flags to -use. - -For linting with compilers like `gcc` and `clang`, and with other tools, you -will need to tell ALE which compiler flags to use yourself. You can use -different options for different projects with the `g:ale_pattern_options` -setting. Consult the documentation for that setting for more information. -`b:ale_linters` can be used to select which tools you want to run, say if you -want to use only `gcc` for one project, and only `clang` for another. - -You may also configure buffer-local settings for linters with project-specific -vimrc files. [local_vimrc](https://github.com/LucHermitte/local_vimrc) can be -used for executing local vimrc files which can be shared in your project. - - - -### 5.xv. How can I configure ALE differently for different buffers? - -ALE offers various ways to configure which linters or fixers are run, and -other settings. For the majority of ALE's settings, they can either be -configured globally with a `g:` variable prefix, or for a specific buffer -with a `b:` variable prefix. For example, you can configure a Python ftplugin -file like so. - -```vim -" In ~/.vim/ftplugin/python.vim - -" Check Python files with flake8 and pylint. -let b:ale_linters = ['flake8', 'pylint'] -" Fix Python files with autopep8 and yapf. -let b:ale_fixers = ['autopep8', 'yapf'] -" Disable warnings about trailing whitespace for Python files. -let b:ale_warn_about_trailing_whitespace = 0 -``` - -For configuring files based on regular expression patterns matched against the -absolute path to a file, you can use `g:ale_pattern_options`. - -```vim -" Do not lint or fix minified files. -let g:ale_pattern_options = { -\ '\.min\.js$': {'ale_linters': [], 'ale_fixers': []}, -\ '\.min\.css$': {'ale_linters': [], 'ale_fixers': []}, -\} -" If you configure g:ale_pattern_options outside of vimrc, you need this. -let g:ale_pattern_options_enabled = 1 -``` - -Buffer-local variables for settings always override the global settings. - - - -### 5.xvi. How can I configure the height of the list in which ALE displays errors? - -To set a default height for the error list, use the `g:ale_list_window_size` variable. - -```vim -" Show 5 lines of errors (default: 10) -let g:ale_list_window_size = 5 -``` diff --git a/README.md b/README.md new file mode 100644 index 00000000..6196512d --- /dev/null +++ b/README.md @@ -0,0 +1,818 @@ +# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) + + +![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true) + +ALE (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim +0.2.0+ and Vim 8 while you edit your text files, and acts as a Vim +[Language Server Protocol](https://langserver.org/) client. + +![linting example](img/example.gif?raw=true) + +ALE makes use of NeoVim and Vim 8 job control functions and timers to +run linters on the contents of text buffers and return errors as +text is changed in Vim. This allows for displaying warnings and +errors in files being edited in Vim before files have been saved +back to a filesystem. + +In other words, this plugin allows you to lint while you type. + +ALE offers support for fixing code with command line tools in a non-blocking +manner with the `:ALEFix` feature, supporting tools in many languages, like +`prettier`, `eslint`, `autopep8`, and more. + +ALE acts as a "language client" to support a variety of Language Server Protocol +features, including: + +* Diagnostics (via Language Server Protocol linters) +* Go To Definition (`:ALEGoToDefinition`) +* Completion (`let g:ale_completion_enabled = 1`) +* Finding references (`:ALEFindReferences`) +* Hover information (`:ALEHover`) + +If you don't care about Language Server Protocol, ALE won't load any of the code +for working with it unless needed. One of ALE's general missions is that you +won't pay for the features that you don't use. + +## Table of Contents + +1. [Supported Languages and Tools](#supported-languages) +2. [Usage](#usage) + 1. [Linting](#usage-linting) + 2. [Fixing](#usage-fixing) + 3. [Completion](#usage-completion) + 4. [Go To Definition](#usage-go-to-definition) + 5. [Find References](#usage-find-references) + 6. [Hovering](#usage-hover) +3. [Installation](#installation) + 1. [Installation with Vim package management](#standard-installation) + 2. [Installation with Pathogen](#installation-with-pathogen) + 3. [Installation with Vundle](#installation-with-vundle) +4. [Contributing](#contributing) +5. [FAQ](#faq) + 1. [How do I disable particular linters?](#faq-disable-linters) + 2. [How can I keep the sign gutter open?](#faq-keep-signs) + 3. [How can I change the signs ALE uses?](#faq-change-signs) + 4. [How can I change or disable the highlights ALE uses?](#faq-change-highlights) + 5. [How can I show errors or warnings in my statusline?](#faq-statusline) + 6. [How can I show errors or warnings in my lightline?](#faq-lightline) + 7. [How can I change the format for echo messages?](#faq-echo-format) + 8. [How can I execute some code when ALE starts or stops linting?](#faq-autocmd) + 9. [How can I navigate between errors quickly?](#faq-navigation) + 10. [How can I run linters only when I save files?](#faq-lint-on-save) + 11. [How can I use the quickfix list instead of the loclist?](#faq-quickfix) + 12. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint) + 13. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad) + 14. [How can I configure my C or C++ project?](#faq-c-configuration) + 15. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration) + 16. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height) + + + +## 1. 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. + + + +**Notes:** + +* *^ No linters for text or Vim help filetypes are enabled by default.* +* *!! These linters check only files on disk. See `:help ale-lint-file-linters`* + +| Language | Tools | +| -------- | ----- | +| ASM | [gcc](https://gcc.gnu.org) | +| Ansible | [ansible-lint](https://github.com/willthames/ansible-lint) | +| API Blueprint | [drafter](https://github.com/apiaryio/drafter) | +| AsciiDoc | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [write-good](https://github.com/btford/write-good) | +| Awk | [gawk](https://www.gnu.org/software/gawk/)| +| Bash | [language-server](https://github.com/mads-hartmann/bash-language-server), shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | +| Bourne Shell | shell [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | +| C | [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [clang](http://clang.llvm.org/), [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | +| C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) !!, [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) !!, [cquery](https://github.com/cquery-project/cquery), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | +| CUDA | [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) | +| C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) see:`help ale-cs-mcs` for details, [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) !! see:`help ale-cs-mcsc` for details and configuration| +| Chef | [foodcritic](http://www.foodcritic.io/) | +| Clojure | [joker](https://github.com/candid82/joker) | +| CloudFormation | [cfn-python-lint](https://github.com/awslabs/cfn-python-lint) | +| CMake | [cmakelint](https://github.com/richq/cmake-lint) | +| CoffeeScript | [coffee](http://coffeescript.org/), [coffeelint](https://www.npmjs.com/package/coffeelint) | +| Crystal | [crystal](https://crystal-lang.org/) !! | +| CSS | [csslint](http://csslint.net/), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) | +| Cucumber | [cucumber](https://cucumber.io/) | +| Cython (pyrex filetype) | [cython](http://cython.org/) | +| D | [dmd](https://dlang.org/dmd-linux.html) | +| Dafny | [dafny](https://rise4fun.com/Dafny) !! | +| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) | +| Dockerfile | [hadolint](https://github.com/hadolint/hadolint) | +| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!| +| Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) | +| Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) | +| Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) | +| Fish | fish [-n flag](https://linux.die.net/man/1/fish) +| 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 | [gofmt](https://golang.org/cmd/gofmt/), [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/) !!, [golint](https://godoc.org/github.com/golang/lint), [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) !!, [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !! | +| GraphQL | [eslint](http://eslint.org/), [gqlint](https://github.com/happylinks/gqlint), [prettier](https://github.com/prettier/prettier) | +| Haml | [haml-lint](https://github.com/brigade/haml-lint) | +| Handlebars | [ember-template-lint](https://github.com/rwjblue/ember-template-lint) | +| Haskell | [brittany](https://github.com/lspitzner/brittany), [ghc](https://www.haskell.org/ghc/), [stack-ghc](https://haskellstack.org/), [stack-build](https://haskellstack.org/) !!, [ghc-mod](https://github.com/DanielG/ghc-mod), [stack-ghc-mod](https://github.com/DanielG/ghc-mod), [hlint](https://hackage.haskell.org/package/hlint), [hdevtools](https://hackage.haskell.org/package/hdevtools), [hfmt](https://github.com/danstiner/hfmt) | +| HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [write-good](https://github.com/btford/write-good) | +| Idris | [idris](http://www.idris-lang.org/) | +| Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/) | +| JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint-cli), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo) +| JSON | [fixjson](https://github.com/rhysd/fixjson), [jsonlint](http://zaa.ch/jsonlint/), [jq](https://stedolan.github.io/jq/), [prettier](https://github.com/prettier/prettier) | +| Kotlin | [kotlinc](https://kotlinlang.org) !!, [ktlint](https://ktlint.github.io) !!, [languageserver](https://github.com/fwcd/KotlinLanguageServer) see `:help ale-integration-kotlin` for configuration instructions | +| LaTeX | [alex](https://github.com/wooorm/alex) !!, [chktex](http://www.nongnu.org/chktex/), [lacheck](https://www.ctan.org/pkg/lacheck), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | +| Less | [lessc](https://www.npmjs.com/package/less), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) | +| LLVM | [llc](https://llvm.org/docs/CommandGuide/llc.html) | +| Lua | [luac](https://www.lua.org/manual/5.1/luac.html), [luacheck](https://github.com/mpeterv/luacheck) | +| Mail | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [vale](https://github.com/ValeLint/vale) | +| Make | [checkmake](https://github.com/mrtazz/checkmake) | +| Markdown | [alex](https://github.com/wooorm/alex) !!, [markdownlint](https://github.com/DavidAnson/markdownlint) !!, [mdl](https://github.com/mivok/markdownlint), [prettier](https://github.com/prettier/prettier), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [remark-lint](https://github.com/wooorm/remark-lint), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | +| MATLAB | [mlint](https://www.mathworks.com/help/matlab/ref/mlint.html) | +| Mercury | [mmc](http://mercurylang.org) !! | +| NASM | [nasm](https://www.nasm.us/) !! | +| Nim | [nim check](https://nim-lang.org/docs/nimc.html) !! | +| nix | [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) | +| nroff | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)| +| Objective-C | [clang](http://clang.llvm.org/) | +| Objective-C++ | [clang](http://clang.llvm.org/) | +| OCaml | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-ocaml-merlin` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server) | +| Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic), [perltidy](https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy) | +| PHP | [hack](http://hacklang.org/), [hackfmt](https://github.com/facebook/flow/tree/master/hack/hackfmt), [langserver](https://github.com/felixfbecker/php-language-server), [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions, [php -l](https://secure.php.net/), [phpcs](https://github.com/squizlabs/PHP_CodeSniffer), [phpmd](https://phpmd.org), [phpstan](https://github.com/phpstan/phpstan), [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer), [php-cs-fixer](http://cs.sensiolabs.org/) | +| PO | [alex](https://github.com/wooorm/alex) !!, [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html), [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | +| Pod | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | +| Pony | [ponyc](https://github.com/ponylang/ponyc) | +| proto | [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) | +| Pug | [pug-lint](https://github.com/pugjs/pug-lint) | +| Puppet | [languageserver](https://github.com/lingua-pupuli/puppet-editor-services), [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) | +| Python | [autopep8](https://github.com/hhatto/autopep8), [black](https://github.com/ambv/black), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [prospector](http://github.com/landscapeio/prospector), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pyls](https://github.com/palantir/python-language-server), [pyre](https://github.com/facebook/pyre-check), [pylint](https://www.pylint.org/) !!, [yapf](https://github.com/google/yapf) | +| QML | [qmlfmt](https://github.com/jesperhh/qmlfmt), [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) | +| R | [lintr](https://github.com/jimhester/lintr) | +| ReasonML | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server), [refmt](https://github.com/reasonml/reason-cli) | +| reStructuredText | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [rstcheck](https://github.com/myint/rstcheck), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | +| Re:VIEW | [redpen](http://redpen.cc/) | +| RPM spec | [rpmlint](https://github.com/rpm-software-management/rpmlint) (disabled by default; see `:help ale-integration-spec`) | +| Ruby | [brakeman](http://brakemanscanner.org/) !!, [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) !!, [reek](https://github.com/troessner/reek), [rubocop](https://github.com/bbatsov/rubocop), [ruby](https://www.ruby-lang.org), [rufo](https://github.com/ruby-formatter/rufo) | +| Rust | cargo !! (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/), [rustfmt](https://github.com/rust-lang-nursery/rustfmt) | +| SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) | +| SCSS | [prettier](https://github.com/prettier/prettier), [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint), [stylelint](https://github.com/stylelint/stylelint) | +| Scala | [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html), [scalac](http://scala-lang.org), [scalafmt](https://scalameta.org/scalafmt/), [scalastyle](http://www.scalastyle.org) | +| Slim | [slim-lint](https://github.com/sds/slim-lint) | +| SML | [smlnj](http://www.smlnj.org/) | +| Solidity | [solhint](https://github.com/protofire/solhint), [solium](https://github.com/duaraghav8/Solium) | +| Stylus | [stylelint](https://github.com/stylelint/stylelint) | +| SQL | [sqlint](https://github.com/purcell/sqlint) | +| Swift | [swiftlint](https://github.com/realm/SwiftLint), [swiftformat](https://github.com/nicklockwood/SwiftFormat) | +| Tcl | [nagelfar](http://nagelfar.sourceforge.net) !! | +| Terraform | [tflint](https://github.com/wata727/tflint) | +| Texinfo | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)| +| Text^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | +| Thrift | [thrift](http://thrift.apache.org/) | +| TypeScript | [eslint](http://eslint.org/), [prettier](https://github.com/prettier/prettier), [tslint](https://github.com/palantir/tslint), tsserver, typecheck | +| Verilog | [iverilog](https://github.com/steveicarus/iverilog), [verilator](http://www.veripool.org/projects/verilator/wiki/Intro) | +| Vim | [vint](https://github.com/Kuniwak/vint) | +| Vim help^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | +| Vue | [prettier](https://github.com/prettier/prettier), [vls](https://github.com/vuejs/vetur/tree/master/server) | +| XHTML | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | +| XML | [xmllint](http://xmlsoft.org/xmllint.html) | +| YAML | [swaglint](https://github.com/byCedric/swaglint), [yamllint](https://yamllint.readthedocs.io/) | + + + +## 2. Usage + + + +### 2.i Linting + +Once this plugin is installed, while editing your files in supported +languages and tools which have been correctly installed, +this plugin will send the contents of your text buffers to a variety of +programs for checking the syntax and semantics of your programs. By default, +linters will be re-run in the background to check your syntax when you open +new buffers or as you make edits to your files. + +The behaviour of linting can be configured with a variety of options, +documented in [the Vim help file](doc/ale.txt). For more information on the +options ALE offers, consult `:help ale-options` for global options and `:help +ale-linter-options` for options specified to particular linters. + + + +### 2.ii Fixing + +ALE can fix files with the `ALEFix` command. Functions need to be configured +either in each buffer with a `b:ale_fixers`, or globally with `g:ale_fixers`. + +The recommended way to configure fixers is to define a List in an ftplugin file. + +```vim +" In ~/.vim/ftplugin/javascript.vim, or somewhere similar. + +" Fix files with prettier, and then ESLint. +let b:ale_fixers = ['prettier', 'eslint'] +" Equivalent to the above. +let b:ale_fixers = {'javascript': ['prettier', 'eslint']} +``` + +You can also configure your fixers from vimrc using `g:ale_fixers`, before +or after ALE has been loaded. + +```vim +" In ~/.vim/vimrc, or somewhere similar. +let g:ale_fixers = { +\ 'javascript': ['eslint'], +\} +``` + +If you want to automatically fix files when you save them, you need to turn +a setting on in vimrc. + +```vim +" Set this variable to 1 to fix files when you save them. +let g:ale_fix_on_save = 1 +``` + +The `:ALEFixSuggest` command will suggest some supported tools for fixing code. +Both `g:ale_fixers` and `b:ale_fixers` can also accept functions, including +lambda functions, as fixers, for fixing files with custom tools. + +See `:help ale-fix` for complete information on how to fix files with ALE. + + + +### 2.iii Completion + +ALE offers some support for completion via hijacking of omnicompletion while you +type. All of ALE's completion information must come from Language Server +Protocol linters, or from `tsserver` for TypeScript. + +```vim +" Enable completion where available. +let g:ale_completion_enabled = 1 +``` + +See `:help ale-completion` for more information. + + + +### 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. + +On vim/gvim with `balloon` support you can see the information in a tooltip +that appears under the mouse when you mouseover a symbol. + +See `:help ale-hover` for more information. + + + +## 3. Installation + +To install this plugin, you should use one of the following methods. +For Windows users, replace usage of the Unix `~/.vim` directory with +`%USERPROFILE%\vimfiles`, or another directory if you have configured +Vim differently. On Windows, your `~/.vimrc` file will be similarly +stored in `%USERPROFILE%\_vimrc`. + + + +### 3.i. Installation with Vim package management + +In Vim 8 and NeoVim, you can install plugins easily without needing to use +any other tools. Simply clone the plugin into your `pack` directory. + +#### Vim 8 on Unix + +```bash +mkdir -p ~/.vim/pack/git-plugins/start +git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale +``` + +#### NeoVim on Unix + +```bash +mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start +git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale +``` + +#### Vim 8 on Windows + +```bash +# Run these commands in the "Git for Windows" Bash terminal +mkdir -p ~/vimfiles/pack/git-plugins/start +git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale +``` + +#### Generating Vim help files + +You can add the following line to your vimrc files to generate documentation +tags automatically, if you don't have something similar already, so you can use +the `:help` command to consult ALE's online documentation: + +```vim +" Put these lines at the very end of your vimrc file. + +" Load all plugins now. +" Plugins need to be added to runtimepath before helptags can be generated. +packloadall +" Load all of the helptags now, after plugins have been loaded. +" All messages and errors will be ignored. +silent! helptags ALL +``` + + + +### 3.ii. Installation with Pathogen + +To install this module with [Pathogen](https://github.com/tpope/vim-pathogen), +you should clone this repository to your bundle directory, and ensure +you have the line `execute pathogen#infect()` in your `~/.vimrc` file. +You can run the following commands in your terminal to do so: + +```bash +cd ~/.vim/bundle +git clone https://github.com/w0rp/ale.git +``` + + + +### 3.iii. Installation with Vundle + +You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.vim) +by using the path on GitHub for this repository. + +```vim +Plugin 'w0rp/ale' +``` + +See the Vundle documentation for more information. + + + +## 4. Contributing + +If you would like to see support for more languages and tools, please +[create an issue](https://github.com/w0rp/ale/issues) +or [create a pull request](https://github.com/w0rp/ale/pulls). +If your tool can read from stdin or you have code to suggest which is good, +support can be happily added for it. + +If you are interested in the general direction of the project, check out the +[wiki home page](https://github.com/w0rp/ale/wiki). The wiki includes a +Roadmap for the future, and more. + +If you'd liked to discuss the project more directly, check out the `#vim-ale` channel +on Freenode. Web chat is available [here](https://webchat.freenode.net/?channels=vim-ale). + + + +## 5. FAQ + + + +### 5.i. How do I disable particular linters? + +By default, all available tools for all supported languages will be run. If you +want to only select a subset of the tools, 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 keep the sign gutter open? + +You can keep the sign gutter open at all times by setting the +`g:ale_sign_column_always` to 1 + +```vim +let g:ale_sign_column_always = 1 +``` + + + +### 5.iii. How can I change the signs ALE uses? + +Use these options to specify what text should be used for signs: + +```vim +let g:ale_sign_error = '>>' +let g:ale_sign_warning = '--' +``` + +ALE sets some background colors automatically for warnings and errors +in the sign gutter, with the names `ALEErrorSign` and `ALEWarningSign`. +These colors can be customised, or even removed completely: + +```vim +highlight clear ALEErrorSign +highlight clear ALEWarningSign +``` + + + +### 5.iv. How can I 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.v. How can I show errors or warnings in my statusline? + +[vim-airline](https://github.com/vim-airline/vim-airline) integrates with ALE +for displaying error information in the status bar. If you want to see the +status for ALE in a nice format, it is recommended to use vim-airline with ALE. +The airline extension can be enabled by adding the following to your vimrc: + +```vim +" Set this. Airline will handle the rest. +let g:airline#extensions#ale#enabled = 1 +``` + +If you don't want to use vim-airline, you can implement your own statusline +function without adding any other plugins. ALE provides a function for counting +the number of problems for this purpose, named `ale#statusline#Count`. + +Say you want to display all errors as one figure, and all non-errors as another +figure. You can do the following: + +```vim +function! LinterStatus() abort + let l:counts = ale#statusline#Count(bufnr('')) + + let l:all_errors = l:counts.error + l:counts.style_error + let l:all_non_errors = l:counts.total - l:all_errors + + return l:counts.total == 0 ? 'OK' : printf( + \ '%dW %dE', + \ all_non_errors, + \ all_errors + \) +endfunction + +set statusline=%{LinterStatus()} +``` + +See `:help ale#statusline#Count()` for more information. + + + +### 5.vi. How can I show errors or warnings in my lightline? + +[lightline](https://github.com/itchyny/lightline.vim) does not have built-in +support for ALE, nevertheless there is a plugin that adds this functionality: [maximbaz/lightline-ale](https://github.com/maximbaz/lightline-ale). + +For more information, check out the sources of that plugin, `:help ale#statusline#Count()` and [lightline documentation](https://github.com/itchyny/lightline.vim#advanced-configuration). + + + +### 5.vii. How can I change the format for echo messages? + +There are 3 global options that allow customizing the echoed message. + +- `g:ale_echo_msg_format` where: + * `%s` is the error message itself + * `%...code...%` is an optional error code, and most characters can be + written between the `%` characters. + * `%linter%` is the linter name + * `%severity` is the severity type +- `g:ale_echo_msg_error_str` is the string used for error severity. +- `g:ale_echo_msg_warning_str` is the string used for warning severity. + +So for example this: + +```vim +let g:ale_echo_msg_error_str = 'E' +let g:ale_echo_msg_warning_str = 'W' +let g:ale_echo_msg_format = '[%linter%] %s [%severity%]' +``` + +Will give you: + +![Echoed message](img/echo.png) + +See `:help g:ale_echo_msg_format` for more information. + + + +### 5.viii. How can I execute some code when ALE starts or stops linting? + +ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html) +events when a lint or fix cycle are started and stopped. There is also an event +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.ix. 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.x. How can I run linters only when I save files? + +ALE offers an option `g:ale_lint_on_save` for enabling running the linters +when files are saved. This option is enabled by default. If you only +wish to run linters when files are saved, you can turn the other +options off. + +```vim +" Write this in your vimrc file +let g:ale_lint_on_text_changed = 'never' +" You can disable this option too +" if you don't want linters to run on opening a file +let g:ale_lint_on_enter = 0 +``` + +If for whatever reason you don't wish to run linters again when you save +files, you can set `g:ale_lint_on_save` to `0`. + + + +### 5.xi. How can I use the quickfix list instead of the loclist? + +The quickfix list can be enabled by turning the `g:ale_set_quickfix` +option on. If you wish to also disable the loclist, you can disable +the `g:ale_set_loclist` option. + +```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.xii. How can I check JSX files with both stylelint and eslint? + +If you configure ALE options correctly in your vimrc file, and install +the right tools, you can check JSX files with stylelint and eslint. + +First, install eslint and install stylelint with +[stylelint-processor-styled-components](https://github.com/styled-components/stylelint-processor-styled-components). + +Supposing you have installed both tools correctly, configure your .jsx files so +`jsx` is included in the filetype. You can use an `autocmd` for this. + +```vim +augroup FiletypeGroup + autocmd! + au BufNewFile,BufRead *.jsx set filetype=javascript.jsx +augroup END +``` + +Supposing the filetype has been set correctly, you can set the following +options in a jsx.vim ftplugin file. + +```vim +" In ~/.vim/ftplugin/jsx.vim, or somewhere similar. +let b:ale_linters = ['stylelint', 'eslint'] +let b:ale_linter_aliases = ['css'] +``` + +Or if you want, you can configure the linters from your vimrc file. + +```vim +" In ~/.vim/vimrc, or somewhere similar. +let g:ale_linters = {'jsx': ['stylelint', 'eslint']} +let g:ale_linter_aliases = {'jsx': 'css'} +``` + +ALE will alias the `jsx` filetype so it uses the `css` filetype linters, and +use the original Array of selected linters for `jsx` from the `g:ale_linters` +object. All available linters will be used for the filetype `javascript`, and +no linter will be run twice for the same file. + + + +### 5.xiii. Will this plugin eat all of my laptop battery power? + +ALE takes advantage of the power of various tools to check your code. This of +course means that CPU time will be used to continuously check your code. If you +are concerned about the CPU time ALE will spend, which will of course imply +some cost to battery life, you can adjust your settings to make your CPU do +less work. + +First, consider increasing the delay before which ALE will run any linters +while you type. ALE uses a timeout which is cancelled and reset every time you +type, and this delay can be increased so linters are run less often. See +`:help g:ale_lint_delay` for more information. + +If you don't wish to run linters while you type, you can disable that +behaviour. Set `g:ale_lint_on_text_changed` to `never` or `normal`. You won't +get as frequent error checking, but ALE shouldn't block your ability to edit a +document after you save a file, so the asynchronous nature of the plugin will +still be an advantage. + +If you are still concerned, you can turn the automatic linting off altogether, +including the option `g:ale_lint_on_enter`, and you can run ALE manually with +`:ALELint`. + + + +### 5.xiv. How can I configure my C or C++ project? + +The structure of C and C++ projects varies wildly from project to project, with +many different build tools being used for building them, and many different +formats for project configuration files. ALE can run compilers easily, but +ALE cannot easily detect which compiler flags to use. + +Some tools and build configurations can generate +[compile_commands.json](https://clang.llvm.org/docs/JSONCompilationDatabase.html) +files. The `cppcheck`, `clangcheck`, `clangtidy` and `cquery` linters can read +these files for automatically determining the appropriate compiler flags to +use. + +For linting with compilers like `gcc` and `clang`, and with other tools, you +will need to tell ALE which compiler flags to use yourself. You can use +different options for different projects with the `g:ale_pattern_options` +setting. Consult the documentation for that setting for more information. +`b:ale_linters` can be used to select which tools you want to run, say if you +want to use only `gcc` for one project, and only `clang` for another. + +You may also configure buffer-local settings for linters with project-specific +vimrc files. [local_vimrc](https://github.com/LucHermitte/local_vimrc) can be +used for executing local vimrc files which can be shared in your project. + + + +### 5.xv. How can I configure ALE differently for different buffers? + +ALE offers various ways to configure which linters or fixers are run, and +other settings. For the majority of ALE's settings, they can either be +configured globally with a `g:` variable prefix, or for a specific buffer +with a `b:` variable prefix. For example, you can configure a Python ftplugin +file like so. + +```vim +" In ~/.vim/ftplugin/python.vim + +" Check Python files with flake8 and pylint. +let b:ale_linters = ['flake8', 'pylint'] +" Fix Python files with autopep8 and yapf. +let b:ale_fixers = ['autopep8', 'yapf'] +" Disable warnings about trailing whitespace for Python files. +let b:ale_warn_about_trailing_whitespace = 0 +``` + +For configuring files based on regular expression patterns matched against the +absolute path to a file, you can use `g:ale_pattern_options`. + +```vim +" Do not lint or fix minified files. +let g:ale_pattern_options = { +\ '\.min\.js$': {'ale_linters': [], 'ale_fixers': []}, +\ '\.min\.css$': {'ale_linters': [], 'ale_fixers': []}, +\} +" If you configure g:ale_pattern_options outside of vimrc, you need this. +let g:ale_pattern_options_enabled = 1 +``` + +Buffer-local variables for settings always override the global settings. + + + +### 5.xvi. How can I configure the height of the list in which ALE displays errors? + +To set a default height for the error list, use the `g:ale_list_window_size` variable. + +```vim +" Show 5 lines of errors (default: 10) +let g:ale_list_window_size = 5 +``` -- cgit v1.2.3 From f937b98e27b506d6addf5faf53ad0ae34a240f92 Mon Sep 17 00:00:00 2001 From: Kyle Fuller Date: Sun, 22 Jul 2018 16:32:39 +0100 Subject: Make drafter linter use stdin instead of writing to tmp file Writing to a tmp file is unnecessary as drafter will use stdin if a path is not provided. --- ale_linters/apiblueprint/drafter.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/apiblueprint/drafter.vim b/ale_linters/apiblueprint/drafter.vim index 9cded359..198709f9 100644 --- a/ale_linters/apiblueprint/drafter.vim +++ b/ale_linters/apiblueprint/drafter.vim @@ -31,6 +31,6 @@ call ale#linter#Define('apiblueprint', { \ 'name': 'drafter', \ 'output_stream': 'stderr', \ 'executable': 'drafter', -\ 'command': 'drafter --use-line-num --validate %t', +\ 'command': 'drafter --use-line-num --validate', \ 'callback': 'ale_linters#apiblueprint#drafter#HandleErrors', \}) -- cgit v1.2.3 From 6dc737cda1d640d2067b417ec270fbb623e3f960 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 22 Jul 2018 19:04:45 +0100 Subject: Check LSP capabilities before using them --- autoload/ale/completion.vim | 82 ++++++----- autoload/ale/definition.vim | 61 ++++---- autoload/ale/hover.vim | 58 ++++---- autoload/ale/lsp.vim | 154 +++++++++++++-------- autoload/ale/lsp_linter.vim | 56 ++++---- autoload/ale/references.vim | 47 ++++--- test/completion/test_lsp_completion_messages.vader | 31 ++++- test/lsp/test_did_save_event.vader | 6 +- test/lsp/test_lsp_command_formatting.vader | 9 +- test/lsp/test_lsp_connections.vader | 34 +++-- .../test_other_initialize_message_handling.vader | 6 + test/test_find_references.vader | 33 ++++- test/test_go_to_definition.vader | 47 ++++++- 13 files changed, 391 insertions(+), 233 deletions(-) diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index e7da4028..5c054dd7 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -422,54 +422,60 @@ endfunction function! s:GetLSPCompletions(linter) abort let l:buffer = bufnr('') - let l:Callback = a:linter.lsp is# 'tsserver' - \ ? function('ale#completion#HandleTSServerResponse') - \ : function('ale#completion#HandleLSPResponse') - - let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) + let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter) if empty(l:lsp_details) return 0 endif let l:id = l:lsp_details.connection_id + let l:root = l:lsp_details.project_root + + function! OnReady(...) abort closure + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#completion#HandleTSServerResponse') + \ : function('ale#completion#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#Completions( + \ l:buffer, + \ b:ale_completion_info.line, + \ b:ale_completion_info.column, + \ b:ale_completion_info.prefix, + \) + else + " Send a message saying the buffer has changed first, otherwise + " completions won't know what text is nearby. + call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) + + " For LSP completions, we need to clamp the column to the length of + " the line. python-language-server and perhaps others do not implement + " this correctly. + let l:message = ale#lsp#message#Completion( + \ l:buffer, + \ b:ale_completion_info.line, + \ min([ + \ b:ale_completion_info.line_length, + \ b:ale_completion_info.column, + \ ]), + \ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix), + \) + endif - if a:linter.lsp is# 'tsserver' - let l:message = ale#lsp#tsserver_message#Completions( - \ l:buffer, - \ b:ale_completion_info.line, - \ b:ale_completion_info.column, - \ b:ale_completion_info.prefix, - \) - else - " Send a message saying the buffer has changed first, otherwise - " completions won't know what text is nearby. - call ale#lsp#NotifyForChanges(l:lsp_details) - - " For LSP completions, we need to clamp the column to the length of - " the line. python-language-server and perhaps others do not implement - " this correctly. - let l:message = ale#lsp#message#Completion( - \ l:buffer, - \ b:ale_completion_info.line, - \ min([ - \ b:ale_completion_info.line_length, - \ b:ale_completion_info.column, - \ ]), - \ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix), - \) - endif - - let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) + let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) - if l:request_id - let b:ale_completion_info.conn_id = l:id - let b:ale_completion_info.request_id = l:request_id + if l:request_id + let b:ale_completion_info.conn_id = l:id + let b:ale_completion_info.request_id = l:request_id - if has_key(a:linter, 'completion_filter') - let b:ale_completion_info.completion_filter = a:linter.completion_filter + if has_key(a:linter, 'completion_filter') + let b:ale_completion_info.completion_filter = a:linter.completion_filter + endif endif - endif + endfunction + + call ale#lsp#WaitForCapability(l:id, l:root, 'completion', function('OnReady')) endfunction function! ale#completion#GetCompletions() abort diff --git a/autoload/ale/definition.vim b/autoload/ale/definition.vim index 6c70b64c..6c7d7d32 100644 --- a/autoload/ale/definition.vim +++ b/autoload/ale/definition.vim @@ -60,43 +60,50 @@ endfunction function! s:GoToLSPDefinition(linter, options) 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) - let l:Callback = a:linter.lsp is# 'tsserver' - \ ? function('ale#definition#HandleTSServerResponse') - \ : function('ale#definition#HandleLSPResponse') - - let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) + 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 + let l:root = l:lsp_details.project_root + + function! OnReady(...) abort closure + 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, + \ l:line, + \ l:column + \) + else + " Send a message saying the buffer has changed first, or the + " definition position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) + + " For LSP completions, we need to clamp the column to the length of + " the line. python-language-server and perhaps others do not implement + " this correctly. + let l:message = ale#lsp#message#Definition(l:buffer, l:line, l:column) + endif - if a:linter.lsp is# 'tsserver' - let l:message = ale#lsp#tsserver_message#Definition( - \ l:buffer, - \ l:line, - \ l:column - \) - else - " Send a message saying the buffer has changed first, or the - " definition position probably won't make sense. - call ale#lsp#NotifyForChanges(l:lsp_details) - - let l:column = min([l:column, len(getline(l:line))]) - - " For LSP completions, we need to clamp the column to the length of - " the line. python-language-server and perhaps others do not implement - " this correctly. - let l:message = ale#lsp#message#Definition(l:buffer, l:line, l:column) - endif + let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) - let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) + let s:go_to_definition_map[l:request_id] = { + \ 'open_in_tab': get(a:options, 'open_in_tab', 0), + \} + endfunction - let s:go_to_definition_map[l:request_id] = { - \ 'open_in_tab': get(a:options, 'open_in_tab', 0), - \} + call ale#lsp#WaitForCapability(l:id, l:root, 'definition', function('OnReady')) endfunction function! ale#definition#GoTo(options) abort diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim index 6d131adc..5e97e16e 100644 --- a/autoload/ale/hover.vim +++ b/autoload/ale/hover.vim @@ -93,45 +93,51 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort endfunction function! s:ShowDetails(linter, buffer, line, column, opt) abort - let l:Callback = a:linter.lsp is# 'tsserver' - \ ? function('ale#hover#HandleTSServerResponse') - \ : function('ale#hover#HandleLSPResponse') - - let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter, l:Callback) + 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 + let l:root = l:lsp_details.project_root let l:language_id = l:lsp_details.language_id - if a:linter.lsp is# 'tsserver' - let l:column = a:column + function! OnReady(...) abort closure + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#hover#HandleTSServerResponse') + \ : function('ale#hover#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) - let l:message = ale#lsp#tsserver_message#Quickinfo( - \ a:buffer, - \ a:line, - \ l:column - \) - else - " Send a message saying the buffer has changed first, or the - " hover position probably won't make sense. - call ale#lsp#NotifyForChanges(l:lsp_details) + if a:linter.lsp is# 'tsserver' + let l:column = a:column - let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])]) + let l:message = ale#lsp#tsserver_message#Quickinfo( + \ a:buffer, + \ a:line, + \ l:column + \) + else + " Send a message saying the buffer has changed first, or the + " hover position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:root, a:buffer) - let l:message = ale#lsp#message#Hover(a:buffer, a:line, l:column) - endif + let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])]) + + let l:message = ale#lsp#message#Hover(a:buffer, a:line, l:column) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) - let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) + let s:hover_map[l:request_id] = { + \ 'buffer': a:buffer, + \ 'line': a:line, + \ 'column': l:column, + \ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0), + \} + endfunction - let s:hover_map[l:request_id] = { - \ 'buffer': a:buffer, - \ 'line': a:line, - \ 'column': l:column, - \ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0), - \} + call ale#lsp#WaitForCapability(l:id, l:root, 'hover', function('OnReady')) endfunction " Obtain Hover information for the specified position diff --git a/autoload/ale/lsp.vim b/autoload/ale/lsp.vim index 1dac3ab1..312319ab 100644 --- a/autoload/ale/lsp.vim +++ b/autoload/ale/lsp.vim @@ -18,6 +18,7 @@ function! ale#lsp#NewConnection(initialization_options) abort " initialization_options: Options to send to the server. " capabilities: Features the server supports. let l:conn = { + \ 'is_tsserver': 0, \ 'id': '', \ 'data': '', \ 'projects': {}, @@ -188,6 +189,16 @@ function! s:MarkProjectAsInitialized(conn, project) abort " Remove the messages now. let a:conn.message_queue = [] + + " Call capabilities callbacks queued for the project. + for [l:capability, l:Callback] in a:project.capabilities_queue + if a:conn.is_tsserver || a:conn.capabilities[l:capability] + call call(l:Callback, [a:conn.id, a:project.root]) + endif + endfor + + " Clear the queued callbacks now. + let a:project.capabilities_queue = [] endfunction function! s:HandleInitializeResponse(conn, response) abort @@ -302,22 +313,43 @@ function! s:HandleCommandMessage(job_id, message) abort call ale#lsp#HandleMessage(l:conn, a:message) endfunction -function! ale#lsp#RegisterProject(conn, project_root) abort +" Given a connection ID, mark it as a tsserver connection, so it will be +" handled that way. +function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort + let l:conn = s:FindConnection('id', a:conn_id) + + if !empty(l:conn) + let l:conn.is_tsserver = 1 + endif +endfunction + +" Register a project for an LSP connection. +" +" This function will throw if the connection doesn't exist. +function! ale#lsp#RegisterProject(conn_id, project_root) abort + let l:conn = s:FindConnection('id', a:conn_id) + " Empty strings can't be used for Dictionary keys in NeoVim, due to E713. " This appears to be a nonsensical bug in NeoVim. let l:key = empty(a:project_root) ? '<>' : a:project_root - if !has_key(a:conn.projects, l:key) + if !has_key(l:conn.projects, l:key) " Tools without project roots are ready right away, like tsserver. - let a:conn.projects[l:key] = { + let l:conn.projects[l:key] = { + \ 'root': a:project_root, \ 'initialized': empty(a:project_root), \ 'init_request_id': 0, \ 'message_queue': [], + \ 'capabilities_queue': [], \} endif endfunction function! ale#lsp#GetProject(conn, project_root) abort + if empty(a:conn) + return {} + endif + let l:key = empty(a:project_root) ? '<>' : a:project_root return get(a:conn.projects, l:key, {}) @@ -327,7 +359,7 @@ endfunction " " The job ID will be returned for for the program if it ran, otherwise " 0 will be returned. -function! ale#lsp#StartProgram(executable, command, project_root, callback, initialization_options) abort +function! ale#lsp#StartProgram(executable, command, init_options) abort if !executable(a:executable) return 0 endif @@ -335,7 +367,7 @@ function! ale#lsp#StartProgram(executable, command, project_root, callback, init let l:conn = s:FindConnection('executable', a:executable) " Get the current connection or a new one. - let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:initialization_options) + let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:init_options) let l:conn.executable = a:executable if !has_key(l:conn, 'id') || !ale#job#IsRunning(l:conn.id) @@ -353,18 +385,15 @@ function! ale#lsp#StartProgram(executable, command, project_root, callback, init endif let l:conn.id = l:job_id - " Add the callback to the List if it's not there already. - call uniq(sort(add(l:conn.callback_list, a:callback))) - call ale#lsp#RegisterProject(l:conn, a:project_root) return l:job_id endfunction " Connect to an address and set up a callback for handling responses. -function! ale#lsp#ConnectToAddress(address, project_root, callback, initialization_options) abort +function! ale#lsp#ConnectToAddress(address, init_options) abort let l:conn = s:FindConnection('id', a:address) " Get the current connection or a new one. - let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:initialization_options) + let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:init_options) if !has_key(l:conn, 'channel_id') || !ale#socket#IsOpen(l:conn.channel_id) let l:conn.channel_id = ale#socket#Open(a:address, { @@ -377,13 +406,21 @@ function! ale#lsp#ConnectToAddress(address, project_root, callback, initializati endif let l:conn.id = a:address - " Add the callback to the List if it's not there already. - call uniq(sort(add(l:conn.callback_list, a:callback))) - call ale#lsp#RegisterProject(l:conn, a:project_root) return a:address endfunction +" Given a connection ID and a callback, register that callback for handling +" messages if the connection exists. +function! ale#lsp#RegisterCallback(conn_id, callback) abort + let l:conn = s:FindConnection('id', a:conn_id) + + if !empty(l:conn) + " Add the callback to the List if it's not there already. + call uniq(sort(add(l:conn.callback_list, a:callback))) + endif +endfunction + " Stop all LSP connections, closing all jobs and channels, and removing any " queued messages. function! ale#lsp#StopAll() abort @@ -421,11 +458,6 @@ function! ale#lsp#Send(conn_id, message, ...) abort let l:project_root = get(a:000, 0, '') let l:conn = s:FindConnection('id', a:conn_id) - - if empty(l:conn) - return 0 - endif - let l:project = ale#lsp#GetProject(l:conn, l:project_root) if empty(l:project) @@ -459,45 +491,22 @@ function! ale#lsp#Send(conn_id, message, ...) abort return l:id == 0 ? -1 : l:id endfunction -" The Document details Dictionary should contain the following keys. -" -" buffer - The buffer number for the document. -" connection_id - The connection ID for the LSP server. -" command - The command to run to start the LSP connection. -" project_root - The project root for the LSP project. -" language_id - The language ID for the project, like 'python', 'rust', etc. - -" Create a new Dictionary containing more connection details, with the -" following information added: -" -" conn - An existing LSP connection for the document. -" document_open - 1 if the document is currently open, 0 otherwise. -function! s:ExtendDocumentDetails(details) abort - let l:extended = copy(a:details) - let l:conn = s:FindConnection('id', a:details.connection_id) - - let l:extended.conn = l:conn - let l:extended.document_open = !empty(l:conn) - \ && has_key(l:conn.open_documents, a:details.buffer) - - return l:extended -endfunction - " Notify LSP servers or tsserver if a document is opened, if needed. " If a document is opened, 1 will be returned, otherwise 0 will be returned. -function! ale#lsp#OpenDocument(basic_details) abort - let l:d = s:ExtendDocumentDetails(a:basic_details) +function! ale#lsp#OpenDocument(conn_id, project_root, buffer, language_id) abort + let l:conn = s:FindConnection('id', a:conn_id) let l:opened = 0 - if !empty(l:d.conn) && !l:d.document_open - if empty(l:d.language_id) - let l:message = ale#lsp#tsserver_message#Open(l:d.buffer) + " FIXME: Return 1 if the document is already open? + if !empty(l:conn) && !has_key(l:conn.open_documents, a:buffer) + if l:conn.is_tsserver + let l:message = ale#lsp#tsserver_message#Open(a:buffer) else - let l:message = ale#lsp#message#DidOpen(l:d.buffer, l:d.language_id) + let l:message = ale#lsp#message#DidOpen(a:buffer, a:language_id) endif - call ale#lsp#Send(l:d.connection_id, l:message, l:d.project_root) - let l:d.conn.open_documents[l:d.buffer] = getbufvar(l:d.buffer, 'changedtick') + call ale#lsp#Send(a:conn_id, l:message, a:project_root) + let l:conn.open_documents[a:buffer] = getbufvar(a:buffer, 'changedtick') let l:opened = 1 endif @@ -506,25 +515,50 @@ 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(basic_details) abort - let l:d = s:ExtendDocumentDetails(a:basic_details) +function! ale#lsp#NotifyForChanges(conn_id, project_root, buffer) abort + let l:conn = s:FindConnection('id', a:conn_id) let l:notified = 0 - if l:d.document_open - let l:new_tick = getbufvar(l:d.buffer, 'changedtick') + if !empty(l:conn) && has_key(l:conn.open_documents, a:buffer) + let l:new_tick = getbufvar(a:buffer, 'changedtick') - if l:d.conn.open_documents[l:d.buffer] < l:new_tick - if empty(l:d.language_id) - let l:message = ale#lsp#tsserver_message#Change(l:d.buffer) + if l:conn.open_documents[a:buffer] < l:new_tick + if l:conn.is_tsserver + let l:message = ale#lsp#tsserver_message#Change(a:buffer) else - let l:message = ale#lsp#message#DidChange(l:d.buffer) + let l:message = ale#lsp#message#DidChange(a:buffer) endif - call ale#lsp#Send(l:d.connection_id, l:message, l:d.project_root) - let l:d.conn.open_documents[l:d.buffer] = l:new_tick + call ale#lsp#Send(a:conn_id, l:message, a:project_root) + let l:conn.open_documents[a:buffer] = l:new_tick let l:notified = 1 endif endif 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, project_root, capability, callback) abort + let l:conn = s:FindConnection('id', a:conn_id) + let l:project = ale#lsp#GetProject(l:conn, a:project_root) + + if empty(l:project) + return 0 + endif + + if type(get(l:conn.capabilities, a:capability, v:null)) isnot type(0) + throw 'Invalid capability ' . a:capability + endif + + if l:project.initialized + if l:conn.is_tsserver || l:conn.capabilities[a:capability] + " The project has been initialized, so call the callback now. + call call(a:callback, [a:conn_id, a:project_root]) + endif + else + " Call the callback later, once we have the information we need. + call add(l:project.capabilities_queue, [a:capability, a:callback]) + endif +endfunction diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim index 6dc78e4c..87aee759 100644 --- a/autoload/ale/lsp_linter.vim +++ b/autoload/ale/lsp_linter.vim @@ -126,10 +126,9 @@ function! ale#lsp_linter#GetOptions(buffer, linter) abort return l:initialization_options endfunction -" Given a buffer, an LSP linter, and a callback to register for handling -" messages, start up an LSP linter and get ready to receive errors or -" completions. -function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort +" 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) @@ -140,16 +139,11 @@ function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort return {} endif - let l:initialization_options = ale#lsp_linter#GetOptions(a:buffer, a:linter) + let l:init_options = ale#lsp_linter#GetOptions(a:buffer, a:linter) if a:linter.lsp is# 'socket' let l:address = ale#linter#GetAddress(a:buffer, a:linter) - let l:conn_id = ale#lsp#ConnectToAddress( - \ l:address, - \ l:root, - \ a:callback, - \ l:initialization_options, - \) + let l:conn_id = ale#lsp#ConnectToAddress(l:address, l:init_options) else let l:executable = ale#linter#GetExecutable(a:buffer, a:linter) @@ -164,14 +158,10 @@ function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort let l:conn_id = ale#lsp#StartProgram( \ l:executable, \ l:command, - \ l:root, - \ a:callback, - \ l:initialization_options, + \ l:init_options, \) endif - let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer) - if empty(l:conn_id) if g:ale_history_enabled && !empty(l:command) call ale#history#Add(a:buffer, 'failed', l:conn_id, l:command) @@ -180,6 +170,16 @@ function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort return {} endif + " tsserver behaves differently, so tell the LSP API that it is tsserver. + if a:linter.lsp is# 'tsserver' + call ale#lsp#MarkConnectionAsTsserver(l:conn_id) + endif + + " Register the project now the connection is ready. + call ale#lsp#RegisterProject(l:conn_id, l:root) + + let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer) + let l:details = { \ 'buffer': a:buffer, \ 'connection_id': l:conn_id, @@ -188,7 +188,7 @@ function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort \ 'language_id': l:language_id, \} - if ale#lsp#OpenDocument(l:details) + if ale#lsp#OpenDocument(l:conn_id, l:root, 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 @@ -196,7 +196,7 @@ function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort " The change message needs to be sent for tsserver before doing anything. if a:linter.lsp is# 'tsserver' - call ale#lsp#NotifyForChanges(l:details) + call ale#lsp#NotifyForChanges(l:conn_id, l:root, a:buffer) endif return l:details @@ -204,11 +204,7 @@ 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('ale#lsp_linter#HandleLSPResponse'), - \) + let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter) if empty(l:lsp_details) return 0 @@ -217,25 +213,25 @@ function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort let l:id = l:lsp_details.connection_id let l:root = l:lsp_details.project_root + " Register a callback now for handling errors now. + let l:Callback = function('ale#lsp_linter#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + " Remember the linter this connection is for. let s:lsp_linter_map[l:id] = a:linter.name if a:linter.lsp is# 'tsserver' let l:message = ale#lsp#tsserver_message#Geterr(a:buffer) - let l:request_id = ale#lsp#Send(l:id, l:message, l:root) - - let l:notified = l:request_id != 0 + let l:notified = ale#lsp#Send(l:id, l:message, l:root) != 0 else - let l:notified = ale#lsp#NotifyForChanges(l:lsp_details) + let l:notified = ale#lsp#NotifyForChanges(l:id, l:root, a: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) - let l:request_id = ale#lsp#Send(l:id, l:save_message, l:root) - - let l:notified = l:request_id != 0 + let l:notified = ale#lsp#Send(l:id, l:save_message, l:root) != 0 endif if l:notified diff --git a/autoload/ale/references.vim b/autoload/ale/references.vim index 89df69eb..3a710b7b 100644 --- a/autoload/ale/references.vim +++ b/autoload/ale/references.vim @@ -68,37 +68,46 @@ function! s:FindReferences(linter) abort let l:buffer = bufnr('') let [l:line, l:column] = getcurpos()[1:2] - let l:Callback = a:linter.lsp is# 'tsserver' - \ ? function('ale#references#HandleTSServerResponse') - \ : function('ale#references#HandleLSPResponse') + if a:linter.lsp isnot# 'tsserver' + let l:column = min([l:column, len(getline(l:line))]) + endif - let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) + let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter) if empty(l:lsp_details) return 0 endif let l:id = l:lsp_details.connection_id + let l:root = l:lsp_details.project_root - if a:linter.lsp is# 'tsserver' - let l:message = ale#lsp#tsserver_message#References( - \ l:buffer, - \ l:line, - \ l:column - \) - else - " Send a message saying the buffer has changed first, or the - " references position probably won't make sense. - call ale#lsp#NotifyForChanges(l:lsp_details) + function! OnReady(...) abort closure + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#references#HandleTSServerResponse') + \ : function('ale#references#HandleLSPResponse') - let l:column = min([l:column, len(getline(l:line))]) + call ale#lsp#RegisterCallback(l:id, l:Callback) - let l:message = ale#lsp#message#References(l:buffer, l:line, l:column) - endif + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#References( + \ l:buffer, + \ l:line, + \ l:column + \) + else + " Send a message saying the buffer has changed first, or the + " references position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) + + let l:message = ale#lsp#message#References(l:buffer, l:line, l:column) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) - let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) + let s:references_map[l:request_id] = {} + endfunction - let s:references_map[l:request_id] = {} + call ale#lsp#WaitForCapability(l:id, l:root, 'references', function('OnReady')) endfunction function! ale#references#Find() abort diff --git a/test/completion/test_lsp_completion_messages.vader b/test/completion/test_lsp_completion_messages.vader index 00a174dc..30a9c8e1 100644 --- a/test/completion/test_lsp_completion_messages.vader +++ b/test/completion/test_lsp_completion_messages.vader @@ -13,11 +13,11 @@ Before: runtime autoload/ale/lsp.vim let g:message_list = [] + let g:capability_checked = '' let g:Callback = '' + let g:WaitCallback = v:null - function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort - let g:Callback = a:callback - + function! ale#lsp_linter#StartLSP(buffer, linter) abort let l:conn = ale#lsp#NewConnection({}) let l:conn.id = 347 let l:conn.open_documents = {a:buffer : -1} @@ -35,6 +35,15 @@ Before: return 'i' endfunction + function! ale#lsp#WaitForCapability(conn_id, project_root, capability, callback) abort + let g:capability_checked = a:capability + let g:WaitCallback = a:callback + 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) @@ -44,6 +53,8 @@ After: Restore unlet! g:message_list + unlet! g:capability_checked + unlet! g:WaitCallback unlet! g:Callback unlet! b:ale_old_omnifunc unlet! b:ale_old_completopt @@ -84,6 +95,13 @@ Execute(The right message should be sent for the initial tsserver request): call ale#completion#GetCompletions() + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 'completion', g:capability_checked + call call(g:WaitCallback, [347, '/foo/bar']) + " We should send the right callback. AssertEqual \ 'function(''ale#completion#HandleTSServerResponse'')', @@ -164,6 +182,13 @@ Execute(The right message should be sent for the initial LSP request): call ale#completion#GetCompletions() + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 'completion', g:capability_checked + call call(g:WaitCallback, [347, '/foo/bar']) + " We should send the right callback. AssertEqual \ 'function(''ale#completion#HandleLSPResponse'')', diff --git a/test/lsp/test_did_save_event.vader b/test/lsp/test_did_save_event.vader index b696ee4b..428135fb 100644 --- a/test/lsp/test_did_save_event.vader +++ b/test/lsp/test_did_save_event.vader @@ -14,7 +14,6 @@ Before: let g:ale_lsp_next_message_id = 1 let g:ale_run_synchronously = 1 let g:message_list = [] - let g:Callback = '' function! LanguageCallback() abort return 'foobar' @@ -34,9 +33,7 @@ Before: \ }) let g:ale_linters = {'foobar': ['dummy_linter']} - function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort - let g:Callback = a:callback - + function! ale#lsp_linter#StartLSP(buffer, linter) abort let l:conn = ale#lsp#NewConnection({}) let l:conn.id = 347 let l:conn.open_documents = {a:buffer : -1} @@ -59,7 +56,6 @@ After: unlet! b:ale_enabled unlet! b:ale_linters - unlet! g:Callback unlet! g:message_list delfunction LanguageCallback diff --git a/test/lsp/test_lsp_command_formatting.vader b/test/lsp/test_lsp_command_formatting.vader index f436397f..9d2c84ee 100644 --- a/test/lsp/test_lsp_command_formatting.vader +++ b/test/lsp/test_lsp_command_formatting.vader @@ -23,15 +23,14 @@ Execute(Command formatting should be applied correctly for LSP linters): \ 'executable': has('win32') ? 'cmd': 'true', \ 'command': '%e --foo', \ }, - \ {->0} \) if has('win32') AssertEqual - \ ['cmd', 'cmd /s/c "cmd --foo"', '/foo/bar'], - \ g:args[:2] + \ ['cmd', 'cmd /s/c "cmd --foo"', {}], + \ g:args else AssertEqual - \ ['true', [&shell, '-c', '''true'' --foo'], '/foo/bar'], - \ g:args[:2] + \ ['true', [&shell, '-c', '''true'' --foo'], {}], + \ g:args endif diff --git a/test/lsp/test_lsp_connections.vader b/test/lsp/test_lsp_connections.vader index 8651d801..ae64eadb 100644 --- a/test/lsp/test_lsp_connections.vader +++ b/test/lsp/test_lsp_connections.vader @@ -2,6 +2,10 @@ 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 @@ -223,17 +227,20 @@ Execute(ale#lsp#ReadMessageData() should handle a message with part of a second \ ) Execute(Projects with regular project roots should be registered correctly): - let b:conn = {'projects': {}} - - call ale#lsp#RegisterProject(b:conn, '/foo/bar') + let b:conn = ale#lsp#NewConnection({}) + call ale#lsp#RegisterProject(b:conn.id, '/foo/bar') AssertEqual \ { - \ 'projects': { - \ '/foo/bar': {'initialized': 0, 'message_queue': [], 'init_request_id': 0}, + \ '/foo/bar': { + \ 'root': '/foo/bar', + \ 'initialized': 0, + \ 'message_queue': [], + \ 'capabilities_queue': [], + \ 'init_request_id': 0, \ }, \ }, - \ b:conn + \ b:conn.projects Execute(Projects with regular project roots should be fetched correctly): let b:conn = { @@ -247,17 +254,20 @@ Execute(Projects with regular project roots should be fetched correctly): \ ale#lsp#GetProject(b:conn, '/foo/bar') Execute(Projects with empty project roots should be registered correctly): - let b:conn = {'projects': {}} - - call ale#lsp#RegisterProject(b:conn, '') + let b:conn = ale#lsp#NewConnection({}) + call ale#lsp#RegisterProject(b:conn.id, '') AssertEqual \ { - \ 'projects': { - \ '<>': {'initialized': 1, 'message_queue': [], 'init_request_id': 0}, + \ '<>': { + \ 'root': '', + \ 'initialized': 1, + \ 'message_queue': [], + \ 'capabilities_queue': [], + \ 'init_request_id': 0, \ }, \ }, - \ b:conn + \ b:conn.projects Execute(Projects with empty project roots should be fetched correctly): let b:conn = { diff --git a/test/lsp/test_other_initialize_message_handling.vader b/test/lsp/test_other_initialize_message_handling.vader index f9567ee0..45457979 100644 --- a/test/lsp/test_other_initialize_message_handling.vader +++ b/test/lsp/test_other_initialize_message_handling.vader @@ -3,6 +3,7 @@ Before: \ 'initialized': 0, \ 'init_request_id': 3, \ 'message_queue': [], + \ 'capabilities_queue': [], \} let b:conn = { @@ -34,6 +35,7 @@ Execute(publishDiagnostics messages with files inside project directories should \ 'initialized': 0, \ 'init_request_id': 3, \ 'message_queue': [], + \ 'capabilities_queue': [], \ }, \ b:project @@ -47,6 +49,7 @@ Execute(publishDiagnostics messages with files inside project directories should \ 'initialized': 1, \ 'init_request_id': 3, \ 'message_queue': [], + \ 'capabilities_queue': [], \ }, \ b:project @@ -60,6 +63,7 @@ Execute(Messages with no method and capabilities should initialize projects): \ 'initialized': 1, \ 'init_request_id': 3, \ 'message_queue': [], + \ 'capabilities_queue': [], \ }, \ b:project @@ -120,6 +124,7 @@ Execute(Capabilities should bet set up correctly): \ '/foo/bar': { \ 'initialized': 1, \ 'message_queue': [], + \ 'capabilities_queue': [], \ 'init_request_id': 3, \ }, \ }, @@ -170,6 +175,7 @@ Execute(Disabled capabilities should be recognised correctly): \ '/foo/bar': { \ 'initialized': 1, \ 'message_queue': [], + \ 'capabilities_queue': [], \ 'init_request_id': 3, \ }, \ }, diff --git a/test/test_find_references.vader b/test/test_find_references.vader index 150e0471..ecced068 100644 --- a/test/test_find_references.vader +++ b/test/test_find_references.vader @@ -3,20 +3,20 @@ Before: call ale#test#SetFilename('dummy.txt') let g:old_filename = expand('%:p') - let g:Callback = 0 + let g:Callback = '' let g:expr_list = [] let g:message_list = [] let g:preview_called = 0 let g:item_list = [] + let g:capability_checked = '' + let g:WaitCallback = v:null runtime autoload/ale/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:Callback = a:callback - + function! ale#lsp_linter#StartLSP(buffer, linter) abort let l:conn = ale#lsp#NewConnection({}) let l:conn.id = 347 let l:conn.open_documents = {a:buffer : -1} @@ -29,6 +29,15 @@ Before: \} endfunction + function! ale#lsp#WaitForCapability(conn_id, project_root, capability, callback) abort + let g:capability_checked = a:capability + let g:WaitCallback = a:callback + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + function! ale#lsp#Send(conn_id, message, root) abort call add(g:message_list, a:message) @@ -50,6 +59,8 @@ After: call ale#test#RestoreDirectory() call ale#linter#Reset() + unlet! g:capability_checked + unlet! g:WaitCallback unlet! g:old_filename unlet! g:Callback unlet! g:message_list @@ -152,6 +163,13 @@ Execute(tsserver reference requests should be sent): ALEFindReferences + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 'references', g:capability_checked + call call(g:WaitCallback, [347, '/foo/bar']) + AssertEqual \ 'function(''ale#references#HandleTSServerResponse'')', \ string(g:Callback) @@ -226,6 +244,13 @@ Execute(LSP reference requests should be sent): ALEFindReferences + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 'references', g:capability_checked + call call(g:WaitCallback, [347, '/foo/bar']) + AssertEqual \ 'function(''ale#references#HandleLSPResponse'')', \ string(g:Callback) diff --git a/test/test_go_to_definition.vader b/test/test_go_to_definition.vader index 749f4d7e..7f0e3fcb 100644 --- a/test/test_go_to_definition.vader +++ b/test/test_go_to_definition.vader @@ -3,17 +3,17 @@ Before: call ale#test#SetFilename('dummy.txt') let g:old_filename = expand('%:p') - let g:Callback = 0 + let g:Callback = '' let g:message_list = [] let g:expr_list = [] + let g:capability_checked = '' + let g:WaitCallback = v:null runtime autoload/ale/linter.vim runtime autoload/ale/lsp.vim runtime autoload/ale/util.vim - function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort - let g:Callback = a:callback - + function! ale#lsp_linter#StartLSP(buffer, linter) abort let l:conn = ale#lsp#NewConnection({}) let l:conn.id = 347 let l:conn.open_documents = {a:buffer : -1} @@ -26,6 +26,15 @@ Before: \} endfunction + function! ale#lsp#WaitForCapability(conn_id, project_root, capability, callback) abort + let g:capability_checked = a:capability + let g:WaitCallback = a:callback + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + function! ale#lsp#Send(conn_id, message, root) abort call add(g:message_list, a:message) @@ -42,6 +51,8 @@ After: call ale#test#RestoreDirectory() call ale#linter#Reset() + unlet! g:capability_checked + unlet! g:WaitCallback unlet! g:old_filename unlet! g:Callback unlet! g:message_list @@ -137,6 +148,13 @@ Execute(tsserver completion requests should be sent): ALEGoToDefinition + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 'definition', g:capability_checked + call call(g:WaitCallback, [347, '/foo/bar']) + AssertEqual \ 'function(''ale#definition#HandleTSServerResponse'')', \ string(g:Callback) @@ -151,6 +169,13 @@ Execute(tsserver tab completion requests should be sent): ALEGoToDefinitionInTab + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 'definition', g:capability_checked + call call(g:WaitCallback, [347, '/foo/bar']) + AssertEqual \ 'function(''ale#definition#HandleTSServerResponse'')', \ string(g:Callback) @@ -276,6 +301,13 @@ Execute(LSP completion requests should be sent): ALEGoToDefinition + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 'definition', g:capability_checked + call call(g:WaitCallback, [347, '/foo/bar']) + AssertEqual \ 'function(''ale#definition#HandleLSPResponse'')', \ string(g:Callback) @@ -305,6 +337,13 @@ Execute(LSP tab completion requests should be sent): ALEGoToDefinitionInTab + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 'definition', g:capability_checked + call call(g:WaitCallback, [347, '/foo/bar']) + AssertEqual \ 'function(''ale#definition#HandleLSPResponse'')', \ string(g:Callback) -- cgit v1.2.3 From 9b4963847d71ea7b53c0bf90a27d4b55fc0696fe Mon Sep 17 00:00:00 2001 From: Andrey Melentyev Date: Sun, 22 Jul 2018 19:30:57 +0200 Subject: Add Clangd language server support for C --- README.md | 2 +- ale_linters/c/clangd.vim | 29 ++++++++++++++++++++ doc/ale-c.txt | 19 +++++++++++++ doc/ale.txt | 3 +- .../clangd_paths/compile_commands.json | 0 .../test_c_clangd_command_callbacks.vader | 32 ++++++++++++++++++++++ 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 ale_linters/c/clangd.vim create mode 100644 test/command_callback/clangd_paths/compile_commands.json create mode 100644 test/command_callback/test_c_clangd_command_callbacks.vader diff --git a/README.md b/README.md index 99ea73ed..66a30bf2 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ formatting. | Awk | [gawk](https://www.gnu.org/software/gawk/)| | Bash | [language-server](https://github.com/mads-hartmann/bash-language-server), shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | | Bourne Shell | shell [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | -| C | [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [clang](http://clang.llvm.org/), [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | +| C | [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [clang](http://clang.llvm.org/), [clangd](https://clang.llvm.org/extra/clangd.html), [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | | C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) !!, [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) !!, [cquery](https://github.com/cquery-project/cquery), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) | | CUDA | [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) | | C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) see:`help ale-cs-mcs` for details, [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) !! see:`help ale-cs-mcsc` for details and configuration| diff --git a/ale_linters/c/clangd.vim b/ale_linters/c/clangd.vim new file mode 100644 index 00000000..5aa2e221 --- /dev/null +++ b/ale_linters/c/clangd.vim @@ -0,0 +1,29 @@ +" Author: Andrey Melentyev +" Description: Clangd language server + +call ale#Set('c_clangd_executable', 'clangd') +call ale#Set('c_clangd_options', '') + +function! ale_linters#c#clangd#GetProjectRoot(buffer) abort + let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') + return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' +endfunction + +function! ale_linters#c#clangd#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'c_clangd_executable') +endfunction + +function! ale_linters#c#clangd#GetCommand(buffer) abort + let l:executable = ale_linters#c#clangd#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'c_clangd_options') + + return ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') +endfunction + +call ale#linter#Define('c', { +\ 'name': 'clangd', +\ 'lsp': 'stdio', +\ 'executable_callback': 'ale_linters#c#clangd#GetExecutable', +\ 'command_callback': 'ale_linters#c#clangd#GetCommand', +\ 'project_root_callback': 'ale_linters#c#clangd#GetProjectRoot', +\}) diff --git a/doc/ale-c.txt b/doc/ale-c.txt index c41f3bc8..acff722c 100644 --- a/doc/ale-c.txt +++ b/doc/ale-c.txt @@ -63,6 +63,25 @@ g:ale_c_clang_options *g:ale_c_clang_options* This variable can be changed to modify flags given to clang. +=============================================================================== +clangd *ale-c-clangd* + +g:ale_c_clangd_executable *g:ale_c_clangd_executable* + *b:ale_c_clangd_executable* + Type: |String| + Default: `'clangd'` + + This variable can be changed to use a different executable for clangd. + + +g:ale_c_clangd_options *g:ale_c_clangd_options* + *b:ale_c_clangd_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clangd. + + =============================================================================== clang-format *ale-c-clangformat* diff --git a/doc/ale.txt b/doc/ale.txt index 1a75c29c..8182c27a 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -26,6 +26,7 @@ CONTENTS *ale-contents* gawk................................|ale-awk-gawk| 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| @@ -335,7 +336,7 @@ Notes: * Awk: `gawk` * Bash: `language-server`, `shell` (-n flag), `shellcheck`, `shfmt` * Bourne Shell: `shell` (-n flag), `shellcheck`, `shfmt` -* C: `cppcheck`, `cpplint`!!, `clang`, `clangtidy`!!, `clang-format`, `flawfinder`, `gcc` +* C: `cppcheck`, `cpplint`!!, `clang`, `clangd`, `clangtidy`!!, `clang-format`, `flawfinder`, `gcc` * C++ (filetype cpp): `clang`, `clangcheck`!!, `clangtidy`!!, `clang-format`, `cppcheck`, `cpplint`!!, `cquery`, `flawfinder`, `gcc` * CUDA: `nvcc`!! * C#: `mcs`, `mcsc`!! diff --git a/test/command_callback/clangd_paths/compile_commands.json b/test/command_callback/clangd_paths/compile_commands.json new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/test_c_clangd_command_callbacks.vader b/test/command_callback/test_c_clangd_command_callbacks.vader new file mode 100644 index 00000000..c8c10b67 --- /dev/null +++ b/test/command_callback/test_c_clangd_command_callbacks.vader @@ -0,0 +1,32 @@ +Before: + call ale#assert#SetUpLinterTest('c', 'clangd') + + Save &filetype + let &filetype = 'c' + +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): + AssertLSPProject '' + + call ale#test#SetFilename('clangd_paths/dummy.c') + + AssertLSPProject ale#path#Simplify(g:dir . '/clangd_paths') + +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 + -- cgit v1.2.3 From 81a8c77d2062fb7b9bb85d2835a64f01b80bb2a4 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 22 Jul 2018 21:14:48 +0100 Subject: #1692 - Only send completion requests to the first server supporting them --- autoload/ale/completion.vim | 5 ++ test/completion/test_lsp_completion_messages.vader | 72 ++++++++++++++++++---- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index 5c054dd7..7b3a0e82 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -432,6 +432,11 @@ function! s:GetLSPCompletions(linter) abort let l:root = l:lsp_details.project_root function! OnReady(...) abort closure + " If we have sent a completion request already, don't send another. + if b:ale_completion_info.request_id + return + endif + let l:Callback = a:linter.lsp is# 'tsserver' \ ? function('ale#completion#HandleTSServerResponse') \ : function('ale#completion#HandleLSPResponse') diff --git a/test/completion/test_lsp_completion_messages.vader b/test/completion/test_lsp_completion_messages.vader index 30a9c8e1..ed0f358b 100644 --- a/test/completion/test_lsp_completion_messages.vader +++ b/test/completion/test_lsp_completion_messages.vader @@ -15,7 +15,7 @@ Before: let g:message_list = [] let g:capability_checked = '' let g:Callback = '' - let g:WaitCallback = v:null + let g:wait_callback_list = [] function! ale#lsp_linter#StartLSP(buffer, linter) abort let l:conn = ale#lsp#NewConnection({}) @@ -37,7 +37,7 @@ Before: function! ale#lsp#WaitForCapability(conn_id, project_root, capability, callback) abort let g:capability_checked = a:capability - let g:WaitCallback = a:callback + call add(g:wait_callback_list, a:callback) endfunction function! ale#lsp#RegisterCallback(conn_id, callback) abort @@ -47,6 +47,8 @@ Before: " 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: @@ -54,7 +56,7 @@ After: unlet! g:message_list unlet! g:capability_checked - unlet! g:WaitCallback + unlet! g:wait_callback_list unlet! g:Callback unlet! b:ale_old_omnifunc unlet! b:ale_old_completopt @@ -98,9 +100,9 @@ Execute(The right message should be sent for the initial tsserver request): " We shouldn't register the callback yet. AssertEqual '''''', string(g:Callback) - AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 1, len(g:wait_callback_list) AssertEqual 'completion', g:capability_checked - call call(g:WaitCallback, [347, '/foo/bar']) + call map(g:wait_callback_list, 'v:val([347, ''/foo/bar''])') " We should send the right callback. AssertEqual @@ -114,9 +116,9 @@ Execute(The right message should be sent for the initial tsserver request): AssertEqual \ { \ 'line_length': 3, - \ 'conn_id': 0, + \ 'conn_id': 347, \ 'column': 3, - \ 'request_id': 0, + \ 'request_id': 1, \ 'line': 1, \ 'prefix': 'fo', \ }, @@ -185,9 +187,9 @@ Execute(The right message should be sent for the initial LSP request): " We shouldn't register the callback yet. AssertEqual '''''', string(g:Callback) - AssertEqual type(function('type')), type(g:WaitCallback) + AssertEqual 1, len(g:wait_callback_list) AssertEqual 'completion', g:capability_checked - call call(g:WaitCallback, [347, '/foo/bar']) + call map(g:wait_callback_list, 'v:val([347, ''/foo/bar''])') " We should send the right callback. AssertEqual @@ -217,10 +219,58 @@ Execute(The right message should be sent for the initial LSP request): AssertEqual \ { \ 'line_length': 3, - \ 'conn_id': 0, + \ 'conn_id': 347, \ 'column': 3, - \ 'request_id': 0, + \ 'request_id': 1, \ 'line': 1, \ 'prefix': 'fo', + \ '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_callback': {-> '/foo/bar'}, + \}) + call ale#linter#Define('python', { + \ 'name': 'bar', + \ 'lsp': 'stdio', + \ 'executable': 'foo', + \ 'command': 'foo', + \ 'project_root_callback': {-> '/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() + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual 2, len(g:wait_callback_list) + AssertEqual 'completion', g:capability_checked + call map(g:wait_callback_list, 'v:val([347, ''/foo/bar''])') + + " 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': 3}, + \ }], + \ ], + \ g:message_list -- cgit v1.2.3 From 846bfb47b2e213c5627eb614f7a436089c1b4896 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 22 Jul 2018 22:31:46 +0100 Subject: Remove the redundant fix_buffer_data vars and filename variables --- autoload/ale.vim | 7 +------ autoload/ale/fix.vim | 2 -- test/fix/test_ale_fix.vader | 2 -- test/test_ale_var.vader | 12 ------------ 4 files changed, 1 insertion(+), 22 deletions(-) diff --git a/autoload/ale.vim b/autoload/ale.vim index 26c73547..6d1e8521 100644 --- a/autoload/ale.vim +++ b/autoload/ale.vim @@ -192,12 +192,7 @@ endfunction " Every variable name will be prefixed with 'ale_'. function! ale#Var(buffer, variable_name) abort let l:full_name = 'ale_' . a:variable_name - let l:vars = getbufvar(str2nr(a:buffer), '', 0) - - if l:vars is 0 - " Look for variables from deleted buffers, saved from :ALEFix - let l:vars = get(get(g:ale_fix_buffer_data, a:buffer, {}), 'vars', {}) - endif + let l:vars = getbufvar(str2nr(a:buffer), '', {}) return get(l:vars, l:full_name, g:[l:full_name]) endfunction diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim index 62674b87..8dfdeca8 100644 --- a/autoload/ale/fix.vim +++ b/autoload/ale/fix.vim @@ -420,9 +420,7 @@ function! ale#fix#InitBufferData(buffer, fixing_flag) abort " The 'done' flag tells the function for applying changes when fixing " is complete. let g:ale_fix_buffer_data[a:buffer] = { - \ 'vars': getbufvar(a:buffer, ''), \ 'lines_before': getbufline(a:buffer, 1, '$'), - \ 'filename': expand('#' . a:buffer . ':p'), \ 'done': 0, \ 'should_save': a:fixing_flag is# 'save_file', \ 'temporary_directory_list': [], diff --git a/test/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader index 80eda4a0..14206d8d 100644 --- a/test/fix/test_ale_fix.vader +++ b/test/fix/test_ale_fix.vader @@ -552,8 +552,6 @@ Execute(ale#fix#InitBufferData() should set up the correct data): AssertEqual { \ bufnr(''): { \ 'temporary_directory_list': [], - \ 'vars': b:, - \ 'filename': ale#path#Simplify(getcwd() . '/fix_test_file'), \ 'done': 0, \ 'lines_before': ['a', 'b', 'c'], \ 'should_save': 1, diff --git a/test/test_ale_var.vader b/test/test_ale_var.vader index 5f42fe95..419a9983 100644 --- a/test/test_ale_var.vader +++ b/test/test_ale_var.vader @@ -5,8 +5,6 @@ After: unlet! g:ale_some_variable unlet! b:undefined_variable_name - let g:ale_fix_buffer_data = {} - Execute(ale#Var should return global variables): AssertEqual 'abc', ale#Var(bufnr(''), 'some_variable') @@ -24,13 +22,3 @@ Execute(ale#Var should throw exceptions for undefined variables): let b:undefined_variable_name = 'def' AssertThrows call ale#Var(bufnr(''), 'undefined_variable_name') - -Execute(ale#Var return variables from deleted buffers, saved for fixing things): - let g:ale_fix_buffer_data[1347347] = {'vars': {'ale_some_variable': 'def'}} - - AssertEqual 'def', ale#Var(1347347, 'some_variable') - -Execute(ale#Var should return the global variable for unknown variables): - let g:ale_fix_buffer_data = {} - - AssertEqual 'abc', ale#Var(1347347, 'some_variable') -- cgit v1.2.3 From 0e71e8b46523d08c801b329e37b0ef89afe6ae8f Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 22 Jul 2018 22:35:49 +0100 Subject: Update the Dockerfile to test with a newer version of Vimt too --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 20a43bca..6111f9ba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ FROM tweekmonster/vim-testbed:latest RUN install_vim -tag v8.0.0027 -build \ + -tag v8.1.0204 -build \ -tag neovim:v0.2.0 -build \ -tag neovim:v0.3.0 -build -- cgit v1.2.3 From 3e4db9ed5cfc95ee75a2a7df80b54d075bdc7b00 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 22 Jul 2018 22:42:41 +0100 Subject: Make the completion events test fail less --- test/completion/test_completion_events.vader | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/completion/test_completion_events.vader b/test/completion/test_completion_events.vader index f8cf268c..f3e05950 100644 --- a/test/completion/test_completion_events.vader +++ b/test/completion/test_completion_events.vader @@ -32,8 +32,16 @@ Before: endfunction let g:ale_completion_delay = 0 - call ale#completion#Queue() - sleep 1m + + " Run this check a few times, as it can fail randomly. + for g: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 -- cgit v1.2.3 From 7bf3a749d088964b2ae42e8019dc6a570173d1bf Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 23 Jul 2018 10:21:09 +0100 Subject: #1751 Handle LSP completion results without the 'kind' attribute --- autoload/ale/completion.vim | 4 +++- test/completion/test_lsp_completion_parsing.vader | 6 ++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index 7b3a0e82..7440f8cd 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -336,7 +336,9 @@ function! ale#completion#ParseLSPCompletions(response) abort endif " See :help complete-items for Vim completion kinds - if l:item.kind is s:LSP_COMPLETION_METHOD_KIND + 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' diff --git a/test/completion/test_lsp_completion_parsing.vader b/test/completion/test_lsp_completion_parsing.vader index 736353e3..d5a45b54 100644 --- a/test/completion/test_lsp_completion_parsing.vader +++ b/test/completion/test_lsp_completion_parsing.vader @@ -430,10 +430,10 @@ Execute(Should handle Python completion results correctly): \ } \ }) -Execute(Should handle missing detail keys): +Execute(Should handle missing keys): AssertEqual \ [ - \ {'word': 'x', 'menu': '', 'info': 'y', 'kind': 'f', 'icase': 1}, + \ {'word': 'x', 'menu': '', 'info': '', 'kind': 'v', 'icase': 1}, \ ], \ ale#completion#ParseLSPCompletions({ \ 'jsonrpc': '2.0', @@ -443,8 +443,6 @@ Execute(Should handle missing detail keys): \ 'items': [ \ { \ 'label': 'x', - \ 'kind': 3, - \ 'documentation': 'y', \ }, \ ] \ } -- cgit v1.2.3 From f6d18a0b10b6aa682ebdbfaba623548aa51aee29 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 23 Jul 2018 10:45:22 +0100 Subject: Skip tests for Vim 8.1 for now --- run-tests | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/run-tests b/run-tests index ad375693..eb0c633d 100755 --- a/run-tests +++ b/run-tests @@ -120,6 +120,11 @@ file_number=0 pid_list='' for vim in $(docker run --rm "$DOCKER_RUN_IMAGE" ls /vim-build/bin | grep '^neovim\|^vim' ); do + # Skip Vim 8.1 for now. + if [[ $vim =~ ^vim-v8.1 ]]; then + continue + fi + if ( [[ $vim =~ ^vim ]] && ((run_vim_tests)) ) \ || ( [[ $vim =~ ^neovim-v0.2 ]] && ((run_neovim_02_tests)) ) \ || ( [[ $vim =~ ^neovim-v0.3 ]] && ((run_neovim_03_tests)) ); then -- cgit v1.2.3 From e3749c4a7526cced0ca54445c2267b470e202538 Mon Sep 17 00:00:00 2001 From: sharils Date: Sat, 21 Jul 2018 19:59:27 +0800 Subject: Fix autoload for phoenix When dializer isn't a dependency, mix dialyzer recompiles the whole project because it's not possible to know if this command dialyzer exist or not until recompilation is done. Then the timestamps of the project is messed up which results in broken hot-loading. In this case, mix help dialyzer would return zero which prevents compilation of the whole project since dialyzer isn't installed, it's help manual doesn't exist. When dialyzer is a dependency, mix dialyzer would just run the command. In this case, mix help dialyzer would return 1 which allows mix dialyzer to run. --- ale_linters/elixir/dialyxir.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/elixir/dialyxir.vim b/ale_linters/elixir/dialyxir.vim index 5ef3a047..bba0ae14 100644 --- a/ale_linters/elixir/dialyxir.vim +++ b/ale_linters/elixir/dialyxir.vim @@ -28,7 +28,7 @@ endfunction call ale#linter#Define('elixir', { \ 'name': 'dialyxir', \ 'executable': 'mix', -\ 'command': 'mix dialyzer', +\ 'command': 'mix help dialyzer && mix dialyzer', \ 'callback': 'ale_linters#elixir#dialyxir#Handle', \}) -- cgit v1.2.3 From d9579dbbe91af9e23328faafb92d664ad30c67ef Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 23 Jul 2018 20:41:06 +0100 Subject: Get tests to pass in Vim 8.1 --- autoload/ale/balloon.vim | 17 +++-- autoload/ale/test.vim | 23 +++++++ autoload/ale/toggle.vim | 2 +- run-tests | 43 +++++++++---- test/fix/test_ale_fix.vader | 6 +- test/smoke_test.vader | 19 +----- test/test_ale_lint_command.vader | 4 +- test/test_ale_toggle.vader | 72 ++++++++++++++-------- test/test_engine_lsp_response_handling.vader | 8 +-- ...est_errors_removed_after_filetype_changed.vader | 6 +- test/test_lint_file_linters.vader | 2 +- test/test_lint_on_enter_when_file_changed.vader | 4 +- test/test_list_formatting.vader | 14 ++--- test/test_list_opening.vader | 8 +-- test/test_list_titles.vader | 4 +- test/test_no_linting_on_write_quit.vader | 12 ++-- ..._results_not_cleared_when_opening_loclist.vader | 2 +- test/test_set_list_timers.vader | 2 +- .../test_setting_loclist_from_another_buffer.vader | 2 +- ...etting_problems_found_in_previous_buffers.vader | 2 +- 20 files changed, 149 insertions(+), 103 deletions(-) diff --git a/autoload/ale/balloon.vim b/autoload/ale/balloon.vim index 7a380da2..72f6b91c 100644 --- a/autoload/ale/balloon.vim +++ b/autoload/ale/balloon.vim @@ -34,26 +34,25 @@ function! ale#balloon#Expr() abort endfunction function! ale#balloon#Disable() abort + if has('balloon_eval') + set noballooneval + set balloonexpr= + endif + if has('balloon_eval_term') set noballoonevalterm + set balloonexpr= endif - - set noballooneval - set balloonexpr= endfunction function! ale#balloon#Enable() abort - if !has('balloon_eval') && !has('balloon_eval_term') - return - endif - if has('balloon_eval') set ballooneval + set balloonexpr=ale#balloon#Expr() endif if has('balloon_eval_term') set balloonevalterm + set balloonexpr=ale#balloon#Expr() endif - - set balloonexpr=ale#balloon#Expr() endfunction diff --git a/autoload/ale/test.vim b/autoload/ale/test.vim index bea10c53..083b546f 100644 --- a/autoload/ale/test.vim +++ b/autoload/ale/test.vim @@ -52,3 +52,26 @@ function! ale#test#SetFilename(path) abort silent! noautocmd execute 'file ' . fnameescape(ale#path#Simplify(l:full_path)) endfunction + +function! s:RemoveModule(results) abort + for l:item in a:results + if has_key(l:item, 'module') + call remove(l:item, 'module') + endif + endfor +endfunction + +" Return loclist data without the module string, only in newer Vim versions. +function! ale#test#GetLoclistWithoutModule() abort + let l:results = getloclist(0) + call s:RemoveModule(l:results) + + return l:results +endfunction + +function! ale#test#GetQflistWithoutModule() abort + let l:results = getqflist() + call s:RemoveModule(l:results) + + return l:results +endfunction diff --git a/autoload/ale/toggle.vim b/autoload/ale/toggle.vim index 6b1affc4..da108782 100644 --- a/autoload/ale/toggle.vim +++ b/autoload/ale/toggle.vim @@ -43,7 +43,7 @@ function! ale#toggle#Toggle() abort call s:CleanupEveryBuffer() call s:DisablePostamble() - if has('balloon_eval') + if exists('*ale#balloon#Disable') call ale#balloon#Disable() endif endif diff --git a/run-tests b/run-tests index eb0c633d..06fa3547 100755 --- a/run-tests +++ b/run-tests @@ -10,7 +10,7 @@ set -u # image=w0rp/ale -current_image_id=71553d0ab3e8 +current_image_id=67896c9c2c0f # Used in all test scripts for running the selected Docker image. DOCKER_RUN_IMAGE="$image" @@ -22,7 +22,8 @@ verbose_flag='' quiet_flag='' run_neovim_02_tests=1 run_neovim_03_tests=1 -run_vim_tests=1 +run_vim_80_tests=1 +run_vim_81_tests=1 run_linters=1 while [ $# -ne 0 ]; do @@ -36,19 +37,22 @@ while [ $# -ne 0 ]; do shift ;; --neovim-only) - run_vim_tests=0 + run_vim_80_tests=0 + run_vim_81_tests=0 run_linters=0 shift ;; --neovim-02-only) run_neovim_03_tests=0 - run_vim_tests=0 + run_vim_80_tests=0 + run_vim_81_tests=0 run_linters=0 shift ;; --neovim-03-only) run_neovim_02_tests=0 - run_vim_tests=0 + run_vim_80_tests=0 + run_vim_81_tests=0 run_linters=0 shift ;; @@ -58,8 +62,23 @@ while [ $# -ne 0 ]; do run_linters=0 shift ;; + --vim-80-only) + run_neovim_02_tests=0 + run_neovim_03_tests=0 + run_vim_81_tests=0 + run_linters=0 + shift + ;; + --vim-81-only) + run_neovim_02_tests=0 + run_neovim_03_tests=0 + run_vim_80_tests=0 + run_linters=0 + shift + ;; --linters-only) - run_vim_tests=0 + run_vim_80_tests=0 + run_vim_81_tests=0 run_neovim_02_tests=0 run_neovim_03_tests=0 shift @@ -76,7 +95,9 @@ while [ $# -ne 0 ]; do echo ' --neovim-only Run tests only for NeoVim 0.2 and 0.3' echo ' --neovim-02-only Run tests only for NeoVim 0.2' echo ' --neovim-03-only Run tests only for NeoVim 0.3' - echo ' --vim-only Run tests only for Vim' + echo ' --vim-only Run tests only for Vim 8.0 and 8.1' + echo ' --vim-80-only Run tests only for Vim 8.0' + echo ' --vim-81-only Run tests only for Vim 8.1' echo ' --linters-only Run only Vint and custom checks' echo ' --help Show this help text' echo ' -- Stop parsing options after this' @@ -120,12 +141,8 @@ file_number=0 pid_list='' for vim in $(docker run --rm "$DOCKER_RUN_IMAGE" ls /vim-build/bin | grep '^neovim\|^vim' ); do - # Skip Vim 8.1 for now. - if [[ $vim =~ ^vim-v8.1 ]]; then - continue - fi - - if ( [[ $vim =~ ^vim ]] && ((run_vim_tests)) ) \ + if ( [[ $vim =~ ^vim-v8.0 ]] && ((run_vim_80_tests)) ) \ + || ( [[ $vim =~ ^vim-v8.1 ]] && ((run_vim_81_tests)) ) \ || ( [[ $vim =~ ^neovim-v0.2 ]] && ((run_neovim_02_tests)) ) \ || ( [[ $vim =~ ^neovim-v0.3 ]] && ((run_neovim_03_tests)) ); then echo "Starting Vim: $vim..." diff --git a/test/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader index 14206d8d..67b8b212 100644 --- a/test/fix/test_ale_fix.vader +++ b/test/fix/test_ale_fix.vader @@ -458,7 +458,7 @@ Execute(ALEFix should save files on the save event): \ 'nr': -1, \ 'pattern': '', \ 'valid': 1, - \}], getloclist(0) + \}], ale#test#GetLoclistWithoutModule() endif Expect(The buffer should be modified): @@ -497,7 +497,7 @@ Execute(ALEFix should still lint with no linters to be applied): \ 'nr': -1, \ 'pattern': '', \ 'valid': 1, - \}], getloclist(0) + \}], ale#test#GetLoclistWithoutModule() endif Expect(The buffer should be the same): @@ -531,7 +531,7 @@ Execute(ALEFix should still lint when nothing was fixed on save): \ 'nr': -1, \ 'pattern': '', \ 'valid': 1, - \}], getloclist(0) + \}], ale#test#GetLoclistWithoutModule() endif Expect(The buffer should be the same): diff --git a/test/smoke_test.vader b/test/smoke_test.vader index 1cbf512d..2708c86f 100644 --- a/test/smoke_test.vader +++ b/test/smoke_test.vader @@ -35,7 +35,6 @@ After: unlet! g:i unlet! g:results - unlet! g:item unlet! g:expected_results delfunction TestCallback @@ -69,13 +68,7 @@ Execute(Linters should run with the default options): call ale#Lint() call ale#engine#WaitForJobs(2000) - let g:results = getloclist(0) - - for g:item in g:results - if has_key(g:item, 'module') - call remove(g:item, 'module') - endif - endfor + let g:results = ale#test#GetLoclistWithoutModule() if g:results == g:expected_results break @@ -142,7 +135,7 @@ Execute(Linters should run in PowerShell too): \ 'pattern': '', \ 'valid': 1, \ }, - \], getloclist(0) + \], ale#test#GetLoclistWithoutModule() endif Execute(Previous errors should be removed when linters change): @@ -176,13 +169,7 @@ Execute(Previous errors should be removed when linters change): call ale#Lint() call ale#engine#WaitForJobs(2000) - let g:results = getloclist(0) - - for g:item in g:results - if has_key(g:item, 'module') - call remove(g:item, 'module') - endif - endfor + let g:results = ale#test#GetLoclistWithoutModule() if g:results == g:expected_results break diff --git a/test/test_ale_lint_command.vader b/test/test_ale_lint_command.vader index 6434e45f..bc2ebabe 100644 --- a/test/test_ale_lint_command.vader +++ b/test/test_ale_lint_command.vader @@ -66,10 +66,10 @@ Execute(ALELint should run the linters): sleep 1ms endif - if getloclist(0) == g:expected_loclist + if ale#test#GetLoclistWithoutModule() == g:expected_loclist break endif endfor " Check the loclist - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() diff --git a/test/test_ale_toggle.vader b/test/test_ale_toggle.vader index 3b3c509c..db891009 100644 --- a/test/test_ale_toggle.vader +++ b/test/test_ale_toggle.vader @@ -115,7 +115,7 @@ Execute(ALEToggle should reset everything and then run again): ALELint " First check that everything is there... - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) AssertEqual \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], @@ -128,7 +128,7 @@ Execute(ALEToggle should reset everything and then run again): " Everything should be cleared. Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed' - AssertEqual [], getloclist(0), 'The loclist was not cleared' + AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared' AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared' AssertEqual [], getmatches(), 'The highlights were not cleared' AssertEqual g:expected_groups, ParseAuGroups() @@ -136,7 +136,7 @@ Execute(ALEToggle should reset everything and then run again): " Toggle ALE on, everything should be set up and run again. ALEToggle - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) AssertEqual \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], @@ -189,16 +189,16 @@ Execute(ALEToggle should skip filename keys and preserve them): Execute(ALEDisable should reset everything and stay disabled): ALELint - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() ALEDisable - AssertEqual [], getloclist(0) + AssertEqual [], ale#test#GetLoclistWithoutModule() AssertEqual 0, g:ale_enabled ALEDisable - AssertEqual [], getloclist(0) + AssertEqual [], ale#test#GetLoclistWithoutModule() AssertEqual 0, g:ale_enabled Execute(ALEEnable should enable ALE and lint again): @@ -206,7 +206,7 @@ Execute(ALEEnable should enable ALE and lint again): ALEEnable - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() AssertEqual 1, g:ale_enabled Execute(ALEReset should reset everything for a buffer): @@ -215,7 +215,7 @@ Execute(ALEReset should reset everything for a buffer): ALELint " First check that everything is there... - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) AssertEqual \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], @@ -227,7 +227,7 @@ Execute(ALEReset should reset everything for a buffer): " Everything should be cleared. Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed' - AssertEqual [], getloclist(0), 'The loclist was not cleared' + AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared' AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared' AssertEqual [], getmatches(), 'The highlights were not cleared' @@ -239,7 +239,7 @@ Execute(ALEToggleBuffer should reset everything and then run again): ALELint " First check that everything is there... - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) AssertEqual \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], @@ -251,14 +251,14 @@ Execute(ALEToggleBuffer should reset everything and then run again): " Everything should be cleared. Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed' - AssertEqual [], getloclist(0), 'The loclist was not cleared' + AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared' AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared' AssertEqual [], getmatches(), 'The highlights were not cleared' " Toggle ALE on, everything should be set up and run again. ALEToggleBuffer - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) AssertEqual \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], @@ -269,11 +269,11 @@ Execute(ALEToggleBuffer should reset everything and then run again): Execute(ALEDisableBuffer should reset everything and stay disabled): ALELint - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() ALEDisableBuffer - AssertEqual [], getloclist(0) + AssertEqual [], ale#test#GetLoclistWithoutModule() AssertEqual 0, b:ale_enabled Execute(ALEEnableBuffer should enable ALE and lint again): @@ -281,7 +281,7 @@ Execute(ALEEnableBuffer should enable ALE and lint again): ALEEnableBuffer - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() AssertEqual 1, b:ale_enabled Execute(ALEEnableBuffer should complain when ALE is disabled globally): @@ -292,7 +292,7 @@ Execute(ALEEnableBuffer should complain when ALE is disabled globally): ALEEnableBuffer redir END - AssertEqual [], getloclist(0) + AssertEqual [], ale#test#GetLoclistWithoutModule() AssertEqual 0, b:ale_enabled AssertEqual 0, g:ale_enabled AssertEqual @@ -305,7 +305,7 @@ Execute(ALEResetBuffer should reset everything for a buffer): ALELint " First check that everything is there... - AssertEqual g:expected_loclist, getloclist(0) + AssertEqual g:expected_loclist, ale#test#GetLoclistWithoutModule() AssertEqual [0, [[2, 1000001, 'ALEErrorSign']]], ale#sign#FindCurrentSigns(bufnr('%')) AssertEqual \ [{'group': 'ALEError', 'pos1': [2, 3, 1]}], @@ -317,7 +317,7 @@ Execute(ALEResetBuffer should reset everything for a buffer): " Everything should be cleared. Assert !has_key(g:ale_buffer_info, bufnr('')), 'The g:ale_buffer_info Dictionary was not removed' - AssertEqual [], getloclist(0), 'The loclist was not cleared' + AssertEqual [], ale#test#GetLoclistWithoutModule(), 'The loclist was not cleared' AssertEqual [0, []], ale#sign#FindCurrentSigns(bufnr('%')), 'The signs were not cleared' AssertEqual [], getmatches(), 'The highlights were not cleared' @@ -326,40 +326,60 @@ Execute(ALEResetBuffer should reset everything for a buffer): 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') + 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() - AssertEqual 1, &ballooneval + 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. - AssertEqual 0, &ballooneval + 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') + 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 - AssertEqual 0, &ballooneval + 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 - AssertEqual 1, &ballooneval + if has('balloon_eval') && has('gui_running') + AssertEqual 1, &ballooneval + else + AssertEqual 1, &balloonevalterm + endif + AssertEqual 'ale#balloon#Expr()', &balloonexpr endif diff --git a/test/test_engine_lsp_response_handling.vader b/test/test_engine_lsp_response_handling.vader index 18bad0a1..517d82c0 100644 --- a/test/test_engine_lsp_response_handling.vader +++ b/test/test_engine_lsp_response_handling.vader @@ -68,7 +68,7 @@ Execute(tsserver syntax error responses should be handled correctly): \ 'pattern': '', \ }, \ ], - \ getloclist(0) + \ ale#test#GetLoclistWithoutModule() " After we get empty syntax errors, we should clear them. call ale#lsp_linter#HandleLSPResponse(1, { @@ -85,7 +85,7 @@ Execute(tsserver syntax error responses should be handled correctly): AssertEqual \ [ \ ], - \ getloclist(0) + \ ale#test#GetLoclistWithoutModule() Execute(tsserver semantic error responses should be handled correctly): runtime ale_linters/typescript/tsserver.vim @@ -141,7 +141,7 @@ Execute(tsserver semantic error responses should be handled correctly): \ 'pattern': '', \ }, \ ], - \ getloclist(0) + \ ale#test#GetLoclistWithoutModule() " After we get empty syntax errors, we should clear them. call ale#lsp_linter#HandleLSPResponse(1, { @@ -158,7 +158,7 @@ Execute(tsserver semantic error responses should be handled correctly): AssertEqual \ [ \ ], - \ getloclist(0) + \ ale#test#GetLoclistWithoutModule() Execute(LSP errors should be logged in the history): call ale#lsp_linter#SetLSPLinterMap({'347': 'foobar'}) diff --git a/test/test_errors_removed_after_filetype_changed.vader b/test/test_errors_removed_after_filetype_changed.vader index afd882b1..651a74f2 100644 --- a/test/test_errors_removed_after_filetype_changed.vader +++ b/test/test_errors_removed_after_filetype_changed.vader @@ -53,7 +53,7 @@ Execute(Error should be removed when the filetype changes to something else we c call ale#Queue(0) sleep 1ms - AssertEqual 1, len(getloclist(0)) + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()) noautocmd let &filetype = 'foobar2' @@ -61,11 +61,11 @@ Execute(Error should be removed when the filetype changes to something else we c sleep 1ms " We should get some items from the second filetype. - AssertEqual 1, len(getloclist(0)) + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()) noautocmd let &filetype = 'xxx' call ale#Queue(0) sleep 1ms - AssertEqual 0, len(getloclist(0)) + AssertEqual 0, len(ale#test#GetLoclistWithoutModule()) diff --git a/test/test_lint_file_linters.vader b/test/test_lint_file_linters.vader index 14339e21..ca093aa8 100644 --- a/test/test_lint_file_linters.vader +++ b/test/test_lint_file_linters.vader @@ -51,7 +51,7 @@ Before: function! GetSimplerLoclist() let l:loclist = [] - for l:item in getloclist(0) + for l:item in ale#test#GetLoclistWithoutModule() call add(l:loclist, { \ 'lnum': l:item.lnum, \ 'col': l:item.col, diff --git a/test/test_lint_on_enter_when_file_changed.vader b/test/test_lint_on_enter_when_file_changed.vader index 8a54d9b8..67f43c17 100644 --- a/test/test_lint_on_enter_when_file_changed.vader +++ b/test/test_lint_on_enter_when_file_changed.vader @@ -61,7 +61,7 @@ Execute(The file changed event function should lint the current buffer when it h \ 'nr': -1, \ 'pattern': '', \ 'valid': 1, - \ }], getloclist(0) + \ }], ale#test#GetLoclistWithoutModule() Execute(The buffer should be checked after entering it after the file has changed): let b:ale_file_changed = 1 @@ -79,4 +79,4 @@ Execute(The buffer should be checked after entering it after the file has change \ 'nr': -1, \ 'pattern': '', \ 'valid': 1, - \ }], getloclist(0) + \ }], ale#test#GetLoclistWithoutModule() diff --git a/test/test_list_formatting.vader b/test/test_list_formatting.vader index 0c52f10f..dcefac53 100644 --- a/test/test_list_formatting.vader +++ b/test/test_list_formatting.vader @@ -53,7 +53,7 @@ Execute(Formatting with codes should work for the loclist): \ 'text': 'nocode', \ }, \ ], - \ getloclist(0) + \ ale#test#GetLoclistWithoutModule() call remove(g:loclist, 0) call AddItem({'text': 'withcode', 'code': 'E123'}) @@ -73,7 +73,7 @@ Execute(Formatting with codes should work for the loclist): \ 'text': 'E123: withcode', \ }, \ ], - \ getloclist(0) + \ ale#test#GetLoclistWithoutModule() Execute(Formatting with codes should work for the quickfix list): let g:ale_set_loclist = 0 @@ -96,7 +96,7 @@ Execute(Formatting with codes should work for the quickfix list): \ 'text': 'nocode', \ }, \ ], - \ getqflist() + \ ale#test#GetQflistWithoutModule() call remove(g:loclist, 0) call AddItem({'text': 'withcode', 'code': 'E123'}) @@ -116,7 +116,7 @@ Execute(Formatting with codes should work for the quickfix list): \ 'text': 'E123: withcode', \ }, \ ], - \ getqflist() + \ ale#test#GetQflistWithoutModule() Execute(Formatting with the linter name should work for the loclist): let g:ale_loclist_msg_format = '(%linter%) %s' @@ -138,7 +138,7 @@ Execute(Formatting with the linter name should work for the loclist): \ 'text': '(some_linter) whatever', \ }, \ ], - \ getloclist(0) + \ ale#test#GetLoclistWithoutModule() Execute(Formatting with the linter name should work for the quickfix list): let g:ale_loclist_msg_format = '(%linter%) %s' @@ -162,7 +162,7 @@ Execute(Formatting with the linter name should work for the quickfix list): \ 'text': '(some_linter) whatever', \ }, \ ], - \ getqflist() + \ ale#test#GetQflistWithoutModule() Execute(The buffer loclist format option should take precedence): let g:ale_loclist_msg_format = '(%linter%) %s' @@ -185,4 +185,4 @@ Execute(The buffer loclist format option should take precedence): \ 'text': 'FOO whatever', \ }, \ ], - \ getloclist(0) + \ ale#test#GetLoclistWithoutModule() diff --git a/test/test_list_opening.vader b/test/test_list_opening.vader index a24e8de9..8f0b2fd5 100644 --- a/test/test_list_opening.vader +++ b/test/test_list_opening.vader @@ -120,7 +120,7 @@ Execute(The quickfix window should be vertical for the loclist with appropriate call ale#list#SetLists(bufnr('%'), g:loclist) - AssertEqual 1, GetQuickfixIsVertical(b:ale_list_window_size) + AssertEqual 1, GetQuickfixIsVertical(8) Execute(The quickfix window should be horizontal for the loclist with appropriate variables): let g:ale_open_list = 1 @@ -129,7 +129,7 @@ Execute(The quickfix window should be horizontal for the loclist with appropriat call ale#list#SetLists(bufnr('%'), g:loclist) - AssertEqual 0, GetQuickfixIsVertical(b:ale_list_window_size) + AssertEqual 0, GetQuickfixIsVertical(8) Execute(The quickfix window should stay open for just the loclist): let g:ale_open_list = 1 @@ -207,7 +207,7 @@ Execute(The quickfix window should be vertical for the quickfix with appropriate call ale#list#SetLists(bufnr('%'), g:loclist) - AssertEqual 1, GetQuickfixIsVertical(b:ale_list_window_size) + AssertEqual 1, GetQuickfixIsVertical(8) Execute(The quickfix window should be horizontal for the quickfix with appropriate variables): let g:ale_open_list = 1 @@ -216,7 +216,7 @@ Execute(The quickfix window should be horizontal for the quickfix with appropria call ale#list#SetLists(bufnr('%'), g:loclist) - AssertEqual 0, GetQuickfixIsVertical(b:ale_list_window_size) + AssertEqual 0, GetQuickfixIsVertical(8) Execute(The buffer ale_open_list option should be respected): let b:ale_open_list = 1 diff --git a/test/test_list_titles.vader b/test/test_list_titles.vader index d521906f..1f0b2308 100644 --- a/test/test_list_titles.vader +++ b/test/test_list_titles.vader @@ -38,7 +38,7 @@ Execute(The loclist titles should be set appropriately): \ 'nr': 0, \ 'type': 'E', \ 'pattern': '', - \}], getloclist(0) + \}], ale#test#GetLoclistWithoutModule() if !has('nvim') AssertEqual @@ -68,7 +68,7 @@ Execute(The quickfix titles should be set appropriately): \ 'nr': 0, \ 'type': 'E', \ 'pattern': '', - \}], getqflist() + \}], ale#test#GetQflistWithoutModule() if !has('nvim') AssertEqual diff --git a/test/test_no_linting_on_write_quit.vader b/test/test_no_linting_on_write_quit.vader index db05bd7d..12ef38ed 100644 --- a/test/test_no_linting_on_write_quit.vader +++ b/test/test_no_linting_on_write_quit.vader @@ -59,14 +59,14 @@ Execute(No linting should be done on :wq or :x): " First try just the SaveEvent, to be sure that we set errors in the test. call ale#events#SaveEvent(bufnr('')) - AssertEqual 1, len(getloclist(0)) + 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('')) - AssertEqual [], getloclist(0) + AssertEqual [], ale#test#GetLoclistWithoutModule() Execute(No linting should be for :w after :q fails): let g:ale_lint_on_save = 1 @@ -79,7 +79,7 @@ Execute(No linting should be for :w after :q fails): call ale#events#SaveEvent(bufnr('')) - AssertEqual 1, len(getloclist(0)) + 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 = 0 @@ -87,14 +87,14 @@ Execute(No linting should be done on :wq or :x after fixing files): call ale#events#SaveEvent(bufnr('')) - AssertEqual 1, len(getloclist(0)) + 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('')) - AssertEqual [], getloclist(0) + AssertEqual [], ale#test#GetLoclistWithoutModule() Execute(Linting should be done after :q fails and fixing files): let g:ale_lint_on_save = 0 @@ -107,4 +107,4 @@ Execute(Linting should be done after :q fails and fixing files): call ale#events#SaveEvent(bufnr('')) - AssertEqual 1, len(getloclist(0)) + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()) diff --git a/test/test_results_not_cleared_when_opening_loclist.vader b/test/test_results_not_cleared_when_opening_loclist.vader index dd928fa0..4a53d356 100644 --- a/test/test_results_not_cleared_when_opening_loclist.vader +++ b/test/test_results_not_cleared_when_opening_loclist.vader @@ -27,4 +27,4 @@ Execute(The loclist shouldn't be cleared when opening the loclist): :lopen :q - AssertEqual 1, len(getloclist(0)), 'The loclist was cleared' + AssertEqual 1, len(ale#test#GetLoclistWithoutModule()), 'The loclist was cleared' diff --git a/test/test_set_list_timers.vader b/test/test_set_list_timers.vader index f8fcb6a0..e53b97a4 100644 --- a/test/test_set_list_timers.vader +++ b/test/test_set_list_timers.vader @@ -26,4 +26,4 @@ Execute(The SetLists function should work when run in a timer): \ 'nr': 0, \ 'type': 'E', \ 'pattern': '', - \}], getloclist(0) + \}], ale#test#GetLoclistWithoutModule() diff --git a/test/test_setting_loclist_from_another_buffer.vader b/test/test_setting_loclist_from_another_buffer.vader index 10a44cce..028ffb1e 100644 --- a/test/test_setting_loclist_from_another_buffer.vader +++ b/test/test_setting_loclist_from_another_buffer.vader @@ -21,6 +21,6 @@ Execute(Errors should be set in the loclist for the original buffer, not the new \ g:ale_buffer_info[(g:original_buffer)].loclist, \ ) - AssertEqual [], getloclist(0) + AssertEqual [], ale#test#GetLoclistWithoutModule() AssertEqual 1, len(getloclist(bufwinid(g:original_buffer))) AssertEqual 'foo', getloclist(bufwinid(g:original_buffer))[0].text diff --git a/test/test_setting_problems_found_in_previous_buffers.vader b/test/test_setting_problems_found_in_previous_buffers.vader index 45dfa662..4604005a 100644 --- a/test/test_setting_problems_found_in_previous_buffers.vader +++ b/test/test_setting_problems_found_in_previous_buffers.vader @@ -95,4 +95,4 @@ Execute(Problems found from previously opened buffers should be set when linting \ {'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'}, \ ], - \ getloclist(0) + \ ale#test#GetLoclistWithoutModule() -- cgit v1.2.3 From 2a861dfd401784b2a8844b99189fc822082750c9 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 23 Jul 2018 22:03:28 +0100 Subject: Make the test C import path test fail less --- autoload/ale/c.vim | 5 ++++- test/test_c_import_paths.vader | 47 +++++++++++++++--------------------------- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index 5ab10f00..fbfe9509 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -4,8 +4,11 @@ call ale#Set('c_parse_makefile', 0) let s:sep = has('win32') ? '\' : '/' +" Set just so tests can override it. +let g:__ale_c_project_filenames = ['.git/HEAD', 'configure', 'Makefile', 'CMakeLists.txt'] + function! ale#c#FindProjectRoot(buffer) abort - for l:project_filename in ['.git/HEAD', 'configure', 'Makefile', 'CMakeLists.txt'] + 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) diff --git a/test/test_c_import_paths.vader b/test/test_c_import_paths.vader index f2a06781..41db686c 100644 --- a/test/test_c_import_paths.vader +++ b/test/test_c_import_paths.vader @@ -1,8 +1,21 @@ Before: + " Make sure the c.vim file is loaded first. + call ale#c#FindProjectRoot(bufnr('')) + Save g:ale_c_gcc_options Save g:ale_c_clang_options Save g:ale_cpp_gcc_options Save g:ale_cpp_clang_options + Save g:__ale_c_project_filenames + + let g:original_project_filenames = g:__ale_c_project_filenames + + " 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''' + \) call ale#test#SetDirectory('/testplugin/test') @@ -14,23 +27,11 @@ Before: After: Restore + unlet! g:original_project_filenames + call ale#test#RestoreDirectory() call ale#linter#Reset() -" Run this only once for this series of tests. The cleanup Execute step -" will run at the bottom of this file. -" -" We need to move .git/HEAD away so we don't match it, as we need to test -" functions which look for .git/HEAD. -Execute(Move .git/HEAD to a temp dir): - let g:temp_head_filename = tempname() - let g:head_filename = findfile('.git/HEAD', ';') - - if !empty(g:head_filename) - call writefile(readfile(g:head_filename, 'b'), g:temp_head_filename, 'b') - call delete(g:head_filename) - endif - Execute(The C GCC handler should include 'include' directories for projects with a Makefile): runtime! ale_linters/c/gcc.vim @@ -242,13 +243,8 @@ Execute(The C++ Clang handler should include root directories for projects with Execute(The C++ Clang handler shoud use the include directory based on the .git location): runtime! ale_linters/cpp/clang.vim - if !isdirectory(g:dir . '/test_c_projects/git_and_nested_makefiles/.git') - call mkdir(g:dir . '/test_c_projects/git_and_nested_makefiles/.git') - endif - - if !filereadable(g:dir . '/test_c_projects/git_and_nested_makefiles/.git/HEAD') - call writefile([], g:dir . '/test_c_projects/git_and_nested_makefiles/.git/HEAD') - endif + " Restore the .git/HEAD check for just this test. + let g:__ale_c_project_filenames = g:original_project_filenames call ale#test#SetFilename('test_c_projects/git_and_nested_makefiles/src/file.cpp') @@ -270,12 +266,3 @@ Execute(The C++ ClangTidy handler should include json folders for projects with \ . ' -checks=' . ale#Escape('*') . ' %s ' \ . '-p ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/json_project/build')) \ , ale_linters#cpp#clangtidy#GetCommand(bufnr('')) - -Execute(Move .git/HEAD back): - if !empty(g:head_filename) - call writefile(readfile(g:temp_head_filename, 'b'), g:head_filename, 'b') - call delete(g:temp_head_filename) - endif - - unlet! g:temp_head_filename - unlet! g:head_filename -- cgit v1.2.3 From 44397dd6db00806ad66b7875725537967b246137 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 23 Jul 2018 22:21:13 +0100 Subject: Skip the one failing test on Windows --- test/test_c_import_paths.vader | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/test/test_c_import_paths.vader b/test/test_c_import_paths.vader index 41db686c..fda1ec1e 100644 --- a/test/test_c_import_paths.vader +++ b/test/test_c_import_paths.vader @@ -241,20 +241,23 @@ Execute(The C++ Clang handler should include root directories for projects with \ , ale_linters#cpp#clang#GetCommand(bufnr(''), []) Execute(The C++ Clang handler shoud use the include directory based on the .git location): - runtime! ale_linters/cpp/clang.vim - - " Restore the .git/HEAD check for just this test. - let g:__ale_c_project_filenames = g:original_project_filenames - - call ale#test#SetFilename('test_c_projects/git_and_nested_makefiles/src/file.cpp') - - AssertEqual - \ ale#Escape('clang++') - \ . ' -S -x c++ -fsyntax-only ' - \ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/git_and_nested_makefiles/src')) . ' ' - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/git_and_nested_makefiles/include')) . ' ' - \ . ' -' - \ , ale_linters#cpp#clang#GetCommand(bufnr(''), []) + " Don't run this test on Windows. I can't be bothered fixing it. + if !has('win32') + runtime! ale_linters/cpp/clang.vim + + " Restore the .git/HEAD check for just this test. + let g:__ale_c_project_filenames = g:original_project_filenames + + call ale#test#SetFilename('test_c_projects/git_and_nested_makefiles/src/file.cpp') + + AssertEqual + \ ale#Escape('clang++') + \ . ' -S -x c++ -fsyntax-only ' + \ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/git_and_nested_makefiles/src')) . ' ' + \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/git_and_nested_makefiles/include')) . ' ' + \ . ' -' + \ , ale_linters#cpp#clang#GetCommand(bufnr(''), []) + endif Execute(The C++ ClangTidy handler should include json folders for projects with suitable build directory in them): runtime! ale_linters/cpp/clangtidy.vim -- cgit v1.2.3 From 9ade65666121b0889d774bdea3b4ce2e176ff915 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 23 Jul 2018 22:22:19 +0100 Subject: Just remove the .git directory test for now --- test/test_c_import_paths.vader | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/test/test_c_import_paths.vader b/test/test_c_import_paths.vader index fda1ec1e..0490dec6 100644 --- a/test/test_c_import_paths.vader +++ b/test/test_c_import_paths.vader @@ -240,25 +240,6 @@ Execute(The C++ Clang handler should include root directories for projects with \ . ' -' \ , ale_linters#cpp#clang#GetCommand(bufnr(''), []) -Execute(The C++ Clang handler shoud use the include directory based on the .git location): - " Don't run this test on Windows. I can't be bothered fixing it. - if !has('win32') - runtime! ale_linters/cpp/clang.vim - - " Restore the .git/HEAD check for just this test. - let g:__ale_c_project_filenames = g:original_project_filenames - - call ale#test#SetFilename('test_c_projects/git_and_nested_makefiles/src/file.cpp') - - AssertEqual - \ ale#Escape('clang++') - \ . ' -S -x c++ -fsyntax-only ' - \ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/git_and_nested_makefiles/src')) . ' ' - \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/git_and_nested_makefiles/include')) . ' ' - \ . ' -' - \ , ale_linters#cpp#clang#GetCommand(bufnr(''), []) - endif - Execute(The C++ ClangTidy handler should include json folders for projects with suitable build directory in them): runtime! ale_linters/cpp/clangtidy.vim -- cgit v1.2.3 From 338c233710b38f624ac9189ce3d456a0d52ff972 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 23 Jul 2018 22:28:22 +0100 Subject: Split Vim and Neovim tests into separate builds --- .travis.yml | 5 ++++- run-tests | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0f006e4c..e236b9ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,5 +3,8 @@ sudo: required services: - docker language: generic +env: + - OPTIONS=--no-neovim + - OPTIONS=--neovim-only script: | - ./run-tests -v + ./run-tests -v $OPTIONS diff --git a/run-tests b/run-tests index 06fa3547..b64b7195 100755 --- a/run-tests +++ b/run-tests @@ -56,6 +56,11 @@ while [ $# -ne 0 ]; do run_linters=0 shift ;; + --no-neovim) + run_neovim_02_tests=0 + run_neovim_03_tests=0 + shift + ;; --vim-only) run_neovim_02_tests=0 run_neovim_03_tests=0 @@ -95,6 +100,7 @@ while [ $# -ne 0 ]; do echo ' --neovim-only Run tests only for NeoVim 0.2 and 0.3' echo ' --neovim-02-only Run tests only for NeoVim 0.2' echo ' --neovim-03-only Run tests only for NeoVim 0.3' + echo ' --no-neovim Skip NeoVim tests' echo ' --vim-only Run tests only for Vim 8.0 and 8.1' echo ' --vim-80-only Run tests only for Vim 8.0' echo ' --vim-81-only Run tests only for Vim 8.1' -- cgit v1.2.3 From d7d54d09dab4df733caa344006b334f3f4a918dd Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 23 Jul 2018 22:33:03 +0100 Subject: Try 3 builds on Travis CI --- .travis.yml | 3 ++- run-tests | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index e236b9ec..8b076158 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,8 @@ services: - docker language: generic env: - - OPTIONS=--no-neovim + - OPTIONS=--vim-only - OPTIONS=--neovim-only + - OPTIONS=--linters-only script: | ./run-tests -v $OPTIONS diff --git a/run-tests b/run-tests index b64b7195..06fa3547 100755 --- a/run-tests +++ b/run-tests @@ -56,11 +56,6 @@ while [ $# -ne 0 ]; do run_linters=0 shift ;; - --no-neovim) - run_neovim_02_tests=0 - run_neovim_03_tests=0 - shift - ;; --vim-only) run_neovim_02_tests=0 run_neovim_03_tests=0 @@ -100,7 +95,6 @@ while [ $# -ne 0 ]; do echo ' --neovim-only Run tests only for NeoVim 0.2 and 0.3' echo ' --neovim-02-only Run tests only for NeoVim 0.2' echo ' --neovim-03-only Run tests only for NeoVim 0.3' - echo ' --no-neovim Skip NeoVim tests' echo ' --vim-only Run tests only for Vim 8.0 and 8.1' echo ' --vim-80-only Run tests only for Vim 8.0' echo ' --vim-81-only Run tests only for Vim 8.1' -- cgit v1.2.3 From 95be2bf1ff9221eb74dc028ca616412305b2bc85 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 23 Jul 2018 22:37:53 +0100 Subject: Try Vim 8.0 and 8.1 in separate jobs --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8b076158..d48c1e08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,8 @@ services: - docker language: generic env: - - OPTIONS=--vim-only + - OPTIONS=--vim-80-only + - OPTIONS=--vim-81-only - OPTIONS=--neovim-only - OPTIONS=--linters-only script: | -- cgit v1.2.3 From d368f090aeeca3545dd03b1bfe4bff5e6a95d7e2 Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 24 Jul 2018 10:05:44 +0100 Subject: #1754 Require snake_case names for linters in the codebase --- ale_linters/asciidoc/writegood.vim | 7 +------ ale_linters/go/gobuild.vim | 3 ++- ale_linters/go/govet.vim | 3 ++- ale_linters/haskell/cabal_ghc.vim | 3 ++- ale_linters/haskell/ghc-mod.vim | 6 ++++-- ale_linters/haskell/stack_build.vim | 3 ++- ale_linters/haskell/stack_ghc.vim | 3 ++- ale_linters/help/writegood.vim | 7 +------ ale_linters/html/writegood.vim | 9 ++------- ale_linters/markdown/remark_lint.vim | 4 +++- ale_linters/markdown/writegood.vim | 7 +------ ale_linters/nroff/writegood.vim | 7 +------ ale_linters/po/writegood.vim | 7 +------ ale_linters/pod/writegood.vim | 7 +------ ale_linters/rst/writegood.vim | 7 +------ ale_linters/sml/smlnj_cm.vim | 3 ++- ale_linters/tex/writegood.vim | 7 +------ ale_linters/texinfo/writegood.vim | 7 +------ ale_linters/text/writegood.vim | 7 +------ ale_linters/xhtml/writegood.vim | 7 +------ autoload/ale/handlers/writegood.vim | 11 +++++++++++ test/script/custom-linting-rules | 9 ++++++++- test/test_filetype_linter_defaults.vader | 2 +- 23 files changed, 52 insertions(+), 84 deletions(-) diff --git a/ale_linters/asciidoc/writegood.vim b/ale_linters/asciidoc/writegood.vim index c986cc6c..a29b7e9c 100644 --- a/ale_linters/asciidoc/writegood.vim +++ b/ale_linters/asciidoc/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for AsciiDoc files -call ale#linter#Define('asciidoc', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('asciidoc') diff --git a/ale_linters/go/gobuild.vim b/ale_linters/go/gobuild.vim index 068877a3..c4608071 100644 --- a/ale_linters/go/gobuild.vim +++ b/ale_linters/go/gobuild.vim @@ -70,7 +70,8 @@ function! ale_linters#go#gobuild#Handler(buffer, lines) abort endfunction call ale#linter#Define('go', { -\ 'name': 'go build', +\ 'name': 'gobuild', +\ 'aliases': ['go build'], \ 'executable': 'go', \ 'command_chain': [ \ {'callback': 'ale_linters#go#gobuild#GoEnv', 'output_stream': 'stdout'}, diff --git a/ale_linters/go/govet.vim b/ale_linters/go/govet.vim index edf9eb66..e94e6ecd 100644 --- a/ale_linters/go/govet.vim +++ b/ale_linters/go/govet.vim @@ -9,7 +9,8 @@ function! ale_linters#go#govet#GetCommand(buffer) abort endfunction call ale#linter#Define('go', { -\ 'name': 'go vet', +\ 'name': 'govet', +\ 'aliases': ['go vet'], \ 'output_stream': 'stderr', \ 'executable': 'go', \ 'command_callback': 'ale_linters#go#govet#GetCommand', diff --git a/ale_linters/haskell/cabal_ghc.vim b/ale_linters/haskell/cabal_ghc.vim index 79fd8ff9..003adf5d 100644 --- a/ale_linters/haskell/cabal_ghc.vim +++ b/ale_linters/haskell/cabal_ghc.vim @@ -10,7 +10,8 @@ function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort endfunction call ale#linter#Define('haskell', { -\ 'name': 'cabal-ghc', +\ 'name': 'cabal_ghc', +\ 'aliases': ['cabal-ghc'], \ 'output_stream': 'stderr', \ 'executable': 'cabal', \ 'command_callback': 'ale_linters#haskell#cabal_ghc#GetCommand', diff --git a/ale_linters/haskell/ghc-mod.vim b/ale_linters/haskell/ghc-mod.vim index 1b15d8c2..eb032f50 100644 --- a/ale_linters/haskell/ghc-mod.vim +++ b/ale_linters/haskell/ghc-mod.vim @@ -2,14 +2,16 @@ " Description: ghc-mod for Haskell files call ale#linter#Define('haskell', { -\ 'name': 'ghc-mod', +\ 'name': 'ghc_mod', +\ 'aliases': ['ghc-mod'], \ 'executable': 'ghc-mod', \ 'command': 'ghc-mod --map-file %s=%t check %s', \ 'callback': 'ale#handlers#haskell#HandleGHCFormat', \}) call ale#linter#Define('haskell', { -\ 'name': 'stack-ghc-mod', +\ 'name': 'stack_ghc_mod', +\ 'aliases': ['stack-ghc-mod'], \ 'executable': 'stack', \ 'command': 'stack exec ghc-mod -- --map-file %s=%t check %s', \ 'callback': 'ale#handlers#haskell#HandleGHCFormat', diff --git a/ale_linters/haskell/stack_build.vim b/ale_linters/haskell/stack_build.vim index 44e2e86f..f5bdf4b8 100644 --- a/ale_linters/haskell/stack_build.vim +++ b/ale_linters/haskell/stack_build.vim @@ -13,7 +13,8 @@ function! ale_linters#haskell#stack_build#GetCommand(buffer) abort endfunction call ale#linter#Define('haskell', { -\ 'name': 'stack-build', +\ 'name': 'stack_build', +\ 'aliases': ['stack-build'], \ 'output_stream': 'stderr', \ 'executable': 'stack', \ 'command_callback': 'ale_linters#haskell#stack_build#GetCommand', diff --git a/ale_linters/haskell/stack_ghc.vim b/ale_linters/haskell/stack_ghc.vim index 0367dc24..d702aa68 100644 --- a/ale_linters/haskell/stack_ghc.vim +++ b/ale_linters/haskell/stack_ghc.vim @@ -2,7 +2,8 @@ " Description: ghc for Haskell files, using Stack call ale#linter#Define('haskell', { -\ 'name': 'stack-ghc', +\ 'name': 'stack_ghc', +\ 'aliases': ['stack-ghc'], \ 'output_stream': 'stderr', \ 'executable': 'stack', \ 'command': 'stack ghc -- -fno-code -v0 %t', diff --git a/ale_linters/help/writegood.vim b/ale_linters/help/writegood.vim index 11254cd2..eeb21a73 100644 --- a/ale_linters/help/writegood.vim +++ b/ale_linters/help/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for vim Help files -call ale#linter#Define('help', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('help') diff --git a/ale_linters/html/writegood.vim b/ale_linters/html/writegood.vim index 9fae8821..6a2bd8e5 100644 --- a/ale_linters/html/writegood.vim +++ b/ale_linters/html/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans -" Description: write-good for nroff files +" Description: write-good for html files -call ale#linter#Define('html', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('html') diff --git a/ale_linters/markdown/remark_lint.vim b/ale_linters/markdown/remark_lint.vim index 195b0f5a..d9c2efb6 100644 --- a/ale_linters/markdown/remark_lint.vim +++ b/ale_linters/markdown/remark_lint.vim @@ -1,3 +1,4 @@ +scriptencoding utf-8 " Author rhysd https://rhysd.github.io/, Dirk Roorda (dirkroorda), Adrián González Rus (@adrigzr) " Description: remark-lint for Markdown files call ale#Set('markdown_remark_lint_executable', 'remark') @@ -43,7 +44,8 @@ function! ale_linters#markdown#remark_lint#Handle(buffer, lines) abort endfunction call ale#linter#Define('markdown', { -\ 'name': 'remark-lint', +\ 'name': 'remark_lint', +\ 'aliases': ['remark-lint'], \ 'executable_callback': 'ale_linters#markdown#remark_lint#GetExecutable', \ 'command_callback': 'ale_linters#markdown#remark_lint#GetCommand', \ 'callback': 'ale_linters#markdown#remark_lint#Handle', diff --git a/ale_linters/markdown/writegood.vim b/ale_linters/markdown/writegood.vim index 21dbff1a..7108e7ac 100644 --- a/ale_linters/markdown/writegood.vim +++ b/ale_linters/markdown/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for Markdown files -call ale#linter#Define('markdown', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('markdown') diff --git a/ale_linters/nroff/writegood.vim b/ale_linters/nroff/writegood.vim index d318fb28..bcf344f6 100644 --- a/ale_linters/nroff/writegood.vim +++ b/ale_linters/nroff/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for nroff files -call ale#linter#Define('nroff', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('nroff') diff --git a/ale_linters/po/writegood.vim b/ale_linters/po/writegood.vim index 5a01cb66..14686473 100644 --- a/ale_linters/po/writegood.vim +++ b/ale_linters/po/writegood.vim @@ -1,9 +1,4 @@ " Author: Cian Butler https://github.com/butlerx " Description: write-good for PO files -call ale#linter#Define('po', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('po') diff --git a/ale_linters/pod/writegood.vim b/ale_linters/pod/writegood.vim index 14ed5c0c..9f5461e6 100644 --- a/ale_linters/pod/writegood.vim +++ b/ale_linters/pod/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for Pod files -call ale#linter#Define('pod', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('pod') diff --git a/ale_linters/rst/writegood.vim b/ale_linters/rst/writegood.vim index 12137dbf..26b1152a 100644 --- a/ale_linters/rst/writegood.vim +++ b/ale_linters/rst/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for reStructuredText files -call ale#linter#Define('rst', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('rst') diff --git a/ale_linters/sml/smlnj_cm.vim b/ale_linters/sml/smlnj_cm.vim index 96cd7bd9..7a482307 100644 --- a/ale_linters/sml/smlnj_cm.vim +++ b/ale_linters/sml/smlnj_cm.vim @@ -9,7 +9,8 @@ endfunction " Using CM requires that we set "lint_file: 1", since it reads the files " from the disk itself. call ale#linter#Define('sml', { -\ 'name': 'smlnj-cm', +\ 'name': 'smlnj_cm', +\ 'aliases': ['smlnj-cm'], \ 'executable_callback': 'ale#handlers#sml#GetExecutableSmlnjCm', \ 'lint_file': 1, \ 'command_callback': 'ale_linters#sml#smlnj_cm#GetCommand', diff --git a/ale_linters/tex/writegood.vim b/ale_linters/tex/writegood.vim index dc59de2e..c1aeace9 100644 --- a/ale_linters/tex/writegood.vim +++ b/ale_linters/tex/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for TeX files -call ale#linter#Define('tex', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('tex') diff --git a/ale_linters/texinfo/writegood.vim b/ale_linters/texinfo/writegood.vim index 8104c634..4427f056 100644 --- a/ale_linters/texinfo/writegood.vim +++ b/ale_linters/texinfo/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for Texinfo files -call ale#linter#Define('texinfo', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('texinfo') diff --git a/ale_linters/text/writegood.vim b/ale_linters/text/writegood.vim index ff76ce42..81b935d4 100644 --- a/ale_linters/text/writegood.vim +++ b/ale_linters/text/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for text files -call ale#linter#Define('text', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('text') diff --git a/ale_linters/xhtml/writegood.vim b/ale_linters/xhtml/writegood.vim index 83d1863b..1fcba182 100644 --- a/ale_linters/xhtml/writegood.vim +++ b/ale_linters/xhtml/writegood.vim @@ -1,9 +1,4 @@ " Author: Sumner Evans " Description: write-good for XHTML files -call ale#linter#Define('xhtml', { -\ 'name': 'write-good', -\ 'executable_callback': 'ale#handlers#writegood#GetExecutable', -\ 'command_callback': 'ale#handlers#writegood#GetCommand', -\ 'callback': 'ale#handlers#writegood#Handle', -\}) +call ale#handlers#writegood#DefineLinter('xhtml') diff --git a/autoload/ale/handlers/writegood.vim b/autoload/ale/handlers/writegood.vim index aee7c4de..aff66d5f 100644 --- a/autoload/ale/handlers/writegood.vim +++ b/autoload/ale/handlers/writegood.vim @@ -59,3 +59,14 @@ function! ale#handlers#writegood#Handle(buffer, lines) abort return l:output endfunction + +" Define the writegood linter for a given filetype. +function! ale#handlers#writegood#DefineLinter(filetype) abort + call ale#linter#Define(a:filetype, { + \ 'name': 'writegood', + \ 'aliases': ['write-good'], + \ 'executable_callback': 'ale#handlers#writegood#GetExecutable', + \ 'command_callback': 'ale#handlers#writegood#GetCommand', + \ 'callback': 'ale#handlers#writegood#Handle', + \}) +endfunction diff --git a/test/script/custom-linting-rules b/test/script/custom-linting-rules index 51cf5680..69c4a7a1 100755 --- a/test/script/custom-linting-rules +++ b/test/script/custom-linting-rules @@ -52,12 +52,17 @@ directories=("$@") check_errors() { regex="$1" message="$2" + include_arg='' + + if [ $# -gt 2 ]; then + include_arg="--include $3" + fi for directory in "${directories[@]}"; do while IFS= read -r match; do RETURN_CODE=1 echo "$match $message" - done < <(grep -n "$regex" "$directory"/**/*.vim \ + done < <(grep -n "$regex" $include_arg "$directory"/**/*.vim \ | grep -v 'no-custom-checks' \ | grep -o '^[^:]\+:[0-9]\+' \ | sed 's:^\./::') @@ -75,6 +80,7 @@ if (( FIX_ERRORS )); then done fi +# The arguments are: regex, explanation, [filename_filter] check_errors \ '^function.*) *$' \ 'Function without abort keyword (See :help except-compat)' @@ -95,5 +101,6 @@ 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 $'name.:.*\'[a-z_]*[^a-z_0-9][a-z_0-9]*\',$' 'Use snake_case names for linters' '*/ale_linters/*' exit $RETURN_CODE diff --git a/test/test_filetype_linter_defaults.vader b/test/test_filetype_linter_defaults.vader index ea4a05fb..4f190226 100644 --- a/test/test_filetype_linter_defaults.vader +++ b/test/test_filetype_linter_defaults.vader @@ -22,7 +22,7 @@ Execute(The defaults for the csh filetype should be correct): AssertEqual [], GetLinterNames('csh') Execute(The defaults for the go filetype should be correct): - AssertEqual ['gofmt', 'golint', 'go vet'], GetLinterNames('go') + AssertEqual ['gofmt', 'golint', 'govet'], GetLinterNames('go') let g:ale_linters_explicit = 1 -- cgit v1.2.3 From 341857477011f703664b31d8d76f6872f8399c66 Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 24 Jul 2018 10:11:14 +0100 Subject: Update the developer documentation --- doc/ale-development.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/ale-development.txt b/doc/ale-development.txt index 5688c1cc..8a4c1d7d 100644 --- a/doc/ale-development.txt +++ b/doc/ale-development.txt @@ -115,6 +115,9 @@ these are reported with ALE's `custom-linting-rules` script. See * Don't use the `tempname()` function. It doesn't work when `$TMPDIR` isn't set. Use `ale#util#Tempname()` instead, which temporarily sets `$TMPDIR` appropriately where needed. +* Use `snake_case` names for linter names, so they can be used as part of + variable names. You can define `aliases` for linters, for other names people + might try to configure linters with. Apply the following guidelines when writing Vader test files. @@ -145,9 +148,10 @@ ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE runs tests with the following versions of Vim in the following environments. 1. Vim 8.0.0027 on Linux via Travis CI. -2. NeoVim 0.2.0 on Linux via Travis CI. -3. NeoVim 0.3.0 on Linux via Travis CI. -4. Vim 8 (stable builds) on Windows via AppVeyor. +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. 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 -- cgit v1.2.3