autozimu / LanguageClient-neovim

Language Server Protocol (LSP) support for vim and neovim.
MIT License
3.55k stars 273 forks source link

Add enable_extensions config and set up gopls extensions #1072

Closed martskins closed 3 years ago

martskins commented 4 years ago

This PR adds a new config value (g:LanguageClient_enableExtensions), which provides a way to turn the provided language extensions off.

For example, to turn off Rust language extensions and enable Go extensions:

  let g:LanguageClient_enableExtensions = {
    \ 'go': v:true,
    \ 'rust': v:false,
    \ }

In that example we've enabled Go's extensions and disabled Rust's. Also, as we haven't specified any other filetypes, extensions for all the other filetypes will be disabled. If you wanted to also enable them for, say java, you'd have to include that in the config map as well.

This PR also adds extensions for Go, specifically for Go with gopls as a server. It provides extensions for test and generate code lenses, providing a way to run them in a vim terminal (like we do with the Rust tests). Here's a screencast of that functionality.

Peek 2020-06-29 08-29

I think at some point it will be worth considering moving to an plugin extensions scheme, were we provide additional plugins to plug this sort of language-server-specific functionality into the client via a defined interface. We could even have a wrapper plugin around all those plugins for the users that want to add a single line to their vimrc to get all the goodies. This requires a bit of work though, as some functionality is not properly exposed via vim functions, for example rust-analyzer.showReferences would requires us to re-write the whole UI selection thing in vim or to include a vim function to call into it. But even considering that extra work, and considering that this will probably be a breaking change, I think it would be the best scenario, as we would be able to remove that code from the client's codebase and open up the ecosystem to developers that want to support a very specific command from a very specific language server without us having to get in the way and maintain a zillion extensions baked into the binary.

I was thinking, something in the lines of this:

https://github.com/martskins/lcn-extension-gopls https://github.com/martskins/lcn-extension-rust-analyzer

And have try_handle_commmand_by_client call into the lcn#extension#{language_server}#handle_command function and handle it vim side (or call into the client again if necessary).

I know that this is way out of topic for this PR, but if sounds like a better alternative I'm up for closing this one and focusing on getting those two up to speed and adding the java one and the wrapper for all three so we get the same functionality.

What do you think @autozimu ?

autozimu commented 4 years ago

To be frank, I don't know the answer to extension of extension.

I totally agree that enabling extension will allow more developer to contribute, especially contribute to particular language support oneself cares about.

On the other hand, I'm a bit concerned about the user experiences. Do we keep bare minimum support of LSP in this plugin and ask user to install one more plugin for every one language they want to use? I think that's going to be a sub-optimal user experience. Getting user to properly install one plugin is already hard enough. Another concern is regarding support and compatibility. Once we enable the plugin support, we're effectively becoming a platform, which is kind of bound to keep backwards capabilities.

With that said, I do agree we should try it out and see how it works.

martskins commented 4 years ago

If that's the case I guess we can merge this one and move on to other experiments later on.

martskins commented 3 years ago

Just rebased this one and fixed the gopls specific functions to comply with the new messages the server sends. If you are happy with this @autozimu I'll merge it.

autozimu commented 3 years ago

Looks good to me 👍