LanguageClient-neovim
LanguageClient-neovim copied to clipboard
Single server for multiple filetypes
Is your feature request related to a problem? Please describe.
Some languages have a single server that can target multiple different filetypes. For example typescript-language-server that works with javascript, typescript & jsx.
Or clangd that can work with C, C++, etc.
When working on a project where both filetypes are used, it spins up multiple servers, which feels like a waste of resources and unnecessary duplicated work.
Describe the solution you'd like
It would be great to have a single server set up for multiple filetypes.
I'm unsure if the current way of specifying servers using g:LanguageClient_serverCommands would be sufficient, since it only allows a 1:1 mapping of language to server.
Perhaps it would be possible to extend it? Something like:
let g:LanguageClient_serverCommands = {
\ 'js-ts': { 'server': ['typescript-language-server', '--stdio'], 'languages': ['javascript', 'typescript'] }
\ }
Hm there's an open issue here that actually requests the opposite, being able to launch more than one server for a single language type, but this one I don't think we have considered before. This is a rather involved change, but leaving that complexity aside, does the protocol specify whether a single instance of a server should be able to handle different languages? Or is that property derived from somewhere else maybe? I ask because if this is not specified by the protocol I can imagine servers having different behaviours and possibly not every one of them playing nicely to this.
As a side note, we've recently added a different way to specify the server commands, you can do this:
let g:LanguageClient_serverCommands = {
\ 'rust': ['rustup', 'run', 'stable', 'rls'],
\ 'go': {
\ 'name': 'gopls',
\ 'command': ['gopls'],
\ 'initializationOptions': {
\ 'usePlaceholders': v:true,
\ 'codelens': {
\ 'generate': v:true,
\ 'test': v:true,
\ },
\ },
\ },
\}
or the way we already supported:
let g:LanguageClient_serverCommands = {
\ 'javascript': ['tcp://127.0.0.1:2089'],
\ }
Haven't seen this mentioned in the protocol spec. But I'd say that it would work, since the supported languages can be used together, like importing a js file inside ts. The server would have to do the same work for both of them anyway.
I've also used clients in the past that supported a single server for multiple filetypes, and the servers I mentioned worked fine.
Another benefit I can think of: Unsaved changes in one filetype's buffer can be recognized and considered by the server in another filetype, if both filetypes share a single server.
It wouldn't be possible if the filetypes have separate servers, as they would not be aware of changes outside of their own filetype.