args|a list of command-line arguments passed to the LSP server. Each argument is a separate List item.
initializationOptions|User provided initialization options. May be of any type. For example the *intelephense* PHP language server accept several options here with the License Key among others.
customNotificationHandlers|A dictionary of notifications and functions that can be specified to add support for custom language server notifications.
+features|A dictionary of booleans that can be specified to toggle what things a given LSP is providing (folding, goto definition, etc) This is useful when running multiple servers in one buffer.
The LSP servers are added using the LspAddServer() function. This function accepts a list of LSP servers with the above information.
endif
enddef
-# Returns the LSP server for the buffer 'bnr'. Returns an empty dict if the
-# server is not found.
-export def BufLspServerGet(bnr: number): dict<any>
+# Returns the LSP server for the buffer 'bnr' and optionally 'domain'.
+# Returns an empty dict if the server is not found.
+export def BufLspServerGet(bnr: number, domain: string = null_string): dict<any>
if !bufnrToServers->has_key(bnr)
return {}
endif
return {}
endif
- # TODO implement logic to compute which server to return
- return bufnrToServers[bnr][0]
+ if domain == null_string
+ return bufnrToServers[bnr][0]
+ endif
+
+ var SupportedCheckFns = {
+ }
+
+ if !SupportedCheckFns->has_key(domain)
+ # If this happns it is a programming error, and should be fixed in the source code
+ :throw $'Error: ''{domain}'' is not a valid domain'
+ return {}
+ endif
+
+ var SupportedCheckFn = SupportedCheckFns[domain]
+
+ var possibleLSPs: list<dict<any>> = []
+
+ for lspserver in bufnrToServers[bnr]
+ if !SupportedCheckFn(lspserver)
+ continue
+ endif
+
+ possibleLSPs->add(lspserver)
+ endfor
+
+ if possibleLSPs->len() == 0
+ return {}
+ endif
+
+ # LSP server is configured to be a provider for 'domain'
+ for lspserver in possibleLSPs
+ if lspserver.features->has_key(domain) && lspserver.features[domain]
+ return lspserver
+ endif
+ endfor
+
+ # Return the first LSP server that supports 'domain'
+ return possibleLSPs[0]
enddef
# Returns the LSP server for the buffer 'bnr' and with ID 'id'. Returns an empty
return bufnrToServers[bnr]
enddef
-# Returns the LSP server for the current buffer. Returns an empty dict if the
-# server is not found.
-export def CurbufGetServer(): dict<any>
- return BufLspServerGet(bufnr())
+# Returns the LSP server for the current buffer with the optionally 'domain'.
+# Returns an empty dict if the server is not found.
+export def CurbufGetServer(domain: string = null_string): dict<any>
+ return BufLspServerGet(bufnr(), domain)
enddef
# Returns the LSP servers for the current buffer. Returns an empty list if the
return !lspserver->empty()
enddef
-# Returns the LSP server for the current buffer if it is running and is ready.
+# Returns the LSP server for the current buffer with the optinally 'domain' if
+# it is running and is ready.
# Returns an empty dict if the server is not found or is not ready.
-export def CurbufGetServerChecked(): dict<any>
+export def CurbufGetServerChecked(domain: string = null_string): dict<any>
var fname: string = @%
if fname == ''
return {}
endif
- var lspserver: dict<any> = CurbufGetServer()
+ var lspserver: dict<any> = CurbufGetServer(domain)
if lspserver->empty()
util.ErrMsg($'Error: Language server for "{&filetype}" file type is not found')
return {}
customNotificationHandlers = server.customNotificationHandlers
endif
+ var features: dict<bool> = {}
+ if server->has_key('features')
+ features = server.features
+ endif
+
if server.omnicompl->type() != v:t_bool
util.ErrMsg($'Error: Setting of omnicompl {server.omnicompl} is not a Boolean')
return
server.workspaceConfig,
server.rootSearch,
customNotificationHandlers,
- server.debug)
+ features, server.debug)
var ftypes = server.filetype
if ftypes->type() == v:t_string
workspaceConfig: dict<any>,
rootSearchFiles: list<any>,
customNotificationHandlers: dict<func>,
- debug_arg: bool): dict<any>
+ features: dict<bool>, debug_arg: bool): dict<any>
var lspserver: dict<any> = {
id: GetUniqueServerId(),
name: name_arg,
syncInit: isSync,
initializationOptions: initializationOptions,
customNotificationHandlers: customNotificationHandlers,
+ features: features,
running: false,
ready: false,
job: v:none,
}
}])
<
+ *lsp-cfg-features*
+ features
+ (Optional) toggle which features should be enabled for a
+ given langauge server. See |lsp-multiple-servers| for
+ more information.
*lsp-cfg-omnicompl*
omnicompl (Optional) a boolean value that enables (true)
or disables (false) omni-completion for this file
| createIfNotExists method() |
| ... |
<
+==============================================================================
+16. Multiple Language Servers for a buffer *lsp-multiple-servers*
+
+It's possible to run multiple language servers for a given buffer.
+
+By default the language server defined first will be used for as much as it
+supports, then the next and so on. With the exception that diagnostics from all
+running language servers will be joined together. This means that you can define
+a language server that only supports a subset of features at first and then
+define the general purpose language server after it: >
+
+ vim9script
+ g:LspAddServer([
+ # This language server reports that it only supports
+ # textDocument/documentFormatting, so it will be used
+ # for :LspFormat but nothing else.
+ {
+ filetype: ['html'],
+ path: 'html-pretty-lsp',
+ args: ['--stdio']
+ },
+ # This language server also supports
+ # textDocument/documentFormatting, but since it's been
+ # defined later, the one above will be used instead.
+ # However this server also supports
+ # textDocument/definition, textDocument/declaration,
+ # etc, so it will be used for :LspGotoDefinition,
+ # :LspGotoDeclaration, etc
+ {
+ filetype: ['html'],
+ path: 'html-language-server',
+ args: ['--stdio']
+ }
+ ])
+<
+By proving the configuration |lsp-cfg-features| it's possible specify which
+servers should be used for a given method. The following flags are supported
+>
+#{
+}
+<
vim:tw=78:ts=8:noet:ft=help:norl: