LanguageClient-neovim icon indicating copy to clipboard operation
LanguageClient-neovim copied to clipboard

Single server for multiple filetypes

Open rottencandy opened this issue 4 years ago • 3 comments

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'] }
\ }

rottencandy avatar Jan 28 '21 19:01 rottencandy

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'],
        \ }

martskins avatar Jan 28 '21 21:01 martskins

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.

rottencandy avatar Jan 29 '21 08:01 rottencandy

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.

rottencandy avatar Jan 29 '21 09:01 rottencandy