diff --git a/dot-config/vim/init.vim b/dot-config/vim/init.vim index d7b3a69..e2974e6 100644 --- a/dot-config/vim/init.vim +++ b/dot-config/vim/init.vim @@ -105,7 +105,7 @@ import "./statusline.vim" statusline.Init() import "./lsp.vim" -lsp.LazyConfigure() +lsp.Configure() set formatexpr=lsp#lsp#FormatExpr() set keywordprg=:LspHover diff --git a/dot-config/vim/lsp.vim b/dot-config/vim/lsp.vim index 3d2a361..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,25 +132,22 @@ 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 return MissingServers()->mapnew((_, server): string => server.name) enddef -export def LazyConfigure(): void - augroup lspLazyConfigure - autocmd! - autocmd VimEnter * ++once Configure() - augroup END -enddef - export def Configure(): void # We have to use final rather than const because LspAddServer() assumes it can # modify the dicts it gets, rather than making a fresh copy to mess with. @@ -154,8 +155,8 @@ export def Configure(): void if len(lspServers) != len(installedServers) echo $'{len(lspServers) - len(installedServers)} language servers are configured, but not installed. You may want to run :LspInstall.' endif - g:LspAddServer(installedServers) - g:LspOptionsSet(lspOptions) + g:lsp#lsp#AddServer(installedServers) + g:lsp#options#OptionsSet(lspOptions) enddef export def Install(...serverNames: list): void 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