From 87a0227d01df14c9de7d3469b54cb73a98511ae2 Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Fri, 11 Oct 2019 09:43:55 +0200 Subject: [PATCH 001/167] added support for Ada Language Server --- ale_linters/ada/adalsp.vim | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 ale_linters/ada/adalsp.vim diff --git a/ale_linters/ada/adalsp.vim b/ale_linters/ada/adalsp.vim new file mode 100644 index 00000000..10c4be07 --- /dev/null +++ b/ale_linters/ada/adalsp.vim @@ -0,0 +1,16 @@ +" Author: Bartek Jasicki http://github.com/thindil +" Description: Support for Ada Language Server + +call ale#Set('ada_lsp_executable', 'ada_language_server') + +function! ale_linters#ada#adalsp#GetRootDirectory(buffer) abort + return fnamemodify(bufname(a:buffer), ':p:h') +endfunction + +call ale#linter#Define('ada', { +\ 'name': 'adalsp', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'ada_lsp_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#ada#adalsp#GetRootDirectory'), +\}) From 489b7d64e4a22492e94a18fe5a05703735e63afc Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Fri, 11 Oct 2019 09:55:05 +0200 Subject: [PATCH 002/167] updated documentation --- doc/ale-ada.txt | 11 +++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + 4 files changed, 14 insertions(+) diff --git a/doc/ale-ada.txt b/doc/ale-ada.txt index 2ac30c0a..c439d88a 100644 --- a/doc/ale-ada.txt +++ b/doc/ale-ada.txt @@ -32,5 +32,16 @@ g:ale_ada_gnatpp_options *g:ale_ada_gnatpp_options* This variable can be set to pass extra options to the gnatpp fixer. +=============================================================================== +Ada Language Server *ale-ada-lsp* + +g:ale_ada_lsp_executable *g:ale_ada_lsp_executable* + *b:ale_ada_lsp_executable* + Type: |String| + Default: `'ada_language_server'` + + This variable can be changed to use a different executable for Ada Language + Server. + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index a5b7c35e..626ce260 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -15,6 +15,7 @@ Notes: * Ada * `gcc` * `gnatpp` + * `ada_language_server` * Ansible * `ansible-lint` * API Blueprint diff --git a/doc/ale.txt b/doc/ale.txt index c6e48043..96d9e603 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2106,6 +2106,7 @@ documented in additional help files. ada.....................................|ale-ada-options| gcc...................................|ale-ada-gcc| gnatpp................................|ale-ada-gnatpp| + ada_language_server...................|ale-ada-lsp| ansible.................................|ale-ansible-options| ansible-lint..........................|ale-ansible-ansible-lint| asciidoc................................|ale-asciidoc-options| diff --git a/supported-tools.md b/supported-tools.md index e392f282..8a74b26e 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -24,6 +24,7 @@ formatting. * Ada * [gcc](https://gcc.gnu.org) * [gnatpp](https://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ugn/gnat_utility_programs.html#the-gnat-pretty-printer-gnatpp) :floppy_disk: + * [ada_language_server](https://github.com/AdaCore/ada_language_server) * Ansible * [ansible-lint](https://github.com/willthames/ansible-lint) * API Blueprint From 38e0e3feefad4e5974224a05cfa612c52bd8e358 Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Fri, 11 Oct 2019 10:08:36 +0200 Subject: [PATCH 003/167] added adalsp test --- .../test_adalsp_command_callbacks.vader | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/command_callback/test_adalsp_command_callbacks.vader diff --git a/test/command_callback/test_adalsp_command_callbacks.vader b/test/command_callback/test_adalsp_command_callbacks.vader new file mode 100644 index 00000000..73cbf296 --- /dev/null +++ b/test/command_callback/test_adalsp_command_callbacks.vader @@ -0,0 +1,12 @@ +Before: + call ale#assert#SetUpLinterTest('ada', 'adalsp') + +After: + call ale#assert#TearDownLinterTest() + +Execute(It does not set Ada sources by default): + AssertLinter 'adalsp', ale#Escape('adalsp') + +Execute(Sets adalsp executable): + let g:ale_ada_adalsp_executable = '/path/to /Ada' + AssertLinter 'adalsp', ale#Escape('adalsp') . ' ' . ale#Escape('/path/to /Ada') From c74cc931404ba94ccb71a6db2f54d78ba922aaab Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Fri, 11 Oct 2019 10:35:54 +0200 Subject: [PATCH 004/167] fixed test --- test/command_callback/test_adalsp_command_callbacks.vader | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/command_callback/test_adalsp_command_callbacks.vader b/test/command_callback/test_adalsp_command_callbacks.vader index 73cbf296..e02ade30 100644 --- a/test/command_callback/test_adalsp_command_callbacks.vader +++ b/test/command_callback/test_adalsp_command_callbacks.vader @@ -4,9 +4,6 @@ Before: After: call ale#assert#TearDownLinterTest() -Execute(It does not set Ada sources by default): - AssertLinter 'adalsp', ale#Escape('adalsp') - Execute(Sets adalsp executable): - let g:ale_ada_adalsp_executable = '/path/to /Ada' - AssertLinter 'adalsp', ale#Escape('adalsp') . ' ' . ale#Escape('/path/to /Ada') + let g:ale_ada_lsp_executable = '/path/to /Ada' + AssertLinter 'adalsp', ale#Escape('/path/to /Ada') From 321a3892a73b39bab4b1833b1473a6e0b46dc9fd Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Fri, 11 Oct 2019 10:41:19 +0200 Subject: [PATCH 005/167] fixed test again (this time for sure) --- test/command_callback/test_adalsp_command_callbacks.vader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/command_callback/test_adalsp_command_callbacks.vader b/test/command_callback/test_adalsp_command_callbacks.vader index e02ade30..92c6dfb0 100644 --- a/test/command_callback/test_adalsp_command_callbacks.vader +++ b/test/command_callback/test_adalsp_command_callbacks.vader @@ -6,4 +6,4 @@ After: Execute(Sets adalsp executable): let g:ale_ada_lsp_executable = '/path/to /Ada' - AssertLinter 'adalsp', ale#Escape('/path/to /Ada') + AssertLinter ale#Escape('/path/to /Ada'), ale#Escape('/path/to /Ada') From c30869617f6c829378d1931dc5ddf102924f5650 Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Fri, 11 Oct 2019 10:48:50 +0200 Subject: [PATCH 006/167] another fix for test --- test/command_callback/test_adalsp_command_callbacks.vader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/command_callback/test_adalsp_command_callbacks.vader b/test/command_callback/test_adalsp_command_callbacks.vader index 92c6dfb0..e635acb3 100644 --- a/test/command_callback/test_adalsp_command_callbacks.vader +++ b/test/command_callback/test_adalsp_command_callbacks.vader @@ -6,4 +6,4 @@ After: Execute(Sets adalsp executable): let g:ale_ada_lsp_executable = '/path/to /Ada' - AssertLinter ale#Escape('/path/to /Ada'), ale#Escape('/path/to /Ada') + AssertLinter '/path/to /Ada', ale#Escape('/path/to /Ada') From 5cbf7007ff18d100e5fb081297b6330dd75bdabf Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Fri, 11 Oct 2019 11:00:49 +0200 Subject: [PATCH 007/167] fixed documentation --- doc/ale-ada.txt | 2 +- doc/ale-supported-languages-and-tools.txt | 2 +- doc/ale.txt | 2 +- supported-tools.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/ale-ada.txt b/doc/ale-ada.txt index c439d88a..325bbea8 100644 --- a/doc/ale-ada.txt +++ b/doc/ale-ada.txt @@ -33,7 +33,7 @@ g:ale_ada_gnatpp_options *g:ale_ada_gnatpp_options* =============================================================================== -Ada Language Server *ale-ada-lsp* +Ada Language Server *ale-ada-ada_language_server* g:ale_ada_lsp_executable *g:ale_ada_lsp_executable* *b:ale_ada_lsp_executable* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 626ce260..a9bd47d0 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -13,9 +13,9 @@ Notes: `!!` These linters check only files on disk. See |ale-lint-file-linters| * Ada + * `ada_language_server` * `gcc` * `gnatpp` - * `ada_language_server` * Ansible * `ansible-lint` * API Blueprint diff --git a/doc/ale.txt b/doc/ale.txt index 96d9e603..f275266b 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2106,7 +2106,7 @@ documented in additional help files. ada.....................................|ale-ada-options| gcc...................................|ale-ada-gcc| gnatpp................................|ale-ada-gnatpp| - ada_language_server...................|ale-ada-lsp| + ada_language_server...................|ale-ada-ada_language_server| ansible.................................|ale-ansible-options| ansible-lint..........................|ale-ansible-ansible-lint| asciidoc................................|ale-asciidoc-options| diff --git a/supported-tools.md b/supported-tools.md index 8a74b26e..b28685bd 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -22,9 +22,9 @@ formatting. --- * Ada + * [ada_language_server](https://github.com/AdaCore/ada_language_server) * [gcc](https://gcc.gnu.org) * [gnatpp](https://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ugn/gnat_utility_programs.html#the-gnat-pretty-printer-gnatpp) :floppy_disk: - * [ada_language_server](https://github.com/AdaCore/ada_language_server) * Ansible * [ansible-lint](https://github.com/willthames/ansible-lint) * API Blueprint From 6d5d3fa4dd1cc18a5b90c587502ad37323df08a3 Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Fri, 11 Oct 2019 11:10:02 +0200 Subject: [PATCH 008/167] fixed documentation headers --- doc/ale-ada.txt | 4 ++-- doc/ale.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ale-ada.txt b/doc/ale-ada.txt index 325bbea8..4ffce5b7 100644 --- a/doc/ale-ada.txt +++ b/doc/ale-ada.txt @@ -33,9 +33,9 @@ g:ale_ada_gnatpp_options *g:ale_ada_gnatpp_options* =============================================================================== -Ada Language Server *ale-ada-ada_language_server* +ada-language-server *ale-ada-language-server* -g:ale_ada_lsp_executable *g:ale_ada_lsp_executable* +g:ale_ada_lsp_executable *g:ale_ada_lsp_executable* *b:ale_ada_lsp_executable* Type: |String| Default: `'ada_language_server'` diff --git a/doc/ale.txt b/doc/ale.txt index f275266b..c6c9418a 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2106,7 +2106,7 @@ documented in additional help files. ada.....................................|ale-ada-options| gcc...................................|ale-ada-gcc| gnatpp................................|ale-ada-gnatpp| - ada_language_server...................|ale-ada-ada_language_server| + ada-language-server...................|ale-ada-language-server| ansible.................................|ale-ansible-options| ansible-lint..........................|ale-ansible-ansible-lint| asciidoc................................|ale-asciidoc-options| From 2f181658e6e40798c74e2f58067ab3aeffab8224 Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Fri, 18 Oct 2019 18:26:08 +0200 Subject: [PATCH 009/167] rename command variable to *_adals_* instead of *_lsp_* and whole name to adals instead of adalsp --- ale_linters/ada/adals.vim | 16 ++++++++++++++++ ale_linters/ada/adalsp.vim | 16 ---------------- doc/ale-ada.txt | 4 ++-- .../test_adals_command_callbacks.vader | 9 +++++++++ .../test_adalsp_command_callbacks.vader | 9 --------- 5 files changed, 27 insertions(+), 27 deletions(-) create mode 100644 ale_linters/ada/adals.vim delete mode 100644 ale_linters/ada/adalsp.vim create mode 100644 test/command_callback/test_adals_command_callbacks.vader delete mode 100644 test/command_callback/test_adalsp_command_callbacks.vader diff --git a/ale_linters/ada/adals.vim b/ale_linters/ada/adals.vim new file mode 100644 index 00000000..354156f0 --- /dev/null +++ b/ale_linters/ada/adals.vim @@ -0,0 +1,16 @@ +" Author: Bartek Jasicki http://github.com/thindil +" Description: Support for Ada Language Server + +call ale#Set('ada_adals_executable', 'ada_language_server') + +function! ale_linters#ada#adals#GetRootDirectory(buffer) abort + return fnamemodify(bufname(a:buffer), ':p:h') +endfunction + +call ale#linter#Define('ada', { +\ 'name': 'adals', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'ada_adals_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#ada#adals#GetRootDirectory'), +\}) diff --git a/ale_linters/ada/adalsp.vim b/ale_linters/ada/adalsp.vim deleted file mode 100644 index 10c4be07..00000000 --- a/ale_linters/ada/adalsp.vim +++ /dev/null @@ -1,16 +0,0 @@ -" Author: Bartek Jasicki http://github.com/thindil -" Description: Support for Ada Language Server - -call ale#Set('ada_lsp_executable', 'ada_language_server') - -function! ale_linters#ada#adalsp#GetRootDirectory(buffer) abort - return fnamemodify(bufname(a:buffer), ':p:h') -endfunction - -call ale#linter#Define('ada', { -\ 'name': 'adalsp', -\ 'lsp': 'stdio', -\ 'executable': {b -> ale#Var(b, 'ada_lsp_executable')}, -\ 'command': '%e', -\ 'project_root': function('ale_linters#ada#adalsp#GetRootDirectory'), -\}) diff --git a/doc/ale-ada.txt b/doc/ale-ada.txt index 4ffce5b7..1a31c804 100644 --- a/doc/ale-ada.txt +++ b/doc/ale-ada.txt @@ -35,8 +35,8 @@ g:ale_ada_gnatpp_options *g:ale_ada_gnatpp_options* =============================================================================== ada-language-server *ale-ada-language-server* -g:ale_ada_lsp_executable *g:ale_ada_lsp_executable* - *b:ale_ada_lsp_executable* +g:ale_ada_adals_executable *g:ale_ada_adals_executable* + *b:ale_ada_adals_executable* Type: |String| Default: `'ada_language_server'` diff --git a/test/command_callback/test_adals_command_callbacks.vader b/test/command_callback/test_adals_command_callbacks.vader new file mode 100644 index 00000000..0b1f6006 --- /dev/null +++ b/test/command_callback/test_adals_command_callbacks.vader @@ -0,0 +1,9 @@ +Before: + call ale#assert#SetUpLinterTest('ada', 'adals') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Sets adals executable): + let g:ale_ada_adals_executable = '/path/to /Ada' + AssertLinter '/path/to /Ada', ale#Escape('/path/to /Ada') diff --git a/test/command_callback/test_adalsp_command_callbacks.vader b/test/command_callback/test_adalsp_command_callbacks.vader deleted file mode 100644 index e635acb3..00000000 --- a/test/command_callback/test_adalsp_command_callbacks.vader +++ /dev/null @@ -1,9 +0,0 @@ -Before: - call ale#assert#SetUpLinterTest('ada', 'adalsp') - -After: - call ale#assert#TearDownLinterTest() - -Execute(Sets adalsp executable): - let g:ale_ada_lsp_executable = '/path/to /Ada' - AssertLinter '/path/to /Ada', ale#Escape('/path/to /Ada') From 3c80c67633484c9bf3fd957b8985eee6f23a1a9e Mon Sep 17 00:00:00 2001 From: Bartek Jasicki Date: Tue, 5 Nov 2019 17:58:53 +0100 Subject: [PATCH 010/167] Update ale_linters/ada/adals.vim Co-Authored-By: timlag1305 --- ale_linters/ada/adals.vim | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ale_linters/ada/adals.vim b/ale_linters/ada/adals.vim index 354156f0..e4f86b83 100644 --- a/ale_linters/ada/adals.vim +++ b/ale_linters/ada/adals.vim @@ -2,6 +2,15 @@ " Description: Support for Ada Language Server call ale#Set('ada_adals_executable', 'ada_language_server') +call ale#Set('ada_adals_project, 'default.gpr') +call ale#Set('ada_adals_encoding', 'utf-8') + +function! ale_linters#ada#adals#GetAdaLSConfig(buffer) abort + return { + \ 'ada.projectFile': ale#Var(a:buffer, 'ada_adals_project'), + \ 'ada.defaultCharset': ale#Var(a:buffer, 'ada_adals_encoding') + \} +endfunction function! ale_linters#ada#adals#GetRootDirectory(buffer) abort return fnamemodify(bufname(a:buffer), ':p:h') From 09209dc54b166542d1251dc19f567e455c22efdb Mon Sep 17 00:00:00 2001 From: Bartek Jasicki Date: Tue, 5 Nov 2019 17:59:17 +0100 Subject: [PATCH 011/167] Update ale_linters/ada/adals.vim Co-Authored-By: timlag1305 --- ale_linters/ada/adals.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/ale_linters/ada/adals.vim b/ale_linters/ada/adals.vim index e4f86b83..a710a639 100644 --- a/ale_linters/ada/adals.vim +++ b/ale_linters/ada/adals.vim @@ -22,4 +22,5 @@ call ale#linter#Define('ada', { \ 'executable': {b -> ale#Var(b, 'ada_adals_executable')}, \ 'command': '%e', \ 'project_root': function('ale_linters#ada#adals#GetRootDirectory'), +\ 'lsp_config': function('ale_linters#ada#adals#GetAdaLSConfig') \}) From f63fd23f2e70631a24e9914fee17871f720586cd Mon Sep 17 00:00:00 2001 From: Bartek Jasicki Date: Tue, 5 Nov 2019 17:59:51 +0100 Subject: [PATCH 012/167] Update doc/ale-ada.txt Co-Authored-By: timlag1305 --- doc/ale-ada.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/ale-ada.txt b/doc/ale-ada.txt index 1a31c804..0fc55a9c 100644 --- a/doc/ale-ada.txt +++ b/doc/ale-ada.txt @@ -43,5 +43,24 @@ g:ale_ada_adals_executable *g:ale_ada_adals_executable* This variable can be changed to use a different executable for Ada Language Server. + +g:ale_ada_adals_project *g:ale_ada_adals_project* + *b:ale_ada_adals_project* + Type: |String| + Default: `'default.gpr'` + +This variable can be changed to use a different GPR file for +Ada Language Server. + + +g:ale_ada_adals_encoding *g:ale_ada_adals_encoding* + *b:ale_ada_adals_encoding* + Type: |String| + Default: `'utf-8'` + +This variable can be changed to use a different file encoding for +Ada Language Server. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: From b454e4314301ad5bdf159f849dc6f30bb377d8f2 Mon Sep 17 00:00:00 2001 From: Bartek Jasicki Date: Tue, 5 Nov 2019 18:00:16 +0100 Subject: [PATCH 013/167] Update test/command_callback/test_adals_command_callbacks.vader Co-Authored-By: timlag1305 --- test/command_callback/test_adals_command_callbacks.vader | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/command_callback/test_adals_command_callbacks.vader b/test/command_callback/test_adals_command_callbacks.vader index 0b1f6006..5a04594e 100644 --- a/test/command_callback/test_adals_command_callbacks.vader +++ b/test/command_callback/test_adals_command_callbacks.vader @@ -7,3 +7,11 @@ After: Execute(Sets adals executable): let g:ale_ada_adals_executable = '/path/to /Ada' AssertLinter '/path/to /Ada', ale#Escape('/path/to /Ada') + +Execute(Sets adals encoding): + let b:ale_ada_adals_encoding = 'iso-8859-1' + AssertLSPConfig {'ada.defaultCharset': 'iso-8859-1', 'ada.projectFile': 'default.gpr'} + +Execute(Sets adals project): + let g:ale_ada_adals_project = 'myproject.gpr' + AssertLSPConfig {'ada.defaultCharset': 'utf-8', 'ada.projectFile': 'myproject.gpr'} From b8d69cb0d57fc25fdb8cd821bda99a34487016da Mon Sep 17 00:00:00 2001 From: Bartek thindil Jasicki Date: Tue, 5 Nov 2019 18:59:13 +0100 Subject: [PATCH 014/167] fixed typo --- ale_linters/ada/adals.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/ada/adals.vim b/ale_linters/ada/adals.vim index a710a639..9a41e1df 100644 --- a/ale_linters/ada/adals.vim +++ b/ale_linters/ada/adals.vim @@ -2,7 +2,7 @@ " Description: Support for Ada Language Server call ale#Set('ada_adals_executable', 'ada_language_server') -call ale#Set('ada_adals_project, 'default.gpr') +call ale#Set('ada_adals_project', 'default.gpr') call ale#Set('ada_adals_encoding', 'utf-8') function! ale_linters#ada#adals#GetAdaLSConfig(buffer) abort From ddf4e7e9bab24423ef4388bd923a532d8fb3227f Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Sun, 12 Jul 2020 20:49:04 +0900 Subject: [PATCH 015/167] Enable ktlint fixer for kotlin files. --- autoload/ale/fix/registry.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 1b3ca1a8..ef30f529 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -327,7 +327,7 @@ let s:default_registry = { \ }, \ 'ktlint': { \ 'function': 'ale#fixers#ktlint#Fix', -\ 'suggested_filetypes': ['kt'], +\ 'suggested_filetypes': ['kt', 'kotlin'], \ 'description': 'Fix Kotlin files with ktlint.', \ }, \ 'styler': { From f1080a2bbe701949de16f8b93481375ee5732322 Mon Sep 17 00:00:00 2001 From: toastal Date: Sun, 2 Aug 2020 12:31:06 +0700 Subject: [PATCH 016/167] Dhall language support (fixes #2820) --- autoload/ale/dhall.vim | 21 +++++++++++ autoload/ale/fix/registry.vim | 15 ++++++++ autoload/ale/fixers/dhall_format.vim | 14 ++++++++ autoload/ale/fixers/dhall_freeze.vim | 18 ++++++++++ autoload/ale/fixers/dhall_lint.vim | 14 ++++++++ doc/ale-dhall.txt | 52 ++++++++++++++++++++++++++++ doc/ale.txt | 4 +++ supported-tools.md | 4 +++ 8 files changed, 142 insertions(+) create mode 100644 autoload/ale/dhall.vim create mode 100644 autoload/ale/fixers/dhall_format.vim create mode 100644 autoload/ale/fixers/dhall_freeze.vim create mode 100644 autoload/ale/fixers/dhall_lint.vim create mode 100644 doc/ale-dhall.txt diff --git a/autoload/ale/dhall.vim b/autoload/ale/dhall.vim new file mode 100644 index 00000000..6e57c4a7 --- /dev/null +++ b/autoload/ale/dhall.vim @@ -0,0 +1,21 @@ +" Author: toastal +" Description: Functions for working with Dhall’s executable + +call ale#Set('dhall_executable', 'dhall') +call ale#Set('dhall_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('dhall_options', '') + +function! ale#dhall#GetExecutable(buffer) abort + return ale#Escape(ale#Var(a:buffer, 'dhall_executable')) +endfunction + +function! ale#dhall#GetExecutableWithOptions(buffer) abort + let l:executable = ale#dhall#GetExecutable(a:buffer) + + return l:executable + \ . ale#Pad(ale#Var(a:buffer, 'dhall_options')) +endfunction + +function! ale#dhall#GetCommand(buffer) abort + return '%e ' . ale#Pad(ale#Var(a:buffer, 'dhall_options')) +endfunction diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 02b02699..3dc5c774 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -32,6 +32,21 @@ let s:default_registry = { \ 'suggested_filetypes': ['d'], \ 'description': 'Fix D files with dfmt.', \ }, +\ 'dhall-format': { +\ 'function': 'ale#fixers#dhall_format#Fix', +\ 'suggested_filetypes': ['dhall'], +\ 'description': 'Standard code formatter for the Dhall language', +\ }, +\ 'dhall-freeze': { +\ 'function': 'ale#fixers#dhall_freeze#Freeze', +\ 'suggested_filetypes': ['dhall'], +\ 'description': 'Add integrity checks to remote import statements of an expression for the Dhall language', +\ }, +\ 'dhall-lint': { +\ 'function': 'ale#fixers#dhall_lint#Fix', +\ 'suggested_filetypes': ['dhall'], +\ 'description': 'Standard code formatter for the Dhall language and removing dead code', +\ }, \ 'fecs': { \ 'function': 'ale#fixers#fecs#Fix', \ 'suggested_filetypes': ['javascript', 'css', 'html'], diff --git a/autoload/ale/fixers/dhall_format.vim b/autoload/ale/fixers/dhall_format.vim new file mode 100644 index 00000000..214af2c8 --- /dev/null +++ b/autoload/ale/fixers/dhall_format.vim @@ -0,0 +1,14 @@ +" Author: toastal +" Description: Dhall’s built-in formatter + +function! ale#fixers#dhall_format#Fix(buffer) abort + let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer) + let l:command = l:executable + \ . ' format' + \ . ' --inplace %t' + + return { + \ 'command': l:command, + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/autoload/ale/fixers/dhall_freeze.vim b/autoload/ale/fixers/dhall_freeze.vim new file mode 100644 index 00000000..74ae7530 --- /dev/null +++ b/autoload/ale/fixers/dhall_freeze.vim @@ -0,0 +1,18 @@ +" Author: toastal +" Description: Dhall’s package freezing + +call ale#Set('dhall_freeze_options', '') + +function! ale#fixers#dhall_freeze#Freeze(buffer) abort + let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer) + let l:command = l:executable + \ . ' freeze' + \ . ale#Pad(ale#Var(a:buffer, 'dhall_freeze_options')) + \ . ' --inplace %t' + + + return { + \ 'command': l:command, + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/autoload/ale/fixers/dhall_lint.vim b/autoload/ale/fixers/dhall_lint.vim new file mode 100644 index 00000000..2abbe6f7 --- /dev/null +++ b/autoload/ale/fixers/dhall_lint.vim @@ -0,0 +1,14 @@ +" Author: toastal +" Description: Dhall’s built-in linter/formatter + +function! ale#fixers#dhall_lint#Fix(buffer) abort + let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer) + let l:command = l:executable + \ . ' lint' + \ . ' --inplace %t' + + return { + \ 'command': l:command, + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/doc/ale-dhall.txt b/doc/ale-dhall.txt new file mode 100644 index 00000000..44b0bf32 --- /dev/null +++ b/doc/ale-dhall.txt @@ -0,0 +1,52 @@ +=============================================================================== +ALE Dhall Integration *ale-dhall-options* + +g:ale_dhall_executable *g:ale_dhall_executable* + *b:ale_dhall_executable* + Type: |String| + Default: `'dhall'` + +g:ale_dhall_options g:ale_dhall_options + b:ale_dhall_options + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the 'dhall` executable. + This is shared with `dhall-freeze` and `dhall-lint`. +> + let g:dhall_options = '--ascii' +< + +=============================================================================== +dhall-format *ale-dhall-format* + +Dhall + (https://dhall-lang.org/) + + +=============================================================================== +dhall-freeze *ale-dhall-freeze* + +Dhall + (https://dhall-lang.org/) + +g:ale_dhall_freeze_options g:ale_dhall_freeze_options + b:ale_dhall_freeze_options + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the 'dhall freeze` + executable. +> + let g:dhall_freeze_options = '--all' +< + +=============================================================================== +dhall-lint *ale-dhall-lint* + +Dhall + (https://dhall-lang.org/) + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index ea49eedb..4b914b82 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2374,6 +2374,10 @@ documented in additional help files. dart....................................|ale-dart-options| dartanalyzer..........................|ale-dart-dartanalyzer| dartfmt...............................|ale-dart-dartfmt| + dhall...................................|ale-dhall-options| + dhall-format..........................|ale-dhall-format| + dhall-freeze..........................|ale-dhall-freeze| + dhall-lint............................|ale-dhall-lint| dockerfile..............................|ale-dockerfile-options| dockerfile_lint.......................|ale-dockerfile-dockerfile_lint| hadolint..............................|ale-dockerfile-hadolint| diff --git a/supported-tools.md b/supported-tools.md index 7fa6ec4f..d708ae80 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -127,6 +127,10 @@ formatting. * [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) :floppy_disk: * [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) * [language_server](https://github.com/natebosch/dart_language_server) +* Dhall + * [dhall-format](https://github.com/dhall-lang) + * [dhall-freeze](https://github.com/dhall-lang) + * [dhall-lint](https://github.com/dhall-lang) * Dockerfile * [dockerfile_lint](https://github.com/projectatomic/dockerfile_lint) * [hadolint](https://github.com/hadolint/hadolint) From 167e2e77506c55831921ee40dc30c92f7f2aaae8 Mon Sep 17 00:00:00 2001 From: toastal Date: Sun, 2 Aug 2020 23:58:49 +0700 Subject: [PATCH 017/167] tests --- .../test_dhall_format_fixer_callback.vader | 27 +++++++++++++++++ .../test_dhall_freeze_fixer_callback.vader | 29 +++++++++++++++++++ .../test_dhall_lint_fixer_callback.vader | 27 +++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 test/fixers/test_dhall_format_fixer_callback.vader create mode 100644 test/fixers/test_dhall_freeze_fixer_callback.vader create mode 100644 test/fixers/test_dhall_lint_fixer_callback.vader diff --git a/test/fixers/test_dhall_format_fixer_callback.vader b/test/fixers/test_dhall_format_fixer_callback.vader new file mode 100644 index 00000000..02873473 --- /dev/null +++ b/test/fixers/test_dhall_format_fixer_callback.vader @@ -0,0 +1,27 @@ +Before: + Save g:ale_dhall_executable + Save g:ale_dhall_options + + " Use an invalid global executable, so we don’t match it. + let g:ale_dhall_executable = 'odd-dhall' + let g:ale_dhall_options = '--ascii' + + call ale#test#SetDirectory('/testplugin/test/dhall') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The dhall-format callback should return the correct options): + call ale#test#SetFilename('../dhall_files/testfile.dhall') + + AssertEqual + \ { + \ 'command': ale#Escape('odd-dhall') + \ . ' --ascii' + \ . ' format' + \ . ' --inplace %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#dhall_format#Fix(bufnr('')) diff --git a/test/fixers/test_dhall_freeze_fixer_callback.vader b/test/fixers/test_dhall_freeze_fixer_callback.vader new file mode 100644 index 00000000..6e9650eb --- /dev/null +++ b/test/fixers/test_dhall_freeze_fixer_callback.vader @@ -0,0 +1,29 @@ +Before: + Save g:ale_dhall_executable + Save g:ale_dhall_options + + " Use an invalid global executable, so we don’t match it. + let g:ale_dhall_executable = 'odd-dhall' + let g:ale_dhall_options = '--ascii' + let g:ale_dhall_freeze_options = '--all' + + call ale#test#SetDirectory('/testplugin/test/dhall') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The dhall-freeze callback should return the correct options): + call ale#test#SetFilename('../dhall_files/testfile.dhall') + + AssertEqual + \ { + \ 'command': ale#Escape('odd-dhall') + \ . ' --ascii' + \ . ' freeze' + \ . ' --all' + \ . ' --inplace %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#dhall_freeze#Freeze(bufnr('')) diff --git a/test/fixers/test_dhall_lint_fixer_callback.vader b/test/fixers/test_dhall_lint_fixer_callback.vader new file mode 100644 index 00000000..c60b7a73 --- /dev/null +++ b/test/fixers/test_dhall_lint_fixer_callback.vader @@ -0,0 +1,27 @@ +Before: + Save g:ale_dhall_executable + Save g:ale_dhall_options + + " Use an invalid global executable, so we don’t match it. + let g:ale_dhall_executable = 'odd-dhall' + let g:ale_dhall_options = '--ascii' + + call ale#test#SetDirectory('/testplugin/test/dhall') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The dhall-lint callback should return the correct options): + call ale#test#SetFilename('../dhall_files/testfile.dhall') + + AssertEqual + \ { + \ 'command': ale#Escape('odd-dhall') + \ . ' --ascii' + \ . ' lint' + \ . ' --inplace %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#dhall_lint#Fix(bufnr('')) From 49718e0ec6eb4b9068049048c9373167c19257c9 Mon Sep 17 00:00:00 2001 From: Dmitri Vereshchagin Date: Sun, 1 Sep 2019 17:36:40 +0300 Subject: [PATCH 018/167] Add Elvis handler for Erlang [Elvis][1] is an Erlang style reviewer. [1]: https://github.com/inaka/elvis --- ale_linters/erlang/elvis.vim | 39 +++++++++++++++++++ doc/ale-erlang.txt | 12 ++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + .../test_erlang_elvis_command_callback.vader | 16 ++++++++ test/handler/test_erlang_elvis_handler.vader | 37 ++++++++++++++++++ 7 files changed, 107 insertions(+) create mode 100644 ale_linters/erlang/elvis.vim create mode 100644 test/command_callback/test_erlang_elvis_command_callback.vader create mode 100644 test/handler/test_erlang_elvis_handler.vader diff --git a/ale_linters/erlang/elvis.vim b/ale_linters/erlang/elvis.vim new file mode 100644 index 00000000..31dea3dd --- /dev/null +++ b/ale_linters/erlang/elvis.vim @@ -0,0 +1,39 @@ +" Author: Dmitri Vereshchagin +" Description: Elvis linter for Erlang files + +call ale#Set('erlang_elvis_executable', 'elvis') + +function! ale_linters#erlang#elvis#Handle(buffer, lines) abort + let l:pattern = '\v:(\d+):[^:]+:(.+)' + let l:loclist = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:loclist, { + \ 'lnum': str2nr(l:match[1]), + \ 'text': s:AbbreviateMessage(l:match[2]), + \ 'type': 'W', + \}) + endfor + + return l:loclist +endfunction + +function! s:AbbreviateMessage(text) abort + let l:pattern = '\v\c^(line \d+ is too long):.*$' + + return substitute(a:text, l:pattern, '\1.', '') +endfunction + +function! s:GetCommand(buffer) abort + let l:file = ale#Escape(expand('#' . a:buffer . ':.')) + + return '%e rock --output-format=parsable ' . l:file +endfunction + +call ale#linter#Define('erlang', { +\ 'name': 'elvis', +\ 'callback': 'ale_linters#erlang#elvis#Handle', +\ 'executable': {b -> ale#Var(b, 'erlang_elvis_executable')}, +\ 'command': function('s:GetCommand'), +\ 'lint_file': 1, +\}) diff --git a/doc/ale-erlang.txt b/doc/ale-erlang.txt index 59993a99..38762f08 100644 --- a/doc/ale-erlang.txt +++ b/doc/ale-erlang.txt @@ -31,6 +31,18 @@ g:ale_erlang_dialyzer_rebar3_profile *g:ale_erlang_dialyzer_rebar3_profile* This variable can be changed to specify the profile that is used to run dialyzer with rebar3. + +------------------------------------------------------------------------------- +elvis *ale-erlang-elvis* + +g:ale_erlang_elvis_executable *g:ale_erlang_elvis_executable* + *b:ale_erlang_elvis_executable* + Type: |String| + Default: `'elvis'` + + This variable can be changed to specify the elvis executable. + + ------------------------------------------------------------------------------- erlc *ale-erlang-erlc* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index c6bcf421..73c2e473 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -140,6 +140,7 @@ Notes: * `erubis` * `ruumba` * Erlang + * `elvis`!! * `erlc` * `SyntaxErl` * Fish diff --git a/doc/ale.txt b/doc/ale.txt index d45cada7..4a1dc7cc 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2575,6 +2575,7 @@ documented in additional help files. elm-make..............................|ale-elm-elm-make| erlang..................................|ale-erlang-options| dialyzer..............................|ale-erlang-dialyzer| + elvis.................................|ale-erlang-elvis| erlc..................................|ale-erlang-erlc| syntaxerl.............................|ale-erlang-syntaxerl| eruby...................................|ale-eruby-options| diff --git a/supported-tools.md b/supported-tools.md index 66e46348..cfbed9ef 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -149,6 +149,7 @@ formatting. * [erubis](https://github.com/kwatch/erubis) * [ruumba](https://github.com/ericqweinstein/ruumba) * Erlang + * [elvis](https://github.com/inaka/elvis) :floppy_disk: * [erlc](http://erlang.org/doc/man/erlc.html) * [SyntaxErl](https://github.com/ten0s/syntaxerl) * Fish diff --git a/test/command_callback/test_erlang_elvis_command_callback.vader b/test/command_callback/test_erlang_elvis_command_callback.vader new file mode 100644 index 00000000..4aab49d6 --- /dev/null +++ b/test/command_callback/test_erlang_elvis_command_callback.vader @@ -0,0 +1,16 @@ +Before: + let b:file = fnamemodify(bufname(''), ':.') + call ale#assert#SetUpLinterTest('erlang', 'elvis') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Default command should be correct): + AssertLinter 'elvis', + \ ale#Escape('elvis') . ' rock --output-format=parsable ' . ale#Escape(b:file) + +Execute(Executable should be configurable): + let b:ale_erlang_elvis_executable = '/path/to/elvis' + + AssertLinter '/path/to/elvis', + \ ale#Escape('/path/to/elvis') . ' rock --output-format=parsable ' . ale#Escape(b:file) diff --git a/test/handler/test_erlang_elvis_handler.vader b/test/handler/test_erlang_elvis_handler.vader new file mode 100644 index 00000000..365376c8 --- /dev/null +++ b/test/handler/test_erlang_elvis_handler.vader @@ -0,0 +1,37 @@ +Before: + runtime ale_linters/erlang/elvis.vim + +After: + call ale#linter#Reset() + +Execute(Warning messages should be handled): + AssertEqual + \ [ + \ { + \ 'lnum': 11, + \ 'text': "Replace the 'if' expression on line 11 with a 'case' expression or function clauses.", + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 20, + \ 'text': 'Remove the debug call to io:format/1 on line 20.', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#erlang#elvis#Handle(bufnr(''), [ + \ "src/foo.erl:11:no_if_expression:Replace the 'if' expression on line 11 with a 'case' expression or function clauses.", + \ 'src/foo.erl:20:no_debug_call:Remove the debug call to io:format/1 on line 20.', + \ ]) + +Execute(Line length message shouldn't contain the line itself): + AssertEqual + \ [ + \ { + \ 'lnum': 24, + \ 'text': 'Line 24 is too long.', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#erlang#elvis#Handle(bufnr(''), [ + \ 'src/foo.erl:24:line_length:Line 24 is too long: io:format("Look ma, too long!"),.', + \ ]) From 20f6bebdf22afca71b136a1ce8cff9f8b5ec7410 Mon Sep 17 00:00:00 2001 From: Christian Keil Date: Wed, 9 Sep 2020 17:30:41 +0200 Subject: [PATCH 019/167] Fix handling of ranges at file end. --- autoload/ale/code_action.vim | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/autoload/ale/code_action.vim b/autoload/ale/code_action.vim index 8c7263f3..849942ca 100644 --- a/autoload/ale/code_action.vim +++ b/autoload/ale/code_action.vim @@ -127,10 +127,20 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort endif call extend(l:middle, l:insertions[1:]) - let l:middle[-1] .= l:lines[l:end_line - 1][l:end_column - 1 :] + if l:end_line <= len(l:lines) + " Only extend the last line if end_line is within the range of + " lines. + let l:middle[-1] .= l:lines[l:end_line - 1][l:end_column - 1 :] + endif let l:lines_before_change = len(l:lines) - let l:lines = l:start + l:middle + l:lines[l:end_line :] + + if l:end_line < len(l:lines) + let l:end = l:lines[l:end_line :] + else + let l:end = [] + endif + let l:lines = l:start + l:middle + l:end let l:current_line_offset = len(l:lines) - l:lines_before_change let l:line_offset += l:current_line_offset From d3932c02424eec0520faa2afa42371c27122f5a7 Mon Sep 17 00:00:00 2001 From: Christian Keil Date: Wed, 9 Sep 2020 17:44:09 +0200 Subject: [PATCH 020/167] Fix format linting error. --- autoload/ale/code_action.vim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/autoload/ale/code_action.vim b/autoload/ale/code_action.vim index 849942ca..1959d1b1 100644 --- a/autoload/ale/code_action.vim +++ b/autoload/ale/code_action.vim @@ -127,6 +127,7 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort endif call extend(l:middle, l:insertions[1:]) + if l:end_line <= len(l:lines) " Only extend the last line if end_line is within the range of " lines. @@ -140,6 +141,7 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort else let l:end = [] endif + let l:lines = l:start + l:middle + l:end let l:current_line_offset = len(l:lines) - l:lines_before_change From d1f48e5edef1d622817ffc054e6963e6ca956371 Mon Sep 17 00:00:00 2001 From: Christian Keil Date: Wed, 9 Sep 2020 17:49:21 +0200 Subject: [PATCH 021/167] Remove unnecessary length check. --- autoload/ale/code_action.vim | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/autoload/ale/code_action.vim b/autoload/ale/code_action.vim index 1959d1b1..359bc0d6 100644 --- a/autoload/ale/code_action.vim +++ b/autoload/ale/code_action.vim @@ -135,14 +135,7 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort endif let l:lines_before_change = len(l:lines) - - if l:end_line < len(l:lines) - let l:end = l:lines[l:end_line :] - else - let l:end = [] - endif - - let l:lines = l:start + l:middle + l:end + let l:lines = l:start + l:middle + l:lines[l:end_line :] let l:current_line_offset = len(l:lines) - l:lines_before_change let l:line_offset += l:current_line_offset From ed47008710a2295ff3bf2d2e6372ee29cdbe6c39 Mon Sep 17 00:00:00 2001 From: toastal Date: Mon, 14 Sep 2020 09:20:53 +0700 Subject: [PATCH 022/167] addressing missing docs + cleaning up older Dhall files --- autoload/ale/dhall.vim | 7 ++++-- autoload/ale/fix/registry.vim | 5 ---- autoload/ale/fixers/dhall.vim | 23 ------------------- autoload/ale/fixers/dhall_format.vim | 2 +- doc/ale-supported-languages-and-tools.txt | 2 ++ test/fixers/test_dhall_fixer_callback.vader | 11 --------- .../test_dhall_format_fixer_callback.vader | 11 ++++----- .../test_dhall_freeze_fixer_callback.vader | 13 ++++------- .../test_dhall_lint_fixer_callback.vader | 13 ++++------- 9 files changed, 20 insertions(+), 67 deletions(-) delete mode 100644 autoload/ale/fixers/dhall.vim delete mode 100644 test/fixers/test_dhall_fixer_callback.vader diff --git a/autoload/ale/dhall.vim b/autoload/ale/dhall.vim index 6e57c4a7..cc54418f 100644 --- a/autoload/ale/dhall.vim +++ b/autoload/ale/dhall.vim @@ -1,4 +1,4 @@ -" Author: toastal +" Author: Pat Brisbin , toastal " Description: Functions for working with Dhall’s executable call ale#Set('dhall_executable', 'dhall') @@ -6,7 +6,10 @@ call ale#Set('dhall_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('dhall_options', '') function! ale#dhall#GetExecutable(buffer) abort - return ale#Escape(ale#Var(a:buffer, 'dhall_executable')) + let l:executable = ale#Var(a:buffer, 'dhall_executable') + + " Dhall is written in Haskell and commonly installed with Stack + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'dhall') endfunction function! ale#dhall#GetExecutableWithOptions(buffer) abort diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 0a729cf9..218a0f95 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -390,11 +390,6 @@ let s:default_registry = { \ 'suggested_filetypes': ['html', 'htmldjango'], \ 'description': 'Fix HTML files with html-beautify.', \ }, -\ 'dhall': { -\ 'function': 'ale#fixers#dhall#Fix', -\ 'suggested_filetypes': ['dhall'], -\ 'description': 'Fix Dhall files with dhall-format.', -\ }, \} " Reset the function registry to the default entries. diff --git a/autoload/ale/fixers/dhall.vim b/autoload/ale/fixers/dhall.vim deleted file mode 100644 index 18f6006c..00000000 --- a/autoload/ale/fixers/dhall.vim +++ /dev/null @@ -1,23 +0,0 @@ -" Author: Pat Brisbin -" Description: Integration of dhall-format with ALE. - -call ale#Set('dhall_format_executable', 'dhall') - -function! ale#fixers#dhall#GetExecutable(buffer) abort - let l:executable = ale#Var(a:buffer, 'dhall_format_executable') - - " Dhall is written in Haskell and commonly installed with Stack - return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'dhall') -endfunction - -function! ale#fixers#dhall#Fix(buffer) abort - let l:executable = ale#fixers#dhall#GetExecutable(a:buffer) - - return { - \ 'command': l:executable - \ . ' format' - \ . ' --inplace' - \ . ' %t', - \ 'read_temporary_file': 1, - \} -endfunction diff --git a/autoload/ale/fixers/dhall_format.vim b/autoload/ale/fixers/dhall_format.vim index 214af2c8..d4021983 100644 --- a/autoload/ale/fixers/dhall_format.vim +++ b/autoload/ale/fixers/dhall_format.vim @@ -1,6 +1,6 @@ " Author: toastal " Description: Dhall’s built-in formatter - +" function! ale#fixers#dhall_format#Fix(buffer) abort let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer) let l:command = l:executable diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index c6bcf421..7579566a 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -121,6 +121,8 @@ Notes: * `language_server` * Dhall * `dhall-format` + * `dhall-freeze` + * `dhall-lint` * Dockerfile * `dockerfile_lint` * `hadolint` diff --git a/test/fixers/test_dhall_fixer_callback.vader b/test/fixers/test_dhall_fixer_callback.vader deleted file mode 100644 index f27880b7..00000000 --- a/test/fixers/test_dhall_fixer_callback.vader +++ /dev/null @@ -1,11 +0,0 @@ -Before: - call ale#assert#SetUpFixerTest('dhall', 'dhall') - -After: - call ale#assert#TearDownFixerTest() - -Execute(The default command should be correct): - AssertFixer - \ { 'read_temporary_file': 1, - \ 'command': ale#Escape('dhall') . ' format --inplace %t' - \ } diff --git a/test/fixers/test_dhall_format_fixer_callback.vader b/test/fixers/test_dhall_format_fixer_callback.vader index 02873473..9bc17f7e 100644 --- a/test/fixers/test_dhall_format_fixer_callback.vader +++ b/test/fixers/test_dhall_format_fixer_callback.vader @@ -6,22 +6,19 @@ Before: let g:ale_dhall_executable = 'odd-dhall' let g:ale_dhall_options = '--ascii' - call ale#test#SetDirectory('/testplugin/test/dhall') + call ale#assert#SetUpFixerTest('dhall-format', 'dhall-format') After: - Restore - - call ale#test#RestoreDirectory() + call ale#assert#TearDownFixerTest() Execute(The dhall-format callback should return the correct options): call ale#test#SetFilename('../dhall_files/testfile.dhall') - AssertEqual + AssertFixer \ { \ 'command': ale#Escape('odd-dhall') \ . ' --ascii' \ . ' format' \ . ' --inplace %t', \ 'read_temporary_file': 1, - \ }, - \ ale#fixers#dhall_format#Fix(bufnr('')) + \ } diff --git a/test/fixers/test_dhall_freeze_fixer_callback.vader b/test/fixers/test_dhall_freeze_fixer_callback.vader index 6e9650eb..c8f820bb 100644 --- a/test/fixers/test_dhall_freeze_fixer_callback.vader +++ b/test/fixers/test_dhall_freeze_fixer_callback.vader @@ -7,17 +7,13 @@ Before: let g:ale_dhall_options = '--ascii' let g:ale_dhall_freeze_options = '--all' - call ale#test#SetDirectory('/testplugin/test/dhall') + call ale#assert#SetUpFixerTest('dhall-freeze', 'dhall-freeze') After: - Restore - - call ale#test#RestoreDirectory() + call ale#assert#TearDownFixerTest() Execute(The dhall-freeze callback should return the correct options): - call ale#test#SetFilename('../dhall_files/testfile.dhall') - - AssertEqual + AssertFixer \ { \ 'command': ale#Escape('odd-dhall') \ . ' --ascii' @@ -25,5 +21,4 @@ Execute(The dhall-freeze callback should return the correct options): \ . ' --all' \ . ' --inplace %t', \ 'read_temporary_file': 1, - \ }, - \ ale#fixers#dhall_freeze#Freeze(bufnr('')) + \ } diff --git a/test/fixers/test_dhall_lint_fixer_callback.vader b/test/fixers/test_dhall_lint_fixer_callback.vader index c60b7a73..82229363 100644 --- a/test/fixers/test_dhall_lint_fixer_callback.vader +++ b/test/fixers/test_dhall_lint_fixer_callback.vader @@ -6,22 +6,17 @@ Before: let g:ale_dhall_executable = 'odd-dhall' let g:ale_dhall_options = '--ascii' - call ale#test#SetDirectory('/testplugin/test/dhall') + call ale#assert#SetUpFixerTest('dhall-lint', 'dhall-lint') After: - Restore - - call ale#test#RestoreDirectory() + call ale#assert#TearDownFixerTest() Execute(The dhall-lint callback should return the correct options): - call ale#test#SetFilename('../dhall_files/testfile.dhall') - - AssertEqual + AssertFixer \ { \ 'command': ale#Escape('odd-dhall') \ . ' --ascii' \ . ' lint' \ . ' --inplace %t', \ 'read_temporary_file': 1, - \ }, - \ ale#fixers#dhall_lint#Fix(bufnr('')) + \ } From 63a528eac29c9bc34811eba2e0e09eab24b53591 Mon Sep 17 00:00:00 2001 From: Arthur Arnold Date: Mon, 14 Sep 2020 07:57:22 -0300 Subject: [PATCH 023/167] Fix wording in Rust doc --- doc/ale-rust.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ale-rust.txt b/doc/ale-rust.txt index f4b4e7b7..3aa63673 100644 --- a/doc/ale-rust.txt +++ b/doc/ale-rust.txt @@ -22,12 +22,12 @@ Integration Information 3. rls -- If you have `rls` installed, you might prefer using this linter over cargo. rls implements the Language Server Protocol for incremental compilation of Rust code, and can check Rust files while you type. `rls` - requires Rust files to contained in Cargo projects. + requires Rust files to be contained in Cargo projects. 4. analyzer -- If you have rust-analyzer installed, you might prefer using this linter over cargo and rls. rust-analyzer also implements the Language Server Protocol for incremental compilation of Rust code, and is the next iteration of rls. rust-analyzer, like rls, requires Rust files - to contained in Cargo projects. + to be contained in Cargo projects. 5. rustfmt -- If you have `rustfmt` installed, you can use it as a fixer to consistently reformat your Rust code. From 9769565f882b43512105d1b63a2f4ceda7a39d86 Mon Sep 17 00:00:00 2001 From: Raphael Nepomuceno <58113327+rphln@users.noreply.github.com> Date: Mon, 14 Sep 2020 12:11:16 -0300 Subject: [PATCH 024/167] Collapse spaces and lines in the completion menu. --- autoload/ale/completion.vim | 5 ++++- test/completion/test_lsp_completion_parsing.vader | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index ecd93600..882fd5e6 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -606,11 +606,14 @@ function! ale#completion#ParseLSPCompletions(response) abort let l:doc = l:doc.value endif + " Collapse whitespaces and line breaks into a single space. + let l:detail = substitute(get(l:item, 'detail', ''), '\_s\+', ' ', 'g') + let l:result = { \ 'word': l:word, \ 'kind': ale#completion#GetCompletionSymbols(get(l:item, 'kind', '')), \ 'icase': 1, - \ 'menu': get(l:item, 'detail', ''), + \ 'menu': l:detail, \ 'info': (type(l:doc) is v:t_string ? l:doc : ''), \} " This flag is used to tell if this completion came from ALE or not. diff --git a/test/completion/test_lsp_completion_parsing.vader b/test/completion/test_lsp_completion_parsing.vader index d989aefe..36228c10 100644 --- a/test/completion/test_lsp_completion_parsing.vader +++ b/test/completion/test_lsp_completion_parsing.vader @@ -40,6 +40,7 @@ Execute(Should handle Rust completion results correctly): \ {'word': 'from', 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, \ {'word': 'from', 'menu': 'fn from(s: Box) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, \ {'word': 'from', 'menu': 'fn from(s: Cow<''a, str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, + \ {'word': 'to_vec', 'menu': 'pub fn to_vec(&self) -> Vec where T: Clone,', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})}, \], \ ale#completion#ParseLSPCompletions({ \ "jsonrpc":"2.0", @@ -184,6 +185,11 @@ Execute(Should handle Rust completion results correctly): \ "label":"from", \ "kind":3, \ "detail":"fn from(s: Cow<'a, str>) -> String" + \ }, + \ { + \ "label":"to_vec", + \ "kind":3, + \ "detail":"pub fn to_vec(&self) -> Vec\nwhere\n T: Clone," \ } \ ] \ }) From fec6b63494b4f491279c7a01c0d61e515b8d0f46 Mon Sep 17 00:00:00 2001 From: Arnold Chand Date: Tue, 15 Sep 2020 19:14:12 -0400 Subject: [PATCH 025/167] feat: add intelephense support for php --- ale_linters/php/intelephense.vim | 32 +++++++++++++++++ doc/ale-php.txt | 35 +++++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + .../with-composer/composer.json | 0 ...st_php_intelephense_command_callback.vader | 23 ++++++++++++ 7 files changed, 93 insertions(+) create mode 100644 ale_linters/php/intelephense.vim create mode 100644 test/command_callback/php-intelephense-project/with-composer/composer.json create mode 100644 test/command_callback/test_php_intelephense_command_callback.vader diff --git a/ale_linters/php/intelephense.vim b/ale_linters/php/intelephense.vim new file mode 100644 index 00000000..e9e07d1f --- /dev/null +++ b/ale_linters/php/intelephense.vim @@ -0,0 +1,32 @@ +" Author: Eric Stern , +" Arnold Chand +" Description: Intelephense language server integration for ALE + +call ale#Set('php_intelephense_executable', 'intelephense') +call ale#Set('php_intelephense_use_global', 1) +call ale#Set('php_intelephense_config', {}) + +function! ale_linters#php#intelephense#GetProjectRoot(buffer) abort + let l:composer_path = ale#path#FindNearestFile(a:buffer, 'composer.json') + + if (!empty(l:composer_path)) + return fnamemodify(l:composer_path, ':h') + endif + + let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git') + + return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : '' +endfunction + +function! ale_linters#php#intelephense#GetInitializationOptions() abort + return ale#Get('php_intelephense_config') +endfunction + +call ale#linter#Define('php', { +\ 'name': 'intelephense', +\ 'lsp': 'stdio', +\ 'initialization_options': function('ale_linters#php#intelephense#GetInitializationOptions'), +\ 'executable': {b -> ale#node#FindExecutable(b, 'php_intelephense', [])}, +\ 'command': '%e --stdio', +\ 'project_root': function('ale_linters#php#intelephense#GetProjectRoot'), +\}) diff --git a/doc/ale-php.txt b/doc/ale-php.txt index 9fe868f8..79d9a033 100644 --- a/doc/ale-php.txt +++ b/doc/ale-php.txt @@ -243,5 +243,40 @@ g:ale_php_php_executable *g:ale_php_php_executable* This variable sets the executable used for php. +=============================================================================== +intelephense *ale-php-intelephense* + +g:ale_php_intelephense_executable *g:ale_php_intelephense_executable* + *b:ale_php_intelephense_executable* + Type: |String| + Default: `'intelephense'` + + The variable can be set to configure the executable that will be used for + running the intelephense language server. `node_modules` directory + executable will be preferred instead of this setting if + |g:ale_php_intelephense_use_global| is `0`. + + See: |ale-integrations-local-executables| + + +g:ale_php_intelephense_use_global *g:ale_php_intelephense_use_global* + *b:ale_php_intelephense_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable can be set to `1` to force the language server to be run with + the executable set for |g:ale_php_intelephense_executable|. + + See: |ale-integrations-local-executables| + +g:ale_php_intelephense_config *g:ale_php_intelephense_config* + *b:ale_php_intelephense_config* + Type: |Dictionary| + Default: `{}` + + The initialization options config specified by Intelephense. Refer to the + installation docs provided by intelephense (github.com/bmewburn/intelephense + -docs). + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index c6bcf421..7c8c9bac 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -324,6 +324,7 @@ Notes: * Perl6 * `perl6 -c` * PHP + * `intelephense` * `langserver` * `phan` * `phpcbf` diff --git a/doc/ale.txt b/doc/ale.txt index 6ef137c1..67ef531c 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2752,6 +2752,7 @@ documented in additional help files. psalm.................................|ale-php-psalm| php-cs-fixer..........................|ale-php-php-cs-fixer| php...................................|ale-php-php| + intelephense..........................|ale-php-intelephense| po......................................|ale-po-options| write-good............................|ale-po-write-good| pod.....................................|ale-pod-options| diff --git a/supported-tools.md b/supported-tools.md index 66e46348..559f841a 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -333,6 +333,7 @@ formatting. * Perl6 * [perl6 -c](https://perl6.org) :warning: * PHP + * [intelephense](https://github.com/bmewburn/intelephense-docs) * [langserver](https://github.com/felixfbecker/php-language-server) * [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions * [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer) diff --git a/test/command_callback/php-intelephense-project/with-composer/composer.json b/test/command_callback/php-intelephense-project/with-composer/composer.json new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/test_php_intelephense_command_callback.vader b/test/command_callback/test_php_intelephense_command_callback.vader new file mode 100644 index 00000000..283fd615 --- /dev/null +++ b/test/command_callback/test_php_intelephense_command_callback.vader @@ -0,0 +1,23 @@ +Before: + call ale#assert#SetUpLinterTest('php', 'intelephense') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'intelephense', + \ ale#Escape('intelephense') . ' --stdio' + +Execute(The project path should be correct for .git directories): + call ale#test#SetFilename('php-intelephense-project/with-git/test.php') + silent! call mkdir('php-langserver-project/with-git/.git', 'p') + AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-git') + +Execute(The project path should be correct for composer.json file): + call ale#test#SetFilename('php-intelephense-project/with-composer/test.php') + AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-composer') + +Execute(The project should save to a temp dir): + call ale#test#SetFilename('php-intelephense-project/with-composer/test.php') + let g:ale_php_intelephense_config = { 'storagePath': '/tmp/intelephense' } + AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-composer') From 8a855e3e6442a3b1384a07098d166c114a3e01f3 Mon Sep 17 00:00:00 2001 From: Arnold Chand Date: Thu, 17 Sep 2020 09:35:06 -0400 Subject: [PATCH 026/167] fix: tests --- .../test_php_intelephense_command_callback.vader | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/command_callback/test_php_intelephense_command_callback.vader b/test/command_callback/test_php_intelephense_command_callback.vader index 283fd615..164ca26e 100644 --- a/test/command_callback/test_php_intelephense_command_callback.vader +++ b/test/command_callback/test_php_intelephense_command_callback.vader @@ -10,14 +10,17 @@ Execute(The default executable path should be correct): Execute(The project path should be correct for .git directories): call ale#test#SetFilename('php-intelephense-project/with-git/test.php') - silent! call mkdir('php-langserver-project/with-git/.git', 'p') + silent! call mkdir('php-intelephense-project/with-git/.git') + AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-git') Execute(The project path should be correct for composer.json file): call ale#test#SetFilename('php-intelephense-project/with-composer/test.php') + AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-composer') -Execute(The project should save to a temp dir): +Execute(The project cache should be saved in a temp dir): call ale#test#SetFilename('php-intelephense-project/with-composer/test.php') let g:ale_php_intelephense_config = { 'storagePath': '/tmp/intelephense' } + AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-composer') From f8351c1b22d02f194235388779ad47028d5e7a25 Mon Sep 17 00:00:00 2001 From: Arnold Chand Date: Thu, 17 Sep 2020 09:58:45 -0400 Subject: [PATCH 027/167] fix: test: mkdir should create if it doesn't exist --- .../test_php_intelephense_command_callback.vader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/command_callback/test_php_intelephense_command_callback.vader b/test/command_callback/test_php_intelephense_command_callback.vader index 164ca26e..dd6adb3d 100644 --- a/test/command_callback/test_php_intelephense_command_callback.vader +++ b/test/command_callback/test_php_intelephense_command_callback.vader @@ -10,7 +10,7 @@ Execute(The default executable path should be correct): Execute(The project path should be correct for .git directories): call ale#test#SetFilename('php-intelephense-project/with-git/test.php') - silent! call mkdir('php-intelephense-project/with-git/.git') + silent! call mkdir('php-intelephense-project/with-git/.git', 'p') AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-git') From 6bebdcfa30b492b7c71316b707d36c4f4d19a1f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wo=C5=BAniak?= Date: Fri, 18 Sep 2020 12:11:05 +0200 Subject: [PATCH 028/167] Improves fixer performance for large buffers --- autoload/ale/util.vim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim index 1f396377..fcc03eb7 100644 --- a/autoload/ale/util.vim +++ b/autoload/ale/util.vim @@ -486,7 +486,7 @@ function! ale#util#Input(message, value) abort endfunction function! ale#util#HasBuflineApi() abort - return exists('*deletebufline') && exists('*setbufline') + return exists('*deletebufline') && exists('*appendbufline') && exists('*getpos') && exists('*setpos') endfunction " Sets buffer contents to lines @@ -507,8 +507,11 @@ function! ale#util#SetBufferContents(buffer, lines) abort " Use a Vim API for setting lines in other buffers, if available. if l:has_bufline_api - call setbufline(a:buffer, 1, l:new_lines) - call deletebufline(a:buffer, l:first_line_to_remove, '$') + let l:save_cursor = getpos('.') + call deletebufline(a:buffer, 1, '$') + call appendbufline(a:buffer, 1, l:new_lines) + call deletebufline(a:buffer, 1, 1) + call setpos('.', l:save_cursor) " Fall back on setting lines the old way, for the current buffer. else let l:old_line_length = line('$') From 48cbf1cb36e6e289be6275e6643504326963c3a4 Mon Sep 17 00:00:00 2001 From: toastal Date: Fri, 25 Sep 2020 08:26:17 +0700 Subject: [PATCH 029/167] dhall alias --- autoload/ale/fix/registry.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 218a0f95..7b2682bf 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -36,6 +36,7 @@ let s:default_registry = { \ 'function': 'ale#fixers#dhall_format#Fix', \ 'suggested_filetypes': ['dhall'], \ 'description': 'Standard code formatter for the Dhall language', +\ 'aliases': ['dhall'], \ }, \ 'dhall-freeze': { \ 'function': 'ale#fixers#dhall_freeze#Freeze', From e08996940468ce90616a9704a439652f1ab73e31 Mon Sep 17 00:00:00 2001 From: Marcus Zanona Date: Wed, 12 Aug 2020 11:06:35 +0200 Subject: [PATCH 030/167] fix(ale_linters/phpcs): add support for multiline error messages --- ale_linters/php/phpcs.vim | 2 +- test/handler/test_phpcs_handler.vader | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ale_linters/php/phpcs.vim b/ale_linters/php/phpcs.vim index 11b81e84..c5a3faa9 100644 --- a/ale_linters/php/phpcs.vim +++ b/ale_linters/php/phpcs.vim @@ -23,7 +23,7 @@ function! ale_linters#php#phpcs#Handle(buffer, lines) abort " Matches against lines like the following: " " /path/to/some-filename.php:18:3: error - Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact) - let l:pattern = '^.*:\(\d\+\):\(\d\+\): \(.\+\) - \(.\+\) (\(.\+\))$' + let l:pattern = '^.*:\(\d\+\):\(\d\+\): \(.\+\) - \(.\+\) (\(.\+\)).*$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) diff --git a/test/handler/test_phpcs_handler.vader b/test/handler/test_phpcs_handler.vader index 18accece..26d35cb8 100644 --- a/test/handler/test_phpcs_handler.vader +++ b/test/handler/test_phpcs_handler.vader @@ -13,7 +13,16 @@ Execute(phpcs errors should be handled): \ 'type': 'E', \ 'sub_type': 'style', \ 'text': 'Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact)', - \ }], + \ }, + \ { + \ 'lnum': 22, + \ 'col': 3, + \ 'type': 'E', + \ 'sub_type': 'style', + \ 'text': 'All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks)', + \ }, + \ ], \ ale_linters#php#phpcs#Handle(bufnr(''), [ \ '/path/to/some-filename.php:18:3: error - Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact)', + \ "/path/to/some-filename.php:22:3: error - All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks), found '\"\n'.", \ ]) From 9a8ab764d5a77d1ebf18b176ce57e08a0603a5f5 Mon Sep 17 00:00:00 2001 From: rgossiaux Date: Fri, 2 Oct 2020 22:51:54 -0400 Subject: [PATCH 031/167] Fix typo in ale-python.txt --- doc/ale-python.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ale-python.txt b/doc/ale-python.txt index 6b1a6d33..5cf7cd74 100644 --- a/doc/ale-python.txt +++ b/doc/ale-python.txt @@ -687,7 +687,7 @@ g:ale_python_pyre_auto_pipenv *g:ale_python_pyre_auto_pipenv* =============================================================================== pyright *ale-python-pyright* -The `pyrlight` linter requires a recent version of `pyright` which includes +The `pyright` linter requires a recent version of `pyright` which includes the `pyright-langserver` executable. You can install `pyright` on your system through `npm` with `sudo npm install -g pyright` or similar. From 96ec33e6d6119fea01fee7aaed1e8a21ef6ef677 Mon Sep 17 00:00:00 2001 From: Andrey Popp <8mayday@gmail.com> Date: Sat, 3 Oct 2020 17:57:59 +0300 Subject: [PATCH 032/167] Use stdin/stdout to communicate with gofmt --- autoload/ale/fixers/gofmt.vim | 3 --- test/fixers/test_gofmt_fixer_callback.vader | 14 +++----------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/autoload/ale/fixers/gofmt.vim b/autoload/ale/fixers/gofmt.vim index d5a539b9..b9cfbb58 100644 --- a/autoload/ale/fixers/gofmt.vim +++ b/autoload/ale/fixers/gofmt.vim @@ -11,9 +11,6 @@ function! ale#fixers#gofmt#Fix(buffer) abort return { \ 'command': l:env . ale#Escape(l:executable) - \ . ' -l -w' \ . (empty(l:options) ? '' : ' ' . l:options) - \ . ' %t', - \ 'read_temporary_file': 1, \} endfunction diff --git a/test/fixers/test_gofmt_fixer_callback.vader b/test/fixers/test_gofmt_fixer_callback.vader index 16659655..99407173 100644 --- a/test/fixers/test_gofmt_fixer_callback.vader +++ b/test/fixers/test_gofmt_fixer_callback.vader @@ -21,10 +21,7 @@ Execute(The gofmt callback should return the correct default values): AssertEqual \ { - \ 'read_temporary_file': 1, - \ 'command': ale#Escape('xxxinvalid') - \ . ' -l -w' - \ . ' %t', + \ 'command': ale#Escape('xxxinvalid'), \ }, \ ale#fixers#gofmt#Fix(bufnr('')) @@ -35,11 +32,8 @@ Execute(The gofmt callback should include custom gofmt options): AssertEqual \ { - \ 'read_temporary_file': 1, \ 'command': ale#Escape('xxxinvalid') - \ . ' -l -w' - \ . ' ' . g:ale_go_gofmt_options - \ . ' %t', + \ . ' ' . g:ale_go_gofmt_options, \ }, \ ale#fixers#gofmt#Fix(bufnr('')) @@ -50,9 +44,7 @@ Execute(The gofmt callback should support Go environment variables): AssertEqual \ { - \ 'read_temporary_file': 1, \ 'command': ale#Env('GO111MODULE', 'off') - \ . ale#Escape('xxxinvalid') . ' -l -w' - \ . ' %t', + \ . ale#Escape('xxxinvalid') \ }, \ ale#fixers#gofmt#Fix(bufnr('')) From c37cc1c8a3cd2d014258d4252c4b495e48e844a5 Mon Sep 17 00:00:00 2001 From: "D. Ben Knoble" Date: Thu, 8 Oct 2020 11:54:17 -0400 Subject: [PATCH 033/167] dafny: include correct filename in lint results Results can come from included files, not just the current buffer. --- ale_linters/dafny/dafny.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/dafny/dafny.vim b/ale_linters/dafny/dafny.vim index b5b90675..e6021d99 100644 --- a/ale_linters/dafny/dafny.vim +++ b/ale_linters/dafny/dafny.vim @@ -6,7 +6,7 @@ function! ale_linters#dafny#dafny#Handle(buffer, lines) abort for l:match in ale#util#GetMatches(a:lines, l:pattern) call add(l:output, { - \ 'bufnr': a:buffer, + \ 'filename': l:match[1], \ 'col': l:match[3] + 0, \ 'lnum': l:match[2] + 0, \ 'text': l:match[5], From 160af4945079ae8df28f298f6d508f15005418fb Mon Sep 17 00:00:00 2001 From: "D. Ben Knoble" Date: Thu, 8 Oct 2020 12:02:30 -0400 Subject: [PATCH 034/167] update tests --- test/handler/test_dafny_handler.vader | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/handler/test_dafny_handler.vader b/test/handler/test_dafny_handler.vader index 674f691d..797d348e 100644 --- a/test/handler/test_dafny_handler.vader +++ b/test/handler/test_dafny_handler.vader @@ -8,14 +8,14 @@ Execute(The Dafny handler should parse output correctly): AssertEqual \ [ \ { - \ 'bufnr': 0, + \ 'filename': 'File.dfy', \ 'col': 45, \ 'lnum': 123, \ 'text': 'A precondition for this call might not hold.', \ 'type': 'E' \ }, \ { - \ 'bufnr': 0, + \ 'filename': 'File.dfy', \ 'col': 90, \ 'lnum': 678, \ 'text': 'This is the precondition that might not hold.', From f125c11faa778f30fcd775b4104a2271dccf6b6c Mon Sep 17 00:00:00 2001 From: ecly Date: Thu, 15 Oct 2020 13:35:47 +0200 Subject: [PATCH 035/167] Update FindProjectRootIni with poetry.lock and pyproject.toml --- autoload/ale/python.vim | 2 ++ doc/ale-python.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/autoload/ale/python.vim b/autoload/ale/python.vim index 7ed22367..fc6c1130 100644 --- a/autoload/ale/python.vim +++ b/autoload/ale/python.vim @@ -32,6 +32,8 @@ function! ale#python#FindProjectRootIni(buffer) abort \|| filereadable(l:path . '/.pylintrc') \|| filereadable(l:path . '/Pipfile') \|| filereadable(l:path . '/Pipfile.lock') + \|| filereadable(l:path . '/poetry.lock') + \|| filereadable(l:path . '/pyproject.toml') return l:path endif endfor diff --git a/doc/ale-python.txt b/doc/ale-python.txt index 6b1a6d33..1cc97a88 100644 --- a/doc/ale-python.txt +++ b/doc/ale-python.txt @@ -36,6 +36,8 @@ ALE will look for configuration files with the following filenames. > .pylintrc Pipfile Pipfile.lock + poetry.lock + pyproject.toml < The first directory containing any of the files named above will be used. From af5a8e1abfe59e2e8e970e8dac38c00acf1132db Mon Sep 17 00:00:00 2001 From: StephenWithPH Date: Mon, 19 Oct 2020 09:47:54 -0700 Subject: [PATCH 036/167] add sbt as a suggested filetype for scalafmt fixer --- autoload/ale/fix/registry.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index d71668f2..0378b92d 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -122,7 +122,7 @@ let s:default_registry = { \ }, \ 'scalafmt': { \ 'function': 'ale#fixers#scalafmt#Fix', -\ 'suggested_filetypes': ['scala'], +\ 'suggested_filetypes': ['sbt', 'scala'], \ 'description': 'Fix Scala files using scalafmt', \ }, \ 'sorbet': { From cafe8621e2e94c8eff37a430fdccb0b87788620a Mon Sep 17 00:00:00 2001 From: Will Leinweber Date: Tue, 20 Oct 2020 21:54:45 -0700 Subject: [PATCH 037/167] Add Ruby sorbet option to enable watchman --- ale_linters/ruby/sorbet.vim | 5 ++++- doc/ale-ruby.txt | 10 ++++++++++ .../test_sorbet_command_callback.vader | 7 +++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ale_linters/ruby/sorbet.vim b/ale_linters/ruby/sorbet.vim index cae0683c..c67e20cc 100644 --- a/ale_linters/ruby/sorbet.vim +++ b/ale_linters/ruby/sorbet.vim @@ -1,14 +1,17 @@ call ale#Set('ruby_sorbet_executable', 'srb') call ale#Set('ruby_sorbet_options', '') +call ale#Set('ruby_sorbet_enable_watchman', 0) function! ale_linters#ruby#sorbet#GetCommand(buffer) abort let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable') let l:options = ale#Var(a:buffer, 'ruby_sorbet_options') + let l:enable_watchman = ale#Var(a:buffer, 'ruby_sorbet_enable_watchman') return ale#ruby#EscapeExecutable(l:executable, 'srb') \ . ' tc' \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' --lsp --disable-watchman' + \ . ' --lsp' + \ . (l:enable_watchman ? '' : ' --disable-watchman') endfunction call ale#linter#Define('ruby', { diff --git a/doc/ale-ruby.txt b/doc/ale-ruby.txt index 8815404a..edc6144a 100644 --- a/doc/ale-ruby.txt +++ b/doc/ale-ruby.txt @@ -177,6 +177,16 @@ g:ale_ruby_sorbet_options *g:ale_ruby_sorbet_options* This variable can be changed to modify flags given to sorbet. +g:ale_ruby_sorbet_enable_watchman *g:ale_ruby_sorbet_enable_watchman* + *b:ale_ruby_sorbet_enable_watchman* + Type: |Number| + Default: `0` + + Whether or not to use watchman to let the LSP server to know about changes + to files from outside of vim. Defaults to disable watchman because it + requires watchman to be installed separately from sorbet. + + =============================================================================== standardrb *ale-ruby-standardrb* diff --git a/test/command_callback/test_sorbet_command_callback.vader b/test/command_callback/test_sorbet_command_callback.vader index b46e90a4..fe758635 100644 --- a/test/command_callback/test_sorbet_command_callback.vader +++ b/test/command_callback/test_sorbet_command_callback.vader @@ -5,6 +5,7 @@ Before: let g:ale_ruby_sorbet_executable = 'srb' let g:ale_ruby_sorbet_options = '' + let g:ale_ruby_sorbet_enable_watchman = 0 After: call ale#assert#TearDownLinterTest() @@ -13,6 +14,12 @@ Execute(Executable should default to srb): AssertLinter 'srb', ale#Escape('srb') \ . ' tc --lsp --disable-watchman' +Execute(Able to enable watchman): + let g:ale_ruby_sorbet_enable_watchman = 1 + + AssertLinter 'srb', ale#Escape('srb') + \ . ' tc --lsp' + Execute(Should be able to set a custom executable): let g:ale_ruby_sorbet_executable = 'bin/srb' From b496c4b1648cd15f8f6918d7c29853a8a04525c4 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 19 Nov 2019 21:15:35 +0000 Subject: [PATCH 038/167] Add ormolu fixer. This commit adds a fixer for the Haskell language, ormolu (https://github.com/tweag/ormolu). Signed-off-by: David Wood --- autoload/ale/fix/registry.vim | 5 ++++ autoload/ale/fixers/ormolu.vim | 12 ++++++++++ doc/ale-haskell.txt | 20 ++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + test/fixers/test_ormolu_fixer_callback.vader | 24 ++++++++++++++++++++ 7 files changed, 64 insertions(+) create mode 100644 autoload/ale/fixers/ormolu.vim create mode 100644 test/fixers/test_ormolu_fixer_callback.vader diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index d71668f2..377edafd 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -380,6 +380,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['dhall'], \ 'description': 'Fix Dhall files with dhall-format.', \ }, +\ 'ormolu': { +\ 'function': 'ale#fixers#ormolu#Fix', +\ 'suggested_filetypes': ['haskell'], +\ 'description': 'A formatter for Haskell source code.', +\ }, \} " Reset the function registry to the default entries. diff --git a/autoload/ale/fixers/ormolu.vim b/autoload/ale/fixers/ormolu.vim new file mode 100644 index 00000000..69b55c1f --- /dev/null +++ b/autoload/ale/fixers/ormolu.vim @@ -0,0 +1,12 @@ +call ale#Set('haskell_ormolu_executable', 'ormolu') +call ale#Set('haskell_ormolu_options', '') + +function! ale#fixers#ormolu#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_ormolu_executable') + let l:options = ale#Var(a:buffer, 'haskell_ormolu_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options), + \} +endfunction diff --git a/doc/ale-haskell.txt b/doc/ale-haskell.txt index 5dd3ec15..fde439fe 100644 --- a/doc/ale-haskell.txt +++ b/doc/ale-haskell.txt @@ -172,5 +172,25 @@ g:ale_haskell_hie_executable *g:ale_haskell_hie_executable* ide engine. i.e. `'hie-wrapper'` +=============================================================================== +ormolu *ale-haskell-ormolu* + +g:ale_haskell_ormolu_executable *g:ale_haskell_ormolu_executable* + *b:ale_haskell_ormolu_executable* + Type: |String| + Default: `'ormolu'` + + This variable can be changed to use a different executable for ormolu. + + +g:ale_haskell_ormolu_options *g:ale_haskell_ormolu_options* + *b:ale_haskell_ormolu_options* + Type: String + Default: '' + + This variable can be used to pass extra options to the underlying ormolu + executable. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 4f3afd85..57a50dd4 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -195,6 +195,7 @@ Notes: * `hie` * `hindent` * `hlint` + * `ormolu` * `stack-build`!! * `stack-ghc` * `stylish-haskell` diff --git a/doc/ale.txt b/doc/ale.txt index eb8f0275..01357cd1 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2642,6 +2642,7 @@ documented in additional help files. stack-ghc.............................|ale-haskell-stack-ghc| stylish-haskell.......................|ale-haskell-stylish-haskell| hie...................................|ale-haskell-hie| + ormolu................................|ale-haskell-ormolu| hcl.....................................|ale-hcl-options| terraform-fmt.........................|ale-hcl-terraform-fmt| html....................................|ale-html-options| diff --git a/supported-tools.md b/supported-tools.md index 49460892..6aa196b2 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -204,6 +204,7 @@ formatting. * [hie](https://github.com/haskell/haskell-ide-engine) * [hindent](https://hackage.haskell.org/package/hindent) * [hlint](https://hackage.haskell.org/package/hlint) + * [ormolu](https://github.com/tweag/ormolu) * [stack-build](https://haskellstack.org/) :floppy_disk: * [stack-ghc](https://haskellstack.org/) * [stylish-haskell](https://github.com/jaspervdj/stylish-haskell) diff --git a/test/fixers/test_ormolu_fixer_callback.vader b/test/fixers/test_ormolu_fixer_callback.vader new file mode 100644 index 00000000..8df3fca9 --- /dev/null +++ b/test/fixers/test_ormolu_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_haskell_ormolu_executable + Save g:ale_haskell_ormolu_options + +After: + Restore + +Execute(The ormolu callback should return the correct default values): + AssertEqual + \ { + \ 'command': ale#Escape('ormolu') + \ }, + \ ale#fixers#ormolu#Fix(bufnr('')) + +Execute(The ormolu executable and options should be configurable): + let g:ale_nix_nixpkgsfmt_executable = '/path/to/ormolu' + let g:ale_nix_nixpkgsfmt_options = '-h' + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/ormolu') + \ . ' -h', + \ }, + \ ale#fixers#nixpkgsfmt#Fix(bufnr('')) From 513e6ee972ea4ee57b28b8b8c10e0b89bb674f25 Mon Sep 17 00:00:00 2001 From: Lyz Date: Fri, 23 Oct 2020 18:53:38 +0200 Subject: [PATCH 039/167] feat: add autoimport fixer --- autoload/ale/fix/registry.vim | 5 ++ autoload/ale/fixers/autoimport.vim | 25 ++++++++++ doc/ale-python.txt | 26 ++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + .../env/Scripts/autoimport.exe | 0 .../with_virtualenv/env/bin/autoimport | 0 .../test_autoimport_fixer_callback.vader | 50 +++++++++++++++++++ 9 files changed, 109 insertions(+) create mode 100644 autoload/ale/fixers/autoimport.vim create mode 100755 test/command_callback/python_paths/with_virtualenv/env/Scripts/autoimport.exe create mode 100755 test/command_callback/python_paths/with_virtualenv/env/bin/autoimport create mode 100644 test/fixers/test_autoimport_fixer_callback.vader diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index d71668f2..ed9c4370 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -12,6 +12,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['help'], \ 'description': 'Align help tags to the right margin', \ }, +\ 'autoimport': { +\ 'function': 'ale#fixers#autoimport#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Fix import issues with autoimport.', +\ }, \ 'autopep8': { \ 'function': 'ale#fixers#autopep8#Fix', \ 'suggested_filetypes': ['python'], diff --git a/autoload/ale/fixers/autoimport.vim b/autoload/ale/fixers/autoimport.vim new file mode 100644 index 00000000..37a52db8 --- /dev/null +++ b/autoload/ale/fixers/autoimport.vim @@ -0,0 +1,25 @@ +" Author: lyz-code +" Description: Fixing Python imports with autoimport. + +call ale#Set('python_autoimport_executable', 'autoimport') +call ale#Set('python_autoimport_options', '') +call ale#Set('python_autoimport_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#autoimport#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'python_autoimport_options') + + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'python_autoimport', + \ ['autoimport'], + \) + + if !executable(l:executable) + return 0 + endif + + return { + \ 'command': ale#path#BufferCdString(a:buffer) + \ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -', + \} +endfunction diff --git a/doc/ale-python.txt b/doc/ale-python.txt index 6b1a6d33..c6a207ac 100644 --- a/doc/ale-python.txt +++ b/doc/ale-python.txt @@ -41,6 +41,32 @@ ALE will look for configuration files with the following filenames. > The first directory containing any of the files named above will be used. +=============================================================================== +autoimport *ale-python-autoimport* + +g:ale_python_autoimport_executable *g:ale_python_autoimport_executable* + *b:ale_python_autoimport_executable* + Type: |String| + Default: `'autoimport'` + + See |ale-integrations-local-executables| + + +g:ale_python_autoimport_options *g:ale_python_autoimport_options* + *b:ale_python_autoimport_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to autoimport. + + +g:ale_python_autoimport_use_global *g:ale_python_autoimport_use_global* + *b:ale_python_autoimport_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + =============================================================================== autopep8 *ale-python-autopep8* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 4f3afd85..62eed26f 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -361,6 +361,7 @@ Notes: * `purescript-language-server` * `purty` * Python + * `autoimport` * `autopep8` * `bandit` * `black` diff --git a/doc/ale.txt b/doc/ale.txt index eb8f0275..204bd0e2 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2777,6 +2777,7 @@ documented in additional help files. pyrex (cython)..........................|ale-pyrex-options| cython................................|ale-pyrex-cython| python..................................|ale-python-options| + autoimport............................|ale-python-autoimport| autopep8..............................|ale-python-autopep8| bandit................................|ale-python-bandit| black.................................|ale-python-black| diff --git a/supported-tools.md b/supported-tools.md index 49460892..6325e906 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -370,6 +370,7 @@ formatting. * [purescript-language-server](https://github.com/nwolverson/purescript-language-server) * [purty](https://gitlab.com/joneshf/purty) * Python + * [autoimport](https://lyz-code.github.io/autoimport/) * [autopep8](https://github.com/hhatto/autopep8) * [bandit](https://github.com/PyCQA/bandit) :warning: * [black](https://github.com/ambv/black) diff --git a/test/command_callback/python_paths/with_virtualenv/env/Scripts/autoimport.exe b/test/command_callback/python_paths/with_virtualenv/env/Scripts/autoimport.exe new file mode 100755 index 00000000..e69de29b diff --git a/test/command_callback/python_paths/with_virtualenv/env/bin/autoimport b/test/command_callback/python_paths/with_virtualenv/env/bin/autoimport new file mode 100755 index 00000000..e69de29b diff --git a/test/fixers/test_autoimport_fixer_callback.vader b/test/fixers/test_autoimport_fixer_callback.vader new file mode 100644 index 00000000..6952cbb8 --- /dev/null +++ b/test/fixers/test_autoimport_fixer_callback.vader @@ -0,0 +1,50 @@ +Before: + Save g:ale_python_autoimport_executable + Save g:ale_python_autoimport_options + + " Use an invalid global executable, so we don't match it. + let g:ale_python_autoimport_executable = 'xxxinvalid' + let g:ale_python_autoimport_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + silent cd .. + silent cd command_callback + let g:dir = getcwd() + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + Restore + + unlet! b:bin_dir + + call ale#test#RestoreDirectory() + +Execute(The autoimport callback should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#autoimport#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ { + \ 'command': ale#path#BufferCdString(bufnr('')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) . ' -', + \ }, + \ ale#fixers#autoimport#Fix(bufnr('')) + +Execute(The autoimport callback should respect custom options): + let g:ale_python_autoimport_options = '--multi-line=3 --trailing-comma' + + AssertEqual + \ 0, + \ ale#fixers#autoimport#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ { + \ 'command': ale#path#BufferCdString(bufnr('')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) + \ . ' --multi-line=3 --trailing-comma -', + \ }, + \ ale#fixers#autoimport#Fix(bufnr('')) From 6c22936303a3236b471baee81c83683de4c25f47 Mon Sep 17 00:00:00 2001 From: Jason Franklin Date: Mon, 2 Nov 2020 10:46:28 -0500 Subject: [PATCH 040/167] Remove a noise comment --- autoload/ale/handlers/sh.vim | 1 - 1 file changed, 1 deletion(-) diff --git a/autoload/ale/handlers/sh.vim b/autoload/ale/handlers/sh.vim index 1e50cb89..20ed5cb8 100644 --- a/autoload/ale/handlers/sh.vim +++ b/autoload/ale/handlers/sh.vim @@ -1,6 +1,5 @@ " Author: w0rp -" Get the shell type for a buffer, based on the hashbang line. function! ale#handlers#sh#GetShellType(buffer) abort let l:bang_line = get(getbufline(a:buffer, 1), 0, '') From 73632312c2519d7925dc57e5abcd0eacc5f1e55f Mon Sep 17 00:00:00 2001 From: Jason Franklin Date: Mon, 2 Nov 2020 10:46:56 -0500 Subject: [PATCH 041/167] Use the proper term for the "#!" line --- autoload/ale/handlers/sh.vim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autoload/ale/handlers/sh.vim b/autoload/ale/handlers/sh.vim index 20ed5cb8..f99c3dbd 100644 --- a/autoload/ale/handlers/sh.vim +++ b/autoload/ale/handlers/sh.vim @@ -1,17 +1,17 @@ " Author: w0rp function! ale#handlers#sh#GetShellType(buffer) abort - let l:bang_line = get(getbufline(a:buffer, 1), 0, '') + let l:shebang = get(getbufline(a:buffer, 1), 0, '') let l:command = '' - " Take the shell executable from the hashbang, if we can. - if l:bang_line[:1] is# '#!' + " Take the shell executable from the shebang, if we can. + if l:shebang[:1] is# '#!' " Remove options like -e, etc. - let l:command = substitute(l:bang_line, ' --\?[a-zA-Z0-9]\+', '', 'g') + let l:command = substitute(l:shebang, ' --\?[a-zA-Z0-9]\+', '', 'g') endif - " If we couldn't find a hashbang, try the filetype + " If we couldn't find a shebang, try the filetype if l:command is# '' let l:command = &filetype endif From 31b7a2de41d7bfccfd80a563bf3920258230cdc3 Mon Sep 17 00:00:00 2001 From: Jason Franklin Date: Mon, 2 Nov 2020 10:50:14 -0500 Subject: [PATCH 042/167] Move the test for buffer-local variables The "ale#handlers#sh#GetShellType()" function currently falls back to the file type without checking for buffer-local variables first. This causes the function to return "sh" even when a script is known by Vim to be a script of a more specific type (e.g., "bash"). The "ale#handlers#shellcheck#GetDialectArgument()" function then erroneously uses this type even though a more fitting type should be used instead. Files without a "#!" line will be of type "sh" even though they may have a ".bash" suffix. This commit fixes the problem by checking for buffer-local shell type variables (set by Vim) before falling back to the file type. --- autoload/ale/handlers/sh.vim | 11 +++++++++++ autoload/ale/handlers/shellcheck.vim | 9 --------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/autoload/ale/handlers/sh.vim b/autoload/ale/handlers/sh.vim index f99c3dbd..6ed9fea3 100644 --- a/autoload/ale/handlers/sh.vim +++ b/autoload/ale/handlers/sh.vim @@ -11,6 +11,17 @@ function! ale#handlers#sh#GetShellType(buffer) abort let l:command = substitute(l:shebang, ' --\?[a-zA-Z0-9]\+', '', 'g') endif + " With no shebang line, attempt to use Vim's buffer-local variables. + if l:command is# '' + if getbufvar(a:buffer, 'is_bash', 0) + let l:command = 'bash' + elseif getbufvar(a:buffer, 'is_sh', 0) + let l:command = 'sh' + elseif getbufvar(a:buffer, 'is_kornshell', 0) + let l:command = 'ksh' + endif + endif + " If we couldn't find a shebang, try the filetype if l:command is# '' let l:command = &filetype diff --git a/autoload/ale/handlers/shellcheck.vim b/autoload/ale/handlers/shellcheck.vim index b16280f0..351d6d3f 100644 --- a/autoload/ale/handlers/shellcheck.vim +++ b/autoload/ale/handlers/shellcheck.vim @@ -13,15 +13,6 @@ function! ale#handlers#shellcheck#GetDialectArgument(buffer) abort return l:shell_type endif - " If there's no hashbang, try using Vim's buffer variables. - if getbufvar(a:buffer, 'is_bash', 0) - return 'bash' - elseif getbufvar(a:buffer, 'is_sh', 0) - return 'sh' - elseif getbufvar(a:buffer, 'is_kornshell', 0) - return 'ksh' - endif - return '' endfunction From 96d84159469dfc28bde82bacfa1c3bc81b0cbdfa Mon Sep 17 00:00:00 2001 From: Manoel Brunnen Date: Tue, 3 Nov 2020 23:06:14 +0100 Subject: [PATCH 043/167] Add -imacros to C flags --- autoload/ale/c.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index cff53125..c7b1e20a 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -152,6 +152,7 @@ function! ale#c#ParseCFlags(path_prefix, should_quote, raw_arguments) abort \ || stridx(l:option, '-idirafter') == 0 \ || stridx(l:option, '-iframework') == 0 \ || stridx(l:option, '-include') == 0 + \ || stridx(l:option, '-imacros') == 0 if stridx(l:option, '-I') == 0 && l:option isnot# '-I' let l:arg = join(split(l:option, '\zs')[2:], '') let l:option = '-I' From 01800a23addb52788265e0349f519556dab41301 Mon Sep 17 00:00:00 2001 From: Dalius Dobravolskas Date: Sat, 14 Nov 2020 12:15:17 +0200 Subject: [PATCH 044/167] Support for LSP/tsserver Code Actions (#3437) * Added tsserver and LSP code action support. * tsserver refactors support added. * Handling special case when new text is added after new line symbol. * ale#code_action#ApplyChanges simplified. * Initial attempt on LSP Code Actions. * workspace/executeCommand added. * Some null checks added. * Add last column to LSP Code Action message. * Pass diagnostics to LSP code action. Previously ApplyChanges code was applied from top-to-bottom that required extra parameters to track progress and there was bug. I have changed code to bottom-to-top approach as that does not require those extra parameters and solved the bug. Tested with typescript-language-server and it is working. --- ale_linters/python/jedils.vim | 34 + autoload/ale/code_action.vim | 110 +++- autoload/ale/codefix.vim | 388 +++++++++++ autoload/ale/completion.vim | 1 + autoload/ale/lsp.vim | 10 + autoload/ale/lsp/message.vim | 22 + autoload/ale/lsp/response.vim | 1 + autoload/ale/lsp/tsserver_message.vim | 36 ++ autoload/ale/rename.vim | 56 +- doc/ale.txt | 12 + plugin/ale.vim | 3 + ...st_other_initialize_message_handling.vader | 6 +- test/test_code_action.vader | 4 + test/test_code_action_python.vader | 59 ++ test/test_codefix.vader | 604 ++++++++++++++++++ 15 files changed, 1260 insertions(+), 86 deletions(-) create mode 100644 ale_linters/python/jedils.vim create mode 100644 autoload/ale/codefix.vim create mode 100644 test/test_code_action_python.vader create mode 100644 test/test_codefix.vader diff --git a/ale_linters/python/jedils.vim b/ale_linters/python/jedils.vim new file mode 100644 index 00000000..eae5fb07 --- /dev/null +++ b/ale_linters/python/jedils.vim @@ -0,0 +1,34 @@ +" Author: Dalius Dobravolskas +" Description: https://github.com/pappasam/jedi-language-server + +call ale#Set('python_jedils_executable', 'jedi-language-server') +call ale#Set('python_jedils_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_jedils_auto_pipenv', 0) + +function! ale_linters#python#jedils#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_jedils_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_jedils', ['jedi-language-server']) +endfunction + +function! ale_linters#python#jedils#GetCommand(buffer) abort + let l:executable = ale_linters#python#jedils#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run jedi-language-server' + \ : '' + + return ale#Escape(l:executable) . l:exec_args +endfunction + +call ale#linter#Define('python', { +\ 'name': 'jedils', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#python#jedils#GetExecutable'), +\ 'command': function('ale_linters#python#jedils#GetCommand'), +\ 'project_root': function('ale#python#FindProjectRoot'), +\ 'completion_filter': 'ale#completion#python#CompletionItemFilter', +\}) diff --git a/autoload/ale/code_action.vim b/autoload/ale/code_action.vim index 42f4f265..4dbb2d08 100644 --- a/autoload/ale/code_action.vim +++ b/autoload/ale/code_action.vim @@ -33,37 +33,37 @@ endfunction function! s:ChangeCmp(left, right) abort if a:left.start.line < a:right.start.line - return -1 + return 1 endif if a:left.start.line > a:right.start.line - return 1 + return -1 endif if a:left.start.offset < a:right.start.offset - return -1 + return 1 endif if a:left.start.offset > a:right.start.offset - return 1 + return -1 endif if a:left.end.line < a:right.end.line - return -1 + return 1 endif if a:left.end.line > a:right.end.line - return 1 - endif - - if a:left.end.offset < a:right.end.offset return -1 endif - if a:left.end.offset > a:right.end.offset + if a:left.end.offset < a:right.end.offset return 1 endif + if a:left.end.offset > a:right.end.offset + return -1 + endif + return 0 endfunction @@ -85,29 +85,14 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort let l:pos = [1, 1] endif - " We have to keep track of how many lines we have added, and offset - " changes accordingly. - let l:line_offset = 0 - let l:column_offset = 0 - let l:last_end_line = 0 - - " Changes have to be sorted so we apply them from top-to-bottom. + " Changes have to be sorted so we apply them from bottom-to-top for l:code_edit in sort(copy(a:changes), function('s:ChangeCmp')) - if l:code_edit.start.line isnot l:last_end_line - let l:column_offset = 0 - endif - - let l:line = l:code_edit.start.line + l:line_offset - let l:column = l:code_edit.start.offset + l:column_offset - let l:end_line = l:code_edit.end.line + l:line_offset - let l:end_column = l:code_edit.end.offset + l:column_offset + let l:line = l:code_edit.start.line + let l:column = l:code_edit.start.offset + let l:end_line = l:code_edit.end.line + let l:end_column = l:code_edit.end.offset let l:text = l:code_edit.newText - let l:cur_line = l:pos[0] - let l:cur_column = l:pos[1] - - let l:last_end_line = l:end_line - " Adjust the ends according to previous edits. if l:end_line > len(l:lines) let l:end_line_len = 0 @@ -125,6 +110,12 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort let l:start = l:lines[: l:line - 2] endif + " Special case when text must be added after new line + if l:column > len(l:lines[l:line - 1]) + call extend(l:start, [l:lines[l:line - 1]]) + let l:column = 1 + endif + if l:column is 1 " We need to handle column 1 specially, because we can't slice an " empty string ending on index 0. @@ -140,7 +131,6 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort let l:lines = l:start + l:middle + l:lines[l:end_line :] let l:current_line_offset = len(l:lines) - l:lines_before_change - let l:line_offset += l:current_line_offset let l:column_offset = len(l:middle[-1]) - l:end_line_len let l:pos = s:UpdateCursor(l:pos, @@ -215,3 +205,61 @@ function! s:UpdateCursor(cursor, start, end, offset) abort return [l:cur_line, l:cur_column] endfunction + +function! ale#code_action#GetChanges(workspace_edit) abort + let l:changes = {} + + if has_key(a:workspace_edit, 'changes') && !empty(a:workspace_edit.changes) + return a:workspace_edit.changes + elseif has_key(a:workspace_edit, 'documentChanges') + let l:document_changes = [] + + if type(a:workspace_edit.documentChanges) is v:t_dict + \ && has_key(a:workspace_edit.documentChanges, 'edits') + call add(l:document_changes, a:workspace_edit.documentChanges) + elseif type(a:workspace_edit.documentChanges) is v:t_list + let l:document_changes = a:workspace_edit.documentChanges + endif + + for l:text_document_edit in l:document_changes + let l:filename = l:text_document_edit.textDocument.uri + let l:edits = l:text_document_edit.edits + let l:changes[l:filename] = l:edits + endfor + endif + + return l:changes +endfunction + +function! ale#code_action#BuildChangesList(changes_map) abort + let l:changes = [] + + for l:file_name in keys(a:changes_map) + let l:text_edits = a:changes_map[l:file_name] + let l:text_changes = [] + + for l:edit in l:text_edits + let l:range = l:edit.range + let l:new_text = l:edit.newText + + call add(l:text_changes, { + \ 'start': { + \ 'line': l:range.start.line + 1, + \ 'offset': l:range.start.character + 1, + \ }, + \ 'end': { + \ 'line': l:range.end.line + 1, + \ 'offset': l:range.end.character + 1, + \ }, + \ 'newText': l:new_text, + \}) + endfor + + call add(l:changes, { + \ 'fileName': ale#path#FromURI(l:file_name), + \ 'textChanges': l:text_changes, + \}) + endfor + + return l:changes +endfunction diff --git a/autoload/ale/codefix.vim b/autoload/ale/codefix.vim new file mode 100644 index 00000000..b58f5e4b --- /dev/null +++ b/autoload/ale/codefix.vim @@ -0,0 +1,388 @@ +" Author: Dalius Dobravolskas +" Description: Code Fix support for tsserver + +let s:codefix_map = {} + +" Used to get the codefix map in tests. +function! ale#codefix#GetMap() abort + return deepcopy(s:codefix_map) +endfunction + +" Used to set the codefix map in tests. +function! ale#codefix#SetMap(map) abort + let s:codefix_map = a:map +endfunction + +function! ale#codefix#ClearLSPData() abort + let s:codefix_map = {} +endfunction + +function! s:message(message) abort + call ale#util#Execute('echom ' . string(a:message)) +endfunction + +function! ale#codefix#HandleTSServerResponse(conn_id, response) abort + if !has_key(a:response, 'request_seq') + \ || !has_key(s:codefix_map, a:response.request_seq) + return + endif + + let l:location = remove(s:codefix_map, a:response.request_seq) + + if get(a:response, 'command', '') is# 'getCodeFixes' + if get(a:response, 'success', v:false) is v:false + let l:message = get(a:response, 'message', 'unknown') + call s:message('Error while getting code fixes. Reason: ' . l:message) + + return + endif + + if len(a:response.body) == 0 + call s:message('No code fixes available.') + + return + endif + + let l:code_fix_to_apply = 0 + + if len(a:response.body) == 1 + let l:code_fix_to_apply = 1 + else + let l:codefix_no = 1 + let l:codefixstring = "Code Fixes:\n" + + for l:codefix in a:response.body + let l:codefixstring .= l:codefix_no . ') ' . l:codefix.description . "\n" + let l:codefix_no += 1 + endfor + + let l:codefixstring .= 'Type number and (empty cancels): ' + + let l:code_fix_to_apply = ale#util#Input(l:codefixstring, '') + let l:code_fix_to_apply = str2nr(l:code_fix_to_apply) + + if l:code_fix_to_apply == 0 + return + endif + endif + + let l:changes = a:response.body[l:code_fix_to_apply - 1].changes + + call ale#code_action#HandleCodeAction({ + \ 'description': 'codefix', + \ 'changes': l:changes, + \}, {}) + elseif get(a:response, 'command', '') is# 'getApplicableRefactors' + if get(a:response, 'success', v:false) is v:false + let l:message = get(a:response, 'message', 'unknown') + call s:message('Error while getting applicable refactors. Reason: ' . l:message) + + return + endif + + if len(a:response.body) == 0 + call s:message('No applicable refactors available.') + + return + endif + + let l:refactors = [] + + for l:item in a:response.body + for l:action in l:item.actions + call add(l:refactors, { + \ 'name': l:action.description, + \ 'id': [l:item.name, l:action.name], + \}) + endfor + endfor + + let l:refactor_no = 1 + let l:refactorstring = "Applicable refactors:\n" + + for l:refactor in l:refactors + let l:refactorstring .= l:refactor_no . ') ' . l:refactor.name . "\n" + let l:refactor_no += 1 + endfor + + let l:refactorstring .= 'Type number and (empty cancels): ' + + let l:refactor_to_apply = ale#util#Input(l:refactorstring, '') + let l:refactor_to_apply = str2nr(l:refactor_to_apply) + + if l:refactor_to_apply == 0 + return + endif + + let l:id = l:refactors[l:refactor_to_apply - 1].id + + let l:message = ale#lsp#tsserver_message#GetEditsForRefactor( + \ l:location.buffer, + \ l:location.line, + \ l:location.column, + \ l:location.end_line, + \ l:location.end_column, + \ l:id[0], + \ l:id[1], + \) + + let l:request_id = ale#lsp#Send(l:location.connection_id, l:message) + + let s:codefix_map[l:request_id] = l:location + elseif get(a:response, 'command', '') is# 'getEditsForRefactor' + if get(a:response, 'success', v:false) is v:false + let l:message = get(a:response, 'message', 'unknown') + call s:message('Error while getting edits for refactor. Reason: ' . l:message) + + return + endif + + call ale#code_action#HandleCodeAction({ + \ 'description': 'editsForRefactor', + \ 'changes': a:response.body.edits, + \}, {}) + endif +endfunction + +function! ale#codefix#HandleLSPResponse(conn_id, response) abort + if has_key(a:response, 'method') + \ && a:response.method is# 'workspace/applyEdit' + \ && has_key(a:response, 'params') + let l:params = a:response.params + + let l:changes_map = ale#code_action#GetChanges(l:params.edit) + + if empty(l:changes_map) + return + endif + + let l:changes = ale#code_action#BuildChangesList(l:changes_map) + + call ale#code_action#HandleCodeAction({ + \ 'description': 'applyEdit', + \ 'changes': l:changes, + \}, {}) + elseif has_key(a:response, 'id') + \&& has_key(s:codefix_map, a:response.id) + let l:location = remove(s:codefix_map, a:response.id) + + if !has_key(a:response, 'result') + \ || type(a:response.result) != v:t_list + \ || len(a:response.result) == 0 + call s:message('No code actions received from server') + + return + endif + + let l:codeaction_no = 1 + let l:codeactionstring = "Code Fixes:\n" + + for l:codeaction in a:response.result + let l:codeactionstring .= l:codeaction_no . ') ' . l:codeaction.title . "\n" + let l:codeaction_no += 1 + endfor + + let l:codeactionstring .= 'Type number and (empty cancels): ' + + let l:codeaction_to_apply = ale#util#Input(l:codeactionstring, '') + let l:codeaction_to_apply = str2nr(l:codeaction_to_apply) + + if l:codeaction_to_apply == 0 + return + endif + + let l:item = a:response.result[l:codeaction_to_apply - 1] + + if has_key(l:item, 'command') + \ && type(l:item.command) == v:t_dict + let l:command = l:item.command + let l:message = ale#lsp#message#ExecuteCommand( + \ l:command.command, + \ l:command.arguments, + \) + + let l:request_id = ale#lsp#Send(l:location.connection_id, l:message) + elseif has_key(l:item, 'edit') || has_key(l:item, 'arguments') + if has_key(l:item, 'edit') + let l:topass = l:item.edit + else + let l:topass = l:item.arguments[0] + endif + + let l:changes_map = ale#code_action#GetChanges(l:topass) + + if empty(l:changes_map) + return + endif + + let l:changes = ale#code_action#BuildChangesList(l:changes_map) + + call ale#code_action#HandleCodeAction({ + \ 'description': 'codeaction', + \ 'changes': l:changes, + \}, {}) + endif + endif +endfunction + + +function! s:OnReady(line, column, end_line, end_column, linter, lsp_details) abort + let l:id = a:lsp_details.connection_id + + if !ale#lsp#HasCapability(l:id, 'code_actions') + return + endif + + let l:buffer = a:lsp_details.buffer + + if a:linter.lsp is# 'tsserver' + if a:line == a:end_line && a:column == a:end_column + if !has_key(g:ale_buffer_info, l:buffer) + return + endif + + let l:nearest_error = v:null + let l:nearest_error_diff = -1 + + for l:error in get(g:ale_buffer_info[l:buffer], 'loclist', []) + if has_key(l:error, 'code') && l:error.lnum == a:line + let l:diff = abs(l:error.col - a:column) + + if l:nearest_error_diff == -1 || l:diff < l:nearest_error_diff + let l:nearest_error_diff = l:diff + let l:nearest_error = l:error.code + endif + endif + endfor + + let l:message = ale#lsp#tsserver_message#GetCodeFixes( + \ l:buffer, + \ a:line, + \ a:column, + \ a:line, + \ a:column, + \ [l:nearest_error], + \) + else + let l:message = ale#lsp#tsserver_message#GetApplicableRefactors( + \ l:buffer, + \ a:line, + \ a:column, + \ a:end_line, + \ a:end_column, + \) + endif + else + " Send a message saying the buffer has changed first, otherwise + " completions won't know what text is nearby. + call ale#lsp#NotifyForChanges(l:id, l:buffer) + + if a:line == a:end_line && a:column == a:end_column + if !has_key(g:ale_buffer_info, l:buffer) + return + endif + + let l:nearest_error = v:null + let l:nearest_error_diff = -1 + + for l:error in get(g:ale_buffer_info[l:buffer], 'loclist', []) + if has_key(l:error, 'code') && l:error.lnum == a:line + let l:diff = abs(l:error.col - a:column) + + if l:nearest_error_diff == -1 || l:diff < l:nearest_error_diff + let l:nearest_error_diff = l:diff + let l:nearest_error = l:error + endif + endif + endfor + + let l:diagnostics = [] + + if l:nearest_error isnot v:null + let l:diagnostics = [{ + \ 'code': l:nearest_error.code, + \ 'message': l:nearest_error.text, + \ 'range': { + \ 'start': { 'line': l:nearest_error.lnum - 1, 'character': l:nearest_error.col - 1 }, + \ 'end': { 'line': l:nearest_error.end_lnum - 1, 'character': l:nearest_error.end_col - 1 } + \} + \}] + endif + + let l:message = ale#lsp#message#CodeAction( + \ l:buffer, + \ a:line, + \ a:column, + \ a:end_line, + \ a:end_column, + \ l:diagnostics, + \) + else + let l:message = ale#lsp#message#CodeAction( + \ l:buffer, + \ a:line, + \ a:column, + \ a:end_line, + \ a:end_column, + \ [], + \) + endif + endif + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#codefix#HandleTSServerResponse') + \ : function('ale#codefix#HandleLSPResponse') + + call ale#lsp#RegisterCallback(l:id, l:Callback) + + let l:request_id = ale#lsp#Send(l:id, l:message) + + let s:codefix_map[l:request_id] = { + \ 'connection_id': l:id, + \ 'buffer': l:buffer, + \ 'line': a:line, + \ 'column': a:column, + \ 'end_line': a:end_line, + \ 'end_column': a:end_column, + \} +endfunction + +function! s:ExecuteGetCodeFix(linter, range) abort + let l:buffer = bufnr('') + + if a:range == 0 + let [l:line, l:column] = getpos('.')[1:2] + let l:end_line = l:line + let l:end_column = l:column + else + let [l:line, l:column] = getpos("'<")[1:2] + let [l:end_line, l:end_column] = getpos("'>")[1:2] + endif + + let l:column = min([l:column, len(getline(l:line))]) + let l:end_column = min([l:end_column, len(getline(l:end_line))]) + + let l:Callback = function( + \ 's:OnReady', [l:line, l:column, l:end_line, l:end_column]) + call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) +endfunction + +function! ale#codefix#Execute(range) abort + let l:lsp_linters = [] + + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + call add(l:lsp_linters, l:linter) + endif + endfor + + if empty(l:lsp_linters) + call s:message('No active LSPs') + + return + endif + + for l:lsp_linter in l:lsp_linters + call s:ExecuteGetCodeFix(l:lsp_linter, a:range) + endfor +endfunction diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index efbf0fd5..48e9bf7c 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -617,6 +617,7 @@ function! ale#completion#ParseLSPCompletions(response) abort let l:user_data = {'_ale_completion_item': 1} if has_key(l:item, 'additionalTextEdits') + \ && l:item.additionalTextEdits isnot v:null let l:text_changes = [] for l:edit in l:item.additionalTextEdits diff --git a/autoload/ale/lsp.vim b/autoload/ale/lsp.vim index 7d99e9d2..cb0573aa 100644 --- a/autoload/ale/lsp.vim +++ b/autoload/ale/lsp.vim @@ -44,6 +44,7 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort \ 'definition': 0, \ 'typeDefinition': 0, \ 'symbol_search': 0, + \ 'code_actions': 0, \ }, \} endif @@ -219,6 +220,14 @@ function! s:UpdateCapabilities(conn, capabilities) abort let a:conn.capabilities.rename = 1 endif + if get(a:capabilities, 'codeActionProvider') is v:true + let a:conn.capabilities.code_actions = 1 + endif + + if type(get(a:capabilities, 'codeActionProvider')) is v:t_dict + let a:conn.capabilities.code_actions = 1 + endif + if !empty(get(a:capabilities, 'completionProvider')) let a:conn.capabilities.completion = 1 endif @@ -350,6 +359,7 @@ function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort let l:conn.capabilities.definition = 1 let l:conn.capabilities.symbol_search = 1 let l:conn.capabilities.rename = 1 + let l:conn.capabilities.code_actions = 1 endfunction function! s:SendInitMessage(conn) abort diff --git a/autoload/ale/lsp/message.vim b/autoload/ale/lsp/message.vim index 5b0cb8b7..38be4da6 100644 --- a/autoload/ale/lsp/message.vim +++ b/autoload/ale/lsp/message.vim @@ -172,3 +172,25 @@ function! ale#lsp#message#Rename(buffer, line, column, new_name) abort \ 'newName': a:new_name, \}] endfunction + +function! ale#lsp#message#CodeAction(buffer, line, column, end_line, end_column, diagnostics) abort + return [0, 'textDocument/codeAction', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \ 'range': { + \ 'start': {'line': a:line - 1, 'character': a:column - 1}, + \ 'end': {'line': a:end_line - 1, 'character': a:end_column}, + \ }, + \ 'context': { + \ 'diagnostics': a:diagnostics + \ }, + \}] +endfunction + +function! ale#lsp#message#ExecuteCommand(command, arguments) abort + return [0, 'workspace/executeCommand', { + \ 'command': a:command, + \ 'arguments': a:arguments, + \}] +endfunction diff --git a/autoload/ale/lsp/response.vim b/autoload/ale/lsp/response.vim index 30da77e1..a4f80980 100644 --- a/autoload/ale/lsp/response.vim +++ b/autoload/ale/lsp/response.vim @@ -56,6 +56,7 @@ function! ale#lsp#response#ReadDiagnostics(response) abort endif if has_key(l:diagnostic, 'relatedInformation') + \ && l:diagnostic.relatedInformation isnot v:null let l:related = deepcopy(l:diagnostic.relatedInformation) call map(l:related, {key, val -> \ ale#path#FromURI(val.location.uri) . diff --git a/autoload/ale/lsp/tsserver_message.vim b/autoload/ale/lsp/tsserver_message.vim index b9fafaa0..3c1b47ed 100644 --- a/autoload/ale/lsp/tsserver_message.vim +++ b/autoload/ale/lsp/tsserver_message.vim @@ -103,3 +103,39 @@ function! ale#lsp#tsserver_message#OrganizeImports(buffer) abort \ }, \}] endfunction + +function! ale#lsp#tsserver_message#GetCodeFixes(buffer, line, column, end_line, end_column, error_codes) abort + " The lines and columns are 1-based. + " The errors codes must be a list of tsserver error codes to fix. + return [0, 'ts@getCodeFixes', { + \ 'startLine': a:line, + \ 'startOffset': a:column, + \ 'endLine': a:end_line, + \ 'endOffset': a:end_column + 1, + \ 'file': expand('#' . a:buffer . ':p'), + \ 'errorCodes': a:error_codes, + \}] +endfunction + +function! ale#lsp#tsserver_message#GetApplicableRefactors(buffer, line, column, end_line, end_column) abort + " The arguments for this request can also be just 'line' and 'offset' + return [0, 'ts@getApplicableRefactors', { + \ 'startLine': a:line, + \ 'startOffset': a:column, + \ 'endLine': a:end_line, + \ 'endOffset': a:end_column + 1, + \ 'file': expand('#' . a:buffer . ':p'), + \}] +endfunction + +function! ale#lsp#tsserver_message#GetEditsForRefactor(buffer, line, column, end_line, end_column, refactor, action) abort + return [0, 'ts@getEditsForRefactor', { + \ 'startLine': a:line, + \ 'startOffset': a:column, + \ 'endLine': a:end_line, + \ 'endOffset': a:end_column + 1, + \ 'file': expand('#' . a:buffer . ':p'), + \ 'refactor': a:refactor, + \ 'action': a:action, + \}] +endfunction diff --git a/autoload/ale/rename.vim b/autoload/ale/rename.vim index 8190411d..0d074c24 100644 --- a/autoload/ale/rename.vim +++ b/autoload/ale/rename.vim @@ -90,31 +90,6 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort \) endfunction -function! s:getChanges(workspace_edit) abort - let l:changes = {} - - if has_key(a:workspace_edit, 'changes') && !empty(a:workspace_edit.changes) - return a:workspace_edit.changes - elseif has_key(a:workspace_edit, 'documentChanges') - let l:document_changes = [] - - if type(a:workspace_edit.documentChanges) is v:t_dict - \ && has_key(a:workspace_edit.documentChanges, 'edits') - call add(l:document_changes, a:workspace_edit.documentChanges) - elseif type(a:workspace_edit.documentChanges) is v:t_list - let l:document_changes = a:workspace_edit.documentChanges - endif - - for l:text_document_edit in l:document_changes - let l:filename = l:text_document_edit.textDocument.uri - let l:edits = l:text_document_edit.edits - let l:changes[l:filename] = l:edits - endfor - endif - - return l:changes -endfunction - function! ale#rename#HandleLSPResponse(conn_id, response) abort if has_key(a:response, 'id') \&& has_key(s:rename_map, a:response.id) @@ -126,7 +101,7 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort return endif - let l:changes_map = s:getChanges(a:response.result) + let l:changes_map = ale#code_action#GetChanges(a:response.result) if empty(l:changes_map) call s:message('No changes received from server') @@ -134,34 +109,7 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort return endif - let l:changes = [] - - for l:file_name in keys(l:changes_map) - let l:text_edits = l:changes_map[l:file_name] - let l:text_changes = [] - - for l:edit in l:text_edits - let l:range = l:edit.range - let l:new_text = l:edit.newText - - call add(l:text_changes, { - \ 'start': { - \ 'line': l:range.start.line + 1, - \ 'offset': l:range.start.character + 1, - \ }, - \ 'end': { - \ 'line': l:range.end.line + 1, - \ 'offset': l:range.end.character + 1, - \ }, - \ 'newText': l:new_text, - \}) - endfor - - call add(l:changes, { - \ 'fileName': ale#path#FromURI(l:file_name), - \ 'textChanges': l:text_changes, - \}) - endfor + let l:changes = ale#code_action#BuildChangesList(l:changes_map) call ale#code_action#HandleCodeAction( \ { diff --git a/doc/ale.txt b/doc/ale.txt index eb8f0275..4263f698 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3106,6 +3106,18 @@ ALERename *ALERename* in those files will not be updated. +ALECodeAction *ALECodeAction* + + Code Actions support for `tsserver`. + + There are two different kind of actions supported for `tsserver`. If run in + normal mode then code fix will be attempted if there is error in that line. + If there are multiple code fixes available use will be shown input to choose + one. In visual mode `tsserver` will be queries for applicable refactors + (e.g. extract to constant or extract to function) and user will be given + choice to select the one he/she likes. + + ALERepeatSelection *ALERepeatSelection* Repeat the last selection displayed in the preview window. diff --git a/plugin/ale.vim b/plugin/ale.vim index 32ec14ac..7472ea8c 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -240,6 +240,8 @@ command! -bar ALEImport :call ale#completion#Import() " Rename symbols using tsserver and LSP command! -bar -bang ALERename :call ale#rename#Execute({'force_save': '' is# '!'}) +command! -bar -range ALECodeAction :call ale#codefix#Execute() + " Organize import statements using tsserver command! -bar ALEOrganizeImports :call ale#organize_imports#Execute() @@ -283,6 +285,7 @@ nnoremap (ale_documentation) :ALEDocumentation inoremap (ale_complete) :ALEComplete nnoremap (ale_import) :ALEImport nnoremap (ale_rename) :ALERename +nnoremap (ale_code_action) :ALECodeAction nnoremap (ale_repeat_selection) :ALERepeatSelection " Set up autocmd groups now. diff --git a/test/lsp/test_other_initialize_message_handling.vader b/test/lsp/test_other_initialize_message_handling.vader index b6ef852a..f3b53843 100644 --- a/test/lsp/test_other_initialize_message_handling.vader +++ b/test/lsp/test_other_initialize_message_handling.vader @@ -23,6 +23,7 @@ Before: \ 'completion_trigger_characters': [], \ 'definition': 0, \ 'symbol_search': 0, + \ 'code_actions': 0, \ }, \} @@ -102,6 +103,7 @@ Execute(Capabilities should bet set up correctly): \ 'definition': 1, \ 'symbol_search': 1, \ 'rename': 1, + \ 'code_actions': 1, \ }, \ b:conn.capabilities AssertEqual [[1, 'initialized', {}]], g:message_list @@ -125,7 +127,7 @@ Execute(Disabled capabilities should be recognised correctly): \ 'referencesProvider': v:false, \ 'textDocumentSync': 2, \ 'documentFormattingProvider': v:true, - \ 'codeActionProvider': v:true, + \ 'codeActionProvider': v:false, \ 'signatureHelpProvider': { \ 'triggerCharacters': ['(', ','], \ }, @@ -146,6 +148,7 @@ Execute(Disabled capabilities should be recognised correctly): \ 'definition': 0, \ 'symbol_search': 0, \ 'rename': 0, + \ 'code_actions': 0, \ }, \ b:conn.capabilities AssertEqual [[1, 'initialized', {}]], g:message_list @@ -197,6 +200,7 @@ Execute(Capabilities should be enabled when send as Dictionaries): \ 'typeDefinition': 1, \ 'symbol_search': 1, \ 'rename': 1, + \ 'code_actions': 1, \ }, \ b:conn.capabilities AssertEqual [[1, 'initialized', {}]], g:message_list diff --git a/test/test_code_action.vader b/test/test_code_action.vader index 2e5d1381..7eabb759 100644 --- a/test/test_code_action.vader +++ b/test/test_code_action.vader @@ -3,6 +3,9 @@ Before: let g:ale_enabled = 0 + " Enable fix end-of-line as tests below expect that + set fixeol + runtime autoload/ale/code_action.vim runtime autoload/ale/util.vim @@ -211,6 +214,7 @@ Execute(End of file can be modified): \) AssertEqual g:test.text + [ + \ '', \ 'type A: string', \ 'type B: number', \ '', diff --git a/test/test_code_action_python.vader b/test/test_code_action_python.vader new file mode 100644 index 00000000..fd30633d --- /dev/null +++ b/test/test_code_action_python.vader @@ -0,0 +1,59 @@ +Given python(An example Python file): + def main(): + a = 1 + c = a + 1 + +Execute(): + let g:changes = [ + \ {'end': {'offset': 7, 'line': 1}, 'newText': 'func_qtffgsv', 'start': {'offset': 5, 'line': 1}}, + \ {'end': {'offset': 9, 'line': 1}, 'newText': '', 'start': {'offset': 8, 'line': 1}}, + \ {'end': {'offset': 15, 'line': 3}, 'newText': " return c\n\n\ndef main():\n c = func_qtffgsvi()\n", 'start': {'offset': 15, 'line': 3}} + \] + + call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0) + +Expect(The changes should be applied correctly): + def func_qtffgsvi(): + a = 1 + c = a + 1 + return c + + + def main(): + c = func_qtffgsvi() + + +Given python(Second python example): + import sys + import exifread + + def main(): + with open(sys.argv[1], 'rb') as f: + exif = exifread.process_file(f) + dt = str(exif['Image DateTime']) + date = dt[:10].replace(':', '-') + +Execute(): + let g:changes = [ + \ {'end': {'offset': 16, 'line': 2}, 'newText': "\n\ndef func_ivlpdpao(f):\n exif = exifread.process_file(f)\n dt = str(exif['Image DateTime'])\n date = dt[:10].replace(':', '-')\n return date\n", 'start': {'offset': 16, 'line': 2}}, + \ {'end': {'offset': 32, 'line': 6}, 'newText': 'date = func', 'start': {'offset': 9, 'line': 6}}, + \ {'end': {'offset': 42, 'line': 8}, 'newText': "ivlpdpao(f)\n", 'start': {'offset': 33, 'line': 6}} + \] + + call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0) + +Expect(The changes should be applied correctly): + import sys + import exifread + + + def func_ivlpdpao(f): + exif = exifread.process_file(f) + dt = str(exif['Image DateTime']) + date = dt[:10].replace(':', '-') + return date + + + def main(): + with open(sys.argv[1], 'rb') as f: + date = func_ivlpdpao(f) diff --git a/test/test_codefix.vader b/test/test_codefix.vader new file mode 100644 index 00000000..63275d7f --- /dev/null +++ b/test/test_codefix.vader @@ -0,0 +1,604 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('dummy.txt') + Save g:ale_buffer_info + + let g:ale_buffer_info = {} + + let g:old_filename = expand('%:p') + let g:Callback = '' + let g:expr_list = [] + let g:message_list = [] + let g:handle_code_action_called = 0 + let g:code_actions = [] + let g:options = {} + let g:capability_checked = '' + let g:conn_id = v:null + let g:InitCallback = v:null + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/codefix.vim + runtime autoload/ale/code_action.vim + + function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {}) + call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer) + + if a:linter.lsp is# 'tsserver' + call ale#lsp#MarkConnectionAsTsserver(g:conn_id) + endif + + let l:details = { + \ 'command': 'foobar', + \ 'buffer': a:buffer, + \ 'connection_id': g:conn_id, + \ 'project_root': '/foo/bar', + \} + + let g:InitCallback = {-> ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)} + endfunction + + function! ale#lsp#HasCapability(conn_id, capability) abort + let g:capability_checked = a:capability + + return 1 + endfunction + + function! ale#lsp#RegisterCallback(conn_id, callback) abort + let g:Callback = a:callback + endfunction + + function! ale#lsp#Send(conn_id, message) abort + call add(g:message_list, a:message) + + return 42 + endfunction + + function! ale#util#Execute(expr) abort + call add(g:expr_list, a:expr) + endfunction + + function! ale#code_action#HandleCodeAction(code_action, options) abort + let g:handle_code_action_called = 1 + Assert !get(a:options, 'should_save') + call add(g:code_actions, a:code_action) + endfunction + + function! ale#util#Input(message, value) abort + return '2' + endfunction + +After: + Restore + + if g:conn_id isnot v:null + call ale#lsp#RemoveConnectionWithID(g:conn_id) + endif + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + + unlet! g:capability_checked + unlet! g:InitCallback + unlet! g:old_filename + unlet! g:conn_id + unlet! g:Callback + unlet! g:message_list + unlet! g:expr_list + unlet! b:ale_linters + unlet! g:options + unlet! g:code_actions + unlet! g:handle_code_action_called + + runtime autoload/ale/lsp_linter.vim + runtime autoload/ale/lsp.vim + runtime autoload/ale/util.vim + runtime autoload/ale/codefix.vim + runtime autoload/ale/code_action.vim + +Execute(Failed codefix responses should be handled correctly): + call ale#codefix#HandleTSServerResponse( + \ 1, + \ {'command': 'getCodeFixes', 'request_seq': 3} + \) + AssertEqual g:handle_code_action_called, 0 + + + +Given typescript(Some typescript file): + foo + somelongerline + bazxyzxyzxyz + +Execute(getCodeFixes from tsserver should be handled): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, { + \ 'command': 'getCodeFixes', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'type': 'response', + \ 'body': [ + \ { + \ 'description': 'Import default "x" from module "./z"', + \ 'fixName': 'import', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1, + \ }, + \ 'newText': 'import x from "./z";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1, + \ } + \ } + \ ] + \ } + \ ] + \ } + \ ] + \}) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [ + \ { + \ 'description': 'codefix', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1 + \ }, + \ 'newText': 'import x from "./z";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1 + \ } + \ } + \ ] + \ } + \ ] + \ } + \ ], + \ g:code_actions + +Execute(getCodeFixes from tsserver should be handled with user input if there are more than one action): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, { + \ 'command': 'getCodeFixes', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'type': 'response', + \ 'body': [ + \ { + \ 'description': 'Import default "x" from module "./z"', + \ 'fixName': 'import', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1, + \ }, + \ 'newText': 'import x from "./z";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1, + \ } + \ } + \ ] + \ } + \ ] + \ }, + \ { + \ 'description': 'Import default "x" from module "./y"', + \ 'fixName': 'import', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1, + \ }, + \ 'newText': 'import x from "./y";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1, + \ } + \ } + \ ] + \ } + \ ] + \ } + \ ] + \}) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [ + \ { + \ 'description': 'codefix', + \ 'changes': [ + \ { + \ 'fileName': "/foo/bar/file1.ts", + \ 'textChanges': [ + \ { + \ 'end': { + \ 'line': 2, + \ 'offset': 1 + \ }, + \ 'newText': 'import x from "./y";^@', + \ 'start': { + \ 'line': 2, + \ 'offset': 1 + \ } + \ } + \ ] + \ } + \ ] + \ } + \ ], + \ g:code_actions + +Execute(Prints a tsserver error message when getCodeFixes unsuccessful): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, { + \ 'command': 'getCodeFixes', + \ 'request_seq': 3, + \ 'success': v:false, + \ 'message': 'something is wrong', + \}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''Error while getting code fixes. Reason: something is wrong'''], g:expr_list + +Execute(Does nothing when where are no code fixes): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, { + \ 'command': 'getCodeFixes', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': [] + \}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''No code fixes available.'''], g:expr_list + +Execute(tsserver codefix requests should be sent): + call ale#linter#Reset() + + runtime ale_linters/typescript/tsserver.vim + let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'code': 2304}]}} + call setpos('.', [bufnr(''), 2, 5, 0]) + + " ALECodeAction + call ale#codefix#Execute(0) + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'code_actions', g:capability_checked + AssertEqual + \ 'function(''ale#codefix#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@getCodeFixes', { + \ 'startLine': 2, + \ 'startOffset': 5, + \ 'endLine': 2, + \ 'endOffset': 6, + \ 'file': expand('%:p'), + \ 'errorCodes': [2304], + \ }] + \ ], + \ g:message_list + +Execute(tsserver codefix requests should be sent only for error with code): + call ale#linter#Reset() + + runtime ale_linters/typescript/tsserver.vim + let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5}, {'lnum': 2, 'col': 5, 'code': 2304}]}} + call setpos('.', [bufnr(''), 2, 5, 0]) + + " ALECodeAction + call ale#codefix#Execute(0) + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'code_actions', g:capability_checked + AssertEqual + \ 'function(''ale#codefix#HandleTSServerResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ ale#lsp#tsserver_message#Change(bufnr('')), + \ [0, 'ts@getCodeFixes', { + \ 'startLine': 2, + \ 'startOffset': 5, + \ 'endLine': 2, + \ 'endOffset': 6, + \ 'file': expand('%:p'), + \ 'errorCodes': [2304], + \ }] + \ ], + \ g:message_list + +Execute(getApplicableRefactors from tsserver should be handled): + call ale#codefix#SetMap({3: { + \ 'buffer': expand('%:p'), + \ 'line': 1, + \ 'column': 2, + \ 'end_line': 3, + \ 'end_column': 4, + \ 'connection_id': 0, + \}}) + call ale#codefix#HandleTSServerResponse(1, + \ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [{'actions': [{'description': 'Extract to constant in enclosing scope', 'name': 'constant_scope_0'}], 'description': 'Extract constant', 'name': 'Extract Symbol'}, {'actions': [{'description': 'Extract to function in module scope', 'name': 'function_scope_1'}], 'description': 'Extract function', 'name': 'Extract Symbol'}], 'command': 'getApplicableRefactors'}) + + AssertEqual + \ [ + \ [0, 'ts@getEditsForRefactor', { + \ 'startLine': 1, + \ 'startOffset': 2, + \ 'endLine': 3, + \ 'endOffset': 5, + \ 'file': expand('%:p'), + \ 'refactor': 'Extract Symbol', + \ 'action': 'function_scope_1', + \ }] + \ ], + \ g:message_list + +Execute(getApplicableRefactors should print error on failure): + call ale#codefix#SetMap({3: { + \ 'buffer': expand('%:p'), + \ 'line': 1, + \ 'column': 2, + \ 'end_line': 3, + \ 'end_column': 4, + \ 'connection_id': 0, + \}}) + call ale#codefix#HandleTSServerResponse(1, + \ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getApplicableRefactors'}) + + AssertEqual ['echom ''Error while getting applicable refactors. Reason: oops'''], g:expr_list + +Execute(getApplicableRefactors should do nothing if there are no refactors): + call ale#codefix#SetMap({3: { + \ 'buffer': expand('%:p'), + \ 'line': 1, + \ 'column': 2, + \ 'end_line': 3, + \ 'end_column': 4, + \ 'connection_id': 0, + \}}) + call ale#codefix#HandleTSServerResponse(1, + \ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [], 'command': 'getApplicableRefactors'}) + + AssertEqual ['echom ''No applicable refactors available.'''], g:expr_list + +Execute(getEditsForRefactor from tsserver should be handled): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, + \{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': {'edits': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}], 'renameLocation': {'offset': 3, 'line': 8}, 'renameFilename': '/foo/bar/file.ts'}, 'command': 'getEditsForRefactor' } + \) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [ + \ { + \ 'description': 'editsForRefactor', + \ 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}], + \ } + \ ], + \ g:code_actions + +Execute(getEditsForRefactor should print error on failure): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleTSServerResponse(1, + \{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getEditsForRefactor' } + \) + + AssertEqual ['echom ''Error while getting edits for refactor. Reason: oops'''], g:expr_list + +" TODO: I can't figure out how to run ALECodeAction on range +" in test function. Therefore I can't write properly working +" test. If somebody knows how to do that help is appreciated. +" +" Execute(tsserver getApplicableRefactors requests should be sent): +" call ale#linter#Reset() +" +" runtime ale_linters/typescript/tsserver.vim +" let g:ale_buffer_info = {bufnr(''): {'loclist': []}} +" call setpos('.', [bufnr(''), 2, 5, 0]) +" normal "v$" +" +" execute "ALECodeAction" +" +" " We shouldn't register the callback yet. +" AssertEqual '''''', string(g:Callback) +" +" AssertEqual type(function('type')), type(g:InitCallback) +" call g:InitCallback() +" +" AssertEqual 'code_actions', g:capability_checked +" AssertEqual +" \ 'function(''ale#codefix#HandleTSServerResponse'')', +" \ string(g:Callback) +" AssertEqual +" \ [ +" \ ale#lsp#tsserver_message#Change(bufnr('')), +" \ [0, 'ts@getApplicableRefactors', { +" \ 'startLine': 2, +" \ 'startOffset': 5, +" \ 'endLine': 2, +" \ 'endOffset': 15, +" \ 'file': expand('%:p'), +" \ }] +" \ ], +" \ g:message_list + +Execute(Failed LSP responses should be handled correctly): + call ale#codefix#HandleLSPResponse( + \ 1, + \ {'method': 'workspace/applyEdit', 'request_seq': 3} + \) + AssertEqual g:handle_code_action_called, 0 + +Given python(Some python file): + def main(): + a = 1 + b = a + 2 + +Execute("workspace/applyEdit" from LSP should be handled): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 0, 'jsonrpc': '2.0', 'method': 'workspace/applyEdit', 'params': {'edit': {'changes': {'file:///foo/bar/file.ts': [{'range': {'end': {'character': 27, 'line': 7}, 'start': {'character': 27, 'line': 7}}, 'newText': ', Config'}, {'range': {'end': {'character': 12, 'line': 96}, 'start': {'character': 2, 'line': 94}}, 'newText': 'await newFunction(redis, imageKey, cover, config);'}, {'range': {'end': {'character': 2, 'line': 99}, 'start': {'character': 2, 'line': 99}}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@'}]}}}}) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [{'description': 'applyEdit', 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 28, 'line': 8}, 'newText': ', Config', 'start': {'offset': 28, 'line': 8}}, {'end': {'offset': 13, 'line': 97}, 'newText': 'await newFunction(redis, imageKey, cover, config);', 'start': {'offset': 3, 'line': 95}}, {'end': {'offset': 3, 'line': 100}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@', 'start': {'offset': 3, 'line': 100}}]}]}], + \ g:code_actions + +Execute(Code Actions from LSP should be handled with user input if there are more than one action): + call ale#codefix#SetMap({2: {}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 2, 'jsonrpc': '2.0', 'result': [{'title': 'fake for testing'}, {'arguments': [{'documentChanges': [{'edits': [{'range': {'end': {'character': 31, 'line': 2}, 'start': {'character': 31, 'line': 2}}, 'newText': ', createVideo'}], 'textDocument': {'uri': 'file:///foo/bar/file.ts', 'version': 1}}]}], 'title': 'Add ''createVideo'' to existing import declaration from "./video"', 'command': '_typescript.applyWorkspaceEdit'}]}) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [{'description': 'codeaction', 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 32, 'line': 3}, 'newText': ', createVideo', 'start': {'offset': 32, 'line': 3}}]}]}], + \ g:code_actions + +Execute(Code Actions from LSP should be handled when returned with documentChanges): + call ale#codefix#SetMap({2: {}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 2, 'jsonrpc': '2.0', 'result': [{'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 4, 'line': 1}}, 'newText': ''}, {'range': {'end': {'character': 9, 'line': 2}, 'start': {'character': 8, 'line': 2}}, 'newText': '(1)'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.inline', 'title': 'Inline variable', 'command': v:null}, {'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 0, 'line': 0}, 'start': {'character': 0, 'line': 0}}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@'}, {'range': {'end': {'character': 9, 'line': 1}, 'start': {'character': 8, 'line': 1}}, 'newText': 'func_bomdjnxh()^@'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.extract', 'title': 'Extract expression into function ''func_bomdjnxh''', 'command': v:null}]}) + + AssertEqual g:handle_code_action_called, 1 + AssertEqual + \ [{'description': 'codeaction', 'changes': [{'fileName': '/foo/bar/test.py', 'textChanges': [{'end': {'offset': 1, 'line': 1}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@', 'start': {'offset': 1, 'line': 1}}, {'end': {'offset': 10, 'line': 2}, 'newText': 'func_bomdjnxh()^@', 'start': {'offset': 9, 'line': 2}}]}]}], + \ g:code_actions + +Execute(LSP Code Actions handles command responses): + call ale#codefix#SetMap({3: { + \ 'connection_id': 0, + \}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 3, 'jsonrpc': '2.0', 'result': [{'kind': 'refactor', 'title': 'Extract to inner function in function ''getVideo''', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_0', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to inner function in function ''getVideo''', 'command': '_typescript.applyRefactoring'}}, {'kind': 'refactor', 'title': 'Extract to function in module scope', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_1', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to function in module scope', 'command': '_typescript.applyRefactoring'}}]}) + + AssertEqual + \ [[0, 'workspace/executeCommand', {'arguments': [{'file': '/foo/bar/file.ts', 'action': 'function_scope_1', 'endOffset': 0, 'refactor': 'Extract Symbol', 'endLine': 68, 'startLine': 65, 'startOffset': 1}], 'command': '_typescript.applyRefactoring'}]], + \ g:message_list + + +Execute(Prints message when LSP code action returns no results): + call ale#codefix#SetMap({3: {}}) + call ale#codefix#HandleLSPResponse(1, + \ {'id': 3, 'jsonrpc': '2.0', 'result': []}) + + AssertEqual g:handle_code_action_called, 0 + AssertEqual ['echom ''No code actions received from server'''], g:expr_list + +Execute(LSP code action requests should be sent): + call ale#linter#Reset() + + runtime ale_linters/python/jedils.vim + let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}} + call setpos('.', [bufnr(''), 2, 5, 0]) + + " ALECodeAction + call ale#codefix#Execute(0) + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'code_actions', g:capability_checked + AssertEqual + \ 'function(''ale#codefix#HandleLSPResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ [1, 'workspace/didChangeConfiguration', {'settings': {'python': {}}}], + \ [1, 'textDocument/didChange', { + \ 'contentChanges': [{'text': "def main():\n a = 1\n b = a + 2\n"}], + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ }], + \ [0, 'textDocument/codeAction', { + \ 'context': { + \ 'diagnostics': [{'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] + \ }, + \ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))} + \ }] + \ ], + \ g:message_list + +Execute(LSP code action requests should be sent only for error with code): + call ale#linter#Reset() + + runtime ale_linters/python/jedils.vim + let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}} + call setpos('.', [bufnr(''), 2, 5, 0]) + + " ALECodeAction + call ale#codefix#Execute(0) + + " We shouldn't register the callback yet. + AssertEqual '''''', string(g:Callback) + + AssertEqual type(function('type')), type(g:InitCallback) + call g:InitCallback() + + AssertEqual 'code_actions', g:capability_checked + AssertEqual + \ 'function(''ale#codefix#HandleLSPResponse'')', + \ string(g:Callback) + AssertEqual + \ [ + \ [1, 'workspace/didChangeConfiguration', {'settings': {'python': {}}}], + \ [1, 'textDocument/didChange', { + \ 'contentChanges': [{'text': "def main():\n a = 1\n b = a + 2\n"}], + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('%:p')), + \ 'version': g:ale_lsp_next_version_id - 1, + \ }, + \ }], + \ [0, 'textDocument/codeAction', { + \ 'context': { + \ 'diagnostics': [{'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] + \ }, + \ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, + \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))} + \ }] + \ ], + \ g:message_list From e9140c740b8deee05c10aab92fb23c7a5747569e Mon Sep 17 00:00:00 2001 From: w0rp Date: Sat, 14 Nov 2020 10:17:02 +0000 Subject: [PATCH 045/167] cmp forwards, and reverse the code actions --- autoload/ale/code_action.vim | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/autoload/ale/code_action.vim b/autoload/ale/code_action.vim index 4dbb2d08..fe6b175f 100644 --- a/autoload/ale/code_action.vim +++ b/autoload/ale/code_action.vim @@ -33,37 +33,37 @@ endfunction function! s:ChangeCmp(left, right) abort if a:left.start.line < a:right.start.line - return 1 + return -1 endif if a:left.start.line > a:right.start.line - return -1 + return 1 endif if a:left.start.offset < a:right.start.offset - return 1 + return -1 endif if a:left.start.offset > a:right.start.offset - return -1 + return 1 endif if a:left.end.line < a:right.end.line - return 1 + return -1 endif if a:left.end.line > a:right.end.line - return -1 - endif - - if a:left.end.offset < a:right.end.offset return 1 endif - if a:left.end.offset > a:right.end.offset + if a:left.end.offset < a:right.end.offset return -1 endif + if a:left.end.offset > a:right.end.offset + return 1 + endif + return 0 endfunction @@ -86,7 +86,7 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort endif " Changes have to be sorted so we apply them from bottom-to-top - for l:code_edit in sort(copy(a:changes), function('s:ChangeCmp')) + for l:code_edit in reverse(sort(copy(a:changes), function('s:ChangeCmp'))) let l:line = l:code_edit.start.line let l:column = l:code_edit.start.offset let l:end_line = l:code_edit.end.line From 48fe0dd4f629bb1282277ba8a6757a84c13a4dda Mon Sep 17 00:00:00 2001 From: w0rp Date: Sat, 14 Nov 2020 10:41:51 +0000 Subject: [PATCH 046/167] Update documentation for code actions and rename --- README.md | 13 +++++++++++++ doc/ale.txt | 25 ++++++++++++++++++------- plugin/ale.vim | 1 + 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0f1c613b..69ff33ae 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ other content at [w0rp.com](https://w0rp.com). 5. [Find References](#usage-find-references) 6. [Hovering](#usage-hover) 7. [Symbol Search](#usage-symbol-search) + 8. [Refactoring: Rename, Actions](#usage-refactoring) 3. [Installation](#installation) 1. [Installation with Vim package management](#standard-installation) 2. [Installation with Pathogen](#installation-with-pathogen) @@ -253,6 +254,18 @@ similar to a given query string. See `:help ale-symbol-search` for more information. + + +### 2.viii Refactoring: Rename, Actions + +ALE supports renaming symbols in symbols in code such as variables or class +names with the `ALERename` command. + +`ALECodeAction` will execute actions on the cursor or applied to a visual +range selection, such as automatically fixing errors. + +See `:help ale-refactor` for more information. + ## 3. Installation diff --git a/doc/ale.txt b/doc/ale.txt index 4263f698..013b39f9 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -20,6 +20,7 @@ CONTENTS *ale-contents* 5.4 Find References...................|ale-find-references| 5.5 Hovering..........................|ale-hover| 5.6 Symbol Search.....................|ale-symbol-search| + 5.7 Refactoring: Rename, Actions......|ale-refactor| 6. Global Options.......................|ale-options| 6.1 Highlights........................|ale-highlights| 7. Linter/Fixer Options.................|ale-integration-options| @@ -669,6 +670,16 @@ ALE supports searching for workspace symbols via LSP linters with the |ALESymbolSearch| command. See the documentation for the command for a full list of options. +------------------------------------------------------------------------------- +5.7 Refactoring: Rename, Actions *ale-refactor* + +ALE supports renaming symbols in symbols in code such as variables or class +names with the |ALERename| command. + +|ALECodeAction| will execute actions on the cursor or applied to a visual +range selection, such as automatically fixing errors. + + =============================================================================== 6. Global Options *ale-options* @@ -3108,14 +3119,14 @@ ALERename *ALERename* ALECodeAction *ALECodeAction* - Code Actions support for `tsserver`. + Apply a code action via LSP servers or `tsserver`. - There are two different kind of actions supported for `tsserver`. If run in - normal mode then code fix will be attempted if there is error in that line. - If there are multiple code fixes available use will be shown input to choose - one. In visual mode `tsserver` will be queries for applicable refactors - (e.g. extract to constant or extract to function) and user will be given - choice to select the one he/she likes. + If there is an error present on a line that can be fixed, ALE will + automatically fix a line, unless there are multiple possible code fixes to + apply. + + This command can be run in visual mode apply actions, such as applicable + refactors. A menu will be shown to select code action to apply. ALERepeatSelection *ALERepeatSelection* diff --git a/plugin/ale.vim b/plugin/ale.vim index 7472ea8c..c5c1d3d3 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -240,6 +240,7 @@ command! -bar ALEImport :call ale#completion#Import() " Rename symbols using tsserver and LSP command! -bar -bang ALERename :call ale#rename#Execute({'force_save': '' is# '!'}) +" Apply code actions to a range. command! -bar -range ALECodeAction :call ale#codefix#Execute() " Organize import statements using tsserver From b74827de99e842dc7698d8d6274486550d90f05a Mon Sep 17 00:00:00 2001 From: Nathan Herald Date: Wed, 29 Jul 2020 18:23:00 +0200 Subject: [PATCH 047/167] Look for node packages in .yarn/sdks as well --- ale_linters/typescript/tsserver.vim | 1 + autoload/ale/handlers/eslint.vim | 1 + 2 files changed, 2 insertions(+) diff --git a/ale_linters/typescript/tsserver.vim b/ale_linters/typescript/tsserver.vim index 840889f3..4726e40d 100644 --- a/ale_linters/typescript/tsserver.vim +++ b/ale_linters/typescript/tsserver.vim @@ -9,6 +9,7 @@ call ale#linter#Define('typescript', { \ 'name': 'tsserver', \ 'lsp': 'tsserver', \ 'executable': {b -> ale#node#FindExecutable(b, 'typescript_tsserver', [ +\ '.yarn/sdks/typescript/bin/tsserver', \ 'node_modules/.bin/tsserver', \ ])}, \ 'command': '%e', diff --git a/autoload/ale/handlers/eslint.vim b/autoload/ale/handlers/eslint.vim index e37d6902..b8610612 100644 --- a/autoload/ale/handlers/eslint.vim +++ b/autoload/ale/handlers/eslint.vim @@ -5,6 +5,7 @@ let s:executables = [ \ 'node_modules/.bin/eslint_d', \ 'node_modules/eslint/bin/eslint.js', \ 'node_modules/.bin/eslint', +\ '.yarn/sdks/eslint/bin/eslint', \] let s:sep = has('win32') ? '\' : '/' From ddfc43e774fd38e4051ba9fd3619ca9f0da6639f Mon Sep 17 00:00:00 2001 From: Ben Linsay Date: Wed, 18 Nov 2020 20:39:07 -0500 Subject: [PATCH 048/167] pass lsp intialization_options to rust-analyzer fixes #3350 --- ale_linters/rust/analyzer.vim | 2 +- test/command_callback/test_rust_analyzer_callbacks.vader | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ale_linters/rust/analyzer.vim b/ale_linters/rust/analyzer.vim index 3666ec03..77d946f7 100644 --- a/ale_linters/rust/analyzer.vim +++ b/ale_linters/rust/analyzer.vim @@ -17,7 +17,7 @@ endfunction call ale#linter#Define('rust', { \ 'name': 'analyzer', \ 'lsp': 'stdio', -\ 'lsp_config': {b -> ale#Var(b, 'rust_analyzer_config')}, +\ 'initialization_options': {b -> ale#Var(b, 'rust_analyzer_config')}, \ 'executable': {b -> ale#Var(b, 'rust_analyzer_executable')}, \ 'command': function('ale_linters#rust#analyzer#GetCommand'), \ 'project_root': function('ale_linters#rust#analyzer#GetProjectRoot'), diff --git a/test/command_callback/test_rust_analyzer_callbacks.vader b/test/command_callback/test_rust_analyzer_callbacks.vader index 95866076..efab1378 100644 --- a/test/command_callback/test_rust_analyzer_callbacks.vader +++ b/test/command_callback/test_rust_analyzer_callbacks.vader @@ -16,5 +16,5 @@ Execute(The project root should be detected correctly): Execute(Should accept configuration settings): AssertLSPConfig {} - let b:ale_rust_analyzer_config = {'rust': {'clippy_preference': 'on'}} - AssertLSPConfig {'rust': {'clippy_preference': 'on'}} + let b:ale_rust_analyzer_config = {'diagnostics': {'disabled': ['unresolved-import']}} + AssertLSPOptions {'diagnostics': {'disabled': ['unresolved-import']}} From 7c04ee5c200b64ef0886677216fbec1303ec9475 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sat, 21 Nov 2020 01:18:27 +0000 Subject: [PATCH 049/167] Close #1466 - Add GVIM refactor menu support Code actions and ALERename now appear in the right click context menu for GVim by default. --- autoload/ale/code_action.vim | 102 +++++++++ autoload/ale/codefix.vim | 396 ++++++++++++++++++++++------------- doc/ale.txt | 35 +++- plugin/ale.vim | 7 + test/test_codefix.vader | 75 +------ 5 files changed, 398 insertions(+), 217 deletions(-) diff --git a/autoload/ale/code_action.vim b/autoload/ale/code_action.vim index fe6b175f..506107f4 100644 --- a/autoload/ale/code_action.vim +++ b/autoload/ale/code_action.vim @@ -263,3 +263,105 @@ function! ale#code_action#BuildChangesList(changes_map) abort return l:changes endfunction + +function! s:EscapeMenuName(text) abort + return substitute(a:text, '\\\| \|\.\|&', '\\\0', 'g') +endfunction + +function! s:UpdateMenu(data, menu_items) abort + silent! aunmenu PopUp.Refactor\.\.\. + + if empty(a:data) + return + endif + + for [l:type, l:item] in a:menu_items + let l:name = l:type is# 'tsserver' ? l:item.name : l:item.title + let l:func_name = l:type is# 'tsserver' + \ ? 'ale#codefix#ApplyTSServerCodeAction' + \ : 'ale#codefix#ApplyLSPCodeAction' + + execute printf( + \ 'anoremenu PopUp.&Refactor\.\.\..%s' + \ . ' :call %s(%s, %s)', + \ s:EscapeMenuName(l:name), + \ l:func_name, + \ string(a:data), + \ string(l:item), + \) + endfor + + if empty(a:menu_items) + silent! anoremenu PopUp.Refactor\.\.\..(None) :silent + endif +endfunction + +function! s:GetCodeActions(linter, options) abort + let l:buffer = bufnr('') + let [l:line, l:column] = getpos('.')[1:2] + let l:column = min([l:column, len(getline(l:line))]) + + let l:location = { + \ 'buffer': l:buffer, + \ 'line': l:line, + \ 'column': l:column, + \ 'end_line': l:line, + \ 'end_column': l:column, + \} + let l:Callback = function('s:OnReady', [l:location, a:options]) + call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) +endfunction + +function! ale#code_action#GetCodeActions(options) abort + silent! aunmenu PopUp.Rename + silent! aunmenu PopUp.Refactor\.\.\. + + " Only display the menu items if there's an LSP server. + let l:has_lsp = 0 + + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + let l:has_lsp = 1 + + break + endif + endfor + + if l:has_lsp + if !empty(expand('')) + silent! anoremenu PopUp.Rename :ALERename + endif + + silent! anoremenu PopUp.Refactor\.\.\..(None) :silent + + call ale#codefix#Execute( + \ mode() is# 'v' || mode() is# "\", + \ function('s:UpdateMenu') + \) + endif +endfunction + +function! s:Setup(enabled) abort + augroup ALECodeActionsGroup + autocmd! + + if a:enabled + autocmd MenuPopup * :call ale#code_action#GetCodeActions({}) + endif + augroup END + + if !a:enabled + silent! augroup! ALECodeActionsGroup + + silent! aunmenu PopUp.Rename + silent! aunmenu PopUp.Refactor\.\.\. + endif +endfunction + +function! ale#code_action#EnablePopUpMenu() abort + call s:Setup(1) +endfunction + +function! ale#code_action#DisablePopUpMenu() abort + call s:Setup(0) +endfunction diff --git a/autoload/ale/codefix.vim b/autoload/ale/codefix.vim index b58f5e4b..3120e7cb 100644 --- a/autoload/ale/codefix.vim +++ b/autoload/ale/codefix.vim @@ -1,5 +1,5 @@ " Author: Dalius Dobravolskas -" Description: Code Fix support for tsserver +" Description: Code Fix support for tsserver and LSP servers let s:codefix_map = {} @@ -21,23 +21,65 @@ function! s:message(message) abort call ale#util#Execute('echom ' . string(a:message)) endfunction +function! ale#codefix#ApplyTSServerCodeAction(data, item) abort + if has_key(a:item, 'changes') + let l:changes = a:item.changes + + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'codefix', + \ 'changes': l:changes, + \ }, + \ {}, + \) + else + let l:message = ale#lsp#tsserver_message#GetEditsForRefactor( + \ a:data.buffer, + \ a:data.line, + \ a:data.column, + \ a:data.end_line, + \ a:data.end_column, + \ a:item.id[0], + \ a:item.id[1], + \) + + let l:request_id = ale#lsp#Send(a:data.connection_id, l:message) + + let s:codefix_map[l:request_id] = a:data + endif +endfunction + function! ale#codefix#HandleTSServerResponse(conn_id, response) abort if !has_key(a:response, 'request_seq') \ || !has_key(s:codefix_map, a:response.request_seq) return endif - let l:location = remove(s:codefix_map, a:response.request_seq) + let l:data = remove(s:codefix_map, a:response.request_seq) + let l:MenuCallback = get(l:data, 'menu_callback', v:null) if get(a:response, 'command', '') is# 'getCodeFixes' if get(a:response, 'success', v:false) is v:false + \&& l:MenuCallback is v:null let l:message = get(a:response, 'message', 'unknown') call s:message('Error while getting code fixes. Reason: ' . l:message) return endif - if len(a:response.body) == 0 + let l:result = get(a:response, 'body', []) + call filter(l:result, 'has_key(v:val, ''changes'')') + + if l:MenuCallback isnot v:null + call l:MenuCallback( + \ l:data, + \ map(copy(l:result), '[''tsserver'', v:val]') + \) + + return + endif + + if len(l:result) == 0 call s:message('No code fixes available.') return @@ -45,14 +87,15 @@ function! ale#codefix#HandleTSServerResponse(conn_id, response) abort let l:code_fix_to_apply = 0 - if len(a:response.body) == 1 + if len(l:result) == 1 let l:code_fix_to_apply = 1 else let l:codefix_no = 1 let l:codefixstring = "Code Fixes:\n" - for l:codefix in a:response.body - let l:codefixstring .= l:codefix_no . ') ' . l:codefix.description . "\n" + for l:codefix in l:result + let l:codefixstring .= l:codefix_no . ') ' + \ . l:codefix.description . "\n" let l:codefix_no += 1 endfor @@ -66,21 +109,22 @@ function! ale#codefix#HandleTSServerResponse(conn_id, response) abort endif endif - let l:changes = a:response.body[l:code_fix_to_apply - 1].changes - - call ale#code_action#HandleCodeAction({ - \ 'description': 'codefix', - \ 'changes': l:changes, - \}, {}) + call ale#codefix#ApplyTSServerCodeAction( + \ l:data, + \ l:result[l:code_fix_to_apply - 1], + \) elseif get(a:response, 'command', '') is# 'getApplicableRefactors' if get(a:response, 'success', v:false) is v:false + \&& l:MenuCallback is v:null let l:message = get(a:response, 'message', 'unknown') call s:message('Error while getting applicable refactors. Reason: ' . l:message) return endif - if len(a:response.body) == 0 + let l:result = get(a:response, 'body', []) + + if len(l:result) == 0 call s:message('No applicable refactors available.') return @@ -88,7 +132,7 @@ function! ale#codefix#HandleTSServerResponse(conn_id, response) abort let l:refactors = [] - for l:item in a:response.body + for l:item in l:result for l:action in l:item.actions call add(l:refactors, { \ 'name': l:action.description, @@ -97,11 +141,21 @@ function! ale#codefix#HandleTSServerResponse(conn_id, response) abort endfor endfor + if l:MenuCallback isnot v:null + call l:MenuCallback( + \ l:data, + \ map(copy(l:refactors), '[''tsserver'', v:val]') + \) + + return + endif + let l:refactor_no = 1 let l:refactorstring = "Applicable refactors:\n" for l:refactor in l:refactors - let l:refactorstring .= l:refactor_no . ') ' . l:refactor.name . "\n" + let l:refactorstring .= l:refactor_no . ') ' + \ . l:refactor.name . "\n" let l:refactor_no += 1 endfor @@ -116,19 +170,10 @@ function! ale#codefix#HandleTSServerResponse(conn_id, response) abort let l:id = l:refactors[l:refactor_to_apply - 1].id - let l:message = ale#lsp#tsserver_message#GetEditsForRefactor( - \ l:location.buffer, - \ l:location.line, - \ l:location.column, - \ l:location.end_line, - \ l:location.end_column, - \ l:id[0], - \ l:id[1], + call ale#codefix#ApplyTSServerCodeAction( + \ l:data, + \ l:refactors[l:refactor_to_apply - 1], \) - - let l:request_id = ale#lsp#Send(l:location.connection_id, l:message) - - let s:codefix_map[l:request_id] = l:location elseif get(a:response, 'command', '') is# 'getEditsForRefactor' if get(a:response, 'success', v:false) is v:false let l:message = get(a:response, 'message', 'unknown') @@ -137,10 +182,48 @@ function! ale#codefix#HandleTSServerResponse(conn_id, response) abort return endif - call ale#code_action#HandleCodeAction({ - \ 'description': 'editsForRefactor', - \ 'changes': a:response.body.edits, - \}, {}) + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'editsForRefactor', + \ 'changes': a:response.body.edits, + \ }, + \ {}, + \) + endif +endfunction + +function! ale#codefix#ApplyLSPCodeAction(data, item) abort + if has_key(a:item, 'command') + \&& type(a:item.command) == v:t_dict + let l:command = a:item.command + let l:message = ale#lsp#message#ExecuteCommand( + \ l:command.command, + \ l:command.arguments, + \) + + let l:request_id = ale#lsp#Send(a:data.connection_id, l:message) + elseif has_key(a:item, 'edit') || has_key(a:item, 'arguments') + if has_key(a:item, 'edit') + let l:topass = a:item.edit + else + let l:topass = a:item.arguments[0] + endif + + let l:changes_map = ale#code_action#GetChanges(l:topass) + + if empty(l:changes_map) + return + endif + + let l:changes = ale#code_action#BuildChangesList(l:changes_map) + + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'codeaction', + \ 'changes': l:changes, + \ }, + \ {}, + \) endif endfunction @@ -158,17 +241,32 @@ function! ale#codefix#HandleLSPResponse(conn_id, response) abort let l:changes = ale#code_action#BuildChangesList(l:changes_map) - call ale#code_action#HandleCodeAction({ - \ 'description': 'applyEdit', - \ 'changes': l:changes, - \}, {}) + call ale#code_action#HandleCodeAction( + \ { + \ 'description': 'applyEdit', + \ 'changes': l:changes, + \ }, + \ {} + \) elseif has_key(a:response, 'id') \&& has_key(s:codefix_map, a:response.id) - let l:location = remove(s:codefix_map, a:response.id) + let l:data = remove(s:codefix_map, a:response.id) + let l:MenuCallback = get(l:data, 'menu_callback', v:null) - if !has_key(a:response, 'result') - \ || type(a:response.result) != v:t_list - \ || len(a:response.result) == 0 + let l:result = get(a:response, 'result') + + if type(l:result) != v:t_list + let l:result = [] + endif + + " Send the results to the menu callback, if set. + if l:MenuCallback isnot v:null + call l:MenuCallback(map(copy(l:result), '[''lsp'', v:val]')) + + return + endif + + if len(l:result) == 0 call s:message('No code actions received from server') return @@ -177,8 +275,9 @@ function! ale#codefix#HandleLSPResponse(conn_id, response) abort let l:codeaction_no = 1 let l:codeactionstring = "Code Fixes:\n" - for l:codeaction in a:response.result - let l:codeactionstring .= l:codeaction_no . ') ' . l:codeaction.title . "\n" + for l:codeaction in l:result + let l:codeactionstring .= l:codeaction_no . ') ' + \ . l:codeaction.title . "\n" let l:codeaction_no += 1 endfor @@ -191,42 +290,44 @@ function! ale#codefix#HandleLSPResponse(conn_id, response) abort return endif - let l:item = a:response.result[l:codeaction_to_apply - 1] + let l:item = l:result[l:codeaction_to_apply - 1] - if has_key(l:item, 'command') - \ && type(l:item.command) == v:t_dict - let l:command = l:item.command - let l:message = ale#lsp#message#ExecuteCommand( - \ l:command.command, - \ l:command.arguments, - \) - - let l:request_id = ale#lsp#Send(l:location.connection_id, l:message) - elseif has_key(l:item, 'edit') || has_key(l:item, 'arguments') - if has_key(l:item, 'edit') - let l:topass = l:item.edit - else - let l:topass = l:item.arguments[0] - endif - - let l:changes_map = ale#code_action#GetChanges(l:topass) - - if empty(l:changes_map) - return - endif - - let l:changes = ale#code_action#BuildChangesList(l:changes_map) - - call ale#code_action#HandleCodeAction({ - \ 'description': 'codeaction', - \ 'changes': l:changes, - \}, {}) - endif + call ale#codefix#ApplyLSPCodeAction(l:data, l:item) endif endfunction +function! s:FindError(buffer, line, column, end_line, end_column) abort + let l:nearest_error = v:null -function! s:OnReady(line, column, end_line, end_column, linter, lsp_details) abort + if a:line == a:end_line + \&& a:column == a:end_column + \&& has_key(g:ale_buffer_info, a:buffer) + let l:nearest_error_diff = -1 + + for l:error in get(g:ale_buffer_info[a:buffer], 'loclist', []) + if has_key(l:error, 'code') && l:error.lnum == a:line + let l:diff = abs(l:error.col - a:column) + + if l:nearest_error_diff == -1 || l:diff < l:nearest_error_diff + let l:nearest_error_diff = l:diff + let l:nearest_error = l:error + endif + endif + endfor + endif + + return l:nearest_error +endfunction + +function! s:OnReady( +\ line, +\ column, +\ end_line, +\ end_column, +\ MenuCallback, +\ linter, +\ lsp_details, +\) abort let l:id = a:lsp_details.connection_id if !ale#lsp#HasCapability(l:id, 'code_actions') @@ -236,32 +337,17 @@ function! s:OnReady(line, column, end_line, end_column, linter, lsp_details) abo let l:buffer = a:lsp_details.buffer if a:linter.lsp is# 'tsserver' - if a:line == a:end_line && a:column == a:end_column - if !has_key(g:ale_buffer_info, l:buffer) - return - endif - - let l:nearest_error = v:null - let l:nearest_error_diff = -1 - - for l:error in get(g:ale_buffer_info[l:buffer], 'loclist', []) - if has_key(l:error, 'code') && l:error.lnum == a:line - let l:diff = abs(l:error.col - a:column) - - if l:nearest_error_diff == -1 || l:diff < l:nearest_error_diff - let l:nearest_error_diff = l:diff - let l:nearest_error = l:error.code - endif - endif - endfor + let l:nearest_error = + \ s:FindError(l:buffer, a:line, a:column, a:end_line, a:end_column) + if l:nearest_error isnot v:null let l:message = ale#lsp#tsserver_message#GetCodeFixes( \ l:buffer, \ a:line, \ a:column, \ a:line, \ a:column, - \ [l:nearest_error], + \ [l:nearest_error.code], \) else let l:message = ale#lsp#tsserver_message#GetApplicableRefactors( @@ -277,56 +363,37 @@ function! s:OnReady(line, column, end_line, end_column, linter, lsp_details) abo " completions won't know what text is nearby. call ale#lsp#NotifyForChanges(l:id, l:buffer) - if a:line == a:end_line && a:column == a:end_column - if !has_key(g:ale_buffer_info, l:buffer) - return - endif + let l:diagnostics = [] + let l:nearest_error = + \ s:FindError(l:buffer, a:line, a:column, a:end_line, a:end_column) - let l:nearest_error = v:null - let l:nearest_error_diff = -1 - - for l:error in get(g:ale_buffer_info[l:buffer], 'loclist', []) - if has_key(l:error, 'code') && l:error.lnum == a:line - let l:diff = abs(l:error.col - a:column) - - if l:nearest_error_diff == -1 || l:diff < l:nearest_error_diff - let l:nearest_error_diff = l:diff - let l:nearest_error = l:error - endif - endif - endfor - - let l:diagnostics = [] - - if l:nearest_error isnot v:null - let l:diagnostics = [{ - \ 'code': l:nearest_error.code, - \ 'message': l:nearest_error.text, - \ 'range': { - \ 'start': { 'line': l:nearest_error.lnum - 1, 'character': l:nearest_error.col - 1 }, - \ 'end': { 'line': l:nearest_error.end_lnum - 1, 'character': l:nearest_error.end_col - 1 } - \} - \}] - endif - - let l:message = ale#lsp#message#CodeAction( - \ l:buffer, - \ a:line, - \ a:column, - \ a:end_line, - \ a:end_column, - \ l:diagnostics, - \) - else - let l:message = ale#lsp#message#CodeAction( - \ l:buffer, - \ a:line, - \ a:column, - \ a:end_line, - \ a:end_column, - \ [], - \) + if l:nearest_error isnot v:null + let l:diagnostics = [ + \ { + \ 'code': l:nearest_error.code, + \ 'message': l:nearest_error.text, + \ 'range': { + \ 'start': { + \ 'line': l:nearest_error.lnum - 1, + \ 'character': l:nearest_error.col - 1, + \ }, + \ 'end': { + \ 'line': l:nearest_error.end_lnum - 1, + \ 'character': l:nearest_error.end_col - 1, + \ }, + \ }, + \ }, + \] endif + + let l:message = ale#lsp#message#CodeAction( + \ l:buffer, + \ a:line, + \ a:column, + \ a:end_line, + \ a:end_column, + \ l:diagnostics, + \) endif let l:Callback = a:linter.lsp is# 'tsserver' @@ -338,22 +405,40 @@ function! s:OnReady(line, column, end_line, end_column, linter, lsp_details) abo let l:request_id = ale#lsp#Send(l:id, l:message) let s:codefix_map[l:request_id] = { - \ 'connection_id': l:id, - \ 'buffer': l:buffer, - \ 'line': a:line, - \ 'column': a:column, - \ 'end_line': a:end_line, - \ 'end_column': a:end_column, + \ 'connection_id': l:id, + \ 'buffer': l:buffer, + \ 'line': a:line, + \ 'column': a:column, + \ 'end_line': a:end_line, + \ 'end_column': a:end_column, + \ 'menu_callback': a:MenuCallback, \} endfunction -function! s:ExecuteGetCodeFix(linter, range) abort +function! s:ExecuteGetCodeFix(linter, range, MenuCallback) abort let l:buffer = bufnr('') if a:range == 0 let [l:line, l:column] = getpos('.')[1:2] let l:end_line = l:line let l:end_column = l:column + + " Expand the range to cover the current word, if there is one. + let l:cword = expand('') + + if !empty(l:cword) + let l:search_pos = searchpos('\V' . l:cword, 'bn', l:line) + + if l:search_pos != [0, 0] + let l:column = l:search_pos[1] + let l:end_column = l:column + len(l:cword) - 1 + endif + endif + elseif mode() is# 'v' || mode() is# "\" + " You need to get the start and end in a different way when you're in + " visual mode. + let [l:line, l:column] = getpos('v')[1:2] + let [l:end_line, l:end_column] = getpos('.')[1:2] else let [l:line, l:column] = getpos("'<")[1:2] let [l:end_line, l:end_column] = getpos("'>")[1:2] @@ -363,11 +448,18 @@ function! s:ExecuteGetCodeFix(linter, range) abort let l:end_column = min([l:end_column, len(getline(l:end_line))]) let l:Callback = function( - \ 's:OnReady', [l:line, l:column, l:end_line, l:end_column]) + \ 's:OnReady', [l:line, l:column, l:end_line, l:end_column, a:MenuCallback] + \) + call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) endfunction -function! ale#codefix#Execute(range) abort +function! ale#codefix#Execute(range, ...) abort + if a:0 > 1 + throw 'Too many arguments' + endif + + let l:MenuCallback = get(a:000, 0, v:null) let l:lsp_linters = [] for l:linter in ale#linter#Get(&filetype) @@ -377,12 +469,16 @@ function! ale#codefix#Execute(range) abort endfor if empty(l:lsp_linters) - call s:message('No active LSPs') + if l:MenuCallback is v:null + call s:message('No active LSPs') + else + call l:MenuCallback({}, []) + endif return endif for l:lsp_linter in l:lsp_linters - call s:ExecuteGetCodeFix(l:lsp_linter, a:range) + call s:ExecuteGetCodeFix(l:lsp_linter, a:range, l:MenuCallback) endfor endfunction diff --git a/doc/ale.txt b/doc/ale.txt index 013b39f9..20baf355 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -673,13 +673,31 @@ for a full list of options. ------------------------------------------------------------------------------- 5.7 Refactoring: Rename, Actions *ale-refactor* -ALE supports renaming symbols in symbols in code such as variables or class -names with the |ALERename| command. +ALE supports renaming symbols in code such as variables or class names with +the |ALERename| command. |ALECodeAction| will execute actions on the cursor or applied to a visual range selection, such as automatically fixing errors. +Actions will appear in the right click mouse menu by default for GUI versions +of Vim, unless disabled by setting |g:ale_popup_menu_enabled| to `0`. +Make sure to set your Vim to move the cursor position whenever you right +click, and enable the mouse menu: > + + set mouse=a + set mousemodel=popup_setpos +< +You may wish to remove some other menu items you don't want to see: > + + silent! aunmenu PopUp.Select\ Word + silent! aunmenu PopUp.Select\ Sentence + silent! aunmenu PopUp.Select\ Paragraph + silent! aunmenu PopUp.Select\ Line + silent! aunmenu PopUp.Select\ Block + silent! aunmenu PopUp.Select\ Blockwise + silent! aunmenu PopUp.Select\ All +< =============================================================================== 6. Global Options *ale-options* @@ -1784,6 +1802,19 @@ g:ale_pattern_options_enabled *g:ale_pattern_options_enabled* will not set buffer variables per |g:ale_pattern_options|. +g:ale_popup_menu_enabled *g:ale_popup_menu_enabled* + + Type: |Number| + Default: `has('gui')` + + When this option is set to `1`, ALE will show code actions and rename + capabilities in the right click mouse menu when there's a LSP server or + tsserver available. See |ale-refactor|. + + This setting must be set to `1` before ALE is loaded for this behavior + to be enabled. See |ale-lint-settings-on-startup|. + + g:ale_rename_tsserver_find_in_comments *g:ale_rename_tsserver_find_in_comments* Type: |Number| diff --git a/plugin/ale.vim b/plugin/ale.vim index c5c1d3d3..2398956e 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -158,6 +158,9 @@ let g:ale_python_auto_pipenv = get(g:, 'ale_python_auto_pipenv', 0) " This variable can be overridden to set the GO111MODULE environment variable. let g:ale_go_go111module = get(g:, 'ale_go_go111module', '') +" If 1, enable a popup menu for commands. +let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui')) + if g:ale_set_balloons call ale#balloon#Enable() endif @@ -166,6 +169,10 @@ if g:ale_completion_enabled call ale#completion#Enable() endif +if g:ale_popup_menu_enabled + call ale#code_action#EnablePopUpMenu() +endif + " Define commands for moving through warnings and errors. command! -bar -nargs=* ALEPrevious \ :call ale#loclist_jumping#WrapJump('before', ) diff --git a/test/test_codefix.vader b/test/test_codefix.vader index 63275d7f..deb97256 100644 --- a/test/test_codefix.vader +++ b/test/test_codefix.vader @@ -105,11 +105,9 @@ Execute(Failed codefix responses should be handled correctly): \) AssertEqual g:handle_code_action_called, 0 - - Given typescript(Some typescript file): foo - somelongerline + somelongerline () bazxyzxyzxyz Execute(getCodeFixes from tsserver should be handled): @@ -283,7 +281,7 @@ Execute(tsserver codefix requests should be sent): runtime ale_linters/typescript/tsserver.vim let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'code': 2304}]}} - call setpos('.', [bufnr(''), 2, 5, 0]) + call setpos('.', [bufnr(''), 2, 16, 0]) " ALECodeAction call ale#codefix#Execute(0) @@ -303,9 +301,9 @@ Execute(tsserver codefix requests should be sent): \ ale#lsp#tsserver_message#Change(bufnr('')), \ [0, 'ts@getCodeFixes', { \ 'startLine': 2, - \ 'startOffset': 5, + \ 'startOffset': 16, \ 'endLine': 2, - \ 'endOffset': 6, + \ 'endOffset': 17, \ 'file': expand('%:p'), \ 'errorCodes': [2304], \ }] @@ -316,8 +314,8 @@ Execute(tsserver codefix requests should be sent only for error with code): call ale#linter#Reset() runtime ale_linters/typescript/tsserver.vim - let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5}, {'lnum': 2, 'col': 5, 'code': 2304}]}} - call setpos('.', [bufnr(''), 2, 5, 0]) + let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 16}, {'lnum': 2, 'col': 16, 'code': 2304}]}} + call setpos('.', [bufnr(''), 2, 16, 0]) " ALECodeAction call ale#codefix#Execute(0) @@ -337,9 +335,9 @@ Execute(tsserver codefix requests should be sent only for error with code): \ ale#lsp#tsserver_message#Change(bufnr('')), \ [0, 'ts@getCodeFixes', { \ 'startLine': 2, - \ 'startOffset': 5, + \ 'startOffset': 16, \ 'endLine': 2, - \ 'endOffset': 6, + \ 'endOffset': 17, \ 'file': expand('%:p'), \ 'errorCodes': [2304], \ }] @@ -424,43 +422,6 @@ Execute(getEditsForRefactor should print error on failure): AssertEqual ['echom ''Error while getting edits for refactor. Reason: oops'''], g:expr_list -" TODO: I can't figure out how to run ALECodeAction on range -" in test function. Therefore I can't write properly working -" test. If somebody knows how to do that help is appreciated. -" -" Execute(tsserver getApplicableRefactors requests should be sent): -" call ale#linter#Reset() -" -" runtime ale_linters/typescript/tsserver.vim -" let g:ale_buffer_info = {bufnr(''): {'loclist': []}} -" call setpos('.', [bufnr(''), 2, 5, 0]) -" normal "v$" -" -" execute "ALECodeAction" -" -" " We shouldn't register the callback yet. -" AssertEqual '''''', string(g:Callback) -" -" AssertEqual type(function('type')), type(g:InitCallback) -" call g:InitCallback() -" -" AssertEqual 'code_actions', g:capability_checked -" AssertEqual -" \ 'function(''ale#codefix#HandleTSServerResponse'')', -" \ string(g:Callback) -" AssertEqual -" \ [ -" \ ale#lsp#tsserver_message#Change(bufnr('')), -" \ [0, 'ts@getApplicableRefactors', { -" \ 'startLine': 2, -" \ 'startOffset': 5, -" \ 'endLine': 2, -" \ 'endOffset': 15, -" \ 'file': expand('%:p'), -" \ }] -" \ ], -" \ g:message_list - Execute(Failed LSP responses should be handled correctly): call ale#codefix#HandleLSPResponse( \ 1, @@ -545,14 +506,6 @@ Execute(LSP code action requests should be sent): \ string(g:Callback) AssertEqual \ [ - \ [1, 'workspace/didChangeConfiguration', {'settings': {'python': {}}}], - \ [1, 'textDocument/didChange', { - \ 'contentChanges': [{'text': "def main():\n a = 1\n b = a + 2\n"}], - \ 'textDocument': { - \ 'uri': ale#path#ToURI(expand('%:p')), - \ 'version': g:ale_lsp_next_version_id - 1, - \ }, - \ }], \ [0, 'textDocument/codeAction', { \ 'context': { \ 'diagnostics': [{'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] @@ -561,7 +514,7 @@ Execute(LSP code action requests should be sent): \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))} \ }] \ ], - \ g:message_list + \ g:message_list[-1:] Execute(LSP code action requests should be sent only for error with code): call ale#linter#Reset() @@ -585,14 +538,6 @@ Execute(LSP code action requests should be sent only for error with code): \ string(g:Callback) AssertEqual \ [ - \ [1, 'workspace/didChangeConfiguration', {'settings': {'python': {}}}], - \ [1, 'textDocument/didChange', { - \ 'contentChanges': [{'text': "def main():\n a = 1\n b = a + 2\n"}], - \ 'textDocument': { - \ 'uri': ale#path#ToURI(expand('%:p')), - \ 'version': g:ale_lsp_next_version_id - 1, - \ }, - \ }], \ [0, 'textDocument/codeAction', { \ 'context': { \ 'diagnostics': [{'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] @@ -601,4 +546,4 @@ Execute(LSP code action requests should be sent only for error with code): \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))} \ }] \ ], - \ g:message_list + \ g:message_list[-1:] From d0b5909fd8cb96fa65363af44d02eb0038c6112c Mon Sep 17 00:00:00 2001 From: Dalius Dobravolskas Date: Sat, 21 Nov 2020 01:26:16 +0000 Subject: [PATCH 050/167] #3442 Fix code fix clangd issue --- autoload/ale/codefix.vim | 2 +- test/test_codefix.vader | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/autoload/ale/codefix.vim b/autoload/ale/codefix.vim index 3120e7cb..69bf36fa 100644 --- a/autoload/ale/codefix.vim +++ b/autoload/ale/codefix.vim @@ -379,7 +379,7 @@ function! s:OnReady( \ }, \ 'end': { \ 'line': l:nearest_error.end_lnum - 1, - \ 'character': l:nearest_error.end_col - 1, + \ 'character': l:nearest_error.end_col, \ }, \ }, \ }, diff --git a/test/test_codefix.vader b/test/test_codefix.vader index deb97256..fc5470aa 100644 --- a/test/test_codefix.vader +++ b/test/test_codefix.vader @@ -508,7 +508,7 @@ Execute(LSP code action requests should be sent): \ [ \ [0, 'textDocument/codeAction', { \ 'context': { - \ 'diagnostics': [{'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] + \ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] \ }, \ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))} @@ -540,7 +540,7 @@ Execute(LSP code action requests should be sent only for error with code): \ [ \ [0, 'textDocument/codeAction', { \ 'context': { - \ 'diagnostics': [{'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] + \ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}] \ }, \ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}}, \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))} From 2ab46d4b8e9611e25cd880ee1f4b4a71b59f0446 Mon Sep 17 00:00:00 2001 From: Dalius Dobravolskas Date: Wed, 23 Sep 2020 16:08:14 +0300 Subject: [PATCH 051/167] Show tsserver hints/suggestions in Ale. --- autoload/ale/lsp_linter.vim | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim index dcd76e8f..6c286f9c 100644 --- a/autoload/ale/lsp_linter.vim +++ b/autoload/ale/lsp_linter.vim @@ -85,12 +85,18 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort endif let l:info.syntax_loclist = l:thislist - else + elseif a:error_type is# 'semantic' if len(l:thislist) is 0 && len(get(l:info, 'semantic_loclist', [])) is 0 let l:no_changes = 1 endif let l:info.semantic_loclist = l:thislist + else + if len(l:thislist) is 0 && len(get(l:info, 'suggestion_loclist', [])) is 0 + let l:no_changes = 1 + endif + + let l:info.suggestion_loclist = l:thislist endif if l:no_changes @@ -98,6 +104,7 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort endif let l:loclist = get(l:info, 'semantic_loclist', []) + \ + get(l:info, 'suggestion_loclist', []) \ + get(l:info, 'syntax_loclist', []) call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0) @@ -150,6 +157,9 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort elseif get(a:response, 'type', '') is# 'event' \&& get(a:response, 'event', '') is# 'syntaxDiag' call s:HandleTSServerDiagnostics(a:response, 'syntax') + elseif get(a:response, 'type', '') is# 'event' + \&& get(a:response, 'event', '') is# 'suggestionDiag' + call s:HandleTSServerDiagnostics(a:response, 'suggestion') endif endfunction From c098a07d67090442164b4bca82ebbedae992bf50 Mon Sep 17 00:00:00 2001 From: Dalius Dobravolskas Date: Wed, 23 Sep 2020 16:24:45 +0300 Subject: [PATCH 052/167] Tests added. --- ...redundant_tsserver_rendering_avoided.vader | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/test_redundant_tsserver_rendering_avoided.vader b/test/test_redundant_tsserver_rendering_avoided.vader index 6125ebc2..12897da4 100644 --- a/test/test_redundant_tsserver_rendering_avoided.vader +++ b/test/test_redundant_tsserver_rendering_avoided.vader @@ -138,3 +138,31 @@ Execute(Non-empty then non-empty semantic errors should be handled): call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', 'x')) Assert g:ale_handle_loclist_called + +Execute(Subsequent empty lists should be ignored): + let g:ale_buffer_info[bufnr('')].suggestion_loclist [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(Empty then non-empty semantic errors should be handled): + let g:ale_buffer_info[bufnr('')].suggestion_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then empty semantic errors should be handled): + let g:ale_buffer_info[bufnr('')].suggestion_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', '')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then non-empty semantic errors should be handled): + let g:ale_buffer_info[bufnr('')].suggestion_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', 'x')) + + Assert g:ale_handle_loclist_called From 17c0c3c731ddf543161195fa55b73721a3bf490d Mon Sep 17 00:00:00 2001 From: Dalius Dobravolskas Date: Wed, 23 Sep 2020 16:35:47 +0300 Subject: [PATCH 053/167] Test fix. --- test/test_redundant_tsserver_rendering_avoided.vader | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test_redundant_tsserver_rendering_avoided.vader b/test/test_redundant_tsserver_rendering_avoided.vader index 12897da4..bde5d152 100644 --- a/test/test_redundant_tsserver_rendering_avoided.vader +++ b/test/test_redundant_tsserver_rendering_avoided.vader @@ -111,7 +111,7 @@ Execute(An initial list of semantic errors should be handled): Assert g:ale_handle_loclist_called -Execute(Subsequent empty lists should be ignored): +Execute(Subsequent empty lists should be ignored - semantic): let g:ale_buffer_info[bufnr('')].semantic_loclist = [] call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', '')) @@ -139,28 +139,28 @@ Execute(Non-empty then non-empty semantic errors should be handled): Assert g:ale_handle_loclist_called -Execute(Subsequent empty lists should be ignored): - let g:ale_buffer_info[bufnr('')].suggestion_loclist [] +Execute(Subsequent empty lists should be ignored - suggestion): + let g:ale_buffer_info[bufnr('')].suggestion_loclist = [] call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', '')) Assert !g:ale_handle_loclist_called -Execute(Empty then non-empty semantic errors should be handled): +Execute(Empty then non-empty suggestion messages should be handled): let g:ale_buffer_info[bufnr('')].suggestion_loclist = [] call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', 'x')) Assert g:ale_handle_loclist_called -Execute(Non-empty then empty semantic errors should be handled): +Execute(Non-empty then empt suggestion messages should be handled): let g:ale_buffer_info[bufnr('')].suggestion_loclist = CreateLoclist('x') call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', '')) Assert g:ale_handle_loclist_called -Execute(Non-empty then non-empty semantic errors should be handled): +Execute(Non-empty then non-empty suggestion messages should be handled): let g:ale_buffer_info[bufnr('')].suggestion_loclist = CreateLoclist('x') call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', 'x')) From 81d16823a7ff5972d2a352831053f3cd6922b6c3 Mon Sep 17 00:00:00 2001 From: Dalius Dobravolskas Date: Sun, 25 Oct 2020 21:58:22 +0200 Subject: [PATCH 054/167] Settings to control suggestions. --- autoload/ale/lsp_linter.vim | 1 + doc/ale.txt | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim index 6c286f9c..628dde78 100644 --- a/autoload/ale/lsp_linter.vim +++ b/autoload/ale/lsp_linter.vim @@ -159,6 +159,7 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort call s:HandleTSServerDiagnostics(a:response, 'syntax') elseif get(a:response, 'type', '') is# 'event' \&& get(a:response, 'event', '') is# 'suggestionDiag' + \&& get(g:, 'ale_lsp_suggestions', '1') == 1 call s:HandleTSServerDiagnostics(a:response, 'suggestion') endif endfunction diff --git a/doc/ale.txt b/doc/ale.txt index 20baf355..3b72cac7 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1677,6 +1677,15 @@ g:ale_lsp_show_message_severity *g:ale_lsp_show_message_severity* `'disabled'` - Doesn't display any information at all. +g:ale_lsp_suggestions *g:ale_lsp_suggestions* + + Type: |Number| + Default: 1 + + This variable defines if suggestions must be collected from LSP or tsserver + and shown. + + g:ale_lsp_root *g:ale_lsp_root* *b:ale_lsp_root* From e5d16caebe8a57074ee52d9bf0c0334fba4106a9 Mon Sep 17 00:00:00 2001 From: zandr <7629614+deathlyfrantic@users.noreply.github.com> Date: Sat, 21 Nov 2020 10:59:50 -0500 Subject: [PATCH 055/167] Add luafmt fixer (#3289) --- autoload/ale/fix/registry.vim | 5 +++ autoload/ale/fixers/luafmt.vim | 13 ++++++++ doc/ale-lua.txt | 16 +++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + test/fixers/test_luafmt_fixer_callback.vader | 35 ++++++++++++++++++++ test/lua_files/testfile.lua | 0 8 files changed, 72 insertions(+) create mode 100644 autoload/ale/fixers/luafmt.vim create mode 100644 test/fixers/test_luafmt_fixer_callback.vader create mode 100644 test/lua_files/testfile.lua diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index d71668f2..9ea5331b 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -375,6 +375,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['html', 'htmldjango'], \ 'description': 'Fix HTML files with html-beautify.', \ }, +\ 'luafmt': { +\ 'function': 'ale#fixers#luafmt#Fix', +\ 'suggested_filetypes': ['lua'], +\ 'description': 'Fix Lua files with luafmt.', +\ }, \ 'dhall': { \ 'function': 'ale#fixers#dhall#Fix', \ 'suggested_filetypes': ['dhall'], diff --git a/autoload/ale/fixers/luafmt.vim b/autoload/ale/fixers/luafmt.vim new file mode 100644 index 00000000..6cb9ef4a --- /dev/null +++ b/autoload/ale/fixers/luafmt.vim @@ -0,0 +1,13 @@ +call ale#Set('lua_luafmt_executable', 'luafmt') +call ale#Set('lua_luafmt_options', '') + +function! ale#fixers#luafmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'lua_luafmt_executable') + let l:options = ale#Var(a:buffer, 'lua_luafmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' --stdin', + \} +endfunction diff --git a/doc/ale-lua.txt b/doc/ale-lua.txt index f1286f89..408f0c3c 100644 --- a/doc/ale-lua.txt +++ b/doc/ale-lua.txt @@ -30,5 +30,21 @@ g:ale_lua_luacheck_options *g:ale_lua_luacheck_options* This variable can be set to pass additional options to luacheck. +=============================================================================== +luafmt *ale-lua-luafmt* + +g:ale_lua_luafmt_executable *g:ale_lua_luafmt_executable* + *b:ale_lua_luafmt_executable* + Type: |String| + Default: `'luafmt'` + + This variable can be set to use a different executable for luafmt. + +g:ale_lua_luafmt_options *g:ale_lua_luafmt_options* + *b:ale_lua_luafmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the luafmt fixer. =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index ba96c37c..b95c3a9b 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -266,6 +266,7 @@ Notes: * Lua * `luac` * `luacheck` + * `luafmt` * Mail * `alex`!! * `languagetool`!! diff --git a/doc/ale.txt b/doc/ale.txt index fdd95ace..1a2938ee 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2744,6 +2744,7 @@ documented in additional help files. lua.....................................|ale-lua-options| luac..................................|ale-lua-luac| luacheck..............................|ale-lua-luacheck| + luafmt................................|ale-lua-luafmt| markdown................................|ale-markdown-options| markdownlint..........................|ale-markdown-markdownlint| mdl...................................|ale-markdown-mdl| diff --git a/supported-tools.md b/supported-tools.md index cf7ee25a..4567bf10 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -275,6 +275,7 @@ formatting. * Lua * [luac](https://www.lua.org/manual/5.1/luac.html) * [luacheck](https://github.com/mpeterv/luacheck) + * [luafmt](https://github.com/trixnz/lua-fmt) * Mail * [alex](https://github.com/wooorm/alex) :floppy_disk: * [languagetool](https://languagetool.org/) :floppy_disk: diff --git a/test/fixers/test_luafmt_fixer_callback.vader b/test/fixers/test_luafmt_fixer_callback.vader new file mode 100644 index 00000000..362da118 --- /dev/null +++ b/test/fixers/test_luafmt_fixer_callback.vader @@ -0,0 +1,35 @@ +Before: + Save g:ale_lua_luafmt_executable + Save g:ale_lua_luafmt_options + + " Use an invalid global executable, so we don't match it. + let g:ale_lua_luafmt_executable = 'xxxinvalid' + let g:ale_lua_luafmt_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The luafmt callback should return the correct default values): + call ale#test#SetFilename('../lua_files/testfile.lua') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') . ' --stdin', + \ }, + \ ale#fixers#luafmt#Fix(bufnr('')) + +Execute(The luafmt callback should include custom luafmt options): + let g:ale_lua_luafmt_options = "--skip-children" + call ale#test#SetFilename('../lua_files/testfile.lua') + + AssertEqual + \ { + \ 'command': ale#Escape('xxxinvalid') + \ . ' ' . g:ale_lua_luafmt_options + \ . ' --stdin', + \ }, + \ ale#fixers#luafmt#Fix(bufnr('')) diff --git a/test/lua_files/testfile.lua b/test/lua_files/testfile.lua new file mode 100644 index 00000000..e69de29b From 342e5af4e367e225eb1c96cb0ecb4a211c2a4f8e Mon Sep 17 00:00:00 2001 From: w0rp Date: Sat, 21 Nov 2020 16:19:56 +0000 Subject: [PATCH 056/167] Add a missing blank line in documentation --- doc/ale.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/ale.txt b/doc/ale.txt index 95634171..71caf0e5 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1694,6 +1694,7 @@ g:ale_lsp_root *g:ale_lsp_root* If neither variable yields a result, a linter-specific function is invoked to detect a project root. If this, too, yields no result, the linter is disabled. + g:ale_max_buffer_history_size *g:ale_max_buffer_history_size* Type: |Number| From 06e7f2195ef6375be32a63f98b5e46070708a315 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sat, 21 Nov 2020 19:00:53 +0000 Subject: [PATCH 057/167] Fix #3332 - Modify everything for rename/actions ALE now just modifies every open buffer for rename and actions, and sets up a one-time use BufEnter event to reload buffers that are changed so you don't have to think about what to do with changed buffers. --- autoload/ale/code_action.vim | 42 ++++++++++++++++++++++-------------- autoload/ale/rename.vim | 5 +---- doc/ale.txt | 6 ------ plugin/ale.vim | 2 +- test/test_rename.vader | 6 +++--- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/autoload/ale/code_action.vim b/autoload/ale/code_action.vim index 6b808b34..69d40933 100644 --- a/autoload/ale/code_action.vim +++ b/autoload/ale/code_action.vim @@ -1,28 +1,24 @@ " Author: Jerko Steiner " Description: Code action support for LSP / tsserver +function! ale#code_action#ReloadBuffer() abort + let l:buffer = bufnr('') + + execute 'augroup ALECodeActionReloadGroup' . l:buffer + autocmd! + augroup END + + silent! execute 'augroup! ALECodeActionReloadGroup' . l:buffer + + call ale#util#Execute(':e!') +endfunction + function! ale#code_action#HandleCodeAction(code_action, options) abort let l:current_buffer = bufnr('') let l:changes = a:code_action.changes let l:should_save = get(a:options, 'should_save') - let l:force_save = get(a:options, 'force_save') - let l:safe_changes = [] for l:file_code_edit in l:changes - let l:buf = bufnr(l:file_code_edit.fileName) - - if l:buf != -1 && l:buf != l:current_buffer && getbufvar(l:buf, '&mod') - if !l:force_save - call ale#util#Execute('echom ''Aborting action, file is unsaved''') - - return - endif - else - call add(l:safe_changes, l:file_code_edit) - endif - endfor - - for l:file_code_edit in l:safe_changes call ale#code_action#ApplyChanges( \ l:file_code_edit.fileName, \ l:file_code_edit.textChanges, @@ -161,6 +157,20 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort call setpos('.', [0, l:pos[0], l:pos[1], 0]) endif + + if a:should_save && l:buffer > 0 && !l:is_current_buffer + " Set up a one-time use event that will delete itself to reload the + " buffer next time it's entered to view the changes made to it. + execute 'augroup ALECodeActionReloadGroup' . l:buffer + autocmd! + + execute printf( + \ 'autocmd BufEnter ' + \ . ' call ale#code_action#ReloadBuffer()', + \ l:buffer + \) + augroup END + endif endfunction function! s:UpdateCursor(cursor, start, end, offset) abort diff --git a/autoload/ale/rename.vim b/autoload/ale/rename.vim index 0d074c24..9030618e 100644 --- a/autoload/ale/rename.vim +++ b/autoload/ale/rename.vim @@ -85,7 +85,6 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort \ }, \ { \ 'should_save': 1, - \ 'force_save': get(l:options, 'force_save'), \ }, \) endfunction @@ -118,7 +117,6 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort \ }, \ { \ 'should_save': 1, - \ 'force_save': get(l:options, 'force_save'), \ }, \) endif @@ -177,7 +175,7 @@ function! s:ExecuteRename(linter, options) abort call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) endfunction -function! ale#rename#Execute(options) abort +function! ale#rename#Execute() abort let l:lsp_linters = [] for l:linter in ale#linter#Get(&filetype) @@ -205,7 +203,6 @@ function! ale#rename#Execute(options) abort call s:ExecuteRename(l:lsp_linter, { \ 'old_name': l:old_name, \ 'new_name': l:new_name, - \ 'force_save': get(a:options, 'force_save') is 1, \}) endfor endfunction diff --git a/doc/ale.txt b/doc/ale.txt index 71caf0e5..a64f86f0 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3145,12 +3145,6 @@ ALERename *ALERename* The symbol where the cursor is resting will be the symbol renamed, and a prompt will open to request a new name. - ALE will refuse to complete a rename operation if there are files to modify - which have not yet been saved in Vim. If the command is run with a bang - (`:ALERename!`), all warnings will be suppressed, and files that are still - open in Vim and not saved will be ignored and left in a state where symbols - in those files will not be updated. - ALECodeAction *ALECodeAction* diff --git a/plugin/ale.vim b/plugin/ale.vim index 2398956e..1fde9df1 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -245,7 +245,7 @@ command! -bar ALEComplete :call ale#completion#GetCompletions('ale-manual') command! -bar ALEImport :call ale#completion#Import() " Rename symbols using tsserver and LSP -command! -bar -bang ALERename :call ale#rename#Execute({'force_save': '' is# '!'}) +command! -bar -bang ALERename :call ale#rename#Execute() " Apply code actions to a range. command! -bar -range ALECodeAction :call ale#codefix#Execute() diff --git a/test/test_rename.vader b/test/test_rename.vader index 2e8b746e..5bc655f4 100644 --- a/test/test_rename.vader +++ b/test/test_rename.vader @@ -269,7 +269,7 @@ Execute(tsserver rename requests should be sent): \ }] \ ], \ g:message_list - AssertEqual {'42': {'old_name': 'somelongerline', 'new_name': 'a-new-name', 'force_save': 0}}, + AssertEqual {'42': {'old_name': 'somelongerline', 'new_name': 'a-new-name'}}, \ ale#rename#GetMap() Given python(Some Python file): @@ -470,7 +470,7 @@ Execute(LSP rename requests should be sent): let b:ale_linters = ['pyls'] call setpos('.', [bufnr(''), 1, 5, 0]) - ALERename! + ALERename " We shouldn't register the callback yet. AssertEqual '''''', string(g:Callback) @@ -500,5 +500,5 @@ Execute(LSP rename requests should be sent): \ ], \ g:message_list - AssertEqual {'42': {'old_name': 'foo', 'new_name': 'a-new-name', 'force_save': 1}}, + AssertEqual {'42': {'old_name': 'foo', 'new_name': 'a-new-name'}}, \ ale#rename#GetMap() From a139599d3938b2f4fa5c8a97d3280b5f4f859321 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sat, 21 Nov 2020 20:12:09 +0000 Subject: [PATCH 058/167] Close #2727 - Add a hover-only setting for balloons --- autoload/ale/balloon.vim | 32 ++++++++++++++++++++++++-------- autoload/ale/hover.vim | 8 ++++++-- doc/ale.txt | 9 ++++++++- plugin/ale.vim | 2 +- test/test_hover.vader | 4 ++-- 5 files changed, 41 insertions(+), 14 deletions(-) diff --git a/autoload/ale/balloon.vim b/autoload/ale/balloon.vim index 72f6b91c..8678376f 100644 --- a/autoload/ale/balloon.vim +++ b/autoload/ale/balloon.vim @@ -2,23 +2,39 @@ " Description: balloonexpr support for ALE. function! ale#balloon#MessageForPos(bufnr, lnum, col) abort + let l:set_balloons = ale#Var(a:bufnr, 'set_balloons') + let l:show_problems = 0 + let l:show_hover = 0 + + if l:set_balloons is 1 + let l:show_problems = 1 + let l:show_hover = 1 + elseif l:set_balloons is# 'hover' + let l:show_hover = 1 + endif + " Don't show balloons if they are disabled, or linting is disabled. - if !ale#Var(a:bufnr, 'set_balloons') + if !(l:show_problems || l:show_hover) \|| !g:ale_enabled \|| !getbufvar(a:bufnr, 'ale_enabled', 1) return '' endif - let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist - let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col) + if l:show_problems + let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist + let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col) + endif " Show the diagnostics message if found, 'Hover' output otherwise - if l:index >= 0 + if l:show_problems && l:index >= 0 return l:loclist[l:index].text - elseif exists('*balloon_show') || getbufvar( - \ a:bufnr, - \ 'ale_set_balloons_legacy_echo', - \ get(g:, 'ale_set_balloons_legacy_echo', 0) + elseif l:show_hover && ( + \ exists('*balloon_show') + \ || getbufvar( + \ a:bufnr, + \ 'ale_set_balloons_legacy_echo', + \ get(g:, 'ale_set_balloons_legacy_echo', 0) + \ ) \) " Request LSP/tsserver hover information, but only if this version of " Vim supports the balloon_show function, or if we turned a legacy diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim index 38b4b866..1d38f3b9 100644 --- a/autoload/ale/hover.vim +++ b/autoload/ale/hover.vim @@ -24,6 +24,8 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort if get(a:response, 'success', v:false) is v:true \&& get(a:response, 'body', v:null) isnot v:null + let l:set_balloons = ale#Var(l:options.buffer, 'set_balloons') + " If we pass the show_documentation flag, we should show the full " documentation, and always in the preview window. if get(l:options, 'show_documentation', 0) @@ -40,7 +42,7 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort endif elseif get(l:options, 'hover_from_balloonexpr', 0) \&& exists('*balloon_show') - \&& ale#Var(l:options.buffer, 'set_balloons') + \&& (l:set_balloons is 1 || l:set_balloons is# 'hover') call balloon_show(a:response.body.displayString) elseif get(l:options, 'truncated_echo', 0) call ale#cursor#TruncatedEcho(split(a:response.body.displayString, "\n")[0]) @@ -216,9 +218,11 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort let [l:commands, l:lines] = ale#hover#ParseLSPResult(l:result.contents) if !empty(l:lines) + let l:set_balloons = ale#Var(l:options.buffer, 'set_balloons') + if get(l:options, 'hover_from_balloonexpr', 0) \&& exists('*balloon_show') - \&& ale#Var(l:options.buffer, 'set_balloons') + \&& (l:set_balloons is 1 || l:set_balloons is# 'hover') call balloon_show(join(l:lines, "\n")) elseif get(l:options, 'truncated_echo', 0) call ale#cursor#TruncatedEcho(l:lines[0]) diff --git a/doc/ale.txt b/doc/ale.txt index a64f86f0..195e6f13 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1840,7 +1840,7 @@ g:ale_rename_tsserver_find_in_strings *g:ale_rename_tsserver_find_in_strings* g:ale_set_balloons *g:ale_set_balloons* *b:ale_set_balloons* - Type: |Number| + Type: |Number| or |String| Default: `has('balloon_eval') && has('gui_running')` When this option is set to `1`, balloon messages will be displayed for @@ -1851,6 +1851,13 @@ g:ale_set_balloons *g:ale_set_balloons* supporting "Hover" information, per |ale-hover|, then brief information about the symbol under the cursor will be displayed in a balloon. + This option can be set to `'hover'` to only enable balloons for hover + message, so diagnostics are never shown in balloons. You may wish to + configure use this setting only in GUI Vim like so: > + + let g:ale_set_balloons = has('gui_running') ? 'hover' : 0 +< + Balloons can be enabled for terminal versions of Vim that support balloons, but some versions of Vim will produce strange mouse behavior when balloons are enabled. To configure balloons for your terminal, you should first diff --git a/plugin/ale.vim b/plugin/ale.vim index 1fde9df1..b1abb10a 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -161,7 +161,7 @@ let g:ale_go_go111module = get(g:, 'ale_go_go111module', '') " If 1, enable a popup menu for commands. let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui')) -if g:ale_set_balloons +if g:ale_set_balloons is 1 || g:ale_set_balloons is# 'hover' call ale#balloon#Enable() endif diff --git a/test/test_hover.vader b/test/test_hover.vader index 9689cda2..ed756396 100644 --- a/test/test_hover.vader +++ b/test/test_hover.vader @@ -101,7 +101,7 @@ Execute(tsserver quickinfo responses will null missing bodies should be handled) AssertEqual {}, ale#hover#GetMap() Execute(tsserver quickinfo displayString values should be displayed): - call ale#hover#SetMap({3: {}}) + call ale#hover#SetMap({3: {'buffer': bufnr('')}}) call ale#hover#HandleTSServerResponse( \ 1, \ { @@ -169,7 +169,7 @@ Execute(LSP hover response with lists of strings and marked strings should be ha AssertEqual {}, ale#hover#GetMap() Execute(tsserver responses for documentation requests should be handled): - call ale#hover#SetMap({3: {'show_documentation': 1}}) + call ale#hover#SetMap({3: {'show_documentation': 1, 'buffer': bufnr('')}}) call ale#hover#HandleTSServerResponse( \ 1, From 2e91f0e689362e33ae3172ddf8153c7a7631cdcf Mon Sep 17 00:00:00 2001 From: w0rp Date: Sat, 21 Nov 2020 20:16:32 +0000 Subject: [PATCH 059/167] Use has('gui_running') instead of has('gui') --- doc/ale.txt | 2 +- plugin/ale.vim | 2 +- test/test_lint_on_enter_when_file_changed.vader | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ale.txt b/doc/ale.txt index 195e6f13..e00d5f15 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1806,7 +1806,7 @@ g:ale_pattern_options_enabled *g:ale_pattern_options_enabled* g:ale_popup_menu_enabled *g:ale_popup_menu_enabled* Type: |Number| - Default: `has('gui')` + Default: `has('gui_running')` When this option is set to `1`, ALE will show code actions and rename capabilities in the right click mouse menu when there's a LSP server or diff --git a/plugin/ale.vim b/plugin/ale.vim index b1abb10a..5b7be116 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -159,7 +159,7 @@ let g:ale_python_auto_pipenv = get(g:, 'ale_python_auto_pipenv', 0) let g:ale_go_go111module = get(g:, 'ale_go_go111module', '') " If 1, enable a popup menu for commands. -let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui')) +let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui_running')) if g:ale_set_balloons is 1 || g:ale_set_balloons is# 'hover' call ale#balloon#Enable() diff --git a/test/test_lint_on_enter_when_file_changed.vader b/test/test_lint_on_enter_when_file_changed.vader index 88493005..0d4c4af8 100644 --- a/test/test_lint_on_enter_when_file_changed.vader +++ b/test/test_lint_on_enter_when_file_changed.vader @@ -35,7 +35,7 @@ After: Execute(The file changed event function should set b:ale_file_changed): let g:ale_lint_on_enter = 0 - if has('gui') + if has('gui_running') new else e test From 2873be2d6a5e383edd1fead396a53a8a38eebd76 Mon Sep 17 00:00:00 2001 From: Dale Jung Date: Sat, 21 Nov 2020 15:19:02 -0500 Subject: [PATCH 060/167] Add php phpcbf options (#3383) * Taken from phpcs. add add_php_phpcbf_options #3382 * Updated docs for php_phpcbf_options #3382 * Added tests #3382 --- autoload/ale/fixers/phpcbf.vim | 3 ++- doc/ale-php.txt | 8 ++++++++ test/fixers/test_phpcbf_fixer_callback.vader | 11 +++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/autoload/ale/fixers/phpcbf.vim b/autoload/ale/fixers/phpcbf.vim index f14b8406..0a61c657 100644 --- a/autoload/ale/fixers/phpcbf.vim +++ b/autoload/ale/fixers/phpcbf.vim @@ -2,6 +2,7 @@ " Description: Fixing files with phpcbf. call ale#Set('php_phpcbf_standard', '') +call ale#Set('php_phpcbf_options', '') call ale#Set('php_phpcbf_executable', 'phpcbf') call ale#Set('php_phpcbf_use_global', get(g:, 'ale_use_global_executables', 0)) @@ -20,6 +21,6 @@ function! ale#fixers#phpcbf#Fix(buffer) abort \ : '' return { - \ 'command': ale#Escape(l:executable) . ' --stdin-path=%s ' . l:standard_option . ' -' + \ 'command': ale#Escape(l:executable) . ' --stdin-path=%s ' . l:standard_option . ale#Pad(ale#Var(a:buffer, 'php_phpcbf_options')) . ' -' \} endfunction diff --git a/doc/ale-php.txt b/doc/ale-php.txt index 79d9a033..6da21046 100644 --- a/doc/ale-php.txt +++ b/doc/ale-php.txt @@ -85,6 +85,14 @@ g:ale_php_phpcbf_use_global *g:ale_php_phpcbf_use_global* See |ale-integrations-local-executables| +g:ale_php_phpcbf_options *g:ale_php_phpcbf_options* + *b:ale_php_phpcbf_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to php-cbf + + =============================================================================== phpcs *ale-php-phpcs* diff --git a/test/fixers/test_phpcbf_fixer_callback.vader b/test/fixers/test_phpcbf_fixer_callback.vader index 1663c89c..f7bcc2d8 100644 --- a/test/fixers/test_phpcbf_fixer_callback.vader +++ b/test/fixers/test_phpcbf_fixer_callback.vader @@ -5,6 +5,7 @@ Before: let g:ale_php_phpcbf_executable = 'phpcbf_test' let g:ale_php_phpcbf_standard = '' + let g:ale_php_phpcbf_options = '' let g:ale_php_phpcbf_use_global = 0 call ale#test#SetDirectory('/testplugin/test/fixers') @@ -54,6 +55,15 @@ Execute(The phpcbf callback should include the phpcbf_standard option): \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/php_paths/project-with-phpcbf/vendor/bin/phpcbf')) . ' --stdin-path=%s ' . '--standard=phpcbf_ruleset.xml' . ' -'}, \ ale#fixers#phpcbf#Fix(bufnr('')) +Execute(User provided options should be used): + let g:ale_php_phpcbf_options = '--my-user-provided-option my-value' + call ale#test#SetFilename('php_paths/project-with-phpcbf/foo/test.php') + + AssertEqual + \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/php_paths/project-with-phpcbf/vendor/bin/phpcbf')) . ' --stdin-path=%s ' . ale#Pad('--my-user-provided-option my-value') . ' -'}, + \ ale#fixers#phpcbf#Fix(bufnr('')) + + Before: Save g:ale_php_phpcbf_executable Save g:ale_php_phpcbf_standard @@ -61,6 +71,7 @@ Before: let g:ale_php_phpcbf_executable = 'phpcbf_test' let g:ale_php_phpcbf_standard = '' + let g:ale_php_phpcbf_options = '' let g:ale_php_phpcbf_use_global = 0 call ale#test#SetDirectory('/testplugin/test/fixers') From e1184e31f6ed7907b0fdc51eaf4507af6f22d7d9 Mon Sep 17 00:00:00 2001 From: Jose Soto Date: Sat, 21 Nov 2020 12:29:33 -0800 Subject: [PATCH 061/167] Adds support for Tlint - A Tighten Opinionated PHP Linter (#3291) Co-authored-by: w0rp --- ale_linters/php/tlint.vim | 80 +++++++++++++++++++++++ doc/ale-php.txt | 30 +++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + test/handler/test_tlint_handler.vader | 34 ++++++++++ 6 files changed, 147 insertions(+) create mode 100644 ale_linters/php/tlint.vim create mode 100644 test/handler/test_tlint_handler.vader diff --git a/ale_linters/php/tlint.vim b/ale_linters/php/tlint.vim new file mode 100644 index 00000000..6bba8def --- /dev/null +++ b/ale_linters/php/tlint.vim @@ -0,0 +1,80 @@ +" Author: Jose Soto +" +" Description: Tighten Opinionated PHP Linting +" Website: https://github.com/tightenco/tlint + +call ale#Set('php_tlint_executable', 'tlint') +call ale#Set('php_tlint_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('php_tlint_options', '') + +function! ale_linters#php#tlint#GetProjectRoot(buffer) abort + let l:composer_path = ale#path#FindNearestFile(a:buffer, 'composer.json') + + if !empty(l:composer_path) + return fnamemodify(l:composer_path, ':h') + endif + + let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git') + + return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : '' +endfunction + +function! ale_linters#php#tlint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'php_tlint', [ + \ 'vendor/bin/tlint', + \ 'tlint', + \]) +endfunction + +function! ale_linters#php#tlint#GetCommand(buffer) abort + let l:executable = ale_linters#php#tlint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'php_tlint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' lint %s' +endfunction + +function! ale_linters#php#tlint#Handle(buffer, lines) abort + " Matches against lines like the following: + " + " ! There should be 1 space around `.` concatenations, and additional lines should always start with a `.` + " 22 : ` $something = 'a'.'name';` + " + let l:loop_count = 0 + let l:messages_pattern = '^\! \(.*\)' + let l:output = [] + let l:pattern = '^\(\d\+\) \:' + let l:temp_messages = [] + + for l:message in ale#util#GetMatches(a:lines, l:messages_pattern) + call add(l:temp_messages, l:message) + endfor + + let l:loop_count = 0 + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:num = l:match[1] + let l:text = l:temp_messages[l:loop_count] + + call add(l:output, { + \ 'lnum': l:num, + \ 'col': 0, + \ 'text': l:text, + \ 'type': 'W', + \ 'sub_type': 'style', + \}) + + let l:loop_count += 1 + endfor + + return l:output +endfunction + +call ale#linter#Define('php', { +\ 'name': 'tlint', +\ 'executable': function('ale_linters#php#tlint#GetExecutable'), +\ 'command': function('ale_linters#php#tlint#GetCommand'), +\ 'callback': 'ale_linters#php#tlint#Handle', +\ 'project_root': function('ale_linters#php#tlint#GetProjectRoot'), +\}) diff --git a/doc/ale-php.txt b/doc/ale-php.txt index 6da21046..4ee016fb 100644 --- a/doc/ale-php.txt +++ b/doc/ale-php.txt @@ -251,6 +251,34 @@ g:ale_php_php_executable *g:ale_php_php_executable* This variable sets the executable used for php. + +=============================================================================== +tlint *ale-php-tlint* + +g:ale_php_tlint_executable *g:ale_php_tlint_executable* + *b:ale_php_tlint_executable* + Type: |String| + Default: `'tlint'` + + See |ale-integrations-local-executables| + + +g:ale_php_tlint_use_global *g:ale_php_tlint_use_global* + *b:ale_php_tlint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_php_tlint_options *g:ale_php_tlint_options* + *b:ale_php_tlint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to tlint + + =============================================================================== intelephense *ale-php-intelephense* @@ -277,6 +305,7 @@ g:ale_php_intelephense_use_global *g:ale_php_intelephense_use_global* See: |ale-integrations-local-executables| + g:ale_php_intelephense_config *g:ale_php_intelephense_config* *b:ale_php_intelephense_config* Type: |Dictionary| @@ -286,5 +315,6 @@ g:ale_php_intelephense_config *g:ale_php_intelephense_config* installation docs provided by intelephense (github.com/bmewburn/intelephense -docs). + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 60b53c03..0ca82254 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -337,6 +337,7 @@ Notes: * `phpmd` * `phpstan` * `psalm`!! + * `tlint` * PO * `alex`!! * `msgfmt` diff --git a/doc/ale.txt b/doc/ale.txt index c5de4333..208bda4a 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2805,6 +2805,7 @@ documented in additional help files. psalm.................................|ale-php-psalm| php-cs-fixer..........................|ale-php-php-cs-fixer| php...................................|ale-php-php| + tlint.................................|ale-php-tlint| intelephense..........................|ale-php-intelephense| po......................................|ale-po-options| write-good............................|ale-po-write-good| diff --git a/supported-tools.md b/supported-tools.md index ec49ad19..6f467703 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -346,6 +346,7 @@ formatting. * [phpmd](https://phpmd.org) * [phpstan](https://github.com/phpstan/phpstan) * [psalm](https://getpsalm.org) :floppy_disk: + * [tlint](https://github.com/tightenco/tlint) * PO * [alex](https://github.com/wooorm/alex) :floppy_disk: * [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html) diff --git a/test/handler/test_tlint_handler.vader b/test/handler/test_tlint_handler.vader new file mode 100644 index 00000000..e146346c --- /dev/null +++ b/test/handler/test_tlint_handler.vader @@ -0,0 +1,34 @@ +Before: + runtime ale_linters/php/tlint.vim + +After: + call ale#linter#Reset() + +Execute(The tlint handler should calculate line numbers): + AssertEqual + \ [ + \ { + \ 'lnum': '5', + \ 'col': 0, + \ 'sub_type': + \ 'style', + \ 'type': 'W', + \ 'text': ['! There should be no unused imports.', 'There should be no unused imports.', '', '', '', '', '', '', '', ''] + \ }, + \ { + \ 'lnum': '15', + \ 'col': 0, + \ 'sub_type': + \ 'style', + \ 'type': 'W', + \ 'text': ['! There should be no method visibility in test methods.', 'There should be no method visibility in test methods.', '', '', '', '', '', '', '', ''] + \ }, + \ ], + \ ale_linters#php#tlint#Handle(347, [ + \ "Lints for /Users/jose/Code/Tighten/tester/tests/Unit/ExampleTest.php", + \ "============", + \ "! There should be no unused imports.", + \ "5 : `use Illuminate\Foundation\Testing\RefreshDatabase;`", + \ "! There should be no method visibility in test methods.", + \ "15 : ` public function testBasicTest()`", + \ ]) From b09ccc12c3001b4d551d35cb0c4195793d9b6d10 Mon Sep 17 00:00:00 2001 From: Gabriel Petrovay Date: Sat, 21 Nov 2020 21:32:58 +0100 Subject: [PATCH 062/167] Added the Vundle command in installation instructions (#3400) --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 69ff33ae..438af9b6 100644 --- a/README.md +++ b/README.md @@ -341,12 +341,14 @@ git clone https://github.com/dense-analysis/ale.git ### 3.iii. Installation with Vundle You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.vim) -by using the path on GitHub for this repository. +by adding the GitHub path for this repository to your `~/.vimrc`: ```vim Plugin 'dense-analysis/ale' ``` +Then run the command `:PluginInstall` in Vim. + See the Vundle documentation for more information. @@ -354,13 +356,16 @@ See the Vundle documentation for more information. ### 3.iiii. Installation with Vim-Plug You can install this plugin using [Vim-Plug](https://github.com/junegunn/vim-plug) -by adding the GitHub path for this repository to your `~/.vimrc` -and running `:PlugInstall`. +by adding the GitHub path for this repository to your `~/.vimrc`: ```vim Plug 'dense-analysis/ale' ``` +Then run the command `:PlugInstall` in Vim. + +See the Vim-Plug documentation for more information. + ## 4. Contributing From 5458a1b29167b1fefde5fb6545e371a9d77ca36e Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Sun, 22 Nov 2020 05:49:31 +0900 Subject: [PATCH 063/167] Fix 3103 - add shellcheck shell directive detection. (#3216) * Fix 3103 - add shellcheck shell directive detection. Searches for shellcheck shell directive to detect dialects for scripts that do not have shebang. * Change order of detection of shellcheck dialect In a situation where the filetype can be wrong (example: something.sh which is written in bash dialect) and has no hash-bang (since it is meant to be sourced) then the override specified within the script will be ignored. It probably is the most right thing to do if the script author has added a specific directive; it should trump everything else. Co-authored-by: Horacio Sanson Co-authored-by: Dino Korah --- autoload/ale/handlers/shellcheck.vim | 26 ++++++++++++++- test/test_shell_detection.vader | 48 ++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/autoload/ale/handlers/shellcheck.vim b/autoload/ale/handlers/shellcheck.vim index 351d6d3f..701c43b2 100644 --- a/autoload/ale/handlers/shellcheck.vim +++ b/autoload/ale/handlers/shellcheck.vim @@ -1,8 +1,32 @@ " Author: w0rp " Description: This file adds support for using the shellcheck linter +" Shellcheck supports shell directives to define the shell dialect for scripts +" that do not have a shebang for some reason. +" https://github.com/koalaman/shellcheck/wiki/Directive#shell +function! ale#handlers#shellcheck#GetShellcheckDialectDirective(buffer) abort + let l:linenr = 0 + let l:pattern = '\s\{-}#\s\{-}shellcheck\s\{-}shell=\(.*\)' + let l:possible_shell = ['bash', 'dash', 'ash', 'tcsh', 'csh', 'zsh', 'ksh', 'sh'] + + while l:linenr < min([50, line('$')]) + let l:linenr += 1 + let l:match = matchlist(getline(l:linenr), l:pattern) + + if len(l:match) > 1 && index(l:possible_shell, l:match[1]) >= 0 + return l:match[1] + endif + endwhile + + return '' +endfunction + function! ale#handlers#shellcheck#GetDialectArgument(buffer) abort - let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) + let l:shell_type = ale#handlers#shellcheck#GetShellcheckDialectDirective(a:buffer) + + if empty(l:shell_type) + let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) + endif if !empty(l:shell_type) " Use the dash dialect for /bin/ash, etc. diff --git a/test/test_shell_detection.vader b/test/test_shell_detection.vader index 697054d0..11d801c3 100644 --- a/test/test_shell_detection.vader +++ b/test/test_shell_detection.vader @@ -127,3 +127,51 @@ Execute(The dash dialect should be used for the shell and the base function): Execute(dash should be used for shellcheck): AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a Bash shellcheck shell directive): + # shellcheck shell=bash + +Execute(bash dialect should be detected appropriately): + AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a sh shellcheck shell directive): + #shellcheck shell=sh + +Execute(sh dialect should be detected appropriately): + AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a tcsh shellcheck shell directive): + # shellcheck shell=tcsh + +Execute(tcsh dialect should be detected appropriately): + AssertEqual 'tcsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a zsh shellcheck shell directive): + # shellcheck shell=zsh + +Execute(zsh dialect should be detected appropriately): + AssertEqual 'zsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a csh shellcheck shell directive): + # shellcheck shell=csh + +Execute(zsh dialect should be detected appropriately): + AssertEqual 'csh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a ksh shellcheck shell directive): + # shellcheck shell=ksh + +Execute(ksh dialect should be detected appropriately): + AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a dash shellcheck shell directive): + # shellcheck shell=dash + +Execute(dash dialect should be detected appropriately): + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a ash shellcheck shell directive): + # shellcheck shell=ash + +Execute(dash dialect should be detected for ash that shellcheck does not support): + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) From 9692c0c64c83bb8f67962cf35e7dc3f1757aa8cc Mon Sep 17 00:00:00 2001 From: Eric Zhao <21zhaoe@protonmail.com> Date: Sat, 21 Nov 2020 15:56:38 -0500 Subject: [PATCH 064/167] Add support for R languageserver (#3370) --- ale_linters/r/languageserver.vim | 26 +++++++++++++++++++ doc/ale-r.txt | 23 ++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + test/command_callback/r_paths/.Rprofile | 0 .../test_r_languageserver_callbacks.vader | 22 ++++++++++++++++ 7 files changed, 74 insertions(+) create mode 100644 ale_linters/r/languageserver.vim create mode 100644 test/command_callback/r_paths/.Rprofile create mode 100644 test/command_callback/test_r_languageserver_callbacks.vader diff --git a/ale_linters/r/languageserver.vim b/ale_linters/r/languageserver.vim new file mode 100644 index 00000000..c625d8b4 --- /dev/null +++ b/ale_linters/r/languageserver.vim @@ -0,0 +1,26 @@ +" Author: Eric Zhao <21zhaoe@protonmail.com> +" Description: Implementation of the Language Server Protocol for R. + +call ale#Set('r_languageserver_cmd', 'languageserver::run()') +call ale#Set('r_languageserver_options', {}) + +function! ale_linters#r#languageserver#GetCommand(buffer) abort + let l:cmd_string = ale#Var(a:buffer, 'r_languageserver_cmd') + + return 'Rscript --vanilla -e ' . ale#Escape(l:cmd_string) +endfunction + +function! ale_linters#r#languageserver#GetProjectRoot(buffer) abort + let l:project_root = ale#path#FindNearestFile(a:buffer, '.Rprofile') + + return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : fnamemodify(a:buffer, ':h') +endfunction + +call ale#linter#Define('r', { +\ 'name': 'languageserver', +\ 'lsp': 'stdio', +\ 'lsp_config': {b -> ale#Var(b, 'r_languageserver_options')}, +\ 'executable': 'Rscript', +\ 'command': function('ale_linters#r#languageserver#GetCommand'), +\ 'project_root': function('ale_linters#r#languageserver#GetProjectRoot') +\}) diff --git a/doc/ale-r.txt b/doc/ale-r.txt index b5ccebe5..2078b218 100644 --- a/doc/ale-r.txt +++ b/doc/ale-r.txt @@ -2,6 +2,29 @@ ALE R Integration *ale-r-options* +=============================================================================== +languageserver *ale-r-languageserver* + +g:ale_r_languageserver_cmd *g:ale_r_languageserver_cmd* + *b:ale_r_languageserver_cmd* + Type: |String| + Default: `'languageserver::run()'` + + This option can be configured to change the execution command for + languageserver. + + See the languageserver documentation for more options. + + +g:ale_r_languageserver_options *g:ale_r_languageserver_options* + *b:ale_r_languageserver_options* + Type: |Dictionary| + Default: `{}` + + This option can be configured to change settings for languageserver. See the + languageserver documentation for more information. + + =============================================================================== lintr *ale-r-lintr* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index cc514649..f4673ec0 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -389,6 +389,7 @@ Notes: * `qmlfmt` * `qmllint` * R + * `languageserver` * `lintr` * `styler` * Racket diff --git a/doc/ale.txt b/doc/ale.txt index e8c681f9..00f43aa5 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2854,6 +2854,7 @@ documented in additional help files. qml.....................................|ale-qml-options| qmlfmt................................|ale-qml-qmlfmt| r.......................................|ale-r-options| + languageserver........................|ale-r-languageserver| lintr.................................|ale-r-lintr| styler................................|ale-r-styler| reasonml................................|ale-reasonml-options| diff --git a/supported-tools.md b/supported-tools.md index 70c99a8c..e1ac8873 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -398,6 +398,7 @@ formatting. * [qmlfmt](https://github.com/jesperhh/qmlfmt) * [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) * R + * [languageserver](https://github.com/REditorSupport/languageserver) * [lintr](https://github.com/jimhester/lintr) * [styler](https://github.com/r-lib/styler) * Racket diff --git a/test/command_callback/r_paths/.Rprofile b/test/command_callback/r_paths/.Rprofile new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/test_r_languageserver_callbacks.vader b/test/command_callback/test_r_languageserver_callbacks.vader new file mode 100644 index 00000000..7829165c --- /dev/null +++ b/test/command_callback/test_r_languageserver_callbacks.vader @@ -0,0 +1,22 @@ +Before: + call ale#assert#SetUpLinterTest('r', 'languageserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'Rscript', 'Rscript --vanilla -e ' . ale#Escape('languageserver::run()') + +Execute(The project root should be detected correctly): + AssertLSPProject '.' + + call ale#test#SetFilename('r_paths/dummy/test.R') + + AssertLSPProject ale#path#Simplify(g:dir . '/r_paths') + +Execute(Should accept configuration settings): + AssertLSPConfig {} + + let b:ale_r_languageserver_options = {'r': {'lsp': {'debug': 'true', 'diagnostics': 'true'}}} + + AssertLSPConfig {'r': {'lsp': {'debug': 'true', 'diagnostics': 'true'}}} From 681a6e371d02cce9c2414c19f5deeae61aa321fa Mon Sep 17 00:00:00 2001 From: w0rp Date: Sat, 21 Nov 2020 20:58:34 +0000 Subject: [PATCH 065/167] Use _config for LSP config options --- ale_linters/r/languageserver.vim | 4 ++-- doc/ale-r.txt | 10 +++++----- .../test_r_languageserver_callbacks.vader | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ale_linters/r/languageserver.vim b/ale_linters/r/languageserver.vim index c625d8b4..febe66bd 100644 --- a/ale_linters/r/languageserver.vim +++ b/ale_linters/r/languageserver.vim @@ -2,7 +2,7 @@ " Description: Implementation of the Language Server Protocol for R. call ale#Set('r_languageserver_cmd', 'languageserver::run()') -call ale#Set('r_languageserver_options', {}) +call ale#Set('r_languageserver_config', {}) function! ale_linters#r#languageserver#GetCommand(buffer) abort let l:cmd_string = ale#Var(a:buffer, 'r_languageserver_cmd') @@ -19,7 +19,7 @@ endfunction call ale#linter#Define('r', { \ 'name': 'languageserver', \ 'lsp': 'stdio', -\ 'lsp_config': {b -> ale#Var(b, 'r_languageserver_options')}, +\ 'lsp_config': {b -> ale#Var(b, 'r_languageserver_config')}, \ 'executable': 'Rscript', \ 'command': function('ale_linters#r#languageserver#GetCommand'), \ 'project_root': function('ale_linters#r#languageserver#GetProjectRoot') diff --git a/doc/ale-r.txt b/doc/ale-r.txt index 2078b218..3fabf702 100644 --- a/doc/ale-r.txt +++ b/doc/ale-r.txt @@ -16,8 +16,8 @@ g:ale_r_languageserver_cmd *g:ale_r_languageserver_cmd* See the languageserver documentation for more options. -g:ale_r_languageserver_options *g:ale_r_languageserver_options* - *b:ale_r_languageserver_options* +g:ale_r_languageserver_config *g:ale_r_languageserver_config* + *b:ale_r_languageserver_config* Type: |Dictionary| Default: `{}` @@ -45,7 +45,7 @@ g:ale_r_lintr_lint_package *g:ale_r_lintr_lint_package* Default: `0` When set to `1`, the file will be checked with `lintr::lint_package` instead - of `lintr::lint`. This prevents erroneous namespace warnings when linting + of `lintr::lint`. This prevents erroneous namespace warnings when linting package files. @@ -59,8 +59,8 @@ g:ale_r_styler_options *g:ale_r_styler_options* This option can be configured to change the options for styler. - The value of this option will be used as the `style` argument for the - `styler::style_file` options. Consult the styler documentation + The value of this option will be used as the `style` argument for the + `styler::style_file` options. Consult the styler documentation for more information. diff --git a/test/command_callback/test_r_languageserver_callbacks.vader b/test/command_callback/test_r_languageserver_callbacks.vader index 7829165c..9a4a1f87 100644 --- a/test/command_callback/test_r_languageserver_callbacks.vader +++ b/test/command_callback/test_r_languageserver_callbacks.vader @@ -17,6 +17,6 @@ Execute(The project root should be detected correctly): Execute(Should accept configuration settings): AssertLSPConfig {} - let b:ale_r_languageserver_options = {'r': {'lsp': {'debug': 'true', 'diagnostics': 'true'}}} + let b:ale_r_languageserver_config = {'r': {'lsp': {'debug': 'true', 'diagnostics': 'true'}}} AssertLSPConfig {'r': {'lsp': {'debug': 'true', 'diagnostics': 'true'}}} From 373ffa0f316f14559870fb3903d723c6d88597ee Mon Sep 17 00:00:00 2001 From: Ivor Peles Date: Tue, 6 Oct 2020 02:12:05 -0400 Subject: [PATCH 066/167] Use pipenv isort executable when python_auto_pipenv = 1 --- autoload/ale/fixers/isort.vim | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/autoload/ale/fixers/isort.vim b/autoload/ale/fixers/isort.vim index 9070fb27..926822f2 100644 --- a/autoload/ale/fixers/isort.vim +++ b/autoload/ale/fixers/isort.vim @@ -5,14 +5,23 @@ call ale#Set('python_isort_executable', 'isort') call ale#Set('python_isort_options', '') call ale#Set('python_isort_use_global', get(g:, 'ale_use_global_executables', 0)) +function! ale#fixers#isort#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_isort_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_isort', ['isort']) +endfunction + function! ale#fixers#isort#Fix(buffer) abort let l:options = ale#Var(a:buffer, 'python_isort_options') - let l:executable = ale#python#FindExecutable( - \ a:buffer, - \ 'python_isort', - \ ['isort'], - \) + let l:executable = ale#fixers#isort#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run isort' + \ : '' if !executable(l:executable) return 0 @@ -20,6 +29,7 @@ function! ale#fixers#isort#Fix(buffer) abort return { \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -', + \ . ale#Escape(l:executable) . l:exec_args + \ . (!empty(l:options) ? ' ' . l:options : '') . ' -', \} endfunction From 64471e6ea88cc45dcd33e3a0ca5ee857797985e3 Mon Sep 17 00:00:00 2001 From: Ivor Peles Date: Tue, 6 Oct 2020 02:27:08 -0400 Subject: [PATCH 067/167] Document ale_python_isort_auto_pipenv option --- doc/ale-python.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/ale-python.txt b/doc/ale-python.txt index f0c8bfb8..504705f2 100644 --- a/doc/ale-python.txt +++ b/doc/ale-python.txt @@ -280,6 +280,15 @@ g:ale_python_isort_use_global *g:ale_python_isort_use_global* See |ale-integrations-local-executables| +g:ale_python_isort_auto_pipenv *g:ale_python_isort_auto_pipenv* + *b:ale_python_isort_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + =============================================================================== mypy *ale-python-mypy* From ae86d10e48ae27e08665502772886016c3a3aa3b Mon Sep 17 00:00:00 2001 From: Ivor Peles Date: Tue, 6 Oct 2020 04:00:45 -0400 Subject: [PATCH 068/167] Set default value for python_isort_auto_pipenv --- autoload/ale/fixers/isort.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/autoload/ale/fixers/isort.vim b/autoload/ale/fixers/isort.vim index 926822f2..13825f7e 100644 --- a/autoload/ale/fixers/isort.vim +++ b/autoload/ale/fixers/isort.vim @@ -2,8 +2,9 @@ " Description: Fixing Python imports with isort. call ale#Set('python_isort_executable', 'isort') -call ale#Set('python_isort_options', '') call ale#Set('python_isort_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_isort_options', '') +call ale#Set('python_isort_auto_pipenv', 0) function! ale#fixers#isort#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_isort_auto_pipenv')) From 6efca486e8c228e9358d05e0a87d17e973da249e Mon Sep 17 00:00:00 2001 From: Ivor Peles Date: Tue, 6 Oct 2020 04:06:44 -0400 Subject: [PATCH 069/167] Add test for isort with auto_pipenv flag(s) --- test/fixers/test_isort_fixer_callback.vader | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/fixers/test_isort_fixer_callback.vader b/test/fixers/test_isort_fixer_callback.vader index 7f389dcf..76c8a4cb 100644 --- a/test/fixers/test_isort_fixer_callback.vader +++ b/test/fixers/test_isort_fixer_callback.vader @@ -5,6 +5,7 @@ Before: " Use an invalid global executable, so we don't match it. let g:ale_python_isort_executable = 'xxxinvalid' let g:ale_python_isort_options = '' + let g:ale_python_isort_auto_pipenv = 0 call ale#test#SetDirectory('/testplugin/test/fixers') silent cd .. @@ -48,3 +49,12 @@ Execute(The isort callback should respect custom options): \ . ' --multi-line=3 --trailing-comma -', \ }, \ ale#fixers#isort#Fix(bufnr('')) + +Execute(Pipenv is detected when python_isort_auto_pipenv is set): + let g:ale_python_isort_auto_pipenv = 1 + + call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py') + + AssertEqual + \ {'command': 'cd %s:h && ' . ale#Escape('pipenv') . ' run isort -'}, + \ ale#fixers#isort#Fix(bufnr('')) From d27a3f453cc15e6b801486115ef5693a499efcc3 Mon Sep 17 00:00:00 2001 From: Ivor Peles Date: Tue, 6 Oct 2020 04:07:10 -0400 Subject: [PATCH 070/167] Ignore executable check when executable is pipenv --- autoload/ale/fixers/isort.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ale/fixers/isort.vim b/autoload/ale/fixers/isort.vim index 13825f7e..0ef166e5 100644 --- a/autoload/ale/fixers/isort.vim +++ b/autoload/ale/fixers/isort.vim @@ -24,7 +24,7 @@ function! ale#fixers#isort#Fix(buffer) abort \ ? ' run isort' \ : '' - if !executable(l:executable) + if !executable(l:executable) && l:executable != 'pipenv' return 0 endif From 433b23be17095c0211685ff32e25fcdbfffe2ce7 Mon Sep 17 00:00:00 2001 From: Gonzalo Quero Date: Wed, 2 Sep 2020 13:08:46 +0100 Subject: [PATCH 071/167] feat: Add optional configuration file for Credo --- ale_linters/elixir/credo.vim | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ale_linters/elixir/credo.vim b/ale_linters/elixir/credo.vim index 7c298502..15ebefb5 100644 --- a/ale_linters/elixir/credo.vim +++ b/ale_linters/elixir/credo.vim @@ -45,6 +45,16 @@ function! ale_linters#elixir#credo#GetMode() abort endif endfunction +function! ale_linters#elixir#credo#GetConfigFile() abort + let l:config_file = get(g:, 'ale_elixir_credo_config_file', '') + + if len(l:config_file) == 0 + return '' + else + return ' --config-file ' . l:config_file + endif +endfunction + function! ale_linters#elixir#credo#GetCommand(buffer) abort let l:project_root = ale#handlers#elixir#FindMixUmbrellaRoot(a:buffer) let l:mode = ale_linters#elixir#credo#GetMode() @@ -52,6 +62,7 @@ function! ale_linters#elixir#credo#GetCommand(buffer) abort return ale#path#CdString(l:project_root) \ . 'mix help credo && ' \ . 'mix credo ' . ale_linters#elixir#credo#GetMode() + \ . ale_linters#elixir#credo#GetConfigFile() \ . ' --format=flycheck --read-from-stdin %s' endfunction From 7d8275daf57269df0fb8f32f421344bea6364cb5 Mon Sep 17 00:00:00 2001 From: Gonzalo Quero Date: Wed, 2 Sep 2020 13:39:32 +0100 Subject: [PATCH 072/167] chore: Add Elixir Credo tests --- test/test_elixir_credo.vader | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 test/test_elixir_credo.vader diff --git a/test/test_elixir_credo.vader b/test/test_elixir_credo.vader new file mode 100644 index 00000000..db956683 --- /dev/null +++ b/test/test_elixir_credo.vader @@ -0,0 +1,33 @@ +Before: + call ale#test#SetDirectory('/testplugin/test') + + runtime ale_linters/elixir/credo.vim + +After: + call ale#test#RestoreDirectory() + call ale#linter#Reset() + let g:ale_elixir_credo_strict = 0 + let g:ale_elixir_credo_config_file = '' + +Execute(credo runs the right command): + call ale#test#SetFilename('elixir-test-files/testfile.ex') + + AssertEqual + \ ale_linters#elixir#credo#GetCommand(bufnr('')), + \ 'cd ''.'' && mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(credo runs the right command with the strict flag): + let g:ale_elixir_credo_strict = 1 + call ale#test#SetFilename('elixir-test-files/testfile.ex') + + AssertEqual + \ ale_linters#elixir#credo#GetCommand(bufnr('')), + \ 'cd ''.'' && mix help credo && mix credo --strict --format=flycheck --read-from-stdin %s' + +Execute(credo runs the right command with a custom config file): + let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs' + call ale#test#SetFilename('elixir-test-files/testfile.ex') + + AssertEqual + \ ale_linters#elixir#credo#GetCommand(bufnr('')), + \ 'cd ''.'' && mix help credo && mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s' From 05d5cc49881bfef6cfcdf1f6bcf5771d9a8a4b93 Mon Sep 17 00:00:00 2001 From: Gonzalo Quero Date: Wed, 2 Sep 2020 13:39:51 +0100 Subject: [PATCH 073/167] chore: Document config_file variable --- doc/ale-elixir.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/ale-elixir.txt b/doc/ale-elixir.txt index de9daacf..a4e5c2c6 100644 --- a/doc/ale-elixir.txt +++ b/doc/ale-elixir.txt @@ -85,5 +85,12 @@ g:ale_elixir_credo_strict *g:ale_elixir_credo_strict* Tells credo to run in strict mode or suggest mode. Set variable to 1 to enable --strict mode. +g:ale_elixir_credo_config_file g:ale_elixir_credo_config_file + + Type: String + Default: '' + + Tells credo to use a custom configuration file. + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: From 491ceacb64f7be6c4e36fd6586af22adfd6a309e Mon Sep 17 00:00:00 2001 From: Gonzalo Quero Date: Wed, 2 Sep 2020 14:31:11 +0100 Subject: [PATCH 074/167] fix: Use proper CdPath function in test --- test/test_elixir_credo.vader | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/test_elixir_credo.vader b/test/test_elixir_credo.vader index db956683..78d3e0a6 100644 --- a/test/test_elixir_credo.vader +++ b/test/test_elixir_credo.vader @@ -2,19 +2,21 @@ Before: call ale#test#SetDirectory('/testplugin/test') runtime ale_linters/elixir/credo.vim + let g:test_command_start = ale#path#CdString('.') . 'mix help credo && ' After: call ale#test#RestoreDirectory() call ale#linter#Reset() let g:ale_elixir_credo_strict = 0 let g:ale_elixir_credo_config_file = '' + let g:test_command_start = '' Execute(credo runs the right command): call ale#test#SetFilename('elixir-test-files/testfile.ex') AssertEqual \ ale_linters#elixir#credo#GetCommand(bufnr('')), - \ 'cd ''.'' && mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + \ g:test_command_start . 'mix credo suggest --format=flycheck --read-from-stdin %s' Execute(credo runs the right command with the strict flag): let g:ale_elixir_credo_strict = 1 @@ -22,7 +24,7 @@ Execute(credo runs the right command with the strict flag): AssertEqual \ ale_linters#elixir#credo#GetCommand(bufnr('')), - \ 'cd ''.'' && mix help credo && mix credo --strict --format=flycheck --read-from-stdin %s' + \ g:test_command_start . 'mix credo --strict --format=flycheck --read-from-stdin %s' Execute(credo runs the right command with a custom config file): let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs' @@ -30,4 +32,4 @@ Execute(credo runs the right command with a custom config file): AssertEqual \ ale_linters#elixir#credo#GetCommand(bufnr('')), - \ 'cd ''.'' && mix help credo && mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s' + \ g:test_command_start . 'mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s' From 7e9d4fbfc820ae4198b07b204295fc3acd391209 Mon Sep 17 00:00:00 2001 From: Gonzalo Quero Date: Mon, 23 Nov 2020 10:21:09 +0000 Subject: [PATCH 075/167] refactor: Move test to the right file --- ale_linters/elixir/credo.vim | 6 ++-- test/command_callback/test_elixir_credo.vader | 7 ++++ test/test_elixir_credo.vader | 35 ------------------- 3 files changed, 10 insertions(+), 38 deletions(-) delete mode 100644 test/test_elixir_credo.vader diff --git a/ale_linters/elixir/credo.vim b/ale_linters/elixir/credo.vim index 15ebefb5..892d47b9 100644 --- a/ale_linters/elixir/credo.vim +++ b/ale_linters/elixir/credo.vim @@ -48,11 +48,11 @@ endfunction function! ale_linters#elixir#credo#GetConfigFile() abort let l:config_file = get(g:, 'ale_elixir_credo_config_file', '') - if len(l:config_file) == 0 + if empty(l:config_file) return '' - else - return ' --config-file ' . l:config_file endif + + return ' --config-file ' . l:config_file endfunction function! ale_linters#elixir#credo#GetCommand(buffer) abort diff --git a/test/command_callback/test_elixir_credo.vader b/test/command_callback/test_elixir_credo.vader index 3eb88846..b14444c6 100644 --- a/test/command_callback/test_elixir_credo.vader +++ b/test/command_callback/test_elixir_credo.vader @@ -38,3 +38,10 @@ Execute(Builds credo command with suggest mode when set to 0): AssertLinter 'mix', \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) \ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with a custom config file): + let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs' + + AssertLinter 'mix', + \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) + \ . 'mix help credo && mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s' diff --git a/test/test_elixir_credo.vader b/test/test_elixir_credo.vader deleted file mode 100644 index 78d3e0a6..00000000 --- a/test/test_elixir_credo.vader +++ /dev/null @@ -1,35 +0,0 @@ -Before: - call ale#test#SetDirectory('/testplugin/test') - - runtime ale_linters/elixir/credo.vim - let g:test_command_start = ale#path#CdString('.') . 'mix help credo && ' - -After: - call ale#test#RestoreDirectory() - call ale#linter#Reset() - let g:ale_elixir_credo_strict = 0 - let g:ale_elixir_credo_config_file = '' - let g:test_command_start = '' - -Execute(credo runs the right command): - call ale#test#SetFilename('elixir-test-files/testfile.ex') - - AssertEqual - \ ale_linters#elixir#credo#GetCommand(bufnr('')), - \ g:test_command_start . 'mix credo suggest --format=flycheck --read-from-stdin %s' - -Execute(credo runs the right command with the strict flag): - let g:ale_elixir_credo_strict = 1 - call ale#test#SetFilename('elixir-test-files/testfile.ex') - - AssertEqual - \ ale_linters#elixir#credo#GetCommand(bufnr('')), - \ g:test_command_start . 'mix credo --strict --format=flycheck --read-from-stdin %s' - -Execute(credo runs the right command with a custom config file): - let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs' - call ale#test#SetFilename('elixir-test-files/testfile.ex') - - AssertEqual - \ ale_linters#elixir#credo#GetCommand(bufnr('')), - \ g:test_command_start . 'mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s' From c69d696e1b63c7797e8696f923856d131f02f5e9 Mon Sep 17 00:00:00 2001 From: Lyz Date: Tue, 24 Nov 2020 23:56:30 +0100 Subject: [PATCH 076/167] feat: add yamlfix fixer --- autoload/ale/fix/registry.vim | 5 ++ autoload/ale/fixers/yamlfix.vim | 25 ++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale-yaml.txt | 38 +++++++++++++- doc/ale.txt | 1 + supported-tools.md | 1 + .../with_virtualenv/env/Scripts/yamlfix.exe | 0 .../with_virtualenv/env/bin/yamlfix | 0 test/fixers/test_yamlfix_fixer_callback.vader | 50 +++++++++++++++++++ 9 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 autoload/ale/fixers/yamlfix.vim create mode 100644 test/command_callback/python_paths/with_virtualenv/env/Scripts/yamlfix.exe create mode 100755 test/command_callback/python_paths/with_virtualenv/env/bin/yamlfix create mode 100644 test/fixers/test_yamlfix_fixer_callback.vader diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 3a88ede1..e7c8a6b5 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -110,6 +110,11 @@ let s:default_registry = { \ 'suggested_filetypes': [], \ 'description': 'Remove all trailing whitespace characters at the end of every line.', \ }, +\ 'yamlfix': { +\ 'function': 'ale#fixers#yamlfix#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Fix yaml files with yamlfix.', +\ }, \ 'yapf': { \ 'function': 'ale#fixers#yapf#Fix', \ 'suggested_filetypes': ['python'], diff --git a/autoload/ale/fixers/yamlfix.vim b/autoload/ale/fixers/yamlfix.vim new file mode 100644 index 00000000..966556c9 --- /dev/null +++ b/autoload/ale/fixers/yamlfix.vim @@ -0,0 +1,25 @@ +" Author: lyz-code +" Description: Fixing yaml files with yamlfix. + +call ale#Set('yaml_yamlfix_executable', 'yamlfix') +call ale#Set('yaml_yamlfix_options', '') +call ale#Set('yaml_yamlfix_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#yamlfix#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'yaml_yamlfix_options') + + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'yaml_yamlfix', + \ ['yamlfix'], + \) + + if !executable(l:executable) + return 0 + endif + + return { + \ 'command': ale#path#BufferCdString(a:buffer) + \ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -', + \} +endfunction diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index f4673ec0..36e27932 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -524,6 +524,7 @@ Notes: * YAML * `prettier` * `swaglint` + * `yamlfix` * `yamllint` * YANG * `yang-lsp` diff --git a/doc/ale-yaml.txt b/doc/ale-yaml.txt index c9a12ea1..61bfc139 100644 --- a/doc/ale-yaml.txt +++ b/doc/ale-yaml.txt @@ -15,7 +15,6 @@ Install prettier either globally or locally: > npm install prettier -g # global npm install prettier # local < - =============================================================================== swaglint *ale-yaml-swaglint* @@ -49,6 +48,43 @@ g:ale_yaml_swaglint_use_global *g:ale_yaml_swaglint_use_global* See |ale-integrations-local-executables| +=============================================================================== +yamlfix *ale-yaml-yamlfix* + +Website: https://lyz-code.github.io/yamlfix + + +Installation +------------------------------------------------------------------------------- + +Install yamlfix: > + + pip install yamlfix +< + +Options +------------------------------------------------------------------------------- +g:ale_yaml_yamlfix_executable *g:ale_yaml_yamlfix_executable* + *b:ale_yaml_yamlfix_executable* + Type: |String| + Default: `'yamlfix'` + + See |ale-integrations-local-executables| + + +g:ale_yaml_yamlfix_options *g:ale_yaml_yamlfix_options* + *b:ale_yaml_yamlfix_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to yamlfix. + +g:ale_yaml_yamlfix_use_global *g:ale_yaml_yamlfix_use_global* + *b:ale_yaml_yamlfix_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| =============================================================================== yamllint *ale-yaml-yamllint* diff --git a/doc/ale.txt b/doc/ale.txt index 00f43aa5..f9f40d12 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2971,6 +2971,7 @@ documented in additional help files. yaml....................................|ale-yaml-options| prettier..............................|ale-yaml-prettier| swaglint..............................|ale-yaml-swaglint| + yamlfix...............................|ale-yaml-yamlfix| yamllint..............................|ale-yaml-yamllint| yang....................................|ale-yang-options| yang-lsp..............................|ale-yang-lsp| diff --git a/supported-tools.md b/supported-tools.md index e1ac8873..96ef273b 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -533,6 +533,7 @@ formatting. * YAML * [prettier](https://github.com/prettier/prettier) * [swaglint](https://github.com/byCedric/swaglint) + * [yamlfix](https://lyz-code.github.io/yamlfix) * [yamllint](https://yamllint.readthedocs.io/) * YANG * [yang-lsp](https://github.com/theia-ide/yang-lsp) diff --git a/test/command_callback/python_paths/with_virtualenv/env/Scripts/yamlfix.exe b/test/command_callback/python_paths/with_virtualenv/env/Scripts/yamlfix.exe new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/python_paths/with_virtualenv/env/bin/yamlfix b/test/command_callback/python_paths/with_virtualenv/env/bin/yamlfix new file mode 100755 index 00000000..e69de29b diff --git a/test/fixers/test_yamlfix_fixer_callback.vader b/test/fixers/test_yamlfix_fixer_callback.vader new file mode 100644 index 00000000..3ffda91e --- /dev/null +++ b/test/fixers/test_yamlfix_fixer_callback.vader @@ -0,0 +1,50 @@ +Before: + Save g:ale_python_yamlfix_executable + Save g:ale_python_yamlfix_options + + " Use an invalid global executable, so we don't match it. + let g:ale_python_yamlfix_executable = 'xxxinvalid' + let g:ale_python_yamlfix_options = '' + + call ale#test#SetDirectory('/testplugin/test/fixers') + silent cd .. + silent cd command_callback + let g:dir = getcwd() + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + Restore + + unlet! b:bin_dir + + call ale#test#RestoreDirectory() + +Execute(The yamlfix callback should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#yamlfix#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.yaml') + AssertEqual + \ { + \ 'command': ale#path#BufferCdString(bufnr('')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/yamlfix')) . ' -', + \ }, + \ ale#fixers#yamlfix#Fix(bufnr('')) + +Execute(The yamlfix callback should respect custom options): + let g:ale_yaml_yamlfix_options = '--multi-line=3 --trailing-comma' + + AssertEqual + \ 0, + \ ale#fixers#yamlfix#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.yaml') + AssertEqual + \ { + \ 'command': ale#path#BufferCdString(bufnr('')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/yamlfix')) + \ . ' --multi-line=3 --trailing-comma -', + \ }, + \ ale#fixers#yamlfix#Fix(bufnr('')) From 340e9660556b87fafb4b9665115bbdcf831c9bc3 Mon Sep 17 00:00:00 2001 From: Ivor Peles Date: Wed, 25 Nov 2020 17:34:03 -0500 Subject: [PATCH 077/167] Fix comparison operator --- autoload/ale/fixers/isort.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ale/fixers/isort.vim b/autoload/ale/fixers/isort.vim index 0ef166e5..1ae6f590 100644 --- a/autoload/ale/fixers/isort.vim +++ b/autoload/ale/fixers/isort.vim @@ -24,7 +24,7 @@ function! ale#fixers#isort#Fix(buffer) abort \ ? ' run isort' \ : '' - if !executable(l:executable) && l:executable != 'pipenv' + if !executable(l:executable) && l:executable !=# 'pipenv' return 0 endif From 713e53e3f64520b0501cb5d7b4c525946e6c7783 Mon Sep 17 00:00:00 2001 From: Ivor Peles Date: Wed, 25 Nov 2020 17:51:27 -0500 Subject: [PATCH 078/167] Ensure isort / pipenv test conforms to ALE coding standards --- test/fixers/test_isort_fixer_callback.vader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixers/test_isort_fixer_callback.vader b/test/fixers/test_isort_fixer_callback.vader index 76c8a4cb..3941f6dd 100644 --- a/test/fixers/test_isort_fixer_callback.vader +++ b/test/fixers/test_isort_fixer_callback.vader @@ -56,5 +56,5 @@ Execute(Pipenv is detected when python_isort_auto_pipenv is set): call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py') AssertEqual - \ {'command': 'cd %s:h && ' . ale#Escape('pipenv') . ' run isort -'}, + \ {'command': ale#path#BufferCdString(bufnr('')) . ale#Escape('pipenv') . ' run isort -'}, \ ale#fixers#isort#Fix(bufnr('')) From ce3d891bed18f610beb9117518ef560871ef00a0 Mon Sep 17 00:00:00 2001 From: Ivor Peles Date: Wed, 25 Nov 2020 17:57:40 -0500 Subject: [PATCH 079/167] Use better string comparison operators in isort fixer --- autoload/ale/fixers/isort.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ale/fixers/isort.vim b/autoload/ale/fixers/isort.vim index 1ae6f590..55bb550e 100644 --- a/autoload/ale/fixers/isort.vim +++ b/autoload/ale/fixers/isort.vim @@ -24,7 +24,7 @@ function! ale#fixers#isort#Fix(buffer) abort \ ? ' run isort' \ : '' - if !executable(l:executable) && l:executable !=# 'pipenv' + if !executable(l:executable) && l:executable isnot# 'pipenv' return 0 endif From 12eb8d15234e6f4e77672c29659c29a7c0dcf2fb Mon Sep 17 00:00:00 2001 From: Lyz Date: Thu, 26 Nov 2020 12:42:50 +0100 Subject: [PATCH 080/167] fix: correct suggested filetype for yamlfix --- autoload/ale/fix/registry.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index e7c8a6b5..0f146faa 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -112,7 +112,7 @@ let s:default_registry = { \ }, \ 'yamlfix': { \ 'function': 'ale#fixers#yamlfix#Fix', -\ 'suggested_filetypes': ['python'], +\ 'suggested_filetypes': ['yaml'], \ 'description': 'Fix yaml files with yamlfix.', \ }, \ 'yapf': { From 0a2ad516d4c04a408f6bb0ee26640bf6cd531651 Mon Sep 17 00:00:00 2001 From: fwy Date: Thu, 26 Nov 2020 15:29:23 -0600 Subject: [PATCH 081/167] Fix regexp pattern to work correctly in nvim and vim on windows and linux --- ale_linters/java/checkstyle.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/java/checkstyle.vim b/ale_linters/java/checkstyle.vim index ec7339d1..f00734e0 100644 --- a/ale_linters/java/checkstyle.vim +++ b/ale_linters/java/checkstyle.vim @@ -9,7 +9,7 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort let l:output = [] " modern checkstyle versions - let l:pattern = '\v\[(WARN|ERROR)\] [a-zA-Z]?:?[^:]+:(\d+):(\d+)?:? (.*) \[(.+)\]$' + let l:pattern = '\v\[(WARN|ERROR)\] [a-zA-Z]?:?[^:]+:(\d+):(\d+)?:? (.*) \[(.+)\]' for l:match in ale#util#GetMatches(a:lines, l:pattern) call add(l:output, { From f72e60c12a825f30cf25c585c7876fce1c99099d Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Fri, 27 Nov 2020 20:32:51 -0800 Subject: [PATCH 082/167] Fix check-supported-tools-tables check sed wasn't using -E, so '|' wasn't being handled properly. Seems likely that's sed-implementation specific, so now it runs through docker's sed to support portability. --- test/script/check-supported-tools-tables | 4 ++-- test/script/custom-checks | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/script/check-supported-tools-tables b/test/script/check-supported-tools-tables index f4305707..5817de99 100755 --- a/test/script/check-supported-tools-tables +++ b/test/script/check-supported-tools-tables @@ -22,7 +22,7 @@ done < <( grep '^\*\|^ *\*' doc/ale-supported-languages-and-tools.txt \ | sed -e '1,2d' \ | sed 's/^\* */!/' \ - | sed 's/^ *\* *\|!!\|\^\|(.*)\|`//g' \ + | sed -E 's/^ *\* *|!!|\^|(.*)|`//g' \ | sed 's/ *$//' ) > "$doc_file" @@ -36,7 +36,7 @@ while read -r; do done < <( grep '^\*\|^ *\*' supported-tools.md \ | sed 's/^\* */!/' \ - | sed 's/^ *\* *\|:floppy_disk:\|:warning:\|(.*)\|\[\|\].*\|-n flag//g' \ + | sed -E 's/^ *\* *|:floppy_disk:|:warning:|\(.*\)|\[|\].*|-n flag//g' \ | sed 's/ *$//' ) > "$readme_file" diff --git a/test/script/custom-checks b/test/script/custom-checks index ca9069e4..63d39906 100755 --- a/test/script/custom-checks +++ b/test/script/custom-checks @@ -46,7 +46,9 @@ echo '========================================' echo 'Differences follow:' echo -test/script/check-supported-tools-tables || exit_code=$? +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-supported-tools-tables || exit_code=$? +set +o pipefail echo '========================================' echo 'Look for badly aligned doc tags' From 99f1874e865ba1bfd8e3ae3a06a966b9be677a02 Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Sat, 28 Nov 2020 07:51:02 -0800 Subject: [PATCH 083/167] Add non-busybox grep/sed to Dockerfile Tests need extended regexes from sed and --exclude from grep. --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index a21299e6..397277d9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,8 @@ ENV PACKAGES="\ git \ python \ py-pip \ + grep \ + sed \ " RUN apk --update add $PACKAGES && \ rm -rf /var/cache/apk/* /tmp/* /var/tmp/* From 469af2a73472cd81a475c203cf1175caf1db74a9 Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Sat, 28 Nov 2020 07:55:35 -0800 Subject: [PATCH 084/167] Fix TOC tests Sort order is slightly different than the headings --- doc/ale.txt | 4 ++-- test/script/check-toc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ale.txt b/doc/ale.txt index f9f40d12..5d59aed4 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2956,11 +2956,11 @@ documented in additional help files. hdl-checker...........................|ale-vhdl-hdl-checker| vcom..................................|ale-vhdl-vcom| xvhdl.................................|ale-vhdl-xvhdl| + vim help................................|ale-vim-help-options| + write-good............................|ale-vim-help-write-good| vim.....................................|ale-vim-options| vimls.................................|ale-vim-vimls| vint..................................|ale-vim-vint| - vim help................................|ale-vim-help-options| - write-good............................|ale-vim-help-write-good| vue.....................................|ale-vue-options| prettier..............................|ale-vue-prettier| vls...................................|ale-vue-vls| diff --git a/test/script/check-toc b/test/script/check-toc index 87a61262..7a7705ce 100755 --- a/test/script/check-toc +++ b/test/script/check-toc @@ -35,7 +35,7 @@ sed -n "$toc_start_line,$toc_end_line"p doc/ale.txt \ > "$toc_file" # Get all of the doc files in a natural sorted order. -doc_files="$(/usr/bin/env ls -1v doc | grep ^ale- | sed 's/^/doc\//' | paste -sd ' ' -)" +doc_files="$(/usr/bin/env ls -1 doc | awk '/ale-/' | sed 's/^/doc\//' | paste -sd ' ' -)" # shellcheck disable=SC2086 grep -h '\*ale-.*-options\|^[a-z].*\*ale-.*\*$' $doc_files \ From e300a48e13d5863e8281c5843d1128224f73696d Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Sat, 28 Nov 2020 08:23:06 -0800 Subject: [PATCH 085/167] Fix test/script/check-supported-tools-tables --- doc/ale-supported-languages-and-tools.txt | 24 +++++++++++------------ supported-tools.md | 24 +++++++++++------------ test/script/check-supported-tools-tables | 4 +--- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 36e27932..0a80ef0e 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -49,8 +49,8 @@ Notes: * `astyle` * `ccls` * `clang` (`cc`) - * `clangd` * `clang-format` + * `clangd` * `clangtidy`!! * `cppcheck` * `cpplint`!! @@ -67,9 +67,9 @@ Notes: * `astyle` * `ccls` * `clang` (`cc`) + * `clang-format` * `clangcheck`!! * `clangd` - * `clang-format` * `clangtidy`!! * `clazy`!! * `cppcheck` @@ -140,9 +140,9 @@ Notes: * `erubis` * `ruumba` * Erlang + * `SyntaxErl` * `elvis`!! * `erlc` - * `SyntaxErl` * Fish * `fish` (-n flag) * Fortran @@ -160,17 +160,17 @@ Notes: * Go * `bingo` * `go build`!! + * `go mod`!! + * `go vet`!! * `gofmt` * `goimports` * `golangci-lint`!! * `golangserver` * `golint` * `gometalinter`!! - * `go mod`!! * `gopls` * `gosimple`!! * `gotype`!! - * `go vet`!! * `revive`!! * `staticcheck`!! * GraphQL @@ -203,10 +203,10 @@ Notes: * HCL * `terraform-fmt` * HTML + * `HTMLHint` * `alex`!! * `fecs` * `html-beautify` - * `HTMLHint` * `prettier` * `proselint` * `tidy` @@ -218,12 +218,12 @@ Notes: * ISPC * `ispc`!! * Java + * `PMD` * `checkstyle` * `eclipselsp` * `google-java-format` * `javac` * `javalsp` - * `PMD` * `uncrustify` * JavaScript * `eslint` @@ -330,10 +330,10 @@ Notes: * `intelephense` * `langserver` * `phan` + * `php -l` + * `php-cs-fixer` * `phpcbf` * `phpcs` - * `php-cs-fixer` - * `php -l` * `phpmd` * `phpstan` * `psalm`!! @@ -394,6 +394,8 @@ Notes: * `styler` * Racket * `raco` +* Re:VIEW + * `redpen` * ReasonML * `merlin` * `ols` @@ -407,8 +409,6 @@ Notes: * `textlint` * `vale` * `write-good` -* Re:VIEW - * `redpen` * RPM spec * `rpmlint` * Ruby @@ -453,10 +453,10 @@ Notes: * `solium` * SQL * `pgformatter` + * `sql-lint` * `sqlfmt` * `sqlformat` * `sqlint` - * `sql-lint` * Stylus * `stylelint` * SugarSS diff --git a/supported-tools.md b/supported-tools.md index 96ef273b..1c399829 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -58,8 +58,8 @@ formatting. * [astyle](http://astyle.sourceforge.net/) * [ccls](https://github.com/MaskRay/ccls) * [clang](http://clang.llvm.org/) - * [clangd](https://clang.llvm.org/extra/clangd.html) * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) + * [clangd](https://clang.llvm.org/extra/clangd.html) * [clangtidy](http://clang.llvm.org/extra/clang-tidy/) :floppy_disk: * [cppcheck](http://cppcheck.sourceforge.net) * [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) @@ -76,9 +76,9 @@ formatting. * [astyle](http://astyle.sourceforge.net/) * [ccls](https://github.com/MaskRay/ccls) * [clang](http://clang.llvm.org/) + * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) * [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) :floppy_disk: * [clangd](https://clang.llvm.org/extra/clangd.html) - * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) * [clangtidy](http://clang.llvm.org/extra/clang-tidy/) :floppy_disk: * [clazy](https://github.com/KDE/clazy) :floppy_disk: * [cppcheck](http://cppcheck.sourceforge.net) @@ -149,9 +149,9 @@ formatting. * [erubis](https://github.com/kwatch/erubis) * [ruumba](https://github.com/ericqweinstein/ruumba) * Erlang + * [SyntaxErl](https://github.com/ten0s/syntaxerl) * [elvis](https://github.com/inaka/elvis) :floppy_disk: * [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 @@ -169,17 +169,17 @@ formatting. * Go * [bingo](https://github.com/saibing/bingo) :warning: * [go build](https://golang.org/cmd/go/) :warning: :floppy_disk: + * [go mod](https://golang.org/cmd/go/) :warning: :floppy_disk: + * [go vet](https://golang.org/cmd/vet/) :floppy_disk: * [gofmt](https://golang.org/cmd/gofmt/) * [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports) :warning: * [golangci-lint](https://github.com/golangci/golangci-lint) :warning: :floppy_disk: * [golangserver](https://github.com/sourcegraph/go-langserver) :warning: * [golint](https://godoc.org/github.com/golang/lint) * [gometalinter](https://github.com/alecthomas/gometalinter) :warning: :floppy_disk: - * [go mod](https://golang.org/cmd/go/) :warning: :floppy_disk: * [gopls](https://github.com/golang/go/wiki/gopls) :warning: * [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) :warning: :floppy_disk: * [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) :warning: :floppy_disk: - * [go vet](https://golang.org/cmd/vet/) :floppy_disk: * [revive](https://github.com/mgechev/revive) :warning: :floppy_disk: * [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) :warning: :floppy_disk: * GraphQL @@ -212,10 +212,10 @@ formatting. * HCL * [terraform-fmt](https://github.com/hashicorp/terraform) * HTML + * [HTMLHint](http://htmlhint.com/) * [alex](https://github.com/wooorm/alex) :floppy_disk: * [fecs](http://fecs.baidu.com/) * [html-beautify](https://beautifier.io/) - * [HTMLHint](http://htmlhint.com/) * [prettier](https://github.com/prettier/prettier) * [proselint](http://proselint.com/) * [tidy](http://www.html-tidy.org/) @@ -227,12 +227,12 @@ formatting. * ISPC * [ispc](https://ispc.github.io/) :floppy_disk: * Java + * [PMD](https://pmd.github.io/) * [checkstyle](http://checkstyle.sourceforge.net) * [eclipselsp](https://github.com/eclipse/eclipse.jdt.ls) * [google-java-format](https://github.com/google/google-java-format) * [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html) * [javalsp](https://github.com/georgewfraser/vscode-javac) - * [PMD](https://pmd.github.io/) * [uncrustify](https://github.com/uncrustify/uncrustify) * JavaScript * [eslint](http://eslint.org/) @@ -339,10 +339,10 @@ formatting. * [intelephense](https://github.com/bmewburn/intelephense-docs) * [langserver](https://github.com/felixfbecker/php-language-server) * [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions + * [php -l](https://secure.php.net/) + * [php-cs-fixer](http://cs.sensiolabs.org/) * [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer) * [phpcs](https://github.com/squizlabs/PHP_CodeSniffer) - * [php-cs-fixer](http://cs.sensiolabs.org/) - * [php -l](https://secure.php.net/) * [phpmd](https://phpmd.org) * [phpstan](https://github.com/phpstan/phpstan) * [psalm](https://getpsalm.org) :floppy_disk: @@ -403,6 +403,8 @@ formatting. * [styler](https://github.com/r-lib/styler) * Racket * [raco](https://docs.racket-lang.org/raco/) +* Re:VIEW + * [redpen](http://redpen.cc/) * ReasonML * [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions * [ols](https://github.com/freebroccolo/ocaml-language-server) @@ -416,8 +418,6 @@ formatting. * [textlint](https://textlint.github.io/) * [vale](https://github.com/ValeLint/vale) * [write-good](https://github.com/btford/write-good) -* Re:VIEW - * [redpen](http://redpen.cc/) * RPM spec * [rpmlint](https://github.com/rpm-software-management/rpmlint) :warning: (see `:help ale-integration-spec`) * Ruby @@ -462,10 +462,10 @@ formatting. * [solium](https://github.com/duaraghav8/Solium) * SQL * [pgformatter](https://github.com/darold/pgFormatter) + * [sql-lint](https://github.com/joereynolds/sql-lint) * [sqlfmt](https://github.com/jackc/sqlfmt) * [sqlformat](https://github.com/andialbrecht/sqlparse) * [sqlint](https://github.com/purcell/sqlint) - * [sql-lint](https://github.com/joereynolds/sql-lint) * Stylus * [stylelint](https://github.com/stylelint/stylelint) * SugarSS diff --git a/test/script/check-supported-tools-tables b/test/script/check-supported-tools-tables index 5817de99..d238e77f 100755 --- a/test/script/check-supported-tools-tables +++ b/test/script/check-supported-tools-tables @@ -15,14 +15,13 @@ while read -r; do if [[ "$REPLY" =~ ^! ]]; then language="${REPLY/!/}" else - # shellcheck disable=SC2001 echo "$language - $REPLY" fi done < <( grep '^\*\|^ *\*' doc/ale-supported-languages-and-tools.txt \ | sed -e '1,2d' \ | sed 's/^\* */!/' \ - | sed -E 's/^ *\* *|!!|\^|(.*)|`//g' \ + | sed -E 's/^ *\* *|!!|\^|\(.*\)|`//g' \ | sed 's/ *$//' ) > "$doc_file" @@ -30,7 +29,6 @@ while read -r; do if [[ "$REPLY" =~ ^! ]]; then language="${REPLY/!/}" else - # shellcheck disable=SC2001 echo "$language - $REPLY" fi done < <( From d52dce2e6f9ed23103e8d32d41de46c6d9b6717c Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Sat, 28 Nov 2020 08:25:27 -0800 Subject: [PATCH 086/167] Use docker image for custom-check scripts NOTE: The custom-linting-rules test fails due to the following (legit) warnings: ale_linters/clojure/clj_kondo.vim:29 Use snake_case names for linters ale_linters/elixir/elixir_ls.vim:15 Use snake_case names for linters ale_linters/go/golangci_lint.vim:54 Use snake_case names for linters ale_linters/swift/swiftformat.vim:56 Use snake_case names for linters The message wasn't getting printed because docker was explicitly only being asked to connect stdout (ignoring stderr). Unclear yet why the error code wasn't getting bubbled up. --- test/script/check-duplicate-tags | 5 +++++ test/script/check-tag-alignment | 11 +++++++++++ test/script/check-tag-references | 22 ++++++++++++++++++++++ test/script/custom-checks | 30 ++++++++++++++---------------- 4 files changed, 52 insertions(+), 16 deletions(-) create mode 100755 test/script/check-duplicate-tags create mode 100755 test/script/check-tag-alignment create mode 100755 test/script/check-tag-references diff --git a/test/script/check-duplicate-tags b/test/script/check-duplicate-tags new file mode 100755 index 00000000..ec1de788 --- /dev/null +++ b/test/script/check-duplicate-tags @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +grep --exclude=tags -roh '\*.*\*$' doc | sort | uniq -d diff --git a/test/script/check-tag-alignment b/test/script/check-tag-alignment new file mode 100755 index 00000000..d41db160 --- /dev/null +++ b/test/script/check-tag-alignment @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +exit_code=0 + +# Documentation tags need to be aligned to the right margin, so look for +# tags which aren't at the right margin. +grep ' \*[^*]\+\*$' doc/ -r \ + | awk '{ sep = index($0, ":"); if (length(substr($0, sep + 1 )) < 79) { print } }' \ + | grep . && exit_code=1 + +exit $exit_code diff --git a/test/script/check-tag-references b/test/script/check-tag-references new file mode 100755 index 00000000..45e741fb --- /dev/null +++ b/test/script/check-tag-references @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -e + +exit_code=0 +tag_regex='[gb]\?:\?\(ale\|ALE\)[a-zA-Z_\-]\+' + +tags="$(mktemp -t tags.XXXXXXXX)" +refs="$(mktemp -t refs.XXXXXXXX)" +# Grep for tags and references, and complain if we find a reference without +# a tag for the reference. Only our tags will be included. +grep --exclude=tags -roh "\\*$tag_regex\\*" doc | sed 's/*//g' | sort -u > "$tags" +grep --exclude=tags -roh "|$tag_regex|" doc | sed 's/|//g' | sort -u > "$refs" + +exit_code=0 + +if ! [[ $(comm -23 $refs $tags | wc -l) -eq 0 ]]; then + exit_code=1 +fi + +rm "$tags" +rm "$refs" diff --git a/test/script/custom-checks b/test/script/custom-checks index 63d39906..83afb28c 100755 --- a/test/script/custom-checks +++ b/test/script/custom-checks @@ -13,7 +13,7 @@ echo 'Custom warnings/errors follow:' echo set -o pipefail -docker run -a stdout "${docker_flags[@]}" test/script/custom-linting-rules . || exit_code=$? +docker run "${docker_flags[@]}" test/script/custom-linting-rules . || exit_code=$? set +o pipefail echo @@ -23,7 +23,10 @@ echo '========================================' echo 'Duplicate tags follow:' echo -grep --exclude=tags -roh '\*.*\*$' doc | sort | uniq -d || exit_code=$? +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-duplicate-tags . || exit_code=$? +set +o pipefail +echo echo '========================================' echo 'Checking for invalid tag references' @@ -31,14 +34,9 @@ echo '========================================' echo 'Invalid tag references tags follow:' echo -tag_regex='[gb]\?:\?\(ale\|ALE\)[a-zA-Z_\-]\+' - -# Grep for tags and references, and complain if we find a reference without -# a tag for the reference. Only our tags will be included. -diff -u \ - <(grep --exclude=tags -roh "\\*$tag_regex\\*" doc | sort -u | sed 's/*//g') \ - <(grep --exclude=tags -roh "|$tag_regex|" doc | sort -u | sed 's/|//g') \ - | grep '^+[^+]' && exit_code=1 +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-tag-references || exit_code=$? +set +o pipefail echo '========================================' echo 'diff supported-tools.md and doc/ale-supported-languages-and-tools.txt tables' @@ -56,18 +54,18 @@ echo '========================================' echo 'Badly aligned tags follow:' echo -# Documentation tags need to be aligned to the right margin, so look for -# tags which aren't at the right margin. -grep ' \*[^*]\+\*$' doc/ -r \ - | awk '{ sep = index($0, ":"); if (length(substr($0, sep + 1 )) < 79) { print } }' \ - | grep . && exit_code=1 +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-tag-alignment || exit_code=$? +set +o pipefail echo '========================================' echo 'Look for table of contents issues' echo '========================================' echo -test/script/check-toc || exit_code=$? +set -o pipefail +docker run "${docker_flags[@]}" test/script/check-toc || exit_code=$? +set +o pipefail echo '========================================' echo 'Check Python code' From 6b0250a843523810cc7c17db2dbffd582ba115df Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Sat, 28 Nov 2020 09:05:06 -0800 Subject: [PATCH 087/167] Use akevinclark/ale for the updated docker image --- run-tests | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run-tests b/run-tests index 1d452a72..cbd03af2 100755 --- a/run-tests +++ b/run-tests @@ -9,8 +9,8 @@ set -u # options, or read the output below. # -image=w0rp/ale -current_image_id=f58c7bf8900f +image=akevinclark/ale +current_image_id=8e1802ca34b5 # Used in all test scripts for running the selected Docker image. DOCKER_RUN_IMAGE="$image" From 65b09cfa9d6f3b0e11d6b2337846215769910f45 Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Sat, 28 Nov 2020 09:20:50 -0800 Subject: [PATCH 088/167] Restore use of grep in check-toc --- test/script/check-toc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/script/check-toc b/test/script/check-toc index 7a7705ce..f6a80778 100755 --- a/test/script/check-toc +++ b/test/script/check-toc @@ -35,7 +35,7 @@ sed -n "$toc_start_line,$toc_end_line"p doc/ale.txt \ > "$toc_file" # Get all of the doc files in a natural sorted order. -doc_files="$(/usr/bin/env ls -1 doc | awk '/ale-/' | sed 's/^/doc\//' | paste -sd ' ' -)" +doc_files="$(/usr/bin/env ls -1 doc | grep '^ale-' | sed 's/^/doc\//' | paste -sd ' ' -)" # shellcheck disable=SC2086 grep -h '\*ale-.*-options\|^[a-z].*\*ale-.*\*$' $doc_files \ From 84c95aff9b9138a7ae571c40330e84dd822c1f9a Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Sat, 28 Nov 2020 09:44:19 -0800 Subject: [PATCH 089/167] Restore ls -v flag to check-toc --- test/script/check-toc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/script/check-toc b/test/script/check-toc index f6a80778..f3f8a9ea 100755 --- a/test/script/check-toc +++ b/test/script/check-toc @@ -35,7 +35,7 @@ sed -n "$toc_start_line,$toc_end_line"p doc/ale.txt \ > "$toc_file" # Get all of the doc files in a natural sorted order. -doc_files="$(/usr/bin/env ls -1 doc | grep '^ale-' | sed 's/^/doc\//' | paste -sd ' ' -)" +doc_files="$(/usr/bin/env ls -1v doc | grep '^ale-' | sed 's/^/doc\//' | paste -sd ' ' -)" # shellcheck disable=SC2086 grep -h '\*ale-.*-options\|^[a-z].*\*ale-.*\*$' $doc_files \ From 3f01cc247c200850046f59676b0dfead22986f9b Mon Sep 17 00:00:00 2001 From: "D. Ben Knoble" Date: Mon, 30 Nov 2020 13:28:04 -0500 Subject: [PATCH 090/167] dafny: add a timeLimit option and message-parsing --- ale_linters/dafny/dafny.vim | 17 ++++++++++++++++- doc/ale-dafny.txt | 16 ++++++++++++++++ doc/ale.txt | 2 ++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 doc/ale-dafny.txt diff --git a/ale_linters/dafny/dafny.vim b/ale_linters/dafny/dafny.vim index b5b90675..b2060d60 100644 --- a/ale_linters/dafny/dafny.vim +++ b/ale_linters/dafny/dafny.vim @@ -14,13 +14,28 @@ function! ale_linters#dafny#dafny#Handle(buffer, lines) abort \ }) endfor + for l:match in ale#util#GetMatches(a:lines, '\v(.*)\((\d+),(\d+)\): (Verification of .{-} timed out after \d+ seconds)') + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'col': l:match[3] + 0, + \ 'lnum': l:match[2] + 0, + \ 'text': l:match[4], + \ 'type': 'E', + \ }) + endfor + return l:output endfunction +function! ale_linters#dafny#dafny#GetCommand(buffer) abort + return printf('dafny %%s /compile:0 /timeLimit:%d', ale#Var(a:buffer, 'dafny_dafny_timelimit')) +endfunction + +call ale#Set('dafny_dafny_timelimit', 10) call ale#linter#Define('dafny', { \ 'name': 'dafny', \ 'executable': 'dafny', -\ 'command': 'dafny %s /compile:0', +\ 'command': function('ale_linters#dafny#dafny#GetCommand'), \ 'callback': 'ale_linters#dafny#dafny#Handle', \ 'lint_file': 1, \ }) diff --git a/doc/ale-dafny.txt b/doc/ale-dafny.txt new file mode 100644 index 00000000..005170ad --- /dev/null +++ b/doc/ale-dafny.txt @@ -0,0 +1,16 @@ +=============================================================================== +ALE Dafny Integration *ale-dafny-options* + + +=============================================================================== +dafny *ale-dafny-dafny* + +g:ale_dafny_dafny_timelimit *g:ale_dafny_dafny_timelimit* + *b:ale_dafny_dafny_timelimit* + Type: |Number| + Default: `10` + + This variable sets the `/timeLimit` used for dafny. + + + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index 6ef137c1..06fe9ee8 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2571,6 +2571,8 @@ documented in additional help files. dfmt..................................|ale-d-dfmt| dls...................................|ale-d-dls| uncrustify............................|ale-d-uncrustify| + dafny...................................|ale-dafny-options| + dafny.................................|ale-dafny-dafny| dart....................................|ale-dart-options| dartanalyzer..........................|ale-dart-dartanalyzer| dartfmt...............................|ale-dart-dartfmt| From 303b89a6b4ace2ee41818499b958a2f486e8864c Mon Sep 17 00:00:00 2001 From: "D. Ben Knoble" Date: Mon, 30 Nov 2020 13:40:57 -0500 Subject: [PATCH 091/167] add tests --- test/handler/test_dafny_handler.vader | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/handler/test_dafny_handler.vader b/test/handler/test_dafny_handler.vader index 674f691d..75567414 100644 --- a/test/handler/test_dafny_handler.vader +++ b/test/handler/test_dafny_handler.vader @@ -20,9 +20,17 @@ Execute(The Dafny handler should parse output correctly): \ 'lnum': 678, \ 'text': 'This is the precondition that might not hold.', \ 'type': 'W' - \ } + \ }, + \ { + \ 'bufnr': 0, + \ 'col': 45, + \ 'lnum': 123, + \ 'text': "Verification of 'Impl$$_22_Proof.__default.PutKeepsMapsFull' timed out after 2 seconds", + \ 'type': 'E' + \ }, \ ], \ ale_linters#dafny#dafny#Handle(0, [ \ 'File.dfy(123,45): Error BP5002: A precondition for this call might not hold.', - \ 'File.dfy(678,90): Related location: This is the precondition that might not hold.' + \ 'File.dfy(678,90): Related location: This is the precondition that might not hold.', + \ "File.dfy(123,45): Verification of 'Impl$$_22_Proof.__default.PutKeepsMapsFull' timed out after 2 seconds", \ ]) From 6d7cff9c0062d03c5a2dd1287c2956b81b203eba Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Wed, 2 Dec 2020 14:58:35 +0000 Subject: [PATCH 092/167] codefix: Fix LSP MenuCallback invocation (E119, not enough args) --- autoload/ale/codefix.vim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/autoload/ale/codefix.vim b/autoload/ale/codefix.vim index 69bf36fa..4a78063b 100644 --- a/autoload/ale/codefix.vim +++ b/autoload/ale/codefix.vim @@ -261,7 +261,10 @@ function! ale#codefix#HandleLSPResponse(conn_id, response) abort " Send the results to the menu callback, if set. if l:MenuCallback isnot v:null - call l:MenuCallback(map(copy(l:result), '[''lsp'', v:val]')) + call l:MenuCallback( + \ l:data, + \ map(copy(l:result), '[''lsp'', v:val]') + \) return endif From fa2186d95e30faa9c7e00400100ceca67ad45872 Mon Sep 17 00:00:00 2001 From: Andrea Conti Date: Sat, 12 Dec 2020 00:16:09 +0100 Subject: [PATCH 093/167] Update Julia language server run command --- ale_linters/julia/languageserver.vim | 4 ++-- .../test_julia_languageserver_callbacks.vader | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ale_linters/julia/languageserver.vim b/ale_linters/julia/languageserver.vim index 564bec39..ab105e7d 100644 --- a/ale_linters/julia/languageserver.vim +++ b/ale_linters/julia/languageserver.vim @@ -6,9 +6,9 @@ call ale#Set('julia_executable', 'julia') function! ale_linters#julia#languageserver#GetCommand(buffer) abort let l:julia_executable = ale#Var(a:buffer, 'julia_executable') - let l:cmd_string = 'using LanguageServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, false); server.runlinter = true; run(server);' + let l:cmd_string = 'using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);' - return ale#Escape(l:julia_executable) . ' --startup-file=no --history-file=no -e ' . ale#Escape(l:cmd_string) + return ale#Escape(l:julia_executable) . '--project=@. --startup-file=no --history-file=no -e ' . ale#Escape(l:cmd_string) endfunction call ale#linter#Define('julia', { diff --git a/test/command_callback/test_julia_languageserver_callbacks.vader b/test/command_callback/test_julia_languageserver_callbacks.vader index 3bc46e3d..75b858e5 100644 --- a/test/command_callback/test_julia_languageserver_callbacks.vader +++ b/test/command_callback/test_julia_languageserver_callbacks.vader @@ -11,16 +11,16 @@ After: Execute(The default executable path should be correct): AssertLinter 'julia', \ ale#Escape('julia') . - \' --startup-file=no --history-file=no -e ' . - \ ale#Escape('using LanguageServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, false); server.runlinter = true; run(server);') + \'--project=@. --startup-file=no --history-file=no -e ' . + \ ale#Escape('using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);') Execute(The executable should be configurable): let g:ale_julia_executable = 'julia-new' AssertLinter 'julia-new', \ ale#Escape('julia-new') . - \' --startup-file=no --history-file=no -e ' . - \ ale#Escape('using LanguageServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, false); server.runlinter = true; run(server);') + \'--project=@. --startup-file=no --history-file=no -e ' . + \ ale#Escape('using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);') Execute(The project root should be detected correctly): AssertLSPProject '' From 1f0cbc7dbd4f1957ac223d83027079c1dea7938d Mon Sep 17 00:00:00 2001 From: Andrea Conti Date: Sat, 12 Dec 2020 00:37:14 +0100 Subject: [PATCH 094/167] Fix space error in string concat --- ale_linters/julia/languageserver.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/julia/languageserver.vim b/ale_linters/julia/languageserver.vim index ab105e7d..999ad815 100644 --- a/ale_linters/julia/languageserver.vim +++ b/ale_linters/julia/languageserver.vim @@ -8,7 +8,7 @@ function! ale_linters#julia#languageserver#GetCommand(buffer) abort let l:julia_executable = ale#Var(a:buffer, 'julia_executable') let l:cmd_string = 'using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);' - return ale#Escape(l:julia_executable) . '--project=@. --startup-file=no --history-file=no -e ' . ale#Escape(l:cmd_string) + return ale#Escape(l:julia_executable) . ' --project=@. --startup-file=no --history-file=no -e ' . ale#Escape(l:cmd_string) endfunction call ale#linter#Define('julia', { From 6043eeb25ad9019aa1322912de1081fa8a0fa299 Mon Sep 17 00:00:00 2001 From: Andrea Conti Date: Sat, 12 Dec 2020 00:41:05 +0100 Subject: [PATCH 095/167] Fix test space bug --- .../test_julia_languageserver_callbacks.vader | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/command_callback/test_julia_languageserver_callbacks.vader b/test/command_callback/test_julia_languageserver_callbacks.vader index 75b858e5..96df81f1 100644 --- a/test/command_callback/test_julia_languageserver_callbacks.vader +++ b/test/command_callback/test_julia_languageserver_callbacks.vader @@ -11,7 +11,7 @@ After: Execute(The default executable path should be correct): AssertLinter 'julia', \ ale#Escape('julia') . - \'--project=@. --startup-file=no --history-file=no -e ' . + \' --project=@. --startup-file=no --history-file=no -e ' . \ ale#Escape('using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);') Execute(The executable should be configurable): @@ -19,7 +19,7 @@ Execute(The executable should be configurable): AssertLinter 'julia-new', \ ale#Escape('julia-new') . - \'--project=@. --startup-file=no --history-file=no -e ' . + \' --project=@. --startup-file=no --history-file=no -e ' . \ ale#Escape('using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);') Execute(The project root should be detected correctly): From e358afdd9ba5108680afc6aa017075b44f6c18fa Mon Sep 17 00:00:00 2001 From: Benjamin Binier Date: Thu, 17 Dec 2020 08:59:57 +0100 Subject: [PATCH 096/167] Add salt-lint support --- ale_linters/salt/salt_lint.vim | 32 +++++++++++++++++ doc/ale-salt.tmt | 43 +++++++++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 2 ++ doc/ale.txt | 2 ++ supported-tools.md | 2 ++ test/handler/test_salt_salt_lint.vader | 34 ++++++++++++++++++ 6 files changed, 115 insertions(+) create mode 100644 ale_linters/salt/salt_lint.vim create mode 100644 doc/ale-salt.tmt create mode 100644 test/handler/test_salt_salt_lint.vader diff --git a/ale_linters/salt/salt_lint.vim b/ale_linters/salt/salt_lint.vim new file mode 100644 index 00000000..d2027119 --- /dev/null +++ b/ale_linters/salt/salt_lint.vim @@ -0,0 +1,32 @@ +" Author: Benjamin BINIER +" Description: salt-lint, saltstack linter + +call ale#Set('salt_salt_lint_executable', 'salt-lint') +call ale#Set('salt_salt_lint_options', '') + +function! ale_linters#salt#salt_lint#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'salt_salt_lint_options')) + \ . ' --json' +endfunction + +function! ale_linters#salt#salt_lint#Handle(buffer, lines) abort + let l:output = [] + + for l:error in ale#util#FuzzyJSONDecode(a:lines, []) + call add(l:output, { + \ 'lnum': l:error.linenumber + 0, + \ 'code': l:error.id + 0, + \ 'text': l:error.message, + \ 'type': l:error.severity is# 'HIGH' ? 'E' : 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('salt', { +\ 'name': 'salt-lint', +\ 'executable': {b -> ale#Var(b, 'salt_salt_lint_executable')}, +\ 'command': function('ale_linters#salt#salt_lint#GetCommand'), +\ 'callback': 'ale_linters#salt#salt_lint#Handle' +\}) diff --git a/doc/ale-salt.tmt b/doc/ale-salt.tmt new file mode 100644 index 00000000..ac500d37 --- /dev/null +++ b/doc/ale-salt.tmt @@ -0,0 +1,43 @@ +=============================================================================== +ALE SALT Integration *ale-salt-options* + +=============================================================================== +salt-lint *ale-salt-salt-lint* + +Website: https://github.com/warpnet/salt-lint + + +Installation +------------------------------------------------------------------------------- + +Install salt-lint in your a virtualenv directory, locally, or globally: > + + pip install salt-lint # After activating virtualenv + pip install --user salt-lint # Install to ~/.local/bin + sudo pip install salt-lint # Install globally + +See |g:ale_virtualenv_dir_names| for configuring how ALE searches for +virtualenv directories. + + +Options +------------------------------------------------------------------------------- + +g:ale_salt_salt-lint_executable *g:ale_salt_salt_lint_executable* + *b:ale_salt_salt_lint_executable* + Type: |String| + Default: `'salt-lint'` + + This variable can be set to change the path to salt-lint. + + +g:ale_salt_salt-lint_options *g:ale_salt_salt-lint_options* + *b:ale_salt_salt-lint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to salt-lint. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 36e27932..4844d0aa 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -428,6 +428,8 @@ Notes: * `rust-analyzer` * `rustc` (see |ale-integration-rust|) * `rustfmt` +* Salt + * `salt-lint` * Sass * `sass-lint` * `stylelint` diff --git a/doc/ale.txt b/doc/ale.txt index f9f40d12..d23e6fb6 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2882,6 +2882,8 @@ documented in additional help files. rls...................................|ale-rust-rls| rustc.................................|ale-rust-rustc| rustfmt...............................|ale-rust-rustfmt| + salt....................................|ale-salt-options| + salt-lint.............................|ale-salt-salt-lint| sass....................................|ale-sass-options| sasslint..............................|ale-sass-sasslint| stylelint.............................|ale-sass-stylelint| diff --git a/supported-tools.md b/supported-tools.md index 96ef273b..9d70b6b2 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -437,6 +437,8 @@ formatting. * [rust-analyzer](https://github.com/rust-analyzer/rust-analyzer) :warning: * [rustc](https://www.rust-lang.org/) :warning: * [rustfmt](https://github.com/rust-lang-nursery/rustfmt) +* Salt + * [salt-lint](https://github.com/warpnet/salt-lint) * Sass * [sass-lint](https://www.npmjs.com/package/sass-lint) * [stylelint](https://github.com/stylelint/stylelint) diff --git a/test/handler/test_salt_salt_lint.vader b/test/handler/test_salt_salt_lint.vader new file mode 100644 index 00000000..7e234785 --- /dev/null +++ b/test/handler/test_salt_salt_lint.vader @@ -0,0 +1,34 @@ +Before: + runtime ale_linters/salt/salt_lint.vim + +After: + call ale#linter#Reset() + +Execute(The salt handler should parse lines correctly and show error in severity HIGH): + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'code': 207, + \ 'text': 'File modes should always be encapsulated in quotation marks', + \ 'type': 'E' + \ } + \ ], + \ ale_linters#salt#salt_lint#Handle(255, [ + \ '[{"id": "207", "message": "File modes should always be encapsulated in quotation marks", "filename": "test.sls", "linenumber": 5, "line": " - mode: 0755", "severity": "HIGH"}]' + \ ]) + + +Execute(The salt handler should parse lines correctly and show error in severity not HIGH): + AssertEqual + \ [ + \ { + \ 'lnum': 27, + \ 'code': 204, + \ 'text': 'Lines should be no longer that 160 chars', + \ 'type': 'W' + \ } + \ ], + \ ale_linters#salt#salt_lint#Handle(255, [ + \ '[{"id": "204", "message": "Lines should be no longer that 160 chars", "filename": "test2.sls", "linenumber": 27, "line": "this line is definitely longer than 160 chars, this line is definitely longer than 160 chars, this line is definitely longer than 160 chars", "severity": "VERY_LOW"}]' + \ ]) From 02255dd967cd127d4910bf489a655009fa66ba14 Mon Sep 17 00:00:00 2001 From: Manoel Brunnen Date: Mon, 21 Dec 2020 14:59:08 +0100 Subject: [PATCH 097/167] Add tests for -imacros C flag --- test/test_c_flag_parsing.vader | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader index 99722b17..8b02f2b9 100644 --- a/test/test_c_flag_parsing.vader +++ b/test/test_c_flag_parsing.vader @@ -482,6 +482,7 @@ Execute(We should include several important flags): \ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incafter')) \ . ' -iframework ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incframework')) \ . ' -include ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/foo bar')) + \ . ' -imacros ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incmacros')) \ . ' -Dmacro="value"' \ . ' -DGoal=9' \ . ' -D macro2' @@ -511,6 +512,8 @@ Execute(We should include several important flags): \ 'incframework', \ '-include', \ '''foo bar''', + \ '-imacros', + \ 'incmacros', \ '-Dmacro="value"', \ '-DGoal=9', \ '-D', @@ -559,6 +562,7 @@ Execute(We should quote the flags we need to quote): \ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incafter')) \ . ' -iframework ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incframework')) \ . ' -include ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/foo bar')) + \ . ' -imacros ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incmacros')) \ . ' ' . ale#Escape('-Dmacro="value"') \ . ' -DGoal=9' \ . ' -D macro2' @@ -591,6 +595,8 @@ Execute(We should quote the flags we need to quote): \ 'incframework', \ '-include', \ '''foo bar''', + \ '-imacros', + \ 'incmacros', \ '-Dmacro="value"', \ '-DGoal=9', \ '-D', From 8375ee2766c4d69462b8c883ddf76d58a86891e4 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 29 Oct 2020 18:27:27 +0100 Subject: [PATCH 098/167] Add linter for Inko This adds a linter for Inko (https://inko-lang.org/). The linter makes use of Inko's own compiler, and a newly introduced --check flag to only check for errors; instead of also compiling source code. --- ale_linters/inko/inko.vim | 33 ++++++++++++ autoload/ale/handlers/inko.vim | 37 +++++++++++++ autoload/ale/linter.vim | 1 + doc/ale-inko.txt | 22 ++++++++ doc/ale-supported-languages-and-tools.txt | 2 + doc/ale.txt | 3 ++ supported-tools.md | 2 + test/command_callback/inko_paths/test.inko | 0 .../inko_paths/tests/test/test_foo.inko | 0 .../test_inko_inko_callbacks.vader | 20 +++++++ test/handler/test_inko_handler.vader | 54 +++++++++++++++++++ 11 files changed, 174 insertions(+) create mode 100644 ale_linters/inko/inko.vim create mode 100644 autoload/ale/handlers/inko.vim create mode 100644 doc/ale-inko.txt create mode 100644 test/command_callback/inko_paths/test.inko create mode 100644 test/command_callback/inko_paths/tests/test/test_foo.inko create mode 100644 test/command_callback/test_inko_inko_callbacks.vader create mode 100644 test/handler/test_inko_handler.vader diff --git a/ale_linters/inko/inko.vim b/ale_linters/inko/inko.vim new file mode 100644 index 00000000..11558897 --- /dev/null +++ b/ale_linters/inko/inko.vim @@ -0,0 +1,33 @@ +" Author: Yorick Peterse +" Description: linting of Inko source code using the Inko compiler + +call ale#Set('inko_inko_executable', 'inko') + +function! ale_linters#inko#inko#GetCommand(buffer) abort + let l:include = '' + + " Include the tests source directory, but only for test files. + if expand('#' . a:buffer . ':p') =~? '\vtests[/\\]test[/\\]' + let l:test_dir = ale#path#FindNearestDirectory(a:buffer, 'tests') + + if isdirectory(l:test_dir) + let l:include = '--include ' . ale#Escape(l:test_dir) + endif + endif + + " We use %s instead of %t so the compiler determines the correct module + " names for the file being edited. Not doing so may lead to errors in + " certain cases. + return '%e build --check --format=json' + \ . ale#Pad(l:include) + \ . ' %s' +endfunction + +call ale#linter#Define('inko', { +\ 'name': 'inko', +\ 'executable': {b -> ale#Var(b, 'inko_inko_executable')}, +\ 'command': function('ale_linters#inko#inko#GetCommand'), +\ 'callback': 'ale#handlers#inko#Handle', +\ 'output_stream': 'stderr', +\ 'lint_file': 1 +\}) diff --git a/autoload/ale/handlers/inko.vim b/autoload/ale/handlers/inko.vim new file mode 100644 index 00000000..73f06871 --- /dev/null +++ b/autoload/ale/handlers/inko.vim @@ -0,0 +1,37 @@ +" Author: Yorick Peterse +" Description: output handlers for the Inko JSON format + +function! ale#handlers#inko#GetType(severity) abort + if a:severity is? 'warning' + return 'W' + endif + + return 'E' +endfunction + +function! ale#handlers#inko#Handle(buffer, lines) abort + try + let l:errors = json_decode(join(a:lines, '')) + catch + return [] + endtry + + if empty(l:errors) + return [] + endif + + let l:output = [] + let l:dir = expand('#' . a:buffer . ':p:h') + + for l:error in l:errors + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:error['file']), + \ 'lnum': l:error['line'], + \ 'col': l:error['column'], + \ 'text': l:error['message'], + \ 'type': ale#handlers#inko#GetType(l:error['level']), + \}) + endfor + + return l:output +endfunction diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index 645c25f9..ba11e1eb 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -43,6 +43,7 @@ let s:default_ale_linters = { \ 'go': ['gofmt', 'golint', 'go vet'], \ 'hack': ['hack'], \ 'help': [], +\ 'inko': ['inko'], \ 'perl': ['perlcritic'], \ 'perl6': [], \ 'python': ['flake8', 'mypy', 'pylint', 'pyright'], diff --git a/doc/ale-inko.txt b/doc/ale-inko.txt new file mode 100644 index 00000000..5ca14af6 --- /dev/null +++ b/doc/ale-inko.txt @@ -0,0 +1,22 @@ +=============================================================================== +ALE Inko Integration *ale-inko-options* + *ale-integration-inko* + +=============================================================================== +Integration Information + + Currently, the only supported linter for Inko is the Inko compiler itself. + +=============================================================================== +inko *ale-inko-inko* + +g:ale_inko_inko_executable *g:ale_inko_inko_executable* + *b:ale_inko_inko_executable* + Type: |String| + Default: `'inko'` + + This variable can be modified to change the executable path for `inko`. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 4f3afd85..613bf2b8 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -213,6 +213,8 @@ Notes: * `idris` * Ink * `ink-language-server` +* Inko + * `inko` !! * ISPC * `ispc`!! * Java diff --git a/doc/ale.txt b/doc/ale.txt index eb8f0275..a5613d33 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1502,6 +1502,7 @@ g:ale_linters *g:ale_linters* \ 'go': ['gofmt', 'golint', 'go vet'], \ 'hack': ['hack'], \ 'help': [], + \ 'inko': ['inko'], \ 'perl': ['perlcritic'], \ 'perl6': [], \ 'python': ['flake8', 'mypy', 'pylint', 'pyright'], @@ -2656,6 +2657,8 @@ documented in additional help files. idris.................................|ale-idris-idris| ink.....................................|ale-ink-options| ink-language-server...................|ale-ink-language-server| + inko....................................|ale-inko-options| + inko..................................|ale-inko-inko| ispc....................................|ale-ispc-options| ispc..................................|ale-ispc-ispc| java....................................|ale-java-options| diff --git a/supported-tools.md b/supported-tools.md index 49460892..49b53841 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -222,6 +222,8 @@ formatting. * [idris](http://www.idris-lang.org/) * Ink * [ink-language-server](https://github.com/ephread/ink-language-server) +* Inko + * [inko](https://inko-lang.org/) :floppy_disk: * ISPC * [ispc](https://ispc.github.io/) :floppy_disk: * Java diff --git a/test/command_callback/inko_paths/test.inko b/test/command_callback/inko_paths/test.inko new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/inko_paths/tests/test/test_foo.inko b/test/command_callback/inko_paths/tests/test/test_foo.inko new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/test_inko_inko_callbacks.vader b/test/command_callback/test_inko_inko_callbacks.vader new file mode 100644 index 00000000..93295c91 --- /dev/null +++ b/test/command_callback/test_inko_inko_callbacks.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('inko', 'inko') + call ale#test#SetFilename('inko_paths/test.inko') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'inko', ale#Escape('inko') . ' build --check --format=json %s' + +Execute(The inko callback should include tests/ for test paths): + call ale#engine#Cleanup(bufnr('')) + noautocmd e! inko_paths/tests/test/test_foo.inko + call ale#engine#InitBufferInfo(bufnr('')) + + AssertLinter 'inko', + \ ale#Escape('inko') + \ . ' build --check --format=json --include ' + \ . ale#Escape(ale#path#Simplify(g:dir . '/inko_paths/tests/')) + \ . ' %s' diff --git a/test/handler/test_inko_handler.vader b/test/handler/test_inko_handler.vader new file mode 100644 index 00000000..6621d2d6 --- /dev/null +++ b/test/handler/test_inko_handler.vader @@ -0,0 +1,54 @@ +Before: + runtime ale_linters/inko/inko.vim + +After: + call ale#linter#Reset() + +Execute(The inko handler should parse errors correctly): + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Simplify('/tmp/foo.inko'), + \ 'lnum': 4, + \ 'col': 5, + \ 'text': 'this is an error', + \ 'type': 'E', + \ } + \ ], + \ ale#handlers#inko#Handle(bufnr(''), [ + \ '[', + \ ' {', + \ ' "file": "/tmp/foo.inko",', + \ ' "line": 4,', + \ ' "column": 5,', + \ ' "message": "this is an error",', + \ ' "level": "error"', + \ ' }', + \ ']' + \ ]) + +Execute(The inko handler should parse warnings correctly): + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Simplify('/tmp/foo.inko'), + \ 'lnum': 4, + \ 'col': 5, + \ 'text': 'this is a warning', + \ 'type': 'W', + \ } + \ ], + \ ale#handlers#inko#Handle(bufnr(''), [ + \ '[', + \ ' {', + \ ' "file": "/tmp/foo.inko",', + \ ' "line": 4,', + \ ' "column": 5,', + \ ' "message": "this is a warning",', + \ ' "level": "warning"', + \ ' }', + \ ']' + \ ]) + +Execute(The inko handler should handle empty output): + AssertEqual [], ale#handlers#inko#Handle(bufnr(''), []) From 6b97af680d579fcabb9d05f7341cd325bbd9bc04 Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Fri, 1 Jan 2021 14:48:10 -0800 Subject: [PATCH 099/167] Exclude grandfathered-in non-snakecased lints Prior to #3448, several linters should have been failing the custom-checks that look for non-snake-cased lint names. They weren't, but now the bug that hid those is fixed. So to avoid breaking users, we just exclude those from the check. Linters excluded: * clojure/clj_kondo.vim * elixir/elixir_ls.vim * go/golangci_lint.vim * swift/swiftformat.vim --- test/script/custom-linting-rules | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/test/script/custom-linting-rules b/test/script/custom-linting-rules index 981a9459..86294f71 100755 --- a/test/script/custom-linting-rules +++ b/test/script/custom-linting-rules @@ -53,17 +53,29 @@ check_errors() { regex="$1" message="$2" include_arg='' + exclude_arg='' if [ $# -gt 2 ]; then include_arg="--include $3" fi + if [ $# -gt 3 ]; then + shift + shift + shift + + while (( "$#" )); do + exclude_arg="$exclude_arg --exclude $1" + shift + done + fi + for directory in "${directories[@]}"; do # shellcheck disable=SC2086 while read -r; do RETURN_CODE=1 echo "$REPLY $message" - done < <(grep -H -n "$regex" $include_arg "$directory"/**/*.vim \ + done < <(grep -H -n "$regex" $include_arg $exclude_arg "$directory"/**/*.vim \ | grep -v 'no-custom-checks' \ | grep -o '^[^:]\+:[0-9]\+' \ | sed 's:^\./::') @@ -92,7 +104,7 @@ if (( FIX_ERRORS )); then done fi -# The arguments are: regex, explanation, [filename_filter] +# The arguments are: regex, explanation, [filename_filter], [list, of, exclusions] check_errors \ '^function.*) *$' \ 'Function without abort keyword (See :help except-compat)' @@ -114,7 +126,10 @@ 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/*' +# Exclusions for grandfathered-in exceptions +exclusions="clojure/clj_kondo.vim elixir/elixir_ls.vim go/golangci_lint.vim swift/swiftformat.vim" +# shellcheck disable=SC2086 +check_errors $'name.:.*\'[a-z_]*[^a-z_0-9][a-z_0-9]*\',$' 'Use snake_case names for linters' '*/ale_linters/*' $exclusions # Checks for improving type checks. check_errors $'\\(==.\\?\\|is\\) type([\'"]\+)' "Use 'is v:t_string' instead" check_errors '\(==.\?\|is\) type([0-9]\+)' "Use 'is v:t_number' instead" From b4d889b682c2b55508f006ef8d1377a4ca3d9739 Mon Sep 17 00:00:00 2001 From: ttys3 Date: Mon, 4 Jan 2021 23:10:39 +0800 Subject: [PATCH 100/167] fix: proper initialization options call in php intelephense --- ale_linters/php/intelephense.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 ale_linters/php/intelephense.vim diff --git a/ale_linters/php/intelephense.vim b/ale_linters/php/intelephense.vim old mode 100644 new mode 100755 index e9e07d1f..aca619e3 --- a/ale_linters/php/intelephense.vim +++ b/ale_linters/php/intelephense.vim @@ -18,8 +18,8 @@ function! ale_linters#php#intelephense#GetProjectRoot(buffer) abort return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : '' endfunction -function! ale_linters#php#intelephense#GetInitializationOptions() abort - return ale#Get('php_intelephense_config') +function! ale_linters#php#intelephense#GetInitializationOptions(buffer) abort + return ale#Var(a:buffer, 'php_intelephense_config') endfunction call ale#linter#Define('php', { From 49f8aa4703caea1fc792e372da99f296776872f8 Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Tue, 12 Jan 2021 17:49:30 +0900 Subject: [PATCH 101/167] Revert "Improves fixer performance for large buffers" --- autoload/ale/util.vim | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim index fcc03eb7..1f396377 100644 --- a/autoload/ale/util.vim +++ b/autoload/ale/util.vim @@ -486,7 +486,7 @@ function! ale#util#Input(message, value) abort endfunction function! ale#util#HasBuflineApi() abort - return exists('*deletebufline') && exists('*appendbufline') && exists('*getpos') && exists('*setpos') + return exists('*deletebufline') && exists('*setbufline') endfunction " Sets buffer contents to lines @@ -507,11 +507,8 @@ function! ale#util#SetBufferContents(buffer, lines) abort " Use a Vim API for setting lines in other buffers, if available. if l:has_bufline_api - let l:save_cursor = getpos('.') - call deletebufline(a:buffer, 1, '$') - call appendbufline(a:buffer, 1, l:new_lines) - call deletebufline(a:buffer, 1, 1) - call setpos('.', l:save_cursor) + call setbufline(a:buffer, 1, l:new_lines) + call deletebufline(a:buffer, l:first_line_to_remove, '$') " Fall back on setting lines the old way, for the current buffer. else let l:old_line_length = line('$') From 39f393ef077998028bce697659c3aac37f7aa090 Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Thu, 14 Jan 2021 10:06:20 -0800 Subject: [PATCH 102/167] Add nvim floating window support (replaces #3314) (#3470) * Add nvim floating window hover support * Add configuration for float to replace preview * preview#ShowFloating: qualify local variables * Configure floating preview usecases individually Also: * Extract floating preview to its own file. * Ignore 'stay_here' option. Moving into the floating preview window seems confusing at best. * Re-use existing floating preview window if it's still up. * Flush out floating preview documentation. * Watch cursor position changes per window Floating previews open a new window, so when that window is written to, it moves briefly there at a different position than the original window. This makes repeated positions detected when positions are tracked at a s: level. Instead, we change the variable to window scoped, which only fires a message if the cursor has changed from the last position in *that window*. * g:ale_floating_preview cleanup * floating_preview: add ALEDetail tests * Fix fecs test missing runtime call * Add ALEHover floating preview tests Co-authored-by: Jan-Grimo Sobez --- autoload/ale/cursor.vim | 22 +++-- autoload/ale/floating_preview.vim | 91 ++++++++++++++++++ autoload/ale/hover.vim | 9 ++ doc/ale.txt | 30 ++++++ plugin/ale.vim | 9 ++ .../test_fecs_command_callback.vader | 1 + test/test_floating_preview.vader | 92 +++++++++++++++++++ test/test_hover.vader | 83 +++++++++++++++++ 8 files changed, 330 insertions(+), 7 deletions(-) create mode 100644 autoload/ale/floating_preview.vim create mode 100644 test/test_floating_preview.vader diff --git a/autoload/ale/cursor.vim b/autoload/ale/cursor.vim index 9ca6fb15..e8478e93 100644 --- a/autoload/ale/cursor.vim +++ b/autoload/ale/cursor.vim @@ -9,7 +9,6 @@ let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10) let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s') let s:cursor_timer = -1 -let s:last_pos = [0, 0, 0] function! ale#cursor#TruncatedEcho(original_message) abort let l:message = a:original_message @@ -118,14 +117,18 @@ function! ale#cursor#EchoCursorWarningWithDelay() abort let l:pos = getpos('.')[0:2] + if !exists('w:last_pos') + let w:last_pos = [0, 0, 0] + endif + " Check the current buffer, line, and column number against the last " recorded position. If the position has actually changed, *then* " we should echo something. Otherwise we can end up doing processing " the echo message far too frequently. - if l:pos != s:last_pos + if l:pos != w:last_pos let l:delay = ale#Var(l:buffer, 'echo_delay') - let s:last_pos = l:pos + let w:last_pos = l:pos let s:cursor_timer = timer_start( \ l:delay, \ function('ale#cursor#EchoCursorWarning') @@ -139,11 +142,16 @@ function! s:ShowCursorDetailForItem(loc, options) abort let s:last_detailed_line = line('.') let l:message = get(a:loc, 'detail', a:loc.text) let l:lines = split(l:message, "\n") - call ale#preview#Show(l:lines, {'stay_here': l:stay_here}) - " Clear the echo message if we manually displayed details. - if !l:stay_here - execute 'echo' + if g:ale_floating_preview || g:ale_detail_to_floating_preview + call ale#floating_preview#Show(l:lines) + else + call ale#preview#Show(l:lines, {'stay_here': l:stay_here}) + + " Clear the echo message if we manually displayed details. + if !l:stay_here + execute 'echo' + endif endif endfunction diff --git a/autoload/ale/floating_preview.vim b/autoload/ale/floating_preview.vim new file mode 100644 index 00000000..e6a75689 --- /dev/null +++ b/autoload/ale/floating_preview.vim @@ -0,0 +1,91 @@ +" Author: Jan-Grimo Sobez +" Author: Kevin Clark +" Description: Floating preview window for showing whatever information in. + +" Precondition: exists('*nvim_open_win') + +function! ale#floating_preview#Show(lines, ...) abort + if !exists('*nvim_open_win') + execute 'echom ''Floating windows not supported in this vim instance.''' + + return + endif + + " Remove the close autocmd so it doesn't happen mid update + augroup ale_floating_preview_window + autocmd! + augroup END + + let l:options = get(a:000, 0, {}) + + " Only create a new window if we need it + if !exists('w:preview') || index(nvim_list_wins(), w:preview['id']) is# -1 + call s:Create(l:options) + else + call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:true) + endif + + " Execute commands in window context + let l:parent_window = nvim_get_current_win() + + call nvim_set_current_win(w:preview['id']) + + for l:command in get(l:options, 'commands', []) + call execute(l:command) + endfor + + call nvim_set_current_win(l:parent_window) + + " Return to parent context on move + augroup ale_floating_preview_window + autocmd! + + if g:ale_close_preview_on_insert + autocmd CursorMoved,TabLeave,WinLeave,InsertEnter ++once call s:Close() + else + autocmd CursorMoved,TabLeave,WinLeave ++once call s:Close() + endif + augroup END + + let l:width = max(map(copy(a:lines), 'strdisplaywidth(v:val)')) + let l:height = min([len(a:lines), 10]) + call nvim_win_set_width(w:preview['id'], l:width) + call nvim_win_set_height(w:preview['id'], l:height) + + call nvim_buf_set_lines(w:preview['buffer'], 0, -1, v:false, a:lines) + call nvim_buf_set_option(w:preview['buffer'], 'modified', v:false) + call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:false) +endfunction + +function! s:Create(options) abort + let l:buffer = nvim_create_buf(v:false, v:false) + let l:winid = nvim_open_win(l:buffer, v:false, { + \ 'relative': 'cursor', + \ 'row': 1, + \ 'col': 0, + \ 'width': 42, + \ 'height': 4, + \ 'style': 'minimal' + \ }) + call nvim_buf_set_option(l:buffer, 'buftype', 'acwrite') + call nvim_buf_set_option(l:buffer, 'bufhidden', 'delete') + call nvim_buf_set_option(l:buffer, 'swapfile', v:false) + call nvim_buf_set_option(l:buffer, 'filetype', get(a:options, 'filetype', 'ale-preview')) + + let w:preview = {'id': l:winid, 'buffer': l:buffer} +endfunction + +function! s:Close() abort + if !exists('w:preview') + return + endif + + call setbufvar(w:preview['buffer'], '&modified', 0) + + if win_id2win(w:preview['id']) > 0 + execute win_id2win(w:preview['id']).'wincmd c' + endif + + unlet w:preview +endfunction + diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim index 1d38f3b9..cb0379fd 100644 --- a/autoload/ale/hover.vim +++ b/autoload/ale/hover.vim @@ -46,6 +46,10 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort call balloon_show(a:response.body.displayString) elseif get(l:options, 'truncated_echo', 0) call ale#cursor#TruncatedEcho(split(a:response.body.displayString, "\n")[0]) + elseif g:ale_hover_to_floating_preview || g:ale_floating_preview + call ale#floating_preview#Show(split(a:response.body.displayString, "\n"), { + \ 'filetype': 'ale-preview.message', + \}) elseif g:ale_hover_to_preview call ale#preview#Show(split(a:response.body.displayString, "\n"), { \ 'filetype': 'ale-preview.message', @@ -226,6 +230,11 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort call balloon_show(join(l:lines, "\n")) elseif get(l:options, 'truncated_echo', 0) call ale#cursor#TruncatedEcho(l:lines[0]) + elseif g:ale_hover_to_floating_preview || g:ale_floating_preview + call ale#floating_preview#Show(l:lines, { + \ 'filetype': 'ale-preview.message', + \ 'commands': l:commands, + \}) elseif g:ale_hover_to_preview call ale#preview#Show(l:lines, { \ 'filetype': 'ale-preview.message', diff --git a/doc/ale.txt b/doc/ale.txt index 767d000d..a77407a1 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -646,6 +646,9 @@ problem will be displayed in a balloon instead of hover information. Hover information can be displayed in the preview window instead by setting |g:ale_hover_to_preview| to `1`. +When using Neovim, if |g:ale_hover_to_floating_preview| or |g:ale_floating_preview| +is set to 1, the hover information will show in a floating window. + For Vim 8.1+ terminals, mouse hovering is disabled by default. Enabling |balloonexpr| commands in terminals can cause scrolling issues in terminals, so ALE will not attempt to show balloons unless |g:ale_set_balloons| is set to @@ -954,6 +957,15 @@ g:ale_default_navigation *g:ale_default_navigation* buffer, such as for |ALEFindReferences|, or |ALEGoToDefinition|. +g:ale_detail_to_floating_preview *g:ale_detail_to_floating_preview* + *b:ale_detail_to_floating_preview* + Type: |Number| + Default: `0` + + When this option is set to `1`, Neovim will use a floating window for + ALEDetail output. + + g:ale_disable_lsp *g:ale_disable_lsp* *b:ale_disable_lsp* @@ -1177,6 +1189,16 @@ g:ale_fix_on_save_ignore *g:ale_fix_on_save_ignore* let g:ale_fix_on_save_ignore = [g:AddBar] < +g:ale_floating_preview *g:ale_floating_preview* + + Type: |Number| + Default: `0` + + When set to `1`, Neovim will use a floating window for ale's preview window. + This is equivalent to setting |g:ale_hover_to_floating_preview| and + |g:ale_detail_to_floating_preview| to `1`. + + g:ale_history_enabled *g:ale_history_enabled* Type: |Number| @@ -1235,6 +1257,14 @@ g:ale_hover_to_preview *g:ale_hover_to_preview* instead of in balloons or the message line. +g:ale_hover_to_floating_preview *g:ale_hover_to_floating_preview* + *b:ale_hover_to_floating_preview* + Type: |Number| + Default: `0` + + If set to `1`, Neovim will use floating windows for hover messages. + + g:ale_keep_list_window_open *g:ale_keep_list_window_open* *b:ale_keep_list_window_open* Type: |Number| diff --git a/plugin/ale.vim b/plugin/ale.vim index 5b7be116..1735715d 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -138,6 +138,15 @@ let g:ale_set_balloons = get(g:, 'ale_set_balloons', has('balloon_eval') && has( " Use preview window for hover messages. let g:ale_hover_to_preview = get(g:, 'ale_hover_to_preview', 0) +" Float preview windows in Neovim +let g:ale_floating_preview = get(g:, 'ale_floating_preview', 0) + +" Hovers use floating windows in Neovim +let g:ale_hover_to_floating_preview = get(g:, 'ale_hover_to_floating_preview', 0) + +" Detail uses floating windows in Neovim +let g:ale_detail_to_floating_preview = get(g:, 'ale_detail_to_floating_preview', 0) + " This flag can be set to 0 to disable warnings for trailing whitespace let g:ale_warn_about_trailing_whitespace = get(g:, 'ale_warn_about_trailing_whitespace', 1) " This flag can be set to 0 to disable warnings for trailing blank lines diff --git a/test/command_callback/test_fecs_command_callback.vader b/test/command_callback/test_fecs_command_callback.vader index f70ad084..4287d324 100644 --- a/test/command_callback/test_fecs_command_callback.vader +++ b/test/command_callback/test_fecs_command_callback.vader @@ -1,5 +1,6 @@ Before: call ale#assert#SetUpLinterTest('javascript', 'fecs') + runtime autoload/ale/handlers/fecs.vim After: call ale#assert#TearDownLinterTest() diff --git a/test/test_floating_preview.vader b/test/test_floating_preview.vader new file mode 100644 index 00000000..43415556 --- /dev/null +++ b/test/test_floating_preview.vader @@ -0,0 +1,92 @@ +Before: + let g:ale_floating_preview = 0 + let g:ale_hover_to_floating_preview = 0 + let g:ale_detail_to_floating_preview = 0 + + runtime autoload/ale/floating_preview.vim + + let g:floated_lines = [] + let g:floating_preview_show_called = 0 + + " Stub out so we can track the call + function! ale#floating_preview#Show(lines, ...) abort + let g:floating_preview_show_called = 1 + let g:floated_lines = a:lines + endfunction + + let g:ale_buffer_info = { + \ bufnr('%'): { + \ 'loclist': [ + \ { + \ 'lnum': 1, + \ 'col': 10, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'linter_name': 'notalinter', + \ 'nr': -1, + \ 'type': 'E', + \ 'code': 'semi', + \ 'text': "Missing semicolon.\r", + \ 'detail': "Every statement should end with a semicolon\nsecond line", + \ }, + \ ], + \ } + \} + + call ale#linter#Reset() + call ale#linter#PreventLoading('javascript') + +After: + Restore + + let g:ale_floating_preview = 0 + let g:ale_hover_to_floating_preview = 0 + let g:ale_detail_to_floating_preview = 0 + + call cursor(1, 1) + + let g:ale_buffer_info = {} + + " Close the preview window if it's open. + if &filetype is# 'ale-preview' + noautocmd :q! + endif + + call ale#linter#Reset() + + +Given javascript(A file with warnings/errors): + var x = 3 + 12345678 + var x = 5*2 + parseInt("10"); + // comment + +Execute(Floating preview is used with ALEDetail when g:ale_floating_preview set): + let g:ale_floating_preview = 1 + + call cursor(1, 10) + + ALEDetail + + let expected = ["Every statement should end with a semicolon", "second line"] + + AssertEqual 1, g:floating_preview_show_called + AssertEqual expected, g:floated_lines + +Execute(Floating preview is used with ALEDetail when g:ale_detail_to_floating_preview set): + let g:ale_detail_to_floating_preview = 1 + + call cursor(1, 10) + + ALEDetail + + let expected = ["Every statement should end with a semicolon", "second line"] + + AssertEqual 1, g:floating_preview_show_called + AssertEqual expected, g:floated_lines + +Execute(Floating preview is not used with ALEDetail by default): + call cursor(1, 10) + + ALEDetail + + AssertEqual 0, g:floating_preview_show_called diff --git a/test/test_hover.vader b/test/test_hover.vader index ed756396..7a9c8d91 100644 --- a/test/test_hover.vader +++ b/test/test_hover.vader @@ -7,9 +7,25 @@ Before: let g:item_list = [] let g:show_message_arg_list = [] + let g:ale_floating_preview = 0 + let g:ale_hover_to_floating_preview = 0 + let g:ale_detail_to_floating_preview = 0 + runtime autoload/ale/linter.vim runtime autoload/ale/lsp.vim + runtime autoload/ale/lsp_linter.vim runtime autoload/ale/util.vim + runtime autoload/ale/floating_preview.vim + runtime autoload/ale/hover.vim + + let g:floated_lines = [] + let g:floating_preview_show_called = 0 + + " Stub out so we can track the call + function! ale#floating_preview#Show(lines, ...) abort + let g:floating_preview_show_called = 1 + let g:floated_lines = a:lines + endfunction function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort let g:Callback = a:callback @@ -50,6 +66,7 @@ Before: \) endfunction + After: call ale#hover#SetMap({}) call ale#test#RestoreDirectory() @@ -65,6 +82,7 @@ After: runtime autoload/ale/lsp_linter.vim runtime autoload/ale/lsp.vim runtime autoload/ale/util.vim + runtime autoload/ale/floating_preview.vim Given python(Some Python file): foo @@ -168,6 +186,28 @@ Execute(LSP hover response with lists of strings and marked strings should be ha \], g:show_message_arg_list AssertEqual {}, ale#hover#GetMap() +Execute(LSP hover with ale_floating_preview should float): + let g:ale_floating_preview = 1 + + call HandleValidLSPResult({'contents': "the message\ncontinuing"}) + + AssertEqual 1, g:floating_preview_show_called + AssertEqual ["the message", "continuing"], g:floated_lines + +Execute(LSP hover ale_hover_to_floating_preview should float): + let g:ale_hover_to_floating_preview = 1 + + call HandleValidLSPResult({'contents': "the message\ncontinuing"}) + + AssertEqual 1, g:floating_preview_show_called + AssertEqual ["the message", "continuing"], g:floated_lines + + +Execute(LSP hover by default should not float): + call HandleValidLSPResult({'contents': "the message\ncontinuing"}) + + AssertEqual 0, g:floating_preview_show_called + Execute(tsserver responses for documentation requests should be handled): call ale#hover#SetMap({3: {'show_documentation': 1, 'buffer': bufnr('')}}) @@ -187,3 +227,46 @@ Execute(tsserver responses for documentation requests should be handled): " The preview window should show the text. AssertEqual ['foo is a very good method'], ale#test#GetPreviewWindowText() silent! pclose + +Execute(hover with show_documentation should be in the preview window, not floating): + let g:ale_hover_to_floating_preview = 1 + let g:ale_floating_preview = 1 + + call ale#hover#SetMap({3: {'show_documentation': 1, 'buffer': bufnr('')}}) + + call ale#hover#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'quickinfo', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'documentation': 'foo is a very good method', + \ 'displayString': 'foo bar ', + \ }, + \ } + \) + + let expected = ["Every statement should end with a semicolon", "second line"] + + AssertEqual 0, g:floating_preview_show_called + +Execute(TSServer hover without show_documentation and ale_floating_preview should float): + let g:ale_floating_preview = 1 + + call ale#hover#SetMap({3: {'buffer': bufnr('')}}) + + call ale#hover#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'quickinfo', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'displayString': "the message\ncontinuing", + \ }, + \ } + \) + + AssertEqual 1, g:floating_preview_show_called + AssertEqual ["the message", "continuing"], g:floated_lines From 8dce126a6c379a1f9043061cb4d4c7673a987c39 Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 14 Jan 2021 20:24:19 +0000 Subject: [PATCH 103/167] Update the Docker image; fix an error --- ale_linters/salt/salt_lint.vim | 3 ++- run-tests | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ale_linters/salt/salt_lint.vim b/ale_linters/salt/salt_lint.vim index d2027119..47f66d83 100644 --- a/ale_linters/salt/salt_lint.vim +++ b/ale_linters/salt/salt_lint.vim @@ -25,7 +25,8 @@ function! ale_linters#salt#salt_lint#Handle(buffer, lines) abort endfunction call ale#linter#Define('salt', { -\ 'name': 'salt-lint', +\ 'name': 'salt_lint', +\ 'aliases': ['salt-lint'], \ 'executable': {b -> ale#Var(b, 'salt_salt_lint_executable')}, \ 'command': function('ale_linters#salt#salt_lint#GetCommand'), \ 'callback': 'ale_linters#salt#salt_lint#Handle' diff --git a/run-tests b/run-tests index cbd03af2..06a05384 100755 --- a/run-tests +++ b/run-tests @@ -9,8 +9,8 @@ set -u # options, or read the output below. # -image=akevinclark/ale -current_image_id=8e1802ca34b5 +image=w0rp/ale +current_image_id=1c04720f5d17 # Used in all test scripts for running the selected Docker image. DOCKER_RUN_IMAGE="$image" From a1e6df987c28dd3e0efb7422f4ad85ee3bb3bebc Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Fri, 22 Jan 2021 18:27:36 +0900 Subject: [PATCH 104/167] Fix 354 - Migrate CI from travis to Github Actions (#3549) * Fix 354 - Migrate CI from travis to Github Actions * Use matrix strategy for parallel tests * Don't build image on each run * Add push trigger on tags Co-authored-by: Horacio Sanson --- .github/workflows/main.yml | 23 +++++++++++++++++++++++ .travis.yml | 16 ---------------- 2 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/main.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..7c182758 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,23 @@ +name: CI +on: + push: + branches: [ master ] + tags: + - /^v\d+\.\d+\.(x|\d+)$/ + pull_request: + branches: [ master ] + +jobs: + test_ale: + runs-on: ubuntu-latest + strategy: + matrix: + vim-version: + - '--vim-80-only' + - '--vim-81-only' + - '--neovim-only' + - '--linters-only' + steps: + - uses: actions/checkout@v2 + - name: Run tests + run: ./run-tests -v ${{ matrix.vim-version }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 00baff1c..00000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -sudo: required -services: - - docker -language: generic -branches: - only: - - master - - /^v\d+\.\d+\.(x|\d+)$/ -env: - - OPTIONS=--vim-80-only - - OPTIONS=--vim-81-only - - OPTIONS=--neovim-only - - OPTIONS=--linters-only -script: | - ./run-tests -v $OPTIONS From 7fe61cdf0e961ee459e19ce6cf9e65cdf1f4f30a Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Wed, 6 Jan 2021 10:37:48 +0900 Subject: [PATCH 105/167] Fix 3498 - Change standardrb fixer to read from stdin. Seems standardrb fails to properly use the --config option when using temporary files but works fine when reading from stdin. This commit changes the fixer so it uses stdin instead of temporary files. --- autoload/ale/fixers/standardrb.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autoload/ale/fixers/standardrb.vim b/autoload/ale/fixers/standardrb.vim index 54330a37..acb310c6 100644 --- a/autoload/ale/fixers/standardrb.vim +++ b/autoload/ale/fixers/standardrb.vim @@ -12,12 +12,12 @@ function! ale#fixers#standardrb#GetCommand(buffer) abort return ale#ruby#EscapeExecutable(l:executable, 'standardrb') \ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '') \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' --fix --force-exclusion %t' + \ . ' --fix --force-exclusion --stdin %s' endfunction function! ale#fixers#standardrb#Fix(buffer) abort return { \ 'command': ale#fixers#standardrb#GetCommand(a:buffer), - \ 'read_temporary_file': 1, + \ 'process_with': 'ale#fixers#rubocop#PostProcess' \} endfunction From 27a22e716135776c7c3f4b758213f00bb952095b Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Wed, 6 Jan 2021 11:07:41 +0900 Subject: [PATCH 106/167] Update tests --- test/fixers/test_standardrb_fixer_callback.vader | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/fixers/test_standardrb_fixer_callback.vader b/test/fixers/test_standardrb_fixer_callback.vader index 99234b79..d315651f 100644 --- a/test/fixers/test_standardrb_fixer_callback.vader +++ b/test/fixers/test_standardrb_fixer_callback.vader @@ -21,9 +21,9 @@ Execute(The standardrb callback should return the correct default values): AssertEqual \ { - \ 'read_temporary_file': 1, + \ 'process_with': 'ale#fixers#rubocop#PostProcess', \ 'command': ale#Escape(g:ale_ruby_standardrb_executable) - \ . ' --fix --force-exclusion %t', + \ . ' --fix --force-exclusion --stdin %s', \ }, \ ale#fixers#standardrb#Fix(bufnr('')) @@ -32,10 +32,10 @@ Execute(The standardrb callback should include configuration files): AssertEqual \ { - \ 'read_temporary_file': 1, + \ 'process_with': 'ale#fixers#rubocop#PostProcess', \ 'command': ale#Escape(g:ale_ruby_standardrb_executable) \ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.standard.yml')) - \ . ' --fix --force-exclusion %t', + \ . ' --fix --force-exclusion --stdin %s', \ }, \ ale#fixers#standardrb#Fix(bufnr('')) @@ -45,10 +45,10 @@ Execute(The standardrb callback should include custom rubocop options): AssertEqual \ { - \ 'read_temporary_file': 1, + \ 'process_with': 'ale#fixers#rubocop#PostProcess', \ 'command': ale#Escape(g:ale_ruby_standardrb_executable) \ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.standard.yml')) \ . ' --except Lint/Debugger' - \ . ' --fix --force-exclusion %t', + \ . ' --fix --force-exclusion --stdin %s', \ }, \ ale#fixers#standardrb#Fix(bufnr('')) From 03eae9e085f6020a017ecbe761cccac9a5a89d77 Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Fri, 20 Sep 2019 22:04:44 +0900 Subject: [PATCH 107/167] Fix 2777 - Add IBM openapi validator --- ale_linters/openapi/ibm_validator.vim | 58 +++++++++++++++++++ doc/ale-openapi.txt | 42 ++++++++++++++ doc/ale-supported-languages-and-tools.txt | 2 + doc/ale.txt | 2 + supported-tools.md | 2 + ...m_openapi_validator_command_callback.vader | 15 +++++ .../test_ibm_openapi_validator_handler.vader | 49 ++++++++++++++++ 7 files changed, 170 insertions(+) create mode 100644 ale_linters/openapi/ibm_validator.vim create mode 100644 doc/ale-openapi.txt create mode 100644 test/command_callback/test_ibm_openapi_validator_command_callback.vader create mode 100644 test/handler/test_ibm_openapi_validator_handler.vader diff --git a/ale_linters/openapi/ibm_validator.vim b/ale_linters/openapi/ibm_validator.vim new file mode 100644 index 00000000..c54741d2 --- /dev/null +++ b/ale_linters/openapi/ibm_validator.vim @@ -0,0 +1,58 @@ +" Author: Horacio Sanson + +call ale#Set('openapi_ibm_validator_executable', 'lint-openapi') +call ale#Set('openapi_ibm_validator_options', '') + +function! ale_linters#openapi#ibm_validator#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'openapi_ibm_validator_options')) + \ . ' %t' +endfunction + +function! ale_linters#openapi#ibm_validator#Handle(buffer, lines) abort + let l:output = [] + let l:type = 'E' + let l:message = '' + let l:nr = -1 + + for l:line in a:lines + let l:match = matchlist(l:line, '^errors$') + + if !empty(l:match) + let l:type = 'E' + endif + + let l:match = matchlist(l:line, '^warnings$') + + if !empty(l:match) + let l:type = 'W' + endif + + let l:match = matchlist(l:line, '^ *Message : *\(.\+\)$') + + if !empty(l:match) + let l:message = l:match[1] + endif + + let l:match = matchlist(l:line, '^ *Line *: *\(\d\+\)$') + + if !empty(l:match) + let l:nr = l:match[1] + + call add(l:output, { + \ 'lnum': l:nr + 0, + \ 'col': 0, + \ 'text': l:message, + \ 'type': l:type, + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('openapi', { +\ 'name': 'ibm-validator', +\ 'executable': {b -> ale#Var(b, 'openapi_ibm_validator_executable')}, +\ 'command': function('ale_linters#openapi#ibm_validator#GetCommand'), +\ 'callback': 'ale_linters#openapi#ibm_validator#Handle', +\}) diff --git a/doc/ale-openapi.txt b/doc/ale-openapi.txt new file mode 100644 index 00000000..d0ab9bfc --- /dev/null +++ b/doc/ale-openapi.txt @@ -0,0 +1,42 @@ +=============================================================================== +ALE OpenApi Integration *ale-openapi-options* + +=============================================================================== +ibm-validator *ale-openapi-ibm-validator* + +Website: https://github.com/IBM/openapi-validator + + +Installation +------------------------------------------------------------------------------- + +Install ibm-openapi-validator either globally or locally: > + + npm install ibm-openapi-validator -g # global + npm install ibm-openapi-validator # local +< +Recommended plugin for openapi filetype detection: + + https://github.com/hsanson/vim-openapi + +Options +------------------------------------------------------------------------------- + +g:ale_openapi_ibm_validator_executable *g:ale_openapi_ibm_validator_executable* + *b:ale_openapi_ibm_validator_executable* + Type: |String| + Default: `'lint-openapi'` + + This variable can be set to change the path to lint-openapi. + + +g:ale_openapi_ibm_validator_options *g:ale_openapi_ibm_validator_options* + *b:ale_openapi_ibm_validator_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to lint-openapi. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 5476be47..b73bec4f 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -322,6 +322,8 @@ Notes: * `ocamlformat` * `ocp-indent` * `ols` +* OpenApi + * `ibm-validator` * Pawn * `uncrustify` * Perl diff --git a/doc/ale.txt b/doc/ale.txt index 721ca69d..68ac8498 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2835,6 +2835,8 @@ documented in additional help files. ols...................................|ale-ocaml-ols| ocamlformat...........................|ale-ocaml-ocamlformat| ocp-indent............................|ale-ocaml-ocp-indent| + openapi.................................|ale-openapi-options| + ibm-validator.........................|ale-openapi-ibm-validator| pawn....................................|ale-pawn-options| uncrustify............................|ale-pawn-uncrustify| perl....................................|ale-perl-options| diff --git a/supported-tools.md b/supported-tools.md index b07f6acf..a74fdd99 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -331,6 +331,8 @@ formatting. * [ocamlformat](https://github.com/ocaml-ppx/ocamlformat) * [ocp-indent](https://github.com/OCamlPro/ocp-indent) * [ols](https://github.com/freebroccolo/ocaml-language-server) +* OpenApi + * [ibm-validator](https://github.com/IBM/openapi-validator) * Pawn * [uncrustify](https://github.com/uncrustify/uncrustify) * Perl diff --git a/test/command_callback/test_ibm_openapi_validator_command_callback.vader b/test/command_callback/test_ibm_openapi_validator_command_callback.vader new file mode 100644 index 00000000..3484cc09 --- /dev/null +++ b/test/command_callback/test_ibm_openapi_validator_command_callback.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('openapi', 'ibm_validator') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The yaml ibm-openapi-validator command callback should return the correct default string): + AssertLinter 'lint-openapi', ale#Escape('lint-openapi') . ' %t' + +Execute(The yaml ibm-openapi-validator command callback should be configurable): + let g:ale_openapi_ibm_validator_executable = '~/.local/bin/lint-openapi' + let g:ale_openapi_ibm_validator_options = '-c ~/.config' + + AssertLinter '~/.local/bin/lint-openapi', ale#Escape('~/.local/bin/lint-openapi') + \ . ' -c ~/.config %t' diff --git a/test/handler/test_ibm_openapi_validator_handler.vader b/test/handler/test_ibm_openapi_validator_handler.vader new file mode 100644 index 00000000..e136d5d2 --- /dev/null +++ b/test/handler/test_ibm_openapi_validator_handler.vader @@ -0,0 +1,49 @@ +Before: + runtime! ale_linters/openapi/ibm_validator.vim + +After: + call ale#linter#Reset() + +Execute(Problems should be parsed correctly for openapi-ibm-validator): + AssertEqual + \ [ + \ { + \ 'lnum': 54, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'Items with a description must have content in it.', + \ }, + \ { + \ 'lnum': 24, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'Operations must have a non-empty `operationId`.', + \ }, + \ { + \ 'lnum': 40, + \ 'col': 0, + \ 'type': 'W', + \ 'text': 'operationIds must follow case convention: lower_snake_case', + \ }, + \ ], + \ ale_linters#openapi#ibm_validator#Handle(bufnr(''), [ + \ '', + \ '[Warning] No .validaterc file found. The validator will run in default mode.', + \ 'To configure the validator, create a .validaterc file.', + \ '', + \ 'errors', + \ '', + \ ' Message : Items with a description must have content in it.', + \ ' Path : paths./settings.patch.description', + \ ' Line : 54', + \ '', + \ 'warnings', + \ '', + \ ' Message : Operations must have a non-empty `operationId`.', + \ ' Path : paths./stats.get.operationId', + \ ' Line : 24', + \ '', + \ ' Message : operationIds must follow case convention: lower_snake_case', + \ ' Path : paths./settings.get.operationId', + \ ' Line : 40' + \ ]) From 014b00d4d778bbfe027e927183b44ce3424679b4 Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Sun, 27 Oct 2019 00:16:23 +0900 Subject: [PATCH 108/167] Add yamllint and prettier to openapi. This commit enables yamllint and prettier on openapi files. --- ale_linters/openapi/yamllint.vim | 9 +++++ ale_linters/yaml/yamllint.vim | 43 ++--------------------- autoload/ale/fix/registry.vim | 2 +- autoload/ale/fixers/prettier.vim | 1 + autoload/ale/handlers/yamllint.vim | 39 ++++++++++++++++++++ doc/ale-openapi.txt | 12 +++++++ doc/ale-supported-languages-and-tools.txt | 2 ++ doc/ale.txt | 2 ++ supported-tools.md | 2 ++ test/handler/test_yamllint_handler.vader | 8 ++--- 10 files changed, 74 insertions(+), 46 deletions(-) create mode 100644 ale_linters/openapi/yamllint.vim create mode 100644 autoload/ale/handlers/yamllint.vim diff --git a/ale_linters/openapi/yamllint.vim b/ale_linters/openapi/yamllint.vim new file mode 100644 index 00000000..2b8952cc --- /dev/null +++ b/ale_linters/openapi/yamllint.vim @@ -0,0 +1,9 @@ +call ale#Set('yaml_yamllint_executable', 'yamllint') +call ale#Set('yaml_yamllint_options', '') + +call ale#linter#Define('openapi', { +\ 'name': 'yamllint', +\ 'executable': {b -> ale#Var(b, 'yaml_yamllint_executable')}, +\ 'command': function('ale#handlers#yamllint#GetCommand'), +\ 'callback': 'ale#handlers#yamllint#Handle', +\}) diff --git a/ale_linters/yaml/yamllint.vim b/ale_linters/yaml/yamllint.vim index bedb7bf1..39011df1 100644 --- a/ale_linters/yaml/yamllint.vim +++ b/ale_linters/yaml/yamllint.vim @@ -3,48 +3,9 @@ call ale#Set('yaml_yamllint_executable', 'yamllint') call ale#Set('yaml_yamllint_options', '') -function! ale_linters#yaml#yamllint#GetCommand(buffer) abort - return '%e' . ale#Pad(ale#Var(a:buffer, 'yaml_yamllint_options')) - \ . ' -f parsable %t' -endfunction - -function! ale_linters#yaml#yamllint#Handle(buffer, lines) abort - " Matches patterns line the following: - " something.yaml:1:1: [warning] missing document start "---" (document-start) - " something.yml:2:1: [error] syntax error: expected the node content, but found '' - let l:pattern = '\v^.*:(\d+):(\d+): \[(error|warning)\] (.+)$' - let l:output = [] - - for l:match in ale#util#GetMatches(a:lines, l:pattern) - let l:item = { - \ 'lnum': l:match[1] + 0, - \ 'col': l:match[2] + 0, - \ 'text': l:match[4], - \ 'type': l:match[3] is# 'error' ? 'E' : 'W', - \} - - let l:code_match = matchlist(l:item.text, '\v^(.+) \(([^)]+)\)$') - - if !empty(l:code_match) - if l:code_match[2] is# 'trailing-spaces' - \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') - " Skip warnings for trailing whitespace if the option is off. - continue - endif - - let l:item.text = l:code_match[1] - let l:item.code = l:code_match[2] - endif - - call add(l:output, l:item) - endfor - - return l:output -endfunction - call ale#linter#Define('yaml', { \ 'name': 'yamllint', \ 'executable': {b -> ale#Var(b, 'yaml_yamllint_executable')}, -\ 'command': function('ale_linters#yaml#yamllint#GetCommand'), -\ 'callback': 'ale_linters#yaml#yamllint#Handle', +\ 'command': function('ale#handlers#yamllint#GetCommand'), +\ 'callback': 'ale#handlers#yamllint#Handle', \}) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index f514466e..4564954b 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -102,7 +102,7 @@ let s:default_registry = { \ }, \ 'prettier': { \ 'function': 'ale#fixers#prettier#Fix', -\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'html', 'yaml'], +\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'html', 'yaml', 'openapi'], \ 'description': 'Apply prettier to a file.', \ }, \ 'prettier_eslint': { diff --git a/autoload/ale/fixers/prettier.vim b/autoload/ale/fixers/prettier.vim index e0f4972e..12c018af 100644 --- a/autoload/ale/fixers/prettier.vim +++ b/autoload/ale/fixers/prettier.vim @@ -83,6 +83,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort \ 'markdown': 'markdown', \ 'vue': 'vue', \ 'yaml': 'yaml', + \ 'openapi': 'yaml', \ 'html': 'html', \} diff --git a/autoload/ale/handlers/yamllint.vim b/autoload/ale/handlers/yamllint.vim new file mode 100644 index 00000000..5e04577d --- /dev/null +++ b/autoload/ale/handlers/yamllint.vim @@ -0,0 +1,39 @@ +function! ale#handlers#yamllint#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'yaml_yamllint_options')) + \ . ' -f parsable %t' +endfunction + +function! ale#handlers#yamllint#Handle(buffer, lines) abort + " Matches patterns line the following: + " something.yaml:1:1: [warning] missing document start "---" (document-start) + " something.yml:2:1: [error] syntax error: expected the node content, but found '' + let l:pattern = '\v^.*:(\d+):(\d+): \[(error|warning)\] (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'text': l:match[4], + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \} + + let l:code_match = matchlist(l:item.text, '\v^(.+) \(([^)]+)\)$') + + if !empty(l:code_match) + if l:code_match[2] is# 'trailing-spaces' + \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + " Skip warnings for trailing whitespace if the option is off. + continue + endif + + let l:item.text = l:code_match[1] + let l:item.code = l:code_match[2] + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + diff --git a/doc/ale-openapi.txt b/doc/ale-openapi.txt index d0ab9bfc..27261de6 100644 --- a/doc/ale-openapi.txt +++ b/doc/ale-openapi.txt @@ -38,5 +38,17 @@ g:ale_openapi_ibm_validator_options *g:ale_openapi_ibm_validator_options* This variable can be set to pass additional options to lint-openapi. +=============================================================================== +prettier *ale-openapi-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +yamllint *ale-openapi-yamllint* + +See |ale-yaml-yamllint| for information about the available options. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index b73bec4f..57eb71dc 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -324,6 +324,8 @@ Notes: * `ols` * OpenApi * `ibm-validator` + * `prettier` + * `yamllint` * Pawn * `uncrustify` * Perl diff --git a/doc/ale.txt b/doc/ale.txt index 68ac8498..b2cea4cd 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2837,6 +2837,8 @@ documented in additional help files. ocp-indent............................|ale-ocaml-ocp-indent| openapi.................................|ale-openapi-options| ibm-validator.........................|ale-openapi-ibm-validator| + prettier..............................|ale-openapi-prettier| + yamllint..............................|ale-openapi-yamllint| pawn....................................|ale-pawn-options| uncrustify............................|ale-pawn-uncrustify| perl....................................|ale-perl-options| diff --git a/supported-tools.md b/supported-tools.md index a74fdd99..df9071f8 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -333,6 +333,8 @@ formatting. * [ols](https://github.com/freebroccolo/ocaml-language-server) * OpenApi * [ibm-validator](https://github.com/IBM/openapi-validator) + * [prettier](https://github.com/prettier/prettier) + * [yamllint](https://yamllint.readthedocs.io/) * Pawn * [uncrustify](https://github.com/uncrustify/uncrustify) * Perl diff --git a/test/handler/test_yamllint_handler.vader b/test/handler/test_yamllint_handler.vader index 1aa0b9f5..dd51119c 100644 --- a/test/handler/test_yamllint_handler.vader +++ b/test/handler/test_yamllint_handler.vader @@ -3,7 +3,7 @@ Before: let g:ale_warn_about_trailing_whitespace = 1 - runtime! ale_linters/yaml/yamllint.vim + runtime! ale/handlers/yamllint.vim After: Restore @@ -29,7 +29,7 @@ Execute(Problems should be parsed correctly for yamllint): \ 'text': 'syntax error: expected the node content, but found ''''', \ }, \ ], - \ ale_linters#yaml#yamllint#Handle(bufnr(''), [ + \ ale#handlers#yamllint#Handle(bufnr(''), [ \ 'something.yaml:1:1: [warning] missing document start "---" (document-start)', \ 'something.yml:2:1: [error] syntax error: expected the node content, but found ''''', \ ]) @@ -45,7 +45,7 @@ Execute(The yamllint handler should respect ale_warn_about_trailing_whitespace): \ 'code': 'trailing-spaces', \ }, \ ], - \ ale_linters#yaml#yamllint#Handle(bufnr(''), [ + \ ale#handlers#yamllint#Handle(bufnr(''), [ \ 'something.yml:5:18: [error] trailing spaces (trailing-spaces)', \ ]) @@ -54,6 +54,6 @@ Execute(The yamllint handler should respect ale_warn_about_trailing_whitespace): AssertEqual \ [ \ ], - \ ale_linters#yaml#yamllint#Handle(bufnr(''), [ + \ ale#handlers#yamllint#Handle(bufnr(''), [ \ 'something.yml:5:18: [error] trailing spaces (trailing-spaces)', \ ]) From 4aa11cbc055ccbc18d2d48a944566b08d6815583 Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Fri, 15 May 2020 09:15:57 +0900 Subject: [PATCH 109/167] Improve documentation --- doc/ale-openapi.txt | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/doc/ale-openapi.txt b/doc/ale-openapi.txt index 27261de6..a1137ed8 100644 --- a/doc/ale-openapi.txt +++ b/doc/ale-openapi.txt @@ -15,7 +15,27 @@ Install ibm-openapi-validator either globally or locally: > npm install ibm-openapi-validator -g # global npm install ibm-openapi-validator # local < -Recommended plugin for openapi filetype detection: +Configuration +------------------------------------------------------------------------------- + +OpenAPI files can be written in YAML or JSON so in order for ALE plugins to +work with these files we must set the buffer |filetype| to either |openapi.yaml| +or |openapi.json| respectively. This causes ALE to lint the file with linters +configured for openapi and yaml files or openapi and json files respectively. + +For example setting filetype to |openapi.yaml| on a buffer and the following +|g:ale_linters| configuration will enable linting of openapi files using both +|ibm-validator| and |yamlint|: + +> + let g:ale_linters = { + \ 'yaml': ['yamllint'], + \ 'openapi': ['ibm-validator'] + \} +< + +The following plugin will detect openapi files automatically and set the +filetype to |openapi.yaml| or |openapi.json|: https://github.com/hsanson/vim-openapi From 65824feef320f56a9f645cfe1a3107ff8717372a Mon Sep 17 00:00:00 2001 From: fenuks Date: Fri, 22 Jan 2021 01:01:26 +0100 Subject: [PATCH 110/167] Fix clang-tidy ignoring compile_commands.json --- ale_linters/cpp/clangtidy.vim | 10 ++++++---- .../test_clang_tidy_command_callback.vader | 1 - 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ale_linters/cpp/clangtidy.vim b/ale_linters/cpp/clangtidy.vim index 5e062d86..d6944aae 100644 --- a/ale_linters/cpp/clangtidy.vim +++ b/ale_linters/cpp/clangtidy.vim @@ -23,11 +23,13 @@ function! ale_linters#cpp#clangtidy#GetCommand(buffer, output) abort let l:options = ale#Var(a:buffer, 'cpp_clangtidy_options') let l:cflags = ale#c#GetCFlags(a:buffer, a:output) let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags - endif - " Tell clang-tidy a .h header with a C++ filetype in Vim is a C++ file. - if expand('#' . a:buffer) =~# '\.h$' - let l:options .= !empty(l:options) ? ' -x c++' : '-x c++' + " Tell clang-tidy a .h header with a C++ filetype in Vim is a C++ file + " only when compile-commands.json file is not there. Adding these + " flags makes clang-tidy completely ignore compile commmands. + if expand('#' . a:buffer) =~# '\.h$' + let l:options .= !empty(l:options) ? ' -x c++' : '-x c++' + endif endif " Get the options to pass directly to clang-tidy diff --git a/test/command_callback/test_clang_tidy_command_callback.vader b/test/command_callback/test_clang_tidy_command_callback.vader index f0a07e8c..eb1220be 100644 --- a/test/command_callback/test_clang_tidy_command_callback.vader +++ b/test/command_callback/test_clang_tidy_command_callback.vader @@ -68,7 +68,6 @@ Execute(The build directory should be used for header files): \ ale#Escape('clang-tidy') \ . ' -checks=' . ale#Escape('*') . ' %s' \ . ' -p ' . ale#Escape('/foo/bar') - \ . ' -- -x c++' call ale#test#SetFilename('test.hpp') From 9bc4b468c20e91350cf1a6d3739f91f504e230ed Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Fri, 22 Jan 2021 23:51:29 +0900 Subject: [PATCH 111/167] Fix linter error --- ale_linters/openapi/ibm_validator.vim | 2 +- doc/ale-openapi.txt | 6 +++--- doc/ale-supported-languages-and-tools.txt | 2 +- doc/ale.txt | 2 +- supported-tools.md | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ale_linters/openapi/ibm_validator.vim b/ale_linters/openapi/ibm_validator.vim index c54741d2..446931a2 100644 --- a/ale_linters/openapi/ibm_validator.vim +++ b/ale_linters/openapi/ibm_validator.vim @@ -51,7 +51,7 @@ function! ale_linters#openapi#ibm_validator#Handle(buffer, lines) abort endfunction call ale#linter#Define('openapi', { -\ 'name': 'ibm-validator', +\ 'name': 'ibm_validator', \ 'executable': {b -> ale#Var(b, 'openapi_ibm_validator_executable')}, \ 'command': function('ale_linters#openapi#ibm_validator#GetCommand'), \ 'callback': 'ale_linters#openapi#ibm_validator#Handle', diff --git a/doc/ale-openapi.txt b/doc/ale-openapi.txt index a1137ed8..1fc41add 100644 --- a/doc/ale-openapi.txt +++ b/doc/ale-openapi.txt @@ -2,7 +2,7 @@ ALE OpenApi Integration *ale-openapi-options* =============================================================================== -ibm-validator *ale-openapi-ibm-validator* +ibm_validator *ale-openapi-ibm-validator* Website: https://github.com/IBM/openapi-validator @@ -25,12 +25,12 @@ configured for openapi and yaml files or openapi and json files respectively. For example setting filetype to |openapi.yaml| on a buffer and the following |g:ale_linters| configuration will enable linting of openapi files using both -|ibm-validator| and |yamlint|: +|ibm_validator| and |yamlint|: > let g:ale_linters = { \ 'yaml': ['yamllint'], - \ 'openapi': ['ibm-validator'] + \ 'openapi': ['ibm_validator'] \} < diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 57eb71dc..13538b03 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -323,7 +323,7 @@ Notes: * `ocp-indent` * `ols` * OpenApi - * `ibm-validator` + * `ibm_validator` * `prettier` * `yamllint` * Pawn diff --git a/doc/ale.txt b/doc/ale.txt index b2cea4cd..cfb5beb4 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2836,7 +2836,7 @@ documented in additional help files. ocamlformat...........................|ale-ocaml-ocamlformat| ocp-indent............................|ale-ocaml-ocp-indent| openapi.................................|ale-openapi-options| - ibm-validator.........................|ale-openapi-ibm-validator| + ibm_validator.........................|ale-openapi-ibm-validator| prettier..............................|ale-openapi-prettier| yamllint..............................|ale-openapi-yamllint| pawn....................................|ale-pawn-options| diff --git a/supported-tools.md b/supported-tools.md index df9071f8..0cea2a1b 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -332,7 +332,7 @@ formatting. * [ocp-indent](https://github.com/OCamlPro/ocp-indent) * [ols](https://github.com/freebroccolo/ocaml-language-server) * OpenApi - * [ibm-validator](https://github.com/IBM/openapi-validator) + * [ibm_validator](https://github.com/IBM/openapi-validator) * [prettier](https://github.com/prettier/prettier) * [yamllint](https://yamllint.readthedocs.io/) * Pawn From 4ed520a2192cfee9b93f329e46a0a57c2bd2e771 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Sat, 2 Jan 2021 15:42:38 +0900 Subject: [PATCH 112/167] add initial files --- ale_linters/vala/vala_lint.vim | 44 +++++++++++++++++++++++ test/handler/test_vala_lint_handler.vader | 37 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 ale_linters/vala/vala_lint.vim create mode 100644 test/handler/test_vala_lint_handler.vader diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim new file mode 100644 index 00000000..4aad4dcd --- /dev/null +++ b/ale_linters/vala/vala_lint.vim @@ -0,0 +1,44 @@ +" Author: Atsuya Takagi +" Description: A linter for Vala using Vala-Lint. + +function! ale_linters#vala#vala_lint#GetCommand(buffer) abort + return 'io.elementary.vala-lint' +endfunction + +function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort + let l:pattern = '^\s*\(\d\+\)\.\(\d\+\)\s\+\(\w\+\)\s\+\(.\+\)\s\([A-Za-z0-9_\-]\+\)' + let l:output = [] + + for l:line in a:lines + let l:match = matchlist(l:line, l:pattern) + + if len(l:match) == 0 + continue + endif + + let l:line = l:match[1] + 0 + let l:column = l:match[2] + 0 + let l:type = 'E' + let l:text = substitute(l:match[4], '^\s*\(.\{-}\)\s*$', '\1', '') + let l:code = l:match[5] + + call add(l:output, { + \ 'lnum': l:line, + \ 'col': l:column, + \ 'text': l:text, + \ 'type': l:type, + \ 'code': l:code, + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('vala', { +\ 'name': 'vala-lint', +\ 'output_stream': 'both', +\ 'executable': 'io.elementary.vala-lint', +\ 'command': function('ale_linters#vala#vala_lint#GetCommand'), +\ 'callback': 'ale_linters#vala#vala_lint#Handle', +\ 'lint_file': 1, +\}) diff --git a/test/handler/test_vala_lint_handler.vader b/test/handler/test_vala_lint_handler.vader new file mode 100644 index 00000000..cee8674a --- /dev/null +++ b/test/handler/test_vala_lint_handler.vader @@ -0,0 +1,37 @@ +Before: + runtime ale_linters/vala/vala_lint.vim + +After: + call ale#linter#Reset() + +Execute(The Vala-Lint handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 18, + \ 'col': 18, + \ 'text': 'Expected space before paren', + \ 'code': 'space-before-paren', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 64, + \ 'col': 37, + \ 'text': 'Expected space before paren', + \ 'code': 'space-before-paren', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 73, + \ 'col': 37, + \ 'text': 'Expected space before paren', + \ 'code': 'space-before-paren', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#vala#vala_lint#Handle(bufnr(''), [ + \ 'Application.vala', + \ ' 18.18 error Expected space before paren space-before-paren', + \ ' 64.37 error Expected space before paren space-before-paren', + \ ' 73.37 error Expected space before paren space-before-paren', + \ ]) From 3e820207e7d637a86a16dfce3e2d4fa698b0811d Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Sat, 2 Jan 2021 15:52:10 +0900 Subject: [PATCH 113/167] be precise about output_stream --- ale_linters/vala/vala_lint.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index 4aad4dcd..42434651 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -36,7 +36,7 @@ endfunction call ale#linter#Define('vala', { \ 'name': 'vala-lint', -\ 'output_stream': 'both', +\ 'output_stream': 'stdout', \ 'executable': 'io.elementary.vala-lint', \ 'command': function('ale_linters#vala#vala_lint#GetCommand'), \ 'callback': 'ale_linters#vala#vala_lint#Handle', From 7f1dd5f66ab207676baf79e22edc5e42309306ec Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Sat, 2 Jan 2021 16:02:35 +0900 Subject: [PATCH 114/167] specify a filename of the current buffer --- ale_linters/vala/vala_lint.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index 42434651..8658c17c 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -2,7 +2,7 @@ " Description: A linter for Vala using Vala-Lint. function! ale_linters#vala#vala_lint#GetCommand(buffer) abort - return 'io.elementary.vala-lint' + return 'io.elementary.vala-lint %s' endfunction function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort From e94d23b1d906df77453f111f7e7984385c20eaa2 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Sat, 2 Jan 2021 16:38:45 +0900 Subject: [PATCH 115/167] test my hypotethis --- ale_linters/vala/vala_lint.vim | 44 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index 8658c17c..5b512ad0 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -9,27 +9,35 @@ function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort let l:pattern = '^\s*\(\d\+\)\.\(\d\+\)\s\+\(\w\+\)\s\+\(.\+\)\s\([A-Za-z0-9_\-]\+\)' let l:output = [] - for l:line in a:lines - let l:match = matchlist(l:line, l:pattern) + call add(l:output, { + \ 'lnum': 12, + \ 'col': 30, + \ 'text': 'bad', + \ 'type': 'E', + \ 'code': 'testcode', + \}) - if len(l:match) == 0 - continue - endif + "for l:line in a:lines + " let l:match = matchlist(l:line, l:pattern) - let l:line = l:match[1] + 0 - let l:column = l:match[2] + 0 - let l:type = 'E' - let l:text = substitute(l:match[4], '^\s*\(.\{-}\)\s*$', '\1', '') - let l:code = l:match[5] + " if len(l:match) == 0 + " continue + " endif - call add(l:output, { - \ 'lnum': l:line, - \ 'col': l:column, - \ 'text': l:text, - \ 'type': l:type, - \ 'code': l:code, - \}) - endfor + " let l:line = l:match[1] + 0 + " let l:column = l:match[2] + 0 + " let l:type = 'E' + " let l:text = substitute(l:match[4], '^\s*\(.\{-}\)\s*$', '\1', '') + " let l:code = l:match[5] + + " call add(l:output, { + " \ 'lnum': l:line, + " \ 'col': l:column, + " \ 'text': l:text, + " \ 'type': l:type, + " \ 'code': l:code, + " \}) + "endfor return l:output endfunction From 9eb6dace889174c61fbaa13ed3c59d91172b5c60 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Sat, 2 Jan 2021 16:48:54 +0900 Subject: [PATCH 116/167] escape color sequences --- ale_linters/vala/vala_lint.vim | 49 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index 5b512ad0..f102d567 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -9,35 +9,32 @@ function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort let l:pattern = '^\s*\(\d\+\)\.\(\d\+\)\s\+\(\w\+\)\s\+\(.\+\)\s\([A-Za-z0-9_\-]\+\)' let l:output = [] - call add(l:output, { - \ 'lnum': 12, - \ 'col': 30, - \ 'text': 'bad', - \ 'type': 'E', - \ 'code': 'testcode', - \}) + for l:line in a:lines + " remove color escape sequences since vala-lint doesn't support + " output without colors + let l:cleaned_line = substitute(l:line, '\x1b\[[0-9;]*m', '', 'g') + execute 'echo l:line' + execute 'echo l:cleaned_line' + let l:match = matchlist(l:cleaned, l:pattern) - "for l:line in a:lines - " let l:match = matchlist(l:line, l:pattern) + if len(l:match) == 0 + continue + endif - " if len(l:match) == 0 - " continue - " endif + let l:lnum = l:match[1] + 0 + let l:column = l:match[2] + 0 + let l:type = 'E' + let l:text = substitute(l:match[4], '^\s*\(.\{-}\)\s*$', '\1', '') + let l:code = l:match[5] - " let l:line = l:match[1] + 0 - " let l:column = l:match[2] + 0 - " let l:type = 'E' - " let l:text = substitute(l:match[4], '^\s*\(.\{-}\)\s*$', '\1', '') - " let l:code = l:match[5] - - " call add(l:output, { - " \ 'lnum': l:line, - " \ 'col': l:column, - " \ 'text': l:text, - " \ 'type': l:type, - " \ 'code': l:code, - " \}) - "endfor + call add(l:output, { + \ 'lnum': l:lnum, + \ 'col': l:column, + \ 'text': l:text, + \ 'type': l:type, + \ 'code': l:code, + \}) + endfor return l:output endfunction From b3010ad7930344a06163a99182c21e4c768f8a23 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Sat, 2 Jan 2021 16:54:06 +0900 Subject: [PATCH 117/167] fix the wrong variable name --- ale_linters/vala/vala_lint.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index f102d567..0940f294 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -15,7 +15,7 @@ function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort let l:cleaned_line = substitute(l:line, '\x1b\[[0-9;]*m', '', 'g') execute 'echo l:line' execute 'echo l:cleaned_line' - let l:match = matchlist(l:cleaned, l:pattern) + let l:match = matchlist(l:cleaned_line, l:pattern) if len(l:match) == 0 continue From c15d9538cda6ac4bc7cd258b2a0a271ed22ac350 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Sat, 2 Jan 2021 17:28:06 +0900 Subject: [PATCH 118/167] use the correct regex to match the escape sequences... --- ale_linters/vala/vala_lint.vim | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index 0940f294..b0c86fcc 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -12,9 +12,7 @@ function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort for l:line in a:lines " remove color escape sequences since vala-lint doesn't support " output without colors - let l:cleaned_line = substitute(l:line, '\x1b\[[0-9;]*m', '', 'g') - execute 'echo l:line' - execute 'echo l:cleaned_line' + let l:cleaned_line = substitute(l:line, '\e\[[0-9;]\+[mK]', '', 'g') let l:match = matchlist(l:cleaned_line, l:pattern) if len(l:match) == 0 From 280d2dedaeba09aad139e9b2c6ea37e3213083b4 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Mon, 4 Jan 2021 15:49:29 +0900 Subject: [PATCH 119/167] find and use vala-lint config if exists --- ale_linters/vala/vala_lint.vim | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index b0c86fcc..b53e9b86 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -2,7 +2,14 @@ " Description: A linter for Vala using Vala-Lint. function! ale_linters#vala#vala_lint#GetCommand(buffer) abort - return 'io.elementary.vala-lint %s' + let l:command = 'io.elementary.vala-lint ' + + let l:config_path = ale#path#FindNearestFile(a:buffer, 'vala-lint.conf') + if !empty(l:config_path) + let l:command .= '-c ' . l:config_path . ' ' + endif + + return l:command . '%s' endfunction function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort From 89403b4a0600011ad94d51a7aef9e26afe284fd6 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Mon, 4 Jan 2021 16:00:30 +0900 Subject: [PATCH 120/167] expect warn or error --- ale_linters/vala/vala_lint.vim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index b53e9b86..a38bf9bf 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -13,7 +13,7 @@ function! ale_linters#vala#vala_lint#GetCommand(buffer) abort endfunction function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort - let l:pattern = '^\s*\(\d\+\)\.\(\d\+\)\s\+\(\w\+\)\s\+\(.\+\)\s\([A-Za-z0-9_\-]\+\)' + let l:pattern = '^\s*\(\d\+\)\.\(\d\+\)\s\+\(error\|warn\)\s\+\(.\+\)\s\([A-Za-z0-9_\-]\+\)' let l:output = [] for l:line in a:lines @@ -26,10 +26,13 @@ function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort continue endif + let l:refined_type = l:match[3] is# 'warn' ? 'W' : 'E' + let l:cleaned_text = substitute(l:match[4], '^\s*\(.\{-}\)\s*$', '\1', '') + let l:lnum = l:match[1] + 0 let l:column = l:match[2] + 0 - let l:type = 'E' - let l:text = substitute(l:match[4], '^\s*\(.\{-}\)\s*$', '\1', '') + let l:type = l:refined_type + let l:text = l:cleaned_text let l:code = l:match[5] call add(l:output, { From 823b094f5618c9dd53a0a56bbf131ed077f4105b Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Mon, 4 Jan 2021 16:17:33 +0900 Subject: [PATCH 121/167] support flags for enable/disable config --- ale_linters/vala/vala_lint.vim | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index a38bf9bf..24ade378 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -1,12 +1,18 @@ " Author: Atsuya Takagi " Description: A linter for Vala using Vala-Lint. +let g:ale_vala_vala_lint_enable_config = get(g:, 'ale_vala_vala_lint_enable_config', 0) +let g:ale_vala_vala_lint_config_filename = get(g:, 'ale_vala_vala_lint_config_filename', 'vala-lint.conf') + function! ale_linters#vala#vala_lint#GetCommand(buffer) abort let l:command = 'io.elementary.vala-lint ' - let l:config_path = ale#path#FindNearestFile(a:buffer, 'vala-lint.conf') - if !empty(l:config_path) - let l:command .= '-c ' . l:config_path . ' ' + if ale#Var(a:buffer, 'vala_vala_lint_enable_config') + let l:config_filename = ale#Var(a:buffer, 'vala_vala_lint_config_filename') + let l:config_path = ale#path#FindNearestFile(a:buffer, l:config_filename) + if !empty(l:config_path) + let l:command .= '-c ' . l:config_path . ' ' + endif endif return l:command . '%s' From ed2afafd621503f684c31a5e6e75e358f7ccb6ef Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Mon, 4 Jan 2021 16:28:51 +0900 Subject: [PATCH 122/167] use ale#Set for setting default config variable values --- ale_linters/vala/vala_lint.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index 24ade378..d540323c 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -1,8 +1,8 @@ " Author: Atsuya Takagi " Description: A linter for Vala using Vala-Lint. -let g:ale_vala_vala_lint_enable_config = get(g:, 'ale_vala_vala_lint_enable_config', 0) -let g:ale_vala_vala_lint_config_filename = get(g:, 'ale_vala_vala_lint_config_filename', 'vala-lint.conf') +call ale#Set('vala_vala_lint_enable_config', 0) +call ale#Set('vala_vala_lint_config_filename', 'vala-lint.conf') function! ale_linters#vala#vala_lint#GetCommand(buffer) abort let l:command = 'io.elementary.vala-lint ' From 67c3fa9001c28ea19e1ac09bd733680fb8df4c24 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Mon, 4 Jan 2021 16:44:32 +0900 Subject: [PATCH 123/167] add documentation for vala-lint --- doc/ale-vala.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/ale-vala.txt b/doc/ale-vala.txt index ca24bcf4..94bf5400 100644 --- a/doc/ale-vala.txt +++ b/doc/ale-vala.txt @@ -8,5 +8,24 @@ uncrustify *ale-vala-uncrustify* See |ale-c-uncrustify| for information about the available options. +=============================================================================== +Vala-Lint *ale-vala-vala-lint* + +g:ale_vala_vala_lint_enable_config *g:vala_vala_lint_enable_config* + *b:vala_vala_lint_enable_config* + Type: |Number| + Default: `'0'` + + This variable can be set to enable or diable the use of Vala-Lint config file. + + +g:vala_vala_lint_config_filename *g:vala_vala_lint_config_filename* + *b:vala_vala_lint_config_filename* + Type: |String| + Default: `'vala-lint.conf'` + + This variable can be set to specify a Vala-Lint config filename. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: From 2dbf4ee271600a7e243a6d475c57bf54958e904e Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Mon, 4 Jan 2021 16:45:12 +0900 Subject: [PATCH 124/167] add test to check if it properly ignores outputs with unknown error types --- test/handler/test_vala_lint_handler.vader | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/test/handler/test_vala_lint_handler.vader b/test/handler/test_vala_lint_handler.vader index cee8674a..b8a4fbfa 100644 --- a/test/handler/test_vala_lint_handler.vader +++ b/test/handler/test_vala_lint_handler.vader @@ -19,7 +19,7 @@ Execute(The Vala-Lint handler should parse lines correctly): \ 'col': 37, \ 'text': 'Expected space before paren', \ 'code': 'space-before-paren', - \ 'type': 'E', + \ 'type': 'W', \ }, \ { \ 'lnum': 73, @@ -32,6 +32,23 @@ Execute(The Vala-Lint handler should parse lines correctly): \ ale_linters#vala#vala_lint#Handle(bufnr(''), [ \ 'Application.vala', \ ' 18.18 error Expected space before paren space-before-paren', - \ ' 64.37 error Expected space before paren space-before-paren', + \ ' 64.37 warn Expected space before paren space-before-paren', + \ ' 73.37 error Expected space before paren space-before-paren', + \ ]) + +Execute(The Vala-Lint handler should ignore unknown error types): + AssertEqual + \ [ + \ { + \ 'lnum': 73, + \ 'col': 37, + \ 'text': 'Expected space before paren', + \ 'code': 'space-before-paren', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#vala#vala_lint#Handle(bufnr(''), [ + \ 'Application.vala', + \ ' 18.18 test Expected space before paren space-before-paren', \ ' 73.37 error Expected space before paren space-before-paren', \ ]) From 04550717bf023db549c67510c7df429d154f3934 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Tue, 5 Jan 2021 17:49:43 +0900 Subject: [PATCH 125/167] add Vala-Lint as supported linter --- doc/ale-supported-languages-and-tools.txt | 1 + supported-tools.md | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 5476be47..d8d10379 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -501,6 +501,7 @@ Notes: * `typecheck` * VALA * `uncrustify` + * `vala-lint`!! * Verilog * `hdl-checker` * `iverilog` diff --git a/supported-tools.md b/supported-tools.md index b07f6acf..21035ffb 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -510,6 +510,7 @@ formatting. * typecheck * VALA * [uncrustify](https://github.com/uncrustify/uncrustify) + * [vala-lint](https://github.com/vala-lang/vala-lint) :floppy_disk: * Verilog * [hdl-checker](https://pypi.org/project/hdl-checker) * [iverilog](https://github.com/steveicarus/iverilog) From 4328fe7dca248266a5cbaa0546581f37d0cf4c64 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Tue, 5 Jan 2021 17:51:59 +0900 Subject: [PATCH 126/167] add a blank line before if statement --- ale_linters/vala/vala_lint.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index d540323c..45e9b7d8 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -10,6 +10,7 @@ function! ale_linters#vala#vala_lint#GetCommand(buffer) abort if ale#Var(a:buffer, 'vala_vala_lint_enable_config') let l:config_filename = ale#Var(a:buffer, 'vala_vala_lint_config_filename') let l:config_path = ale#path#FindNearestFile(a:buffer, l:config_filename) + if !empty(l:config_path) let l:command .= '-c ' . l:config_path . ' ' endif From e3e1ddce9558ddad360f1109d48ff9c7c66e4e19 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Thu, 14 Jan 2021 09:52:36 +0900 Subject: [PATCH 127/167] allow setting vala-lint executable --- ale_linters/vala/vala_lint.vim | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index 45e9b7d8..39879303 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -3,9 +3,14 @@ call ale#Set('vala_vala_lint_enable_config', 0) call ale#Set('vala_vala_lint_config_filename', 'vala-lint.conf') +call ale#Set('vala_vala_lint_executable', 'io.elementary.vala-lint') + +function! ale_linters#vala#vala_lint#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'vala_vala_lint_executable') +endfunction function! ale_linters#vala#vala_lint#GetCommand(buffer) abort - let l:command = 'io.elementary.vala-lint ' + let l:command = ale_linters#vala#vala_lint#GetExecutable(a:buffer) if ale#Var(a:buffer, 'vala_vala_lint_enable_config') let l:config_filename = ale#Var(a:buffer, 'vala_vala_lint_config_filename') @@ -57,7 +62,7 @@ endfunction call ale#linter#Define('vala', { \ 'name': 'vala-lint', \ 'output_stream': 'stdout', -\ 'executable': 'io.elementary.vala-lint', +\ 'executable': function('ale_linters#vala#vala_lint#GetExecutable'), \ 'command': function('ale_linters#vala#vala_lint#GetCommand'), \ 'callback': 'ale_linters#vala#vala_lint#Handle', \ 'lint_file': 1, From 8d5b3e827df3fa21de32cd367dca95b76f9b0199 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Thu, 14 Jan 2021 09:54:01 +0900 Subject: [PATCH 128/167] decide whether or not to run with config file based on the presence of config filename value --- ale_linters/vala/vala_lint.vim | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index 39879303..4c39ba42 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -1,7 +1,6 @@ " Author: Atsuya Takagi " Description: A linter for Vala using Vala-Lint. -call ale#Set('vala_vala_lint_enable_config', 0) call ale#Set('vala_vala_lint_config_filename', 'vala-lint.conf') call ale#Set('vala_vala_lint_executable', 'io.elementary.vala-lint') @@ -12,16 +11,14 @@ endfunction function! ale_linters#vala#vala_lint#GetCommand(buffer) abort let l:command = ale_linters#vala#vala_lint#GetExecutable(a:buffer) - if ale#Var(a:buffer, 'vala_vala_lint_enable_config') - let l:config_filename = ale#Var(a:buffer, 'vala_vala_lint_config_filename') - let l:config_path = ale#path#FindNearestFile(a:buffer, l:config_filename) + let l:config_filename = ale#Var(a:buffer, 'vala_vala_lint_config_filename') + let l:config_path = ale#path#FindNearestFile(a:buffer, l:config_filename) - if !empty(l:config_path) - let l:command .= '-c ' . l:config_path . ' ' - endif + if !empty(l:config_path) + let l:command .= ' -c ' . l:config_path endif - return l:command . '%s' + return l:command . ' %s' endfunction function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort From 33485ffb92e3718978793d24850d2adb2b08dbc2 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Thu, 14 Jan 2021 09:54:26 +0900 Subject: [PATCH 129/167] document the variables can be set for the linter --- doc/ale-vala.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/ale-vala.txt b/doc/ale-vala.txt index 94bf5400..d48f68bb 100644 --- a/doc/ale-vala.txt +++ b/doc/ale-vala.txt @@ -11,12 +11,12 @@ See |ale-c-uncrustify| for information about the available options. =============================================================================== Vala-Lint *ale-vala-vala-lint* -g:ale_vala_vala_lint_enable_config *g:vala_vala_lint_enable_config* - *b:vala_vala_lint_enable_config* - Type: |Number| - Default: `'0'` +g:vala_vala_lint_executable *g:vala_vala_lint_executable* + *b:vala_vala_lint_executable* + Type: |String| + Default: `'io.elementary.vala-lint'` - This variable can be set to enable or diable the use of Vala-Lint config file. + This variable can be set to specify a Vala-Lint executable file. g:vala_vala_lint_config_filename *g:vala_vala_lint_config_filename* @@ -24,7 +24,9 @@ g:vala_vala_lint_config_filename *g:vala_vala_lint_config_filename* Type: |String| Default: `'vala-lint.conf'` - This variable can be set to specify a Vala-Lint config filename. + This variable can be set to specify a Vala-Lint config filename. When a file + with the specified name was not found or this variable was set to empty, + Vala-Lint will be executed without specifying a config filename. =============================================================================== From 897f6b2b235f7ed7a6b0df7f228d18b74a7407e0 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Sat, 23 Jan 2021 00:20:11 +0900 Subject: [PATCH 130/167] use snake case for linter name --- ale_linters/vala/vala_lint.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/vala/vala_lint.vim b/ale_linters/vala/vala_lint.vim index 4c39ba42..7f8a566a 100644 --- a/ale_linters/vala/vala_lint.vim +++ b/ale_linters/vala/vala_lint.vim @@ -57,7 +57,7 @@ function! ale_linters#vala#vala_lint#Handle(buffer, lines) abort endfunction call ale#linter#Define('vala', { -\ 'name': 'vala-lint', +\ 'name': 'vala_lint', \ 'output_stream': 'stdout', \ 'executable': function('ale_linters#vala#vala_lint#GetExecutable'), \ 'command': function('ale_linters#vala#vala_lint#GetCommand'), From 6b0b8cec79d6805f57ff925923d7157ffb119a5a Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Sat, 23 Jan 2021 00:20:36 +0900 Subject: [PATCH 131/167] update doc with snake cased linter name --- doc/ale-supported-languages-and-tools.txt | 2 +- supported-tools.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index d8d10379..6fb17594 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -501,7 +501,7 @@ Notes: * `typecheck` * VALA * `uncrustify` - * `vala-lint`!! + * `vala_lint`!! * Verilog * `hdl-checker` * `iverilog` diff --git a/supported-tools.md b/supported-tools.md index 21035ffb..289c20e8 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -510,7 +510,7 @@ formatting. * typecheck * VALA * [uncrustify](https://github.com/uncrustify/uncrustify) - * [vala-lint](https://github.com/vala-lang/vala-lint) :floppy_disk: + * [vala_lint](https://github.com/vala-lang/vala-lint) :floppy_disk: * Verilog * [hdl-checker](https://pypi.org/project/hdl-checker) * [iverilog](https://github.com/steveicarus/iverilog) From 6bfcb9cdffb86bf1a3e6d26cd1964858ff4bc3dd Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Wed, 8 Apr 2020 17:59:17 -0500 Subject: [PATCH 132/167] linters/xo: consolidate xo linters --- ale_linters/javascript/xo.vim | 23 ++------------- ale_linters/typescript/xo.vim | 23 ++------------- autoload/ale/handlers/xo.vim | 28 +++++++++++++++++++ .../test_xo_command_callback.vader | 10 ++++--- .../test_xots_command_callback.vader | 22 +++++++++++++++ 5 files changed, 62 insertions(+), 44 deletions(-) create mode 100644 autoload/ale/handlers/xo.vim create mode 100644 test/command_callback/test_xots_command_callback.vader diff --git a/ale_linters/javascript/xo.vim b/ale_linters/javascript/xo.vim index e24f4a82..5b206df8 100644 --- a/ale_linters/javascript/xo.vim +++ b/ale_linters/javascript/xo.vim @@ -1,26 +1,9 @@ " Author: Daniel Lupu " Description: xo for JavaScript files -call ale#Set('javascript_xo_executable', 'xo') -call ale#Set('javascript_xo_use_global', get(g:, 'ale_use_global_executables', 0)) -call ale#Set('javascript_xo_options', '') - -function! ale_linters#javascript#xo#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'javascript_xo', [ - \ 'node_modules/.bin/xo', - \]) -endfunction - -function! ale_linters#javascript#xo#GetCommand(buffer) abort - return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer)) - \ . ' ' . ale#Var(a:buffer, 'javascript_xo_options') - \ . ' --reporter json --stdin --stdin-filename %s' -endfunction - -" xo uses eslint and the output format is the same call ale#linter#Define('javascript', { \ 'name': 'xo', -\ 'executable': function('ale_linters#javascript#xo#GetExecutable'), -\ 'command': function('ale_linters#javascript#xo#GetCommand'), -\ 'callback': 'ale#handlers#eslint#HandleJSON', +\ 'executable': {b -> ale#handlers#xo#GetExecutable(b, 'javascript')}, +\ 'command': {b -> ale#handlers#xo#GetLintCommand(b, 'javascript')}, +\ 'callback': 'ale#handlers#xo#HandleJSON', \}) diff --git a/ale_linters/typescript/xo.vim b/ale_linters/typescript/xo.vim index 0a3a717b..13ae0cf7 100644 --- a/ale_linters/typescript/xo.vim +++ b/ale_linters/typescript/xo.vim @@ -1,23 +1,6 @@ -call ale#Set('typescript_xo_executable', 'xo') -call ale#Set('typescript_xo_use_global', get(g:, 'ale_use_global_executables', 0)) -call ale#Set('typescript_xo_options', '') - -function! ale_linters#typescript#xo#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'typescript_xo', [ - \ 'node_modules/.bin/xo', - \]) -endfunction - -function! ale_linters#typescript#xo#GetCommand(buffer) abort - return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer)) - \ . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options')) - \ . ' --reporter json --stdin --stdin-filename %s' -endfunction - -" xo uses eslint and the output format is the same call ale#linter#Define('typescript', { \ 'name': 'xo', -\ 'executable': function('ale_linters#typescript#xo#GetExecutable'), -\ 'command': function('ale_linters#typescript#xo#GetCommand'), -\ 'callback': 'ale#handlers#eslint#HandleJSON', +\ 'executable': {b -> ale#handlers#xo#GetExecutable(b, 'typescript')}, +\ 'command': {b -> ale#handlers#xo#GetLintCommand(b, 'typescript')}, +\ 'callback': 'ale#handlers#xo#HandleJSON', \}) diff --git a/autoload/ale/handlers/xo.vim b/autoload/ale/handlers/xo.vim new file mode 100644 index 00000000..38dcf5d5 --- /dev/null +++ b/autoload/ale/handlers/xo.vim @@ -0,0 +1,28 @@ +call ale#Set('javascript_xo_executable', 'xo') +call ale#Set('javascript_xo_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('javascript_xo_options', '') + +call ale#Set('typescript_xo_executable', 'xo') +call ale#Set('typescript_xo_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('typescript_xo_options', '') + +function! ale#handlers#xo#GetExecutable(buffer, type) abort + return ale#node#FindExecutable(a:buffer, a:type . '_xo', [ + \ 'node_modules/.bin/xo', + \]) +endfunction + +function! ale#handlers#xo#GetLintCommand(buffer, type) abort + return ale#Escape(ale#handlers#xo#GetExecutable(a:buffer, a:type)) + \ . ale#Pad(ale#handlers#xo#GetOptions(a:buffer, a:type)) + \ . ' --reporter json --stdin --stdin-filename %s' +endfunction + +function! ale#handlers#xo#GetOptions(buffer, type) abort + return ale#Var(a:buffer, a:type . '_xo_options') +endfunction + +" xo uses eslint and the output format is the same +function! ale#handlers#xo#HandleJSON(buffer, lines) abort + return ale#handlers#eslint#HandleJSON(a:buffer, a:lines) +endfunction diff --git a/test/command_callback/test_xo_command_callback.vader b/test/command_callback/test_xo_command_callback.vader index 65cb4f8a..7a38b2b1 100644 --- a/test/command_callback/test_xo_command_callback.vader +++ b/test/command_callback/test_xo_command_callback.vader @@ -1,8 +1,10 @@ Before: - call ale#assert#SetUpLinterTest('typescript', 'xo') - call ale#test#SetFilename('testfile.ts') + call ale#assert#SetUpLinterTest('javascript', 'xo') + call ale#test#SetFilename('testfile.js') unlet! b:executable + runtime autoload/ale/handlers/xo.vim + After: call ale#assert#TearDownLinterTest() @@ -10,11 +12,11 @@ Execute(The XO executable should be called): AssertLinter 'xo', ale#Escape('xo') . ' --reporter json --stdin --stdin-filename %s' Execute(The XO executable should be configurable): - let b:ale_typescript_xo_executable = 'foobar' + let b:ale_javascript_xo_executable = 'foobar' AssertLinter 'foobar', ale#Escape('foobar') . ' --reporter json --stdin --stdin-filename %s' Execute(The XO options should be configurable): - let b:ale_typescript_xo_options = '--wat' + let b:ale_javascript_xo_options = '--wat' AssertLinter 'xo', ale#Escape('xo') . ' --wat --reporter json --stdin --stdin-filename %s' diff --git a/test/command_callback/test_xots_command_callback.vader b/test/command_callback/test_xots_command_callback.vader new file mode 100644 index 00000000..c614ad59 --- /dev/null +++ b/test/command_callback/test_xots_command_callback.vader @@ -0,0 +1,22 @@ +Before: + call ale#assert#SetUpLinterTest('typescript', 'xo') + call ale#test#SetFilename('testfile.ts') + unlet! b:executable + + runtime autoload/ale/handlers/xo.vim + +After: + call ale#assert#TearDownLinterTest() + +Execute(The XO executable should be called): + AssertLinter 'xo', ale#Escape('xo') . ' --reporter json --stdin --stdin-filename %s' + +Execute(The XO executable should be configurable): + let b:ale_typescript_xo_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --reporter json --stdin --stdin-filename %s' + +Execute(The XO options should be configurable): + let b:ale_typescript_xo_options = '--wat' + + AssertLinter 'xo', ale#Escape('xo') . ' --wat --reporter json --stdin --stdin-filename %s' From 4a6136c27ec2430a1ef5481e0ca10dee03ba178f Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Wed, 8 Apr 2020 18:20:10 -0500 Subject: [PATCH 133/167] fixers/xo: add tests --- autoload/ale/fixers/xo.vim | 4 ++- .../react-app/node_modules/xo/cli.js | 0 test/fixers/test_xo_fixer_callback.vader | 29 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 test/eslint-test-files/react-app/node_modules/xo/cli.js create mode 100644 test/fixers/test_xo_fixer_callback.vader diff --git a/autoload/ale/fixers/xo.vim b/autoload/ale/fixers/xo.vim index 882350be..69d23ea3 100644 --- a/autoload/ale/fixers/xo.vim +++ b/autoload/ale/fixers/xo.vim @@ -14,10 +14,12 @@ endfunction function! ale#fixers#xo#Fix(buffer) abort let l:executable = ale#fixers#xo#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'javascript_xo_options') return { \ 'command': ale#node#Executable(a:buffer, l:executable) - \ . ' --fix %t', + \ . ' --fix %t' + \ . ale#Pad(l:options), \ 'read_temporary_file': 1, \} endfunction diff --git a/test/eslint-test-files/react-app/node_modules/xo/cli.js b/test/eslint-test-files/react-app/node_modules/xo/cli.js new file mode 100644 index 00000000..e69de29b diff --git a/test/fixers/test_xo_fixer_callback.vader b/test/fixers/test_xo_fixer_callback.vader new file mode 100644 index 00000000..8bccd05e --- /dev/null +++ b/test/fixers/test_xo_fixer_callback.vader @@ -0,0 +1,29 @@ +Before: + call ale#assert#SetUpFixerTest('javascript', 'xo') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The xo callback should return the correct default values): + call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ' --fix %t', + \ } + +Execute(The xo callback should include custom xo options): + let g:ale_javascript_xo_options = '--space' + call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ' --fix %t' + \ . ' --space', + \ } From 289f808ccd3098cb19bc3bbbb274524a4fb85ff7 Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Wed, 8 Apr 2020 18:38:47 -0500 Subject: [PATCH 134/167] fixers/xo: refactor to handlers --- autoload/ale/fixers/xo.vim | 15 ++------------- autoload/ale/handlers/xo.vim | 1 + test/fixers/test_xo_fixer_callback.vader | 1 + 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/autoload/ale/fixers/xo.vim b/autoload/ale/fixers/xo.vim index 69d23ea3..06e58508 100644 --- a/autoload/ale/fixers/xo.vim +++ b/autoload/ale/fixers/xo.vim @@ -1,20 +1,9 @@ " Author: Albert Marquez - https://github.com/a-marquez " Description: Fixing files with XO. -call ale#Set('javascript_xo_executable', 'xo') -call ale#Set('javascript_xo_use_global', get(g:, 'ale_use_global_executables', 0)) -call ale#Set('javascript_xo_options', '') - -function! ale#fixers#xo#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'javascript_xo', [ - \ 'node_modules/xo/cli.js', - \ 'node_modules/.bin/xo', - \]) -endfunction - function! ale#fixers#xo#Fix(buffer) abort - let l:executable = ale#fixers#xo#GetExecutable(a:buffer) - let l:options = ale#Var(a:buffer, 'javascript_xo_options') + let l:executable = ale#handlers#xo#GetExecutable(a:buffer, 'javascript') + let l:options = ale#handlers#xo#GetOptions(a:buffer, 'javascript') return { \ 'command': ale#node#Executable(a:buffer, l:executable) diff --git a/autoload/ale/handlers/xo.vim b/autoload/ale/handlers/xo.vim index 38dcf5d5..3f7c72cb 100644 --- a/autoload/ale/handlers/xo.vim +++ b/autoload/ale/handlers/xo.vim @@ -8,6 +8,7 @@ call ale#Set('typescript_xo_options', '') function! ale#handlers#xo#GetExecutable(buffer, type) abort return ale#node#FindExecutable(a:buffer, a:type . '_xo', [ + \ 'node_modules/xo/cli.js', \ 'node_modules/.bin/xo', \]) endfunction diff --git a/test/fixers/test_xo_fixer_callback.vader b/test/fixers/test_xo_fixer_callback.vader index 8bccd05e..0bb3108a 100644 --- a/test/fixers/test_xo_fixer_callback.vader +++ b/test/fixers/test_xo_fixer_callback.vader @@ -1,5 +1,6 @@ Before: call ale#assert#SetUpFixerTest('javascript', 'xo') + runtime autoload/ale/handlers/xo.vim After: call ale#assert#TearDownFixerTest() From e75ac9f4975be35e4f33b955f473ba5e336c9ca0 Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Wed, 8 Apr 2020 18:52:53 -0500 Subject: [PATCH 135/167] fixers/xo: support typescript options --- autoload/ale/fixers/xo.vim | 13 ++++++-- .../react-app/subdir/testfile.ts | 0 test/fixers/test_xo_fixer_callback.vader | 1 + test/fixers/test_xots_fixer_callback.vader | 31 +++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 test/eslint-test-files/react-app/subdir/testfile.ts create mode 100644 test/fixers/test_xots_fixer_callback.vader diff --git a/autoload/ale/fixers/xo.vim b/autoload/ale/fixers/xo.vim index 06e58508..6c2901db 100644 --- a/autoload/ale/fixers/xo.vim +++ b/autoload/ale/fixers/xo.vim @@ -2,8 +2,17 @@ " Description: Fixing files with XO. function! ale#fixers#xo#Fix(buffer) abort - let l:executable = ale#handlers#xo#GetExecutable(a:buffer, 'javascript') - let l:options = ale#handlers#xo#GetOptions(a:buffer, 'javascript') + let l:filetype = getbufvar(a:buffer, '&filetype') + let l:type = '' + + if l:filetype =~# 'javascript' + let l:type = 'javascript' + elseif l:filetype =~# 'typescript' + let l:type = 'typescript' + endif + + let l:executable = ale#handlers#xo#GetExecutable(a:buffer, l:type) + let l:options = ale#handlers#xo#GetOptions(a:buffer, l:type) return { \ 'command': ale#node#Executable(a:buffer, l:executable) diff --git a/test/eslint-test-files/react-app/subdir/testfile.ts b/test/eslint-test-files/react-app/subdir/testfile.ts new file mode 100644 index 00000000..e69de29b diff --git a/test/fixers/test_xo_fixer_callback.vader b/test/fixers/test_xo_fixer_callback.vader index 0bb3108a..d36fe74c 100644 --- a/test/fixers/test_xo_fixer_callback.vader +++ b/test/fixers/test_xo_fixer_callback.vader @@ -1,6 +1,7 @@ Before: call ale#assert#SetUpFixerTest('javascript', 'xo') runtime autoload/ale/handlers/xo.vim + set filetype=javascript After: call ale#assert#TearDownFixerTest() diff --git a/test/fixers/test_xots_fixer_callback.vader b/test/fixers/test_xots_fixer_callback.vader new file mode 100644 index 00000000..1ef6a6dd --- /dev/null +++ b/test/fixers/test_xots_fixer_callback.vader @@ -0,0 +1,31 @@ +Before: + call ale#assert#SetUpFixerTest('typescript', 'xo') + runtime autoload/ale/handlers/xo.vim + set filetype=typescript + +After: + call ale#assert#TearDownFixerTest() + +Execute(The xo callback should return the correct default values): + call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.ts') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ' --fix %t', + \ } + +Execute(The xo callback should include custom xo options): + let g:ale_typescript_xo_options = '--space' + call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.ts') + + AssertFixer + \ { + \ 'read_temporary_file': 1, + \ 'command': (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ' --fix %t' + \ . ' --space', + \ } From 8ffde14039bdc0c12d1edf961461245eb15858e9 Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Wed, 8 Apr 2020 22:59:54 -0500 Subject: [PATCH 136/167] fixers/xo: support stdin relative to the fixed file --- autoload/ale/fixers/xo.vim | 29 ++++++++++++++++++++-- autoload/ale/handlers/xo.vim | 6 +++++ test/fixers/test_xo_fixer_callback.vader | 15 +++++++++++ test/fixers/test_xots_fixer_callback.vader | 15 +++++++++++ 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/autoload/ale/fixers/xo.vim b/autoload/ale/fixers/xo.vim index 6c2901db..2c8ab114 100644 --- a/autoload/ale/fixers/xo.vim +++ b/autoload/ale/fixers/xo.vim @@ -14,10 +14,35 @@ function! ale#fixers#xo#Fix(buffer) abort let l:executable = ale#handlers#xo#GetExecutable(a:buffer, l:type) let l:options = ale#handlers#xo#GetOptions(a:buffer, l:type) + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ l:executable, + \ '%e --version', + \ {b, v -> ale#fixers#xo#ApplyFixForVersion(b, v, l:executable, l:options)} + \) +endfunction + +function! ale#fixers#xo#ApplyFixForVersion(buffer, version, executable, options) abort + let l:executable = ale#node#Executable(a:buffer, a:executable) + let l:options = ale#Pad(a:options) + + " 0.30.0 is the first version with a working --stdin --fix + if ale#semver#GTE(a:version, [0, 30, 0]) + let l:project_root = ale#handlers#xo#GetProjectRoot(a:buffer) + + return { + \ 'command': ale#path#CdString(l:project_root) + \ . l:executable + \ . ' --stdin --stdin-filename %s' + \ . ' --fix' + \ . l:options, + \} + endif + return { - \ 'command': ale#node#Executable(a:buffer, l:executable) + \ 'command': l:executable \ . ' --fix %t' - \ . ale#Pad(l:options), + \ . l:options, \ 'read_temporary_file': 1, \} endfunction diff --git a/autoload/ale/handlers/xo.vim b/autoload/ale/handlers/xo.vim index 3f7c72cb..0bea74e4 100644 --- a/autoload/ale/handlers/xo.vim +++ b/autoload/ale/handlers/xo.vim @@ -27,3 +27,9 @@ endfunction function! ale#handlers#xo#HandleJSON(buffer, lines) abort return ale#handlers#eslint#HandleJSON(a:buffer, a:lines) endfunction + +function! ale#handlers#xo#GetProjectRoot(buffer) abort + let l:package_path = ale#path#FindNearestFile(a:buffer, 'package.json') + + return empty(l:package_path) ? '' : fnamemodify(l:package_path, ':p:h') +endfunction diff --git a/test/fixers/test_xo_fixer_callback.vader b/test/fixers/test_xo_fixer_callback.vader index d36fe74c..ffbecb6c 100644 --- a/test/fixers/test_xo_fixer_callback.vader +++ b/test/fixers/test_xo_fixer_callback.vader @@ -29,3 +29,18 @@ Execute(The xo callback should include custom xo options): \ . ' --fix %t' \ . ' --space', \ } + +Execute(--stdin should be used when xo is new enough): + let g:ale_javascript_xo_options = '--space' + call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') + + GivenCommandOutput ['0.30.0'] + AssertFixer + \ { + \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files')) + \ . (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ' --stdin --stdin-filename %s' + \ . ' --fix' + \ . ' --space', + \ } diff --git a/test/fixers/test_xots_fixer_callback.vader b/test/fixers/test_xots_fixer_callback.vader index 1ef6a6dd..a26ec03c 100644 --- a/test/fixers/test_xots_fixer_callback.vader +++ b/test/fixers/test_xots_fixer_callback.vader @@ -29,3 +29,18 @@ Execute(The xo callback should include custom xo options): \ . ' --fix %t' \ . ' --space', \ } + +Execute(--stdin should be used when xo is new enough): + let g:ale_typescript_xo_options = '--space' + call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.ts') + + GivenCommandOutput ['0.30.0'] + AssertFixer + \ { + \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files')) + \ . (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ' --stdin --stdin-filename %s' + \ . ' --fix' + \ . ' --space', + \ } From f17beadb49a6e57520303ea9a10722df1be4d13e Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Mon, 29 Jun 2020 18:40:43 -0500 Subject: [PATCH 137/167] fixers/xo: support monorepos --- autoload/ale/handlers/xo.vim | 4 ++-- test/fixers/test_xo_fixer_callback.vader | 14 +++++++------- test/fixers/test_xots_fixer_callback.vader | 14 +++++++------- test/xo-test-files/monorepo/node_modules/xo/cli.js | 0 test/xo-test-files/monorepo/package.json | 0 test/xo-test-files/monorepo/packages/a/index.js | 0 test/xo-test-files/monorepo/packages/a/index.ts | 0 .../xo-test-files/monorepo/packages/a/package.json | 0 8 files changed, 16 insertions(+), 16 deletions(-) create mode 100644 test/xo-test-files/monorepo/node_modules/xo/cli.js create mode 100644 test/xo-test-files/monorepo/package.json create mode 100644 test/xo-test-files/monorepo/packages/a/index.js create mode 100644 test/xo-test-files/monorepo/packages/a/index.ts create mode 100644 test/xo-test-files/monorepo/packages/a/package.json diff --git a/autoload/ale/handlers/xo.vim b/autoload/ale/handlers/xo.vim index 0bea74e4..df2659da 100644 --- a/autoload/ale/handlers/xo.vim +++ b/autoload/ale/handlers/xo.vim @@ -29,7 +29,7 @@ function! ale#handlers#xo#HandleJSON(buffer, lines) abort endfunction function! ale#handlers#xo#GetProjectRoot(buffer) abort - let l:package_path = ale#path#FindNearestFile(a:buffer, 'package.json') + let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules') - return empty(l:package_path) ? '' : fnamemodify(l:package_path, ':p:h') + return empty(l:modules_dir) ? '' : fnamemodify(l:modules_dir, ':h:h') endfunction diff --git a/test/fixers/test_xo_fixer_callback.vader b/test/fixers/test_xo_fixer_callback.vader index ffbecb6c..c676bd34 100644 --- a/test/fixers/test_xo_fixer_callback.vader +++ b/test/fixers/test_xo_fixer_callback.vader @@ -7,39 +7,39 @@ After: call ale#assert#TearDownFixerTest() Execute(The xo callback should return the correct default values): - call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') + call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.js') AssertFixer \ { \ 'read_temporary_file': 1, \ 'command': (has('win32') ? 'node.exe ' : '') - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js')) \ . ' --fix %t', \ } Execute(The xo callback should include custom xo options): let g:ale_javascript_xo_options = '--space' - call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') + call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.js') AssertFixer \ { \ 'read_temporary_file': 1, \ 'command': (has('win32') ? 'node.exe ' : '') - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js')) \ . ' --fix %t' \ . ' --space', \ } Execute(--stdin should be used when xo is new enough): let g:ale_javascript_xo_options = '--space' - call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') + call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.js') GivenCommandOutput ['0.30.0'] AssertFixer \ { - \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files')) + \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo')) \ . (has('win32') ? 'node.exe ' : '') - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js')) \ . ' --stdin --stdin-filename %s' \ . ' --fix' \ . ' --space', diff --git a/test/fixers/test_xots_fixer_callback.vader b/test/fixers/test_xots_fixer_callback.vader index a26ec03c..6c8b448c 100644 --- a/test/fixers/test_xots_fixer_callback.vader +++ b/test/fixers/test_xots_fixer_callback.vader @@ -7,39 +7,39 @@ After: call ale#assert#TearDownFixerTest() Execute(The xo callback should return the correct default values): - call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.ts') + call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.ts') AssertFixer \ { \ 'read_temporary_file': 1, \ 'command': (has('win32') ? 'node.exe ' : '') - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js')) \ . ' --fix %t', \ } Execute(The xo callback should include custom xo options): let g:ale_typescript_xo_options = '--space' - call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.ts') + call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.ts') AssertFixer \ { \ 'read_temporary_file': 1, \ 'command': (has('win32') ? 'node.exe ' : '') - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js')) \ . ' --fix %t' \ . ' --space', \ } Execute(--stdin should be used when xo is new enough): let g:ale_typescript_xo_options = '--space' - call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.ts') + call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.ts') GivenCommandOutput ['0.30.0'] AssertFixer \ { - \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files')) + \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo')) \ . (has('win32') ? 'node.exe ' : '') - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/xo/cli.js')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js')) \ . ' --stdin --stdin-filename %s' \ . ' --fix' \ . ' --space', diff --git a/test/xo-test-files/monorepo/node_modules/xo/cli.js b/test/xo-test-files/monorepo/node_modules/xo/cli.js new file mode 100644 index 00000000..e69de29b diff --git a/test/xo-test-files/monorepo/package.json b/test/xo-test-files/monorepo/package.json new file mode 100644 index 00000000..e69de29b diff --git a/test/xo-test-files/monorepo/packages/a/index.js b/test/xo-test-files/monorepo/packages/a/index.js new file mode 100644 index 00000000..e69de29b diff --git a/test/xo-test-files/monorepo/packages/a/index.ts b/test/xo-test-files/monorepo/packages/a/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/test/xo-test-files/monorepo/packages/a/package.json b/test/xo-test-files/monorepo/packages/a/package.json new file mode 100644 index 00000000..e69de29b From 1991313ee734129d056a61d6daf1da2c738f8e1a Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Sat, 4 Jul 2020 14:11:16 -0500 Subject: [PATCH 138/167] xo: update docs --- doc/ale-typescript.txt | 27 +++++++++++++++++++++++++++ doc/ale.txt | 1 + 2 files changed, 28 insertions(+) diff --git a/doc/ale-typescript.txt b/doc/ale-typescript.txt index 2c50d119..026d17ce 100644 --- a/doc/ale-typescript.txt +++ b/doc/ale-typescript.txt @@ -138,5 +138,32 @@ g:ale_typescript_tsserver_use_global *g:ale_typescript_tsserver_use_global* tsserver in node_modules. +=============================================================================== +xo *ale-typescript-xo* + +g:ale_typescript_xo_executable *g:ale_typescript_xo_executable* + *b:ale_typescript_xo_executable* + Type: |String| + Default: `'xo'` + + See |ale-integrations-local-executables| + + +g:ale_typescript_xo_options *g:ale_typescript_xo_options* + *b:ale_typescript_xo_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to xo. + + +g:ale_typescript_xo_use_global *g:ale_typescript_xo_use_global* + *b:ale_typescript_xo_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index cfb5beb4..817201c4 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2997,6 +2997,7 @@ documented in additional help files. standard..............................|ale-typescript-standard| tslint................................|ale-typescript-tslint| tsserver..............................|ale-typescript-tsserver| + xo....................................|ale-typescript-xo| vala....................................|ale-vala-options| uncrustify............................|ale-vala-uncrustify| verilog/systemverilog...................|ale-verilog-options| From 23ff19a162aadb048f3d5b2d4a4aa9cf3ec58a52 Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Sat, 4 Jul 2020 14:12:14 -0500 Subject: [PATCH 139/167] fixers/xo: remove unnecessary directory crawl --- autoload/ale/fixers/xo.vim | 5 +---- autoload/ale/handlers/xo.vim | 6 ------ test/fixers/test_xo_fixer_callback.vader | 3 +-- test/fixers/test_xots_fixer_callback.vader | 3 +-- 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/autoload/ale/fixers/xo.vim b/autoload/ale/fixers/xo.vim index 2c8ab114..0f8f3ec6 100644 --- a/autoload/ale/fixers/xo.vim +++ b/autoload/ale/fixers/xo.vim @@ -28,11 +28,8 @@ function! ale#fixers#xo#ApplyFixForVersion(buffer, version, executable, options) " 0.30.0 is the first version with a working --stdin --fix if ale#semver#GTE(a:version, [0, 30, 0]) - let l:project_root = ale#handlers#xo#GetProjectRoot(a:buffer) - return { - \ 'command': ale#path#CdString(l:project_root) - \ . l:executable + \ 'command': l:executable \ . ' --stdin --stdin-filename %s' \ . ' --fix' \ . l:options, diff --git a/autoload/ale/handlers/xo.vim b/autoload/ale/handlers/xo.vim index df2659da..3f7c72cb 100644 --- a/autoload/ale/handlers/xo.vim +++ b/autoload/ale/handlers/xo.vim @@ -27,9 +27,3 @@ endfunction function! ale#handlers#xo#HandleJSON(buffer, lines) abort return ale#handlers#eslint#HandleJSON(a:buffer, a:lines) endfunction - -function! ale#handlers#xo#GetProjectRoot(buffer) abort - let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules') - - return empty(l:modules_dir) ? '' : fnamemodify(l:modules_dir, ':h:h') -endfunction diff --git a/test/fixers/test_xo_fixer_callback.vader b/test/fixers/test_xo_fixer_callback.vader index c676bd34..a473606e 100644 --- a/test/fixers/test_xo_fixer_callback.vader +++ b/test/fixers/test_xo_fixer_callback.vader @@ -37,8 +37,7 @@ Execute(--stdin should be used when xo is new enough): GivenCommandOutput ['0.30.0'] AssertFixer \ { - \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js')) \ . ' --stdin --stdin-filename %s' \ . ' --fix' diff --git a/test/fixers/test_xots_fixer_callback.vader b/test/fixers/test_xots_fixer_callback.vader index 6c8b448c..5c7fa1d1 100644 --- a/test/fixers/test_xots_fixer_callback.vader +++ b/test/fixers/test_xots_fixer_callback.vader @@ -37,8 +37,7 @@ Execute(--stdin should be used when xo is new enough): GivenCommandOutput ['0.30.0'] AssertFixer \ { - \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js')) \ . ' --stdin --stdin-filename %s' \ . ' --fix' From 4edfac4db64debcfd33d894f169d0c1dc6dc48a4 Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Tue, 19 Jan 2021 22:16:10 -0600 Subject: [PATCH 140/167] xo: inline filetype handling --- ale_linters/javascript/xo.vim | 4 ++-- ale_linters/typescript/xo.vim | 4 ++-- autoload/ale/fixers/xo.vim | 13 ++----------- autoload/ale/handlers/xo.vim | 32 +++++++++++++++++++++++++------- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/ale_linters/javascript/xo.vim b/ale_linters/javascript/xo.vim index 5b206df8..9cc1dc69 100644 --- a/ale_linters/javascript/xo.vim +++ b/ale_linters/javascript/xo.vim @@ -3,7 +3,7 @@ call ale#linter#Define('javascript', { \ 'name': 'xo', -\ 'executable': {b -> ale#handlers#xo#GetExecutable(b, 'javascript')}, -\ 'command': {b -> ale#handlers#xo#GetLintCommand(b, 'javascript')}, +\ 'executable': {b -> ale#handlers#xo#GetExecutable(b)}, +\ 'command': {b -> ale#handlers#xo#GetLintCommand(b)}, \ 'callback': 'ale#handlers#xo#HandleJSON', \}) diff --git a/ale_linters/typescript/xo.vim b/ale_linters/typescript/xo.vim index 13ae0cf7..2e25ba4c 100644 --- a/ale_linters/typescript/xo.vim +++ b/ale_linters/typescript/xo.vim @@ -1,6 +1,6 @@ call ale#linter#Define('typescript', { \ 'name': 'xo', -\ 'executable': {b -> ale#handlers#xo#GetExecutable(b, 'typescript')}, -\ 'command': {b -> ale#handlers#xo#GetLintCommand(b, 'typescript')}, +\ 'executable': {b -> ale#handlers#xo#GetExecutable(b)}, +\ 'command': {b -> ale#handlers#xo#GetLintCommand(b)}, \ 'callback': 'ale#handlers#xo#HandleJSON', \}) diff --git a/autoload/ale/fixers/xo.vim b/autoload/ale/fixers/xo.vim index 0f8f3ec6..dcf4c737 100644 --- a/autoload/ale/fixers/xo.vim +++ b/autoload/ale/fixers/xo.vim @@ -2,17 +2,8 @@ " Description: Fixing files with XO. function! ale#fixers#xo#Fix(buffer) abort - let l:filetype = getbufvar(a:buffer, '&filetype') - let l:type = '' - - if l:filetype =~# 'javascript' - let l:type = 'javascript' - elseif l:filetype =~# 'typescript' - let l:type = 'typescript' - endif - - let l:executable = ale#handlers#xo#GetExecutable(a:buffer, l:type) - let l:options = ale#handlers#xo#GetOptions(a:buffer, l:type) + let l:executable = ale#handlers#xo#GetExecutable(a:buffer) + let l:options = ale#handlers#xo#GetOptions(a:buffer) return ale#semver#RunWithVersionCheck( \ a:buffer, diff --git a/autoload/ale/handlers/xo.vim b/autoload/ale/handlers/xo.vim index 3f7c72cb..2439b4f9 100644 --- a/autoload/ale/handlers/xo.vim +++ b/autoload/ale/handlers/xo.vim @@ -6,21 +6,39 @@ call ale#Set('typescript_xo_executable', 'xo') call ale#Set('typescript_xo_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('typescript_xo_options', '') -function! ale#handlers#xo#GetExecutable(buffer, type) abort - return ale#node#FindExecutable(a:buffer, a:type . '_xo', [ +function! ale#handlers#xo#GetExecutable(buffer) abort + let l:filetype = getbufvar(a:buffer, '&filetype') + let l:type = '' + + if l:filetype =~# 'javascript' + let l:type = 'javascript' + elseif l:filetype =~# 'typescript' + let l:type = 'typescript' + endif + + return ale#node#FindExecutable(a:buffer, l:type . '_xo', [ \ 'node_modules/xo/cli.js', \ 'node_modules/.bin/xo', \]) endfunction -function! ale#handlers#xo#GetLintCommand(buffer, type) abort - return ale#Escape(ale#handlers#xo#GetExecutable(a:buffer, a:type)) - \ . ale#Pad(ale#handlers#xo#GetOptions(a:buffer, a:type)) +function! ale#handlers#xo#GetLintCommand(buffer) abort + return ale#Escape(ale#handlers#xo#GetExecutable(a:buffer)) + \ . ale#Pad(ale#handlers#xo#GetOptions(a:buffer)) \ . ' --reporter json --stdin --stdin-filename %s' endfunction -function! ale#handlers#xo#GetOptions(buffer, type) abort - return ale#Var(a:buffer, a:type . '_xo_options') +function! ale#handlers#xo#GetOptions(buffer) abort + let l:filetype = getbufvar(a:buffer, '&filetype') + let l:type = '' + + if l:filetype =~# 'javascript' + let l:type = 'javascript' + elseif l:filetype =~# 'typescript' + let l:type = 'typescript' + endif + + return ale#Var(a:buffer, l:type . '_xo_options') endfunction " xo uses eslint and the output format is the same From 5fd5fa53051c3514917974d0ba57f18eb50dd37e Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Tue, 19 Jan 2021 23:08:10 -0600 Subject: [PATCH 141/167] linters/xo: fix tests --- test/command_callback/test_xo_command_callback.vader | 3 ++- test/command_callback/test_xots_command_callback.vader | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/command_callback/test_xo_command_callback.vader b/test/command_callback/test_xo_command_callback.vader index 7a38b2b1..1aa4c3f1 100644 --- a/test/command_callback/test_xo_command_callback.vader +++ b/test/command_callback/test_xo_command_callback.vader @@ -1,8 +1,9 @@ Before: call ale#assert#SetUpLinterTest('javascript', 'xo') - call ale#test#SetFilename('testfile.js') + call ale#test#SetFilename('testfile.jsx') unlet! b:executable + set filetype=javascriptreact runtime autoload/ale/handlers/xo.vim After: diff --git a/test/command_callback/test_xots_command_callback.vader b/test/command_callback/test_xots_command_callback.vader index c614ad59..cc38ff02 100644 --- a/test/command_callback/test_xots_command_callback.vader +++ b/test/command_callback/test_xots_command_callback.vader @@ -1,8 +1,9 @@ Before: call ale#assert#SetUpLinterTest('typescript', 'xo') - call ale#test#SetFilename('testfile.ts') + call ale#test#SetFilename('testfile.tsx') unlet! b:executable + set filetype=typescriptreact runtime autoload/ale/handlers/xo.vim After: From 03bd494fd42181f111ee56387a1d40639b42672e Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Tue, 19 Jan 2021 23:07:33 -0600 Subject: [PATCH 142/167] linters/xo: prefer function shorthand --- ale_linters/javascript/xo.vim | 4 ++-- ale_linters/typescript/xo.vim | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ale_linters/javascript/xo.vim b/ale_linters/javascript/xo.vim index 9cc1dc69..5e04ad5c 100644 --- a/ale_linters/javascript/xo.vim +++ b/ale_linters/javascript/xo.vim @@ -3,7 +3,7 @@ call ale#linter#Define('javascript', { \ 'name': 'xo', -\ 'executable': {b -> ale#handlers#xo#GetExecutable(b)}, -\ 'command': {b -> ale#handlers#xo#GetLintCommand(b)}, +\ 'executable': function('ale#handlers#xo#GetExecutable'), +\ 'command': function('ale#handlers#xo#GetLintCommand'), \ 'callback': 'ale#handlers#xo#HandleJSON', \}) diff --git a/ale_linters/typescript/xo.vim b/ale_linters/typescript/xo.vim index 2e25ba4c..6f4ee50c 100644 --- a/ale_linters/typescript/xo.vim +++ b/ale_linters/typescript/xo.vim @@ -1,6 +1,6 @@ call ale#linter#Define('typescript', { \ 'name': 'xo', -\ 'executable': {b -> ale#handlers#xo#GetExecutable(b)}, -\ 'command': {b -> ale#handlers#xo#GetLintCommand(b)}, +\ 'executable': function('ale#handlers#xo#GetExecutable'), +\ 'command': function('ale#handlers#xo#GetLintCommand'), \ 'callback': 'ale#handlers#xo#HandleJSON', \}) From 451e99341ea2abf48ec2e7318748e688a9a93b90 Mon Sep 17 00:00:00 2001 From: Charles B Johnson Date: Tue, 19 Jan 2021 23:07:55 -0600 Subject: [PATCH 143/167] xo: refactor to function --- autoload/ale/handlers/xo.vim | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/autoload/ale/handlers/xo.vim b/autoload/ale/handlers/xo.vim index 2439b4f9..c63278c0 100644 --- a/autoload/ale/handlers/xo.vim +++ b/autoload/ale/handlers/xo.vim @@ -7,14 +7,7 @@ call ale#Set('typescript_xo_use_global', get(g:, 'ale_use_global_executables', 0 call ale#Set('typescript_xo_options', '') function! ale#handlers#xo#GetExecutable(buffer) abort - let l:filetype = getbufvar(a:buffer, '&filetype') - let l:type = '' - - if l:filetype =~# 'javascript' - let l:type = 'javascript' - elseif l:filetype =~# 'typescript' - let l:type = 'typescript' - endif + let l:type = ale#handlers#xo#GetType(a:buffer) return ale#node#FindExecutable(a:buffer, l:type . '_xo', [ \ 'node_modules/xo/cli.js', @@ -29,14 +22,7 @@ function! ale#handlers#xo#GetLintCommand(buffer) abort endfunction function! ale#handlers#xo#GetOptions(buffer) abort - let l:filetype = getbufvar(a:buffer, '&filetype') - let l:type = '' - - if l:filetype =~# 'javascript' - let l:type = 'javascript' - elseif l:filetype =~# 'typescript' - let l:type = 'typescript' - endif + let l:type = ale#handlers#xo#GetType(a:buffer) return ale#Var(a:buffer, l:type . '_xo_options') endfunction @@ -45,3 +31,14 @@ endfunction function! ale#handlers#xo#HandleJSON(buffer, lines) abort return ale#handlers#eslint#HandleJSON(a:buffer, a:lines) endfunction + +function! ale#handlers#xo#GetType(buffer) abort + let l:filetype = getbufvar(a:buffer, '&filetype') + let l:type = 'javascript' + + if l:filetype =~# 'typescript' + let l:type = 'typescript' + endif + + return l:type +endfunction From 53ff5f2d88aeb74ca6a506e11869350312cd6588 Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Tue, 19 Jan 2021 18:03:04 +0900 Subject: [PATCH 144/167] Fix 3546 - check empty executable string. At some point VIM/NVIM started throwing errors if the input string is empty for some functions such as execute() and fnamemodify(). This commit checks if the executable string is empty before passing it to the executable() function. Resources: - https://github.com/vim/vim/issues/7465 - https://github.com/vim/vim/releases/tag/v8.2.2117 --- autoload/ale/maven.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ale/maven.vim b/autoload/ale/maven.vim index 745f8c93..42735286 100644 --- a/autoload/ale/maven.vim +++ b/autoload/ale/maven.vim @@ -25,7 +25,7 @@ function! ale#maven#FindExecutable(buffer) abort let l:wrapper_cmd = has('unix') ? 'mvnw' : 'mvnw.cmd' let l:wrapper_path = ale#path#FindNearestFile(a:buffer, l:wrapper_cmd) - if executable(l:wrapper_path) + if !empty(l:wrapper_path) && executable(l:wrapper_path) return l:wrapper_path endif From 35b8bb8a554741e9cd132ae82e9cc4a82f8f361d Mon Sep 17 00:00:00 2001 From: Nelson Yeung Date: Sun, 22 Mar 2020 20:39:40 +0000 Subject: [PATCH 145/167] Add dart analysis server linter --- ale_linters/dart/analysis_server.vim | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 ale_linters/dart/analysis_server.vim diff --git a/ale_linters/dart/analysis_server.vim b/ale_linters/dart/analysis_server.vim new file mode 100644 index 00000000..4a0ea4f2 --- /dev/null +++ b/ale_linters/dart/analysis_server.vim @@ -0,0 +1,28 @@ +" Author: Nelson Yeung +" Description: Check Dart files with dart analysis server LSP + +call ale#Set('dart_analysis_server_executable', 'dart') + +function! ale_linters#dart#analysis_server#GetProjectRoot(buffer) abort + " Note: pub only looks for pubspec.yaml, there's no point in adding + " support for pubspec.yml + let l:pubspec = ale#path#FindNearestFile(a:buffer, 'pubspec.yaml') + + return !empty(l:pubspec) ? fnamemodify(l:pubspec, ':h:h') : '' +endfunction + +function! ale_linters#dart#analysis_server#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'dart_analysis_server_executable') + let l:dart = resolve(exepath(l:executable)) + return '%e ' + \ . fnamemodify(l:dart, ':h') . '/snapshots/analysis_server.dart.snapshot' + \ . ' --lsp' +endfunction + +call ale#linter#Define('dart', { +\ 'name': 'analysis_server', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'dart_analysis_server_executable')}, +\ 'command': function('ale_linters#dart#analysis_server#GetCommand'), +\ 'project_root': function('ale_linters#dart#analysis_server#GetProjectRoot'), +\}) From 075c3e0ad02456db17d28f1b04a14e015c63c11b Mon Sep 17 00:00:00 2001 From: Nelson Yeung Date: Sun, 22 Mar 2020 20:48:39 +0000 Subject: [PATCH 146/167] Add dart analysis_server to supported tools --- supported-tools.md | 1 + 1 file changed, 1 insertion(+) diff --git a/supported-tools.md b/supported-tools.md index ff4a78d8..8ed83d6c 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -125,6 +125,7 @@ formatting. * Dafny * [dafny](https://rise4fun.com/Dafny) :floppy_disk: * Dart + * [analysis_server](https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server) * [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) :floppy_disk: * [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) * [language_server](https://github.com/natebosch/dart_language_server) From 847f729cd4e608e6feb81a342bec6cb3745c9845 Mon Sep 17 00:00:00 2001 From: Nelson Yeung Date: Sun, 22 Mar 2020 21:02:47 +0000 Subject: [PATCH 147/167] Add dart analysis_server doc --- doc/ale-dart.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/ale-dart.txt b/doc/ale-dart.txt index a6d88dd8..fe5ccbcd 100644 --- a/doc/ale-dart.txt +++ b/doc/ale-dart.txt @@ -2,6 +2,31 @@ ALE Dart Integration *ale-dart-options* +=============================================================================== +analysis_server *ale-dart-analysis_server* + +Installation +------------------------------------------------------------------------------- + +Install Dart via whatever means. `analysis_server` will be included in the SDK. + +In case that `dart` is no in your path, try to set the executable option to +its absolute path. : > + " Set the executable path for dart to the absolute path to it. + let g:ale_dart_analysis_server_executable = '/usr/local/bin/dart' +< + +Options +------------------------------------------------------------------------------- + +g:ale_dart_analysis_server_executable *g:ale_dart_analysis_server_executable* + *b:ale_dart_analysis_server_executable* + Type: |String| + Default: `'dart'` + + This variable can be set to change the path to dart. + + =============================================================================== dartanalyzer *ale-dart-dartanalyzer* From 850c41b2a9556254a883a94f3f3c74374109a77b Mon Sep 17 00:00:00 2001 From: Nelson Yeung Date: Wed, 25 Mar 2020 20:36:57 +0000 Subject: [PATCH 148/167] Fix linting errors --- ale_linters/dart/analysis_server.vim | 1 + doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/ale_linters/dart/analysis_server.vim b/ale_linters/dart/analysis_server.vim index 4a0ea4f2..82d91334 100644 --- a/ale_linters/dart/analysis_server.vim +++ b/ale_linters/dart/analysis_server.vim @@ -14,6 +14,7 @@ endfunction function! ale_linters#dart#analysis_server#GetCommand(buffer) abort let l:executable = ale#Var(a:buffer, 'dart_analysis_server_executable') let l:dart = resolve(exepath(l:executable)) + return '%e ' \ . fnamemodify(l:dart, ':h') . '/snapshots/analysis_server.dart.snapshot' \ . ' --lsp' diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 239927be..a44ad75b 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -116,6 +116,7 @@ Notes: * Dafny * `dafny`!! * Dart + * `analysis_server` * `dartanalyzer`!! * `dartfmt`!! * `language_server` diff --git a/doc/ale.txt b/doc/ale.txt index 817201c4..d73987a9 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2664,6 +2664,7 @@ documented in additional help files. dafny...................................|ale-dafny-options| dafny.................................|ale-dafny-dafny| dart....................................|ale-dart-options| + analysis_server.......................|ale-dart-analysis_server| dartanalyzer..........................|ale-dart-dartanalyzer| dartfmt...............................|ale-dart-dartfmt| dhall...................................|ale-dhall-options| From a8acac1f4aea5fbe5bc856da6ce63881332d28d4 Mon Sep 17 00:00:00 2001 From: Nelson Yeung Date: Tue, 8 Dec 2020 21:17:31 +0000 Subject: [PATCH 149/167] Add support for standalone files --- ale_linters/dart/analysis_server.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ale_linters/dart/analysis_server.vim b/ale_linters/dart/analysis_server.vim index 82d91334..ba8839bd 100644 --- a/ale_linters/dart/analysis_server.vim +++ b/ale_linters/dart/analysis_server.vim @@ -8,7 +8,7 @@ function! ale_linters#dart#analysis_server#GetProjectRoot(buffer) abort " support for pubspec.yml let l:pubspec = ale#path#FindNearestFile(a:buffer, 'pubspec.yaml') - return !empty(l:pubspec) ? fnamemodify(l:pubspec, ':h:h') : '' + return !empty(l:pubspec) ? fnamemodify(l:pubspec, ':h:h') : '.' endfunction function! ale_linters#dart#analysis_server#GetCommand(buffer) abort From efe65f347719a34e5d60e056f2cc3dc0356af10e Mon Sep 17 00:00:00 2001 From: Nelson Yeung Date: Wed, 20 Jan 2021 19:29:30 +0000 Subject: [PATCH 150/167] Add command callback tests --- ...st_dart_analysis_server_command_callback.vader | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test/command_callback/test_dart_analysis_server_command_callback.vader diff --git a/test/command_callback/test_dart_analysis_server_command_callback.vader b/test/command_callback/test_dart_analysis_server_command_callback.vader new file mode 100644 index 00000000..1754109a --- /dev/null +++ b/test/command_callback/test_dart_analysis_server_command_callback.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('dart', 'analysis_server') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'dart', ale#Escape('dart') + \ . ' ./snapshots/analysis_server.dart.snapshot --lsp' + +Execute(The executable should be configurable): + let g:ale_dart_analysis_server_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + \ . ' ./snapshots/analysis_server.dart.snapshot --lsp' From 985a5295a9eaa4451ccf5616efd8262adbd06b39 Mon Sep 17 00:00:00 2001 From: Nelson Yeung Date: Wed, 20 Jan 2021 19:32:37 +0000 Subject: [PATCH 151/167] Fix typos --- ale_linters/dart/analysis_server.vim | 2 +- doc/ale-dart.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ale_linters/dart/analysis_server.vim b/ale_linters/dart/analysis_server.vim index ba8839bd..a6870da9 100644 --- a/ale_linters/dart/analysis_server.vim +++ b/ale_linters/dart/analysis_server.vim @@ -1,4 +1,4 @@ -" Author: Nelson Yeung +" Author: Nelson Yeung " Description: Check Dart files with dart analysis server LSP call ale#Set('dart_analysis_server_executable', 'dart') diff --git a/doc/ale-dart.txt b/doc/ale-dart.txt index fe5ccbcd..01089252 100644 --- a/doc/ale-dart.txt +++ b/doc/ale-dart.txt @@ -10,7 +10,7 @@ Installation Install Dart via whatever means. `analysis_server` will be included in the SDK. -In case that `dart` is no in your path, try to set the executable option to +In case that `dart` is not in your path, try to set the executable option to its absolute path. : > " Set the executable path for dart to the absolute path to it. let g:ale_dart_analysis_server_executable = '/usr/local/bin/dart' @@ -24,7 +24,7 @@ g:ale_dart_analysis_server_executable *g:ale_dart_analysis_server_executable* Type: |String| Default: `'dart'` - This variable can be set to change the path to dart. + This variable can be set to change the path of dart. =============================================================================== From 99a809c814880e8e592e8150dc39fd7a5b584371 Mon Sep 17 00:00:00 2001 From: Leo Date: Sat, 31 Oct 2020 18:31:26 -0300 Subject: [PATCH 152/167] Add handler for the output of atools atools is a collection of tools written in ash shell and Lua that provide linting for Alpine Linux's APKBUILD. APKBUILDs are build recipes used by Alpine Linux's build system, abuild, an equivalent would be Arch Linux's PKGBUILD and Gentoo's ebuild. --- autoload/ale/handlers/atools.vim | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 autoload/ale/handlers/atools.vim diff --git a/autoload/ale/handlers/atools.vim b/autoload/ale/handlers/atools.vim new file mode 100644 index 00000000..c273fc40 --- /dev/null +++ b/autoload/ale/handlers/atools.vim @@ -0,0 +1,41 @@ +" Author: Leo +" Description: Handlers for output expected from atools + +function! ale#handlers#atools#Handle(buffer, lines) abort + " Format: SEVERITY:[TAG]:PATH:LINENUM:MSG + " Example: MC:[AL5]:./APKBUILD:12:variable set to empty string: install= + let l:pattern = '\([^:]\+\):\([^:]\+\):\([^:]\+\):\(\d\+\):\(.\+\)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + " We are expected to receive 2 characters, the first character + " can be 'S', 'I', 'M' 'T', which are respectively: + " Serious (Error) + " Important (Error) + " Minor (Warning) + " Style (Warning) + " + " The second character can be either 'C' or 'P', which are respectively: + " Certain (Error) + " Possible (Warning) + let l:severity = matchstr(l:match[1], '^.') + let l:certainty = matchstr(l:match[1], '.$') + + let l:type = 'E' + " If the tag returns 'Minor' or 'Style' or is 'Possible' + " then return a warning + + if l:severity is# 'M' || l:severity is# 'T' || l:certainty is# 'P' + let l:type = 'W' + endif + + call add(l:output, { + \ 'lnum': l:match[4] + 0, + \ 'text': l:match[5], + \ 'type': l:type, + \ 'code': matchstr(l:match[2], 'AL[0-9]*'), + \}) + endfor + + return l:output +endfunction From 32c0eb7c4291086e7af9234efc3762d13047f4c7 Mon Sep 17 00:00:00 2001 From: Leo Date: Sat, 31 Oct 2020 18:38:14 -0300 Subject: [PATCH 153/167] Add linters for apkbuild-lint and secfixes-check from atools --- ale_linters/apkbuild/apkbuild_lint.vim | 12 ++++++++++++ ale_linters/apkbuild/secfixes_check.vim | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 ale_linters/apkbuild/apkbuild_lint.vim create mode 100644 ale_linters/apkbuild/secfixes_check.vim diff --git a/ale_linters/apkbuild/apkbuild_lint.vim b/ale_linters/apkbuild/apkbuild_lint.vim new file mode 100644 index 00000000..285f5534 --- /dev/null +++ b/ale_linters/apkbuild/apkbuild_lint.vim @@ -0,0 +1,12 @@ +" Author: Leo +" Description: apkbuild-lint from atools linter for APKBUILDs + +call ale#Set('apkbuild_apkbuild_lint_executable', 'apkbuild-lint') + +call ale#linter#Define('apkbuild', { +\ 'name': 'apkbuild_lint', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'apkbuild_apkbuild_lint_executable')}, +\ 'command': '%e %t', +\ 'callback': 'ale#handlers#atools#Handle', +\}) diff --git a/ale_linters/apkbuild/secfixes_check.vim b/ale_linters/apkbuild/secfixes_check.vim new file mode 100644 index 00000000..c65267fd --- /dev/null +++ b/ale_linters/apkbuild/secfixes_check.vim @@ -0,0 +1,12 @@ +" Author: Leo +" Description: secfixes-check from atools linter for APKBUILDs + +call ale#Set('apkbuild_secfixes_check_executable', 'secfixes-check') + +call ale#linter#Define('apkbuild', { +\ 'name': 'secfixes_check', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'apkbuild_secfixes_check_executable')}, +\ 'command': '%e %t', +\ 'callback': 'ale#handlers#atools#Handle', +\}) From df91bc904621fcd6e6bb1bd95ea3d4fbbad68f8b Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 1 Nov 2020 00:20:20 -0300 Subject: [PATCH 154/167] document support for apkbuild-lint and secfixes-check for apkbuild --- doc/ale-supported-languages-and-tools.txt | 3 +++ supported-tools.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index a44ad75b..37191561 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -19,6 +19,9 @@ Notes: * `ansible-lint` * API Blueprint * `drafter` +* APKBUILD + * `apkbuild-lint` + * `secfixes-check` * AsciiDoc * `alex`!! * `languagetool`!! diff --git a/supported-tools.md b/supported-tools.md index 8ed83d6c..f632e540 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -28,6 +28,9 @@ formatting. * [ansible-lint](https://github.com/willthames/ansible-lint) * API Blueprint * [drafter](https://github.com/apiaryio/drafter) +* APKBUILD + * [apkbuild-lint](https://gitlab.alpinelinux.org/Leo/atools) + * [secfixes-check](https://gitlab.alpinelinux.org/Leo/atools) * AsciiDoc * [alex](https://github.com/wooorm/alex) :floppy_disk: * [languagetool](https://languagetool.org/) :floppy_disk: From 542ba5a04a3470687075b2b49f95c8f4530c71ee Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 1 Nov 2020 01:12:05 -0300 Subject: [PATCH 155/167] Make apkbuild_lint and secfixes_check default for apkbuild filetype --- autoload/ale/linter.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index ba11e1eb..f9ec48d7 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -38,6 +38,7 @@ let s:default_ale_linter_aliases = { " " NOTE: Update the g:ale_linters documentation when modifying this. let s:default_ale_linters = { +\ 'apkbuild': ['apkbuild_lint', 'secfixes_check'], \ 'csh': ['shell'], \ 'elixir': ['credo', 'dialyxir', 'dogma'], \ 'go': ['gofmt', 'golint', 'go vet'], From 4f8f2a4a0c9ee2e6b5e836a59644ae3b7e54b74d Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 1 Nov 2020 01:12:44 -0300 Subject: [PATCH 156/167] Document new default linters for apkbuild --- doc/ale.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/ale.txt b/doc/ale.txt index d73987a9..a181d78a 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1556,6 +1556,7 @@ g:ale_linters *g:ale_linters* following values: > { + \ 'apkbuild': ['apkbuild_lint', 'secfixes_check'], \ 'csh': ['shell'], \ 'elixir': ['credo', 'dialyxir', 'dogma'], \ 'go': ['gofmt', 'golint', 'go vet'], From 4999ae2e8572d17067d06c94db3fa5adf69a497a Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 1 Nov 2020 01:13:14 -0300 Subject: [PATCH 157/167] Test default linters for apkbuild --- test/test_filetype_linter_defaults.vader | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/test_filetype_linter_defaults.vader b/test/test_filetype_linter_defaults.vader index e9980536..d4e708ec 100644 --- a/test/test_filetype_linter_defaults.vader +++ b/test/test_filetype_linter_defaults.vader @@ -70,3 +70,10 @@ Execute(The defaults for the verilog filetype should be correct): Execute(Default aliases for React should be defined): AssertEqual ['javascript', 'jsx'], ale#linter#ResolveFiletype('javascriptreact') AssertEqual ['typescript', 'tsx'], ale#linter#ResolveFiletype('typescriptreact') + +Execute(The defaults for the apkbuild filetype should be correct): + AssertEqual ['apkbuild_lint', 'secfixes_check'], GetLinterNames('apkbuild') + + let g:ale_linters_explicit = 1 + + AssertEqual [], GetLinterNames('apkbuild') From 56951932e0633454a910d10162800a6122cdaa00 Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 1 Nov 2020 02:38:17 -0300 Subject: [PATCH 158/167] Add tests for atools handler, basic and dealing with Error and Warning --- test/handler/test_atools_handler.vader | 85 ++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 test/handler/test_atools_handler.vader diff --git a/test/handler/test_atools_handler.vader b/test/handler/test_atools_handler.vader new file mode 100644 index 00000000..1bb9ca00 --- /dev/null +++ b/test/handler/test_atools_handler.vader @@ -0,0 +1,85 @@ +Before: + runtime autoload/ale/handlers/atools.vim + +After: + call ale#linter#Reset() + +Execute(The atools handler should handle basic errors or warings): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'text': 'trailing whitespace', + \ 'type': 'E', + \ 'code': 'AL8', + \ }, + \ { + \ 'lnum': 15, + \ 'text': '$pkgname should not be used in the source url', + \ 'type': 'W', + \ 'code': 'AL29', + \ }, + \ ], + \ ale#handlers#atools#Handle(bufnr(''), [ + \ 'IC:[AL8]:APKBUILD:2:trailing whitespace', + \ 'MC:[AL29]:APKBUILD:15:$pkgname should not be used in the source url', + \ ]) + +" Regardless of the severity, if the certainty is [P]ossible and not [C]ertain +" or if regardless of the Certainity the Severity is not [I]mportant or [S]erious +" then it must be a [W]arning +Execute(If we are not Certain or Importantly Serious, be a Warning): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'text': 'This violation is Serious but Possible false positive, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 4, + \ 'text': 'This violation is Important but Possible false positive, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 5, + \ 'text': 'This violation is Minor, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 6, + \ 'text': 'This violation is Style, I am a Warning!', + \ 'type': 'W', + \ 'code': 'AL', + \ }, + \ ], + \ ale#handlers#atools#Handle(bufnr(''), [ + \ 'SP:[AL]:APKBUILD:3:This violation is Serious but Possible false positive, I am a Warning!', + \ 'IP:[AL]:APKBUILD:4:This violation is Important but Possible false positive, I am a Warning!', + \ 'MC:[AL]:APKBUILD:5:This violation is Minor, I am a Warning!', + \ 'TC:[AL]:APKBUILD:6:This violation is Style, I am a Warning!', + \ ]) + +Execute(We should be error if we are Certain it is Serious or Important): + AssertEqual + \ [ + \ { + \ 'lnum': 7, + \ 'text': 'This is Certainly Serious, I am an Error!', + \ 'type': 'E', + \ 'code': 'AL', + \ }, + \ { + \ 'lnum': 8, + \ 'text': 'This is Certainly Important, I am an Error!', + \ 'type': 'E', + \ 'code': 'AL', + \ }, + \ ], + \ ale#handlers#atools#Handle(bufnr(''), [ + \ 'SC:[AL]:APKBUILD:7:This is Certainly Serious, I am an Error!', + \ 'IC:[AL]:APKBUILD:8:This is Certainly Important, I am an Error!', + \ ]) From d7ed80346c2cc9ddf9d72a075d5516d24708034a Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 1 Nov 2020 02:50:24 -0300 Subject: [PATCH 159/167] Add document for apkbuild filetype --- doc/ale-apkbuild.txt | 30 ++++++++++++++++++++++++++++++ doc/ale.txt | 3 +++ 2 files changed, 33 insertions(+) create mode 100644 doc/ale-apkbuild.txt diff --git a/doc/ale-apkbuild.txt b/doc/ale-apkbuild.txt new file mode 100644 index 00000000..05261400 --- /dev/null +++ b/doc/ale-apkbuild.txt @@ -0,0 +1,30 @@ +=============================================================================== +ALE APKBUILD Integration *ale-apkbuild-options* + + +=============================================================================== +apkbuild-lint *ale-apkbuild-apkbuild-lint* + +g:ale_apkbuild_apkbuild_lint_executable + *g:ale_apkbuild_apkbuild_lint_executable* + *b:ale_apkbuild_apkbuild_lint_executable* + + Type: |String| + Default: `'apkbuild-lint'` + + This variable can be set to change the path to apkbuild-lint + +=============================================================================== +secfixes-check *ale-apkbuild-secfixes-check* + +g:ale_apkbuild_secfixes_check_executable + *g:ale_apkbuild_secfixes_check_executable* + *b:ale_apkbuild_secfixes_check_executable* + + Type: |String| + Default: `'secfixes-check'` + + This variable can be set to change the path to secfixes-check + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index a181d78a..08b2f0e6 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2599,6 +2599,9 @@ documented in additional help files. gnatpp................................|ale-ada-gnatpp| ansible.................................|ale-ansible-options| ansible-lint..........................|ale-ansible-ansible-lint| + apkbuild................................|ale-apkbuild-options| + apkbuild-lint.........................|ale-apkbuild-apkbuild-lint| + secfixes-check........................|ale-apkbuild-secfixes-check| asciidoc................................|ale-asciidoc-options| write-good............................|ale-asciidoc-write-good| textlint..............................|ale-asciidoc-textlint| From 4f2666265a09cceac2e4091dc871107e418f1f67 Mon Sep 17 00:00:00 2001 From: Mohammed Chelouti <70812484+motato1@users.noreply.github.com> Date: Sun, 27 Dec 2020 01:18:53 +0100 Subject: [PATCH 160/167] feat: Add Deno fmt fixer --- autoload/ale/fix/registry.vim | 5 +++++ autoload/ale/fixers/deno.vim | 17 +++++++++++++++++ autoload/ale/handlers/deno.vim | 9 +++++++++ test/test_deno_executable_detection.vader | 19 +++++++++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 autoload/ale/fixers/deno.vim create mode 100644 autoload/ale/handlers/deno.vim create mode 100644 test/test_deno_executable_detection.vader diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 4564954b..a591a57b 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -32,6 +32,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['python'], \ 'description': 'Fix PEP8 issues with black.', \ }, +\ 'deno': { +\ 'function': 'ale#fixers#deno#Fix', +\ 'suggested_filetypes': ['typescript'], +\ 'description': 'Fix TypeScript using deno fmt.', +\ }, \ 'dfmt': { \ 'function': 'ale#fixers#dfmt#Fix', \ 'suggested_filetypes': ['d'], diff --git a/autoload/ale/fixers/deno.vim b/autoload/ale/fixers/deno.vim new file mode 100644 index 00000000..7154c6ee --- /dev/null +++ b/autoload/ale/fixers/deno.vim @@ -0,0 +1,17 @@ +function! ale#fixers#deno#Fix(buffer) abort + let l:executable = ale#handlers#deno#GetExecutable(a:buffer) + + if !executable(l:executable) + return 0 + endif + + let l:options = ' fmt -' + + if ale#Var(a:buffer, 'deno_unstable') + let l:options = l:options . ' --unstable' + endif + + return { + \ 'command': ale#Escape(l:executable) . l:options + \} +endfunction diff --git a/autoload/ale/handlers/deno.vim b/autoload/ale/handlers/deno.vim new file mode 100644 index 00000000..636c25da --- /dev/null +++ b/autoload/ale/handlers/deno.vim @@ -0,0 +1,9 @@ +" Author: Mohammed Chelouti - https://github.com/motato1 +" Description: Handler functions for Deno. + +call ale#Set('deno_executable', 'deno') +call ale#Set('deno_unstable', 0) + +function! ale#handlers#deno#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'deno_executable') +endfunction diff --git a/test/test_deno_executable_detection.vader b/test/test_deno_executable_detection.vader new file mode 100644 index 00000000..edd408b1 --- /dev/null +++ b/test/test_deno_executable_detection.vader @@ -0,0 +1,19 @@ +Before: + runtime autoload/ale/handlers/deno.vim + +After: + unlet! g:ale_deno_executable + + call ale#linter#Reset() + +Execute(Default executable should be detected correctly): + AssertEqual + \ 'deno', + \ ale#handlers#deno#GetExecutable(bufnr('')) + +Execute(User specified executable should override default): + let g:ale_deno_executable = '/path/to/deno-bin' + AssertEqual + \ '/path/to/deno-bin', + \ ale#handlers#deno#GetExecutable(bufnr('')) + From 9b362634f7210657d94870b017e969bdcdda8de0 Mon Sep 17 00:00:00 2001 From: Mohammed Chelouti <70812484+motato1@users.noreply.github.com> Date: Tue, 29 Dec 2020 21:46:02 +0100 Subject: [PATCH 161/167] feat: Add Deno lsp support --- ale_linters/typescript/deno.vim | 25 ++++++++ autoload/ale/handlers/deno.vim | 43 +++++++++++++ .../test_typescript_deno_lsp.vader | 61 +++++++++++++++++++ test/typescript/test.ts | 0 test/typescript/tsconfig.json | 0 5 files changed, 129 insertions(+) create mode 100644 ale_linters/typescript/deno.vim create mode 100644 test/command_callback/test_typescript_deno_lsp.vader create mode 100644 test/typescript/test.ts create mode 100644 test/typescript/tsconfig.json diff --git a/ale_linters/typescript/deno.vim b/ale_linters/typescript/deno.vim new file mode 100644 index 00000000..051cb208 --- /dev/null +++ b/ale_linters/typescript/deno.vim @@ -0,0 +1,25 @@ +" Author: Mohammed Chelouti - https://github.com/motato1 +" Description: Deno lsp linter for TypeScript files. + +call ale#linter#Define('typescript', { +\ 'name': 'deno', +\ 'lsp': 'stdio', +\ 'executable': function('ale#handlers#deno#GetExecutable'), +\ 'command': '%e lsp', +\ 'project_root': function('ale#handlers#deno#GetProjectRoot'), +\ 'initialization_options': function('ale_linters#typescript#deno#GetInitializationOptions'), +\}) + +function! ale_linters#typescript#deno#GetInitializationOptions(buffer) abort + let l:options = { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false, + \ } + + if ale#Var(a:buffer, 'deno_unstable') + let l:options.unstable = v:true + endif + + return l:options +endfunction diff --git a/autoload/ale/handlers/deno.vim b/autoload/ale/handlers/deno.vim index 636c25da..4bf4546a 100644 --- a/autoload/ale/handlers/deno.vim +++ b/autoload/ale/handlers/deno.vim @@ -3,7 +3,50 @@ call ale#Set('deno_executable', 'deno') call ale#Set('deno_unstable', 0) +call ale#Set('deno_lsp_project_root', '') function! ale#handlers#deno#GetExecutable(buffer) abort return ale#Var(a:buffer, 'deno_executable') endfunction + +" Find project root for Deno's language server. +" +" Deno projects do not require a project or configuration file at the project root. +" This means the root directory has to be guessed, +" unless it is explicitly specified by the user. +" +" The project root is determined by ... +" 1. using a user-specified value from deno_lsp_project_root +" 2. looking for common top-level files/dirs +" 3. using the buffer's directory +function! ale#handlers#deno#GetProjectRoot(buffer) abort + let l:project_root = ale#Var(a:buffer, 'deno_lsp_project_root') + + if !empty(l:project_root) + return l:project_root + endif + + let l:possible_project_roots = [ + \ 'tsconfig.json', + \ '.git', + \ bufname(a:buffer), + \] + + for l:possible_root in l:possible_project_roots + let l:project_root = ale#path#FindNearestFile(a:buffer, l:possible_root) + + if empty(l:project_root) + let l:project_root = ale#path#FindNearestDirectory(a:buffer, l:possible_root) + endif + + if !empty(l:project_root) + " dir:p expands to /full/path/to/dir/ whereas + " file:p expands to /full/path/to/file (no trailing slash) + " Appending '/' ensures that :h:h removes the path's last segment + " regardless of whether it is a directory or not. + return fnamemodify(l:project_root . '/', ':p:h:h') + endif + endfor + + return '' +endfunction diff --git a/test/command_callback/test_typescript_deno_lsp.vader b/test/command_callback/test_typescript_deno_lsp.vader new file mode 100644 index 00000000..b6e4db0e --- /dev/null +++ b/test/command_callback/test_typescript_deno_lsp.vader @@ -0,0 +1,61 @@ +Before: + let g:ale_deno_unstable = 0 + let g:ale_deno_executable = 'deno' + let g:ale_deno_project_root = '' + + runtime autoload/ale/handlers/deno.vim + call ale#assert#SetUpLinterTest('typescript', 'deno') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Should set deno lsp for TypeScript projects using stable Deno API): + AssertLSPLanguage 'typescript' + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../..') + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false + \} + +Execute(Should set deno lsp using unstable Deno API if enabled by user): + let g:ale_deno_unstable = 1 + AssertLSPLanguage 'typescript' + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../..') + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:true + \} + +Execute(Should find project root containing tsconfig.json): + call ale#test#SetFilename('../typescript/test.ts') + AssertLSPLanguage 'typescript' + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../typescript') + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false + \} + +Execute(Should use user-specified project root): + let g:ale_deno_lsp_project_root = '/' + + call ale#test#SetFilename('../typescript/test.ts') + AssertLSPLanguage 'typescript' + AssertLSPConfig {} + AssertLSPProject '/' + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false + \} + + +Execute(Check Deno LSP command): + AssertLinter 'deno', [ + \ ale#Escape('deno') . ' lsp', + \] diff --git a/test/typescript/test.ts b/test/typescript/test.ts new file mode 100644 index 00000000..e69de29b diff --git a/test/typescript/tsconfig.json b/test/typescript/tsconfig.json new file mode 100644 index 00000000..e69de29b From e16c3b09f74dfa6c096fb50c8cd09b1974e75fb0 Mon Sep 17 00:00:00 2001 From: Mohammed Chelouti <70812484+motato1@users.noreply.github.com> Date: Mon, 11 Jan 2021 21:55:17 +0100 Subject: [PATCH 162/167] doc: Add documentation for Deno --- doc/ale-supported-languages-and-tools.txt | 1 + doc/ale-typescript.txt | 33 +++++++++++++++++++ supported-tools.md | 1 + .../test_typescript_deno_lsp.vader | 1 - 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index a44ad75b..b47e1b2c 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -498,6 +498,7 @@ Notes: * `thrift` * TypeScript * `eslint` + * `deno` * `fecs` * `prettier` * `standard` diff --git a/doc/ale-typescript.txt b/doc/ale-typescript.txt index 026d17ce..56735b55 100644 --- a/doc/ale-typescript.txt +++ b/doc/ale-typescript.txt @@ -10,6 +10,39 @@ the two languages are, the `eslint` linter for TypeScript uses the JavaScript options for `eslint` too. See: |ale-javascript-eslint|. +=============================================================================== +deno *ale-typescript-deno* + +Starting from version 1.6.0, Deno comes with its own language server. Earlier +versions are not supported. + +g:ale_deno_executable *g:ale_deno_executable* + *b:ale_deno_executable* + Type: |String| + Default: `'deno'` + + +g:ale_deno_lsp_project_root *g:ale_deno_lsp_project_root* + *b:ale_deno_lsp_project_root* + Type: |String| + Default: `''` + + If this variable is left unset, ALE will try to find the project root by + executing the following steps in the given order: + + 1. Find an ancestor directory containing a tsconfig.json. + 2. Find an ancestory irectory containing a .git folder. + 3. Use the directory of the current buffer (if the buffer was opened from + a file). + +g:ale_deno_unstable *g:ale_deno_unstable* + *b:ale_deno_unstable* + Type: |Number| + Default: `0` + + Enable or disable unstable Deno features and APIs. + + =============================================================================== prettier *ale-typescript-prettier* diff --git a/supported-tools.md b/supported-tools.md index 8ed83d6c..88ad70a4 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -507,6 +507,7 @@ formatting. * [thrift](http://thrift.apache.org/) * TypeScript * [eslint](http://eslint.org/) + * [deno](https://deno.land/) * [fecs](http://fecs.baidu.com/) * [prettier](https://github.com/prettier/prettier) * [standard](http://standardjs.com/) diff --git a/test/command_callback/test_typescript_deno_lsp.vader b/test/command_callback/test_typescript_deno_lsp.vader index b6e4db0e..01cbc851 100644 --- a/test/command_callback/test_typescript_deno_lsp.vader +++ b/test/command_callback/test_typescript_deno_lsp.vader @@ -54,7 +54,6 @@ Execute(Should use user-specified project root): \ 'unstable': v:false \} - Execute(Check Deno LSP command): AssertLinter 'deno', [ \ ale#Escape('deno') . ' lsp', From fe666a7a6c38a7026b1969e6be00eb5d380f8b13 Mon Sep 17 00:00:00 2001 From: Mohammed Chelouti <70812484+motato1@users.noreply.github.com> Date: Sat, 23 Jan 2021 00:43:33 +0100 Subject: [PATCH 163/167] doc: Fix linter issues --- doc/ale-supported-languages-and-tools.txt | 2 +- doc/ale-typescript.txt | 16 ++++++++-------- doc/ale.txt | 1 + supported-tools.md | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index b47e1b2c..e1c65e15 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -497,8 +497,8 @@ Notes: * Thrift * `thrift` * TypeScript - * `eslint` * `deno` + * `eslint` * `fecs` * `prettier` * `standard` diff --git a/doc/ale-typescript.txt b/doc/ale-typescript.txt index 56735b55..a2446c2c 100644 --- a/doc/ale-typescript.txt +++ b/doc/ale-typescript.txt @@ -2,14 +2,6 @@ ALE TypeScript Integration *ale-typescript-options* -=============================================================================== -eslint *ale-typescript-eslint* - -Because of how TypeScript compiles code to JavaScript and how interrelated -the two languages are, the `eslint` linter for TypeScript uses the JavaScript -options for `eslint` too. See: |ale-javascript-eslint|. - - =============================================================================== deno *ale-typescript-deno* @@ -43,6 +35,14 @@ g:ale_deno_unstable *g:ale_deno_unstable* Enable or disable unstable Deno features and APIs. +=============================================================================== +eslint *ale-typescript-eslint* + +Because of how TypeScript compiles code to JavaScript and how interrelated +the two languages are, the `eslint` linter for TypeScript uses the JavaScript +options for `eslint` too. See: |ale-javascript-eslint|. + + =============================================================================== prettier *ale-typescript-prettier* diff --git a/doc/ale.txt b/doc/ale.txt index d73987a9..0261c03c 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2993,6 +2993,7 @@ documented in additional help files. thrift..................................|ale-thrift-options| thrift................................|ale-thrift-thrift| typescript..............................|ale-typescript-options| + deno..................................|ale-typescript-deno| eslint................................|ale-typescript-eslint| prettier..............................|ale-typescript-prettier| standard..............................|ale-typescript-standard| diff --git a/supported-tools.md b/supported-tools.md index 88ad70a4..78c2f6df 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -506,8 +506,8 @@ formatting. * Thrift * [thrift](http://thrift.apache.org/) * TypeScript - * [eslint](http://eslint.org/) * [deno](https://deno.land/) + * [eslint](http://eslint.org/) * [fecs](http://fecs.baidu.com/) * [prettier](https://github.com/prettier/prettier) * [standard](http://standardjs.com/) From 5a47d878fbb837af4c89ab545f473f8526bd4d64 Mon Sep 17 00:00:00 2001 From: tatsuya Date: Sun, 13 Dec 2020 17:06:23 +0900 Subject: [PATCH 164/167] add spectral linter for yaml ci --- ale_linters/yaml/spectral.vim | 42 +++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale-yaml.txt | 32 ++++++++++++ doc/ale.txt | 1 + supported-tools.md | 1 + .../spectral_paths/node_modules/.bin/spectral | 0 .../spectral_paths/openapi.yaml | 0 .../test_spectral_command_callback.vader | 31 +++++++++++ test/handler/test_spectral_handler.vader | 52 +++++++++++++++++++ 9 files changed, 160 insertions(+) create mode 100644 ale_linters/yaml/spectral.vim create mode 100644 test/command_callback/spectral_paths/node_modules/.bin/spectral create mode 100644 test/command_callback/spectral_paths/openapi.yaml create mode 100644 test/command_callback/test_spectral_command_callback.vader create mode 100644 test/handler/test_spectral_handler.vader diff --git a/ale_linters/yaml/spectral.vim b/ale_linters/yaml/spectral.vim new file mode 100644 index 00000000..c1644f3e --- /dev/null +++ b/ale_linters/yaml/spectral.vim @@ -0,0 +1,42 @@ +" Author: t2h5 +" Description: Integration of Stoplight Spectral CLI with ALE. + +call ale#Set('yaml_spectral_executable', 'spectral') +call ale#Set('yaml_spectral_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#yaml#spectral#Handle(buffer, lines) abort + " Matches patterns like the following: + " openapi.yml:1:1 error oas3-schema "Object should have required property `info`." + " openapi.yml:1:1 warning oas3-api-servers "OpenAPI `servers` must be present and non-empty array." + let l:pattern = '\v^.*:(\d+):(\d+) (error|warning) (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:obj = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \ 'text': l:match[4], + \} + + let l:code_match = matchlist(l:obj.text, '\v^(.+) "(.+)"$') + + if !empty(l:code_match) + let l:obj.code = l:code_match[1] + let l:obj.text = l:code_match[2] + endif + + call add(l:output, l:obj) + endfor + + return l:output +endfunction + +call ale#linter#Define('yaml', { +\ 'name': 'spectral', +\ 'executable': {b -> ale#node#FindExecutable(b, 'yaml_spectral', [ +\ 'node_modules/.bin/spectral', +\ ])}, +\ 'command': '%e lint --ignore-unknown-format -q -f text %t', +\ 'callback': 'ale_linters#yaml#spectral#Handle' +\}) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 6744e30e..0b864b48 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -537,6 +537,7 @@ Notes: * `xmllint` * YAML * `prettier` + * `spectral` * `swaglint` * `yamlfix` * `yamllint` diff --git a/doc/ale-yaml.txt b/doc/ale-yaml.txt index 61bfc139..04871403 100644 --- a/doc/ale-yaml.txt +++ b/doc/ale-yaml.txt @@ -15,6 +15,38 @@ Install prettier either globally or locally: > npm install prettier -g # global npm install prettier # local < +=============================================================================== +spectral *ale-yaml-spectral* + +Website: https://github.com/stoplightio/spectral + +Installation +------------------------------------------------------------------------------- + +Install spectral either globally or locally: > + + npm install @stoplight/spectral -g # global + npm install @stoplight/spectral # local +< + +Options +------------------------------------------------------------------------------- + +g:ale_yaml_spectral_executable *g:ale_yaml_spectral_executable* + *b:ale_yaml_spectral_executable* + Type: |String| + Default: `'spectral'` + + This variable can be set to change the path to spectral. + +g:ale_yaml_spectral_use_global *g:ale_yaml_spectral_use_global* + *b:ale_yaml_spectral_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== swaglint *ale-yaml-swaglint* diff --git a/doc/ale.txt b/doc/ale.txt index 97fb0786..f8fea05b 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3028,6 +3028,7 @@ documented in additional help files. xmllint...............................|ale-xml-xmllint| yaml....................................|ale-yaml-options| prettier..............................|ale-yaml-prettier| + spectral..............................|ale-yaml-spectral| swaglint..............................|ale-yaml-swaglint| yamlfix...............................|ale-yaml-yamlfix| yamllint..............................|ale-yaml-yamllint| diff --git a/supported-tools.md b/supported-tools.md index cd8a8fdc..cf0370a9 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -546,6 +546,7 @@ formatting. * [xmllint](http://xmlsoft.org/xmllint.html) * YAML * [prettier](https://github.com/prettier/prettier) + * [spectral](https://github.com/stoplightio/spectral) * [swaglint](https://github.com/byCedric/swaglint) * [yamlfix](https://lyz-code.github.io/yamlfix) * [yamllint](https://yamllint.readthedocs.io/) diff --git a/test/command_callback/spectral_paths/node_modules/.bin/spectral b/test/command_callback/spectral_paths/node_modules/.bin/spectral new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/spectral_paths/openapi.yaml b/test/command_callback/spectral_paths/openapi.yaml new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/test_spectral_command_callback.vader b/test/command_callback/test_spectral_command_callback.vader new file mode 100644 index 00000000..ed3795b9 --- /dev/null +++ b/test/command_callback/test_spectral_command_callback.vader @@ -0,0 +1,31 @@ +Before: + call ale#assert#SetUpLinterTest('yaml', 'spectral') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The yaml spectral command callback should return the correct default string): + AssertLinter 'spectral', ale#Escape('spectral') . ' lint --ignore-unknown-format -q -f text %t' + +Execute(The yaml spectral command callback should be configurable): + let g:ale_yaml_spectral_executable = '~/.local/bin/spectral' + + AssertLinter '~/.local/bin/spectral', + \ ale#Escape('~/.local/bin/spectral') + \ . ' lint --ignore-unknown-format -q -f text %t' + +Execute(The yaml spectral command callback should allow a global installation to be used): + let g:ale_yaml_spectral_executable = '/usr/local/bin/spectral' + let g:ale_yaml_spectral_use_global = 1 + + AssertLinter '/usr/local/bin/spectral', + \ ale#Escape('/usr/local/bin/spectral') + \ . ' lint --ignore-unknown-format -q -f text %t' + +Execute(The yaml spectral command callback should allow a local installation to be used): + call ale#test#SetFilename('spectral_paths/openapi.yaml') + + AssertLinter + \ ale#path#Simplify(g:dir . '/spectral_paths/node_modules/.bin/spectral'), + \ ale#Escape(ale#path#Simplify(g:dir . '/spectral_paths/node_modules/.bin/spectral')) + \ . ' lint --ignore-unknown-format -q -f text %t' diff --git a/test/handler/test_spectral_handler.vader b/test/handler/test_spectral_handler.vader new file mode 100644 index 00000000..b315168f --- /dev/null +++ b/test/handler/test_spectral_handler.vader @@ -0,0 +1,52 @@ +Before: + runtime ale_linters/yaml/spectral.vim + +After: + call ale#linter#Reset() + +Execute(spectral handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'code': 'oas3-api-servers', + \ 'text': 'OpenAPI `servers` must be present and non-empty array.', + \ 'type': 'W' + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'code': 'oas3-schema', + \ 'text': 'Object should have required property `paths`.', + \ 'type': 'E' + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'code': 'openapi-tags', + \ 'text': 'OpenAPI object should have non-empty `tags` array.', + \ 'type': 'W' + \ }, + \ { + \ 'lnum': 3, + \ 'col': 6, + \ 'code': 'info-contact', + \ 'text': 'Info object should contain `contact` object.', + \ 'type': 'W' + \ }, + \ { + \ 'lnum': 3, + \ 'col': 6, + \ 'code': 'oas3-schema', + \ 'text': '`info` property should have required property `version`.', + \ 'type': 'E' + \ }, + \ ], + \ ale_linters#yaml#spectral#Handle(bufnr(''), [ + \ 'openapi.yml:1:1 warning oas3-api-servers "OpenAPI `servers` must be present and non-empty array."', + \ 'openapi.yml:1:1 error oas3-schema "Object should have required property `paths`."', + \ 'openapi.yml:1:1 warning openapi-tags "OpenAPI object should have non-empty `tags` array."', + \ 'openapi.yml:3:6 warning info-contact "Info object should contain `contact` object."', + \ 'openapi.yml:3:6 error oas3-schema "`info` property should have required property `version`."', + \ ]) From 997dd7f8fe45030e65b418c5f46e20d808b1c5eb Mon Sep 17 00:00:00 2001 From: tatsuya Date: Wed, 6 Jan 2021 13:22:08 +0900 Subject: [PATCH 165/167] add spectral handler --- ale_linters/yaml/spectral.vim | 30 +---------------------- autoload/ale/handlers/spectral.vim | 31 ++++++++++++++++++++++++ test/handler/test_spectral_handler.vader | 2 +- 3 files changed, 33 insertions(+), 30 deletions(-) create mode 100644 autoload/ale/handlers/spectral.vim diff --git a/ale_linters/yaml/spectral.vim b/ale_linters/yaml/spectral.vim index c1644f3e..bd4623a5 100644 --- a/ale_linters/yaml/spectral.vim +++ b/ale_linters/yaml/spectral.vim @@ -4,39 +4,11 @@ call ale#Set('yaml_spectral_executable', 'spectral') call ale#Set('yaml_spectral_use_global', get(g:, 'ale_use_global_executables', 0)) -function! ale_linters#yaml#spectral#Handle(buffer, lines) abort - " Matches patterns like the following: - " openapi.yml:1:1 error oas3-schema "Object should have required property `info`." - " openapi.yml:1:1 warning oas3-api-servers "OpenAPI `servers` must be present and non-empty array." - let l:pattern = '\v^.*:(\d+):(\d+) (error|warning) (.*)$' - let l:output = [] - - for l:match in ale#util#GetMatches(a:lines, l:pattern) - let l:obj = { - \ 'lnum': l:match[1] + 0, - \ 'col': l:match[2] + 0, - \ 'type': l:match[3] is# 'error' ? 'E' : 'W', - \ 'text': l:match[4], - \} - - let l:code_match = matchlist(l:obj.text, '\v^(.+) "(.+)"$') - - if !empty(l:code_match) - let l:obj.code = l:code_match[1] - let l:obj.text = l:code_match[2] - endif - - call add(l:output, l:obj) - endfor - - return l:output -endfunction - call ale#linter#Define('yaml', { \ 'name': 'spectral', \ 'executable': {b -> ale#node#FindExecutable(b, 'yaml_spectral', [ \ 'node_modules/.bin/spectral', \ ])}, \ 'command': '%e lint --ignore-unknown-format -q -f text %t', -\ 'callback': 'ale_linters#yaml#spectral#Handle' +\ 'callback': 'ale#handlers#spectral#HandleSpectralOutput' \}) diff --git a/autoload/ale/handlers/spectral.vim b/autoload/ale/handlers/spectral.vim new file mode 100644 index 00000000..1eb4a5de --- /dev/null +++ b/autoload/ale/handlers/spectral.vim @@ -0,0 +1,31 @@ +" Author: t2h5 +" Description: Integration of Stoplight Spectral CLI with ALE. + +function! ale#handlers#spectral#HandleSpectralOutput(buffer, lines) abort + " Matches patterns like the following: + " openapi.yml:1:1 error oas3-schema "Object should have required property `info`." + " openapi.yml:1:1 warning oas3-api-servers "OpenAPI `servers` must be present and non-empty array." + let l:pattern = '\v^.*:(\d+):(\d+) (error|warning) (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:obj = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \ 'text': l:match[4], + \} + + let l:code_match = matchlist(l:obj.text, '\v^(.+) "(.+)"$') + + if !empty(l:code_match) + let l:obj.code = l:code_match[1] + let l:obj.text = l:code_match[2] + endif + + call add(l:output, l:obj) + endfor + + return l:output +endfunction + diff --git a/test/handler/test_spectral_handler.vader b/test/handler/test_spectral_handler.vader index b315168f..89a3ff1b 100644 --- a/test/handler/test_spectral_handler.vader +++ b/test/handler/test_spectral_handler.vader @@ -43,7 +43,7 @@ Execute(spectral handler should parse lines correctly): \ 'type': 'E' \ }, \ ], - \ ale_linters#yaml#spectral#Handle(bufnr(''), [ + \ ale#handlers#spectral#HandleSpectralOutput(bufnr(''), [ \ 'openapi.yml:1:1 warning oas3-api-servers "OpenAPI `servers` must be present and non-empty array."', \ 'openapi.yml:1:1 error oas3-schema "Object should have required property `paths`."', \ 'openapi.yml:1:1 warning openapi-tags "OpenAPI object should have non-empty `tags` array."', From 66b3e768db55b0c03fa34310a5c79bbd24209694 Mon Sep 17 00:00:00 2001 From: tatsuya Date: Wed, 6 Jan 2021 13:25:52 +0900 Subject: [PATCH 166/167] add spectral support for json --- ale_linters/json/spectral.vim | 14 ++++++++++ doc/ale-json.txt | 32 +++++++++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + 5 files changed, 49 insertions(+) create mode 100644 ale_linters/json/spectral.vim diff --git a/ale_linters/json/spectral.vim b/ale_linters/json/spectral.vim new file mode 100644 index 00000000..c7d56234 --- /dev/null +++ b/ale_linters/json/spectral.vim @@ -0,0 +1,14 @@ +" Author: t2h5 +" Description: Integration of Stoplight Spectral CLI with ALE. + +call ale#Set('json_spectral_executable', 'spectral') +call ale#Set('json_spectral_use_global', get(g:, 'ale_use_global_executables', 0)) + +call ale#linter#Define('json', { +\ 'name': 'spectral', +\ 'executable': {b -> ale#node#FindExecutable(b, 'json_spectral', [ +\ 'node_modules/.bin/spectral', +\ ])}, +\ 'command': '%e lint --ignore-unknown-format -q -f text %t', +\ 'callback': 'ale#handlers#spectral#HandleSpectralOutput' +\}) diff --git a/doc/ale-json.txt b/doc/ale-json.txt index 96499a04..dc91e14c 100644 --- a/doc/ale-json.txt +++ b/doc/ale-json.txt @@ -101,5 +101,37 @@ prettier *ale-json-prettier* See |ale-javascript-prettier| for information about the available options. +=============================================================================== +spectral *ale-json-spectral* + +Website: https://github.com/stoplightio/spectral + +Installation +------------------------------------------------------------------------------- + +Install spectral either globally or locally: > + + npm install @stoplight/spectral -g # global + npm install @stoplight/spectral # local +< + +Options +------------------------------------------------------------------------------- + +g:ale_json_spectral_executable *g:ale_json_spectral_executable* + *b:ale_json_spectral_executable* + Type: |String| + Default: `'spectral'` + + This variable can be set to change the path to spectral. + +g:ale_json_spectral_use_global *g:ale_json_spectral_use_global* + *b:ale_json_spectral_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 0b864b48..ce73136f 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -248,6 +248,7 @@ Notes: * `jq` * `jsonlint` * `prettier` + * `spectral` * Julia * `languageserver` * Kotlin diff --git a/doc/ale.txt b/doc/ale.txt index f8fea05b..5cbc10c4 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2785,6 +2785,7 @@ documented in additional help files. jsonlint..............................|ale-json-jsonlint| jq....................................|ale-json-jq| prettier..............................|ale-json-prettier| + spectral..............................|ale-json-spectral| julia...................................|ale-julia-options| languageserver........................|ale-julia-languageserver| kotlin..................................|ale-kotlin-options| diff --git a/supported-tools.md b/supported-tools.md index cf0370a9..0e1e6b29 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -257,6 +257,7 @@ formatting. * [jq](https://stedolan.github.io/jq/) * [jsonlint](http://zaa.ch/jsonlint/) * [prettier](https://github.com/prettier/prettier) + * [spectral](https://github.com/stoplightio/spectral) * Julia * [languageserver](https://github.com/JuliaEditorSupport/LanguageServer.jl) * Kotlin From c1b6628425a87a7466c09afbd5f6c90217aa9ab0 Mon Sep 17 00:00:00 2001 From: jD91mZM2 Date: Fri, 22 Jan 2021 17:29:51 +0100 Subject: [PATCH 167/167] Add rnix-lsp for Nix diagnostics and completion --- ale_linters/nix/rnix_lsp.vim | 16 ++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + supported-tools.md | 1 + test/nix/test.nix | 0 test/nix/test_rnix_lsp.vader | 14 ++++++++++++++ 5 files changed, 32 insertions(+) create mode 100644 ale_linters/nix/rnix_lsp.vim create mode 100644 test/nix/test.nix create mode 100644 test/nix/test_rnix_lsp.vader diff --git a/ale_linters/nix/rnix_lsp.vim b/ale_linters/nix/rnix_lsp.vim new file mode 100644 index 00000000..949bed1c --- /dev/null +++ b/ale_linters/nix/rnix_lsp.vim @@ -0,0 +1,16 @@ +" Author: jD91mZM2 +" Description: rnix-lsp language client + +function! ale_linters#nix#rnix_lsp#GetProjectRoot(buffer) abort + " rnix-lsp does not yet use the project root, so getting it right is not + " important + return fnamemodify(a:buffer, ':h') +endfunction + +call ale#linter#Define('nix', { +\ 'name': 'rnix_lsp', +\ 'lsp': 'stdio', +\ 'executable': 'rnix-lsp', +\ 'command': '%e', +\ 'project_root': function('ale_linters#nix#rnix_lsp#GetProjectRoot'), +\}) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 239927be..2a3fe137 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -304,6 +304,7 @@ Notes: * nix * `nix-instantiate` * `nixpkgs-fmt` + * `rnix-lsp` * nroff * `alex`!! * `proselint` diff --git a/supported-tools.md b/supported-tools.md index ff4a78d8..6994a337 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -313,6 +313,7 @@ formatting. * nix * [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) * [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt) + * [rnix-lsp](https://github.com/nix-community/rnix-lsp) * nroff * [alex](https://github.com/wooorm/alex) :floppy_disk: * [proselint](http://proselint.com/) diff --git a/test/nix/test.nix b/test/nix/test.nix new file mode 100644 index 00000000..e69de29b diff --git a/test/nix/test_rnix_lsp.vader b/test/nix/test_rnix_lsp.vader new file mode 100644 index 00000000..bf62616b --- /dev/null +++ b/test/nix/test_rnix_lsp.vader @@ -0,0 +1,14 @@ +" Author: jD91mZM2 +" Description: Tests for rnix-lsp language client + +Before: + call ale#assert#SetUpLinterTest('nix', 'rnix_lsp') + +After: + call ale#assert#TearDownLinterTest() + +Execute(should start rnix-lsp): + call ale#test#SetFilename('./test.nix') + AssertLSPLanguage 'nix' + AssertLSPOptions {} + AssertLSPProject ale#path#Simplify('.')