diff --git a/dot-config/vim/lsp.vim b/dot-config/vim/lsp.vim index 9a1c804..1afca4c 100644 --- a/dot-config/vim/lsp.vim +++ b/dot-config/vim/lsp.vim @@ -1,5 +1,7 @@ vim9script +import './tools/perl.vim' + const lspServers = [ { name: 'dockerfile-langserver', @@ -25,6 +27,8 @@ const lspServers = [ install: 'npm install -g perlnavigator-server', }, + perl.Lsp('Perl::LanguageServer', ['-e', 'Perl::LanguageServer::run']), + { name: 'taplo', filetype: 'toml', @@ -128,12 +132,16 @@ def ToStringSet(stringList: list): dict return stringSet enddef +def IsInstalled(server: dict): bool + return server->has_key('installed') ? server.installed() : executable(server.path) == 1 +enddef + def InstalledServers(): list> - return lspServers->deepcopy()->filter((_, server): bool => executable(server.path) == 1) + return lspServers->deepcopy()->filter((_, server): bool => server->IsInstalled()) enddef def MissingServers(): list> - return lspServers->deepcopy()->filter((_, server): bool => executable(server.path) == 0) + return lspServers->deepcopy()->filter((_, server): bool => !server->isInstalled()) enddef def ListMissingServers(argLead: string, cmdLine: string, cursorPos: number): list diff --git a/dot-config/vim/tools/perl.vim b/dot-config/vim/tools/perl.vim new file mode 100644 index 0000000..17ae67d --- /dev/null +++ b/dot-config/vim/tools/perl.vim @@ -0,0 +1,27 @@ +vim9script + +export def Lsp(module: string, args: list): dict + const lsp = { + name: module, + filetype: 'perl', + path: exepath('perl'), + args: [$'-M{module}']->extend(args), + install: $'cpanm {module}', + installed: (): bool => HasModule(module), + } + return lsp +enddef + +export def HasModule(module: string): bool + # This can more reliably be tested by calling `perl -MModule::Name -E ''` + # and checking the exit status, but simply looking for a matching file on + # disk is much faster and works fine for my purposes. + const libs = $PERL5LIB->split(';') + const filename = module->substitute('::', '/', 'g') .. '.pm' + for lib in libs + if filereadable($'{lib}/{filename}') + return true + endif + endfor + return false +enddef