From 4e365962baf5ee455c1b9946d550927f8a35d0c3 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Tue, 24 Oct 2023 13:27:06 +1100 Subject: [PATCH] Support passing desired servers' names to :LspInstall --- dot-config/vim/lsp.vim | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/dot-config/vim/lsp.vim b/dot-config/vim/lsp.vim index 846bbc2..3d2a361 100644 --- a/dot-config/vim/lsp.vim +++ b/dot-config/vim/lsp.vim @@ -115,7 +115,18 @@ const lspOptions = { ignoreMissingServer: true, } -command! -nargs=0 -bar LspInstall Install() +command! -nargs=* -complete=customlist,ListMissingServers -bar LspInstall Install() + +# Convert a list of strings to a dictionary containing those same strings as +# keys, approximating a set type. You can use has_key() to test set membership +# on the result, rather than index(). +def ToStringSet(stringList: list): dict + var stringSet: dict + for string in stringList + stringSet[string] = true + endfor + return stringSet +enddef def InstalledServers(): list> return lspServers->deepcopy()->filter((_, server): bool => executable(server.path) == 1) @@ -125,6 +136,10 @@ def MissingServers(): list> return lspServers->deepcopy()->filter((_, server): bool => executable(server.path) == 0) 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! @@ -133,6 +148,8 @@ export def LazyConfigure(): void 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. final installedServers = InstalledServers() if len(lspServers) != len(installedServers) echo $'{len(lspServers) - len(installedServers)} language servers are configured, but not installed. You may want to run :LspInstall.' @@ -141,17 +158,23 @@ export def Configure(): void g:LspOptionsSet(lspOptions) enddef -export def Install(): void +export def Install(...serverNames: list): void const missingServers = MissingServers() + if empty(missingServers) echo $"All {len(lspServers)} configured language servers are already installed." return endif - # The installScript runs every missing server's install command, regardless - # of whether any fail in the process. The script's exit status is the number - # of failed installations. - const installScript = "failed=0\n" .. missingServers->copy() + const serverNamesSet = ToStringSet(serverNames) + const serversToInstall = empty(serverNamesSet) + ? missingServers + : missingServers->copy()->filter((_, server): bool => serverNamesSet->has_key(server.name)) + + # The installScript runs every server's install command, regardless of + # whether any fail in the process. The script's exit status is the number of + # failed installations. + const installScript = "failed=0\n" .. serversToInstall->copy() ->map((_, server): string => $"\{ {server.install}; \} || failed=$((failed + 1))") ->join("\n") .. "\nexit $failed\n"