diff --git a/ale_linters/perl/languageserver.vim b/ale_linters/perl/languageserver.vim new file mode 100644 index 00000000..56ad151a --- /dev/null +++ b/ale_linters/perl/languageserver.vim @@ -0,0 +1,43 @@ +" Authors: ophirr33 , rymdbar +" Description: Perl::LanguageServer for perl, from cpan.org + +" This should have the same value as in perl.vim +call ale#Set('perl_perl_executable', 'perl') +" Please note that perl_perl_options does not exist here. + +function! ale_linters#perl#languageserver#GetProjectRoot(buffer) abort + " Makefile.PL, https://perldoc.perl.org/ExtUtils::MakeMaker + " Build.PL, https://metacpan.org/pod/Module::Build + " dist.ini, https://metacpan.org/pod/Dist::Zilla + let l:potential_roots = [ 'Makefile.PL', 'Build.PL', 'dist.ini', '.git' ] + + for l:root in l:potential_roots + let l:project_root = ale#path#FindNearestFile(a:buffer, l:root) + + if !empty(l:project_root) + return fnamemodify(l:project_root . '/', ':p:h:h') + endif + endfor + + return fnamemodify(expand('#' . a:buffer . ':p:h'), ':p:h') +endfunction + +call ale#Set('perl_languageserver_config', {}) + +function! s:get_lsp_config(buffer) abort + " This tool doesn't kick in unless workspace/didChangeConfiguration is + " called, thus this function returning a fallback dict when there is no + " config. + let l:lsp_config = ale#Var(a:buffer, 'perl_languageserver_config') + + return empty(l:lsp_config) ? { 'perl': { 'enable': 1 } } : l:lsp_config +endfunction + +call ale#linter#Define('perl', { +\ 'name': 'languageserver', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'perl_perl_executable')}, +\ 'command': '%e -MPerl::LanguageServer -ePerl::LanguageServer::run', +\ 'lsp_config': {b -> s:get_lsp_config(b)}, +\ 'project_root': function('ale_linters#perl#languageserver#GetProjectRoot'), +\ }) diff --git a/doc/ale-perl.txt b/doc/ale-perl.txt index 0f7553c2..55f2e8e3 100644 --- a/doc/ale-perl.txt +++ b/doc/ale-perl.txt @@ -35,6 +35,42 @@ g:ale_perl_perl_options invocation. +=============================================================================== +perl language server *ale-perl-languageserver* + +perl_perl_executable +g:ale_perl_perl_executable + Type: |String| + Default: `'perl'` + + The language server will use the same variable as |ale-perl-perl| to launch + the perl executable with the Perl::LanguageServer module. + + *ale-options.perl_languageserver_config* + *g:ale_perl_languageserver_config* + *b:ale_perl_languageserver_config* +perl_languageserver_config +g:ale_perl_languageserver_config + Type: |Dictionary| + Default: `'{}'` + + This variable can be changed to customize the lsp_config (sent as a + workspace/didChangeConfiguration command). + For example: > + + let g:ale_perl_languageserver_config = { + \ 'perl': { + \ 'fileFilter': [''], + \ 'logLevel': 2, + \ 'logFile': '/tmp/plls-log.txt', + \ 'perlInc': ['/usr/share/perl5/', '/usr/local/share/perl5/' ], + \ }, + \} +< + For all available options and explanations, visit + https://metacpan.org/pod/Perl::LanguageServer#Extension-Settings + + =============================================================================== perlcritic *ale-perl-perlcritic* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 19c83f26..d2aa06cf 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -472,6 +472,7 @@ Notes: * Pawn * `uncrustify` * Perl + * `languageserver` * `perl -c` * `perl-critic` * `perltidy` diff --git a/doc/ale.txt b/doc/ale.txt index 68116a57..4db6f4f7 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3750,6 +3750,7 @@ documented in additional help files. uncrustify............................|ale-pawn-uncrustify| perl....................................|ale-perl-options| perl..................................|ale-perl-perl| + perl language server..................|ale-perl-languageserver| perlcritic............................|ale-perl-perlcritic| perltidy..............................|ale-perl-perltidy| perl6...................................|ale-perl6-options| diff --git a/supported-tools.md b/supported-tools.md index 310b7d4a..81305eac 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -482,6 +482,7 @@ formatting. * Pawn * [uncrustify](https://github.com/uncrustify/uncrustify) * Perl + * [languageserver](https://metacpan.org/pod/Perl::LanguageServer) * [perl -c](https://perl.org/) :warning: * [perl-critic](https://metacpan.org/pod/Perl::Critic) * [perltidy](https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy) diff --git a/test/linter/test_perl.vader b/test/linter/test_perl.vader index 3c4b661c..bbaa5cec 100644 --- a/test/linter/test_perl.vader +++ b/test/linter/test_perl.vader @@ -12,3 +12,5 @@ Execute(Overriding the executable and command should work): let b:ale_perl_perl_options = '-w' AssertLinter 'foobar', ale#Escape('foobar') . ' -w %t' + unlet b:ale_perl_perl_executable + unlet b:ale_perl_perl_options diff --git a/test/linter/test_perl_languageserver.vader b/test/linter/test_perl_languageserver.vader new file mode 100644 index 00000000..bfcc6c1e --- /dev/null +++ b/test/linter/test_perl_languageserver.vader @@ -0,0 +1,82 @@ +" Author: rymdbar + +Before: + call ale#assert#SetUpLinterTest('perl', 'languageserver') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default Perl command callback should be correct): + AssertLinter 'perl', + \ ale#Escape('perl') . ' -MPerl::LanguageServer -ePerl::LanguageServer::run' + +Execute(Overriding the executable should work): + let b:ale_perl_perl_executable = 'plls' + + AssertLinter 'plls', ale#Escape('plls') . + \ ' -MPerl::LanguageServer -ePerl::LanguageServer::run' + unlet b:ale_perl_perl_executable + +Execute(The project root should be detected correctly in from build files): + for mod in ['extutils-makemaker', 'module-build', 'dist-zilla'] + call ale#test#SetFilename('../test-files/perl/' . mod . '/subdir/empty.pl') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/perl/' . mod) + endfor + +Execute(The project root should be globally configurable): + for mod in ['extutils-makemaker', 'module-build', 'dist-zilla'] + call ale#test#SetFilename('../test-files/perl/'. mod . '/subdir/empty.pl') + " Configuring g:ale_root using a Dictionary works. + let g:ale_root.languageserver = + \ ale#path#Simplify(g:dir . '/../test-files/perl') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/perl') + unlet g:ale_root.languageserver + " As tracked by , there + " is a bug with g:ale_root. + " While attempting to configure g:ale_root using a String might be a quite + " limiting setup, it would be handy for debugging. However the test case is + " missing here. It would unfortunately just fail. + endfor + +Execute(The project root should be per buffer configurable): + for mod in ['extutils-makemaker', 'module-build', 'dist-zilla'] + call ale#test#SetFilename('../test-files/perl/'. mod . '/subdir/empty.pl') + " Configuring b:ale_root using a String works. + let b:ale_root = ale#path#Simplify(g:dir . '/../test-files/perl') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/perl') + unlet b:ale_root + + " Configuring b:ale_root using a Dictionary works. + let b:ale_root = { + \ 'languageserver': ale#path#Simplify(g:dir . '/../test-files/perl') + \ } + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/perl') + unlet b:ale_root.languageserver + endfor + +Execute(The LSP values should be set correctly): + + AssertLSPLanguage 'perl' + + AssertLSPOptions {} + + AssertLSPConfig {'perl': {'enable': 1}} + +Execute(Should accept configuration settings): + let b:ale_perl_languageserver_config = { + \ 'perl': { + \ 'perlInc': ['/usr/share/perl5/', '/usr/local/share/perl5/' ], + \ 'fileFilter': [''], + \ }, + \ } + + AssertLSPConfig { + \ 'perl': { + \ 'perlInc': ['/usr/share/perl5/', '/usr/local/share/perl5/' ], + \ 'fileFilter': [''], + \ }, + \ } diff --git a/test/test-files/perl/dist-zilla/dist.ini b/test/test-files/perl/dist-zilla/dist.ini new file mode 100644 index 00000000..731096dc --- /dev/null +++ b/test/test-files/perl/dist-zilla/dist.ini @@ -0,0 +1 @@ +# https://metacpan.org/pod/Dist::Zilla diff --git a/test/test-files/perl/dist-zilla/subdir/empty.pl b/test/test-files/perl/dist-zilla/subdir/empty.pl new file mode 100644 index 00000000..e69de29b diff --git a/test/test-files/perl/extutils-makemaker/Makefile.PL b/test/test-files/perl/extutils-makemaker/Makefile.PL new file mode 100644 index 00000000..e67c7a9d --- /dev/null +++ b/test/test-files/perl/extutils-makemaker/Makefile.PL @@ -0,0 +1 @@ +# https://perldoc.perl.org/ExtUtils::MakeMaker diff --git a/test/test-files/perl/extutils-makemaker/subdir/empty.pl b/test/test-files/perl/extutils-makemaker/subdir/empty.pl new file mode 100644 index 00000000..e69de29b diff --git a/test/test-files/perl/module-build/Build.PL b/test/test-files/perl/module-build/Build.PL new file mode 100644 index 00000000..f9ec0a25 --- /dev/null +++ b/test/test-files/perl/module-build/Build.PL @@ -0,0 +1 @@ +# https://metacpan.org/pod/Module::Build diff --git a/test/test-files/perl/module-build/subdir/empty.pl b/test/test-files/perl/module-build/subdir/empty.pl new file mode 100644 index 00000000..e69de29b