natebosch / vim-lsc

A vim plugin for communicating with a language server
BSD 3-Clause "New" or "Revised" License
694 stars 79 forks source link

Question: Can you use a settings.json file with vim-lsc #132

Open softinio opened 5 years ago

softinio commented 5 years ago

Some LSP clients use a settings.json file for configuration. VSCode and other LSP clients support this.

Does vim-lsc support it? If so where do you save the settings.json for it to pick up? Or can you specify a path to it?

Eg: https://github.com/autozimu/LanguageClient-neovim/blob/next/doc/LanguageClient.txt#L194

Took a quick look at the code and didn't see it supported but thought I double check.

I am not familiar with vimscript but happy to contribute this if not availabe with some guidance.

Thanks.

natebosch commented 5 years ago

It looks like this is something that either sends initializationOptions during the initialize call, or calls workspace/didChangeConfiguration after startup?

Can you give an example of a server setting you'd like to send with this?

I can probably implement this once I understand the use case. For example it looks like the LanguageClient-neovim implementation has a global configuration for the settings file - shouldn't it be per server?

softinio commented 5 years ago

This is an example of its usage:

https://github.com/haskell/haskell-ide-engine#configuration

Hope this helps. Let me know if I can help. Thanks.

natebosch commented 5 years ago

I think this is doable.

Note that if you are primarily interested in setting initializationOptions and your configuration is consistent instead of specific to a workspace you can accomplish this today with extra configuration. See :help lsc-server-message_hooks. The example shows setting custom initializationOptions in the initialize message.

I'll see if I can put together a PR to allow per-workspace settings in a settings.json file. If the global options are sufficient for you though let me know and I may punt on it for a while.

olafurpg commented 5 years ago

It may be a tall order but it would be great to support a combination of user settings (global) and workspace settings somehow. This is how vscode does it. For example, in Metals (Scala language server) we have settings like “scalafmt config path” which are workspace specific and also “java home “ which is computer specific and global https://scalameta.org/metals/docs/editors/new-editor.html#scalafmt-config-path

Not sure how to best implement that however.

natebosch commented 5 years ago

We could probably merge initializationOptions from both settings.json and the message_hooks server config.

One thing I am a bit worried about is potential confusion around exactly what can be configured through settings.json - it would only be something opaque to vim-lsc that gets forwarded to the server, I would not plan on replacing any of the per-server or global client config with anything in settings.json...

I tried to understand the LanguageClient-neovim implementation for this and got a bit confused - is settings.json there cross-language? That is, do you use a key in the json map to specify which server you are configuring? Or does it assume that for a given workspace only a single server will be used so it sends the entire config to that server? I think for VSCode the server (or language?) is the top level key and then individual settings are nested under it.

I also understand that you can use dots in the keys to flatten the nested, so {"language.setting" :"value"} is equivalent to {"language": {"setting": "value"}}. Do we think that's an important property of the implementation or can we get by without it?

softinio commented 5 years ago

Found another vim lsp plugin. Thought a useful reference for what we are discussing here and your merge suggestion:

https://github.com/neoclide/coc.nvim/tree/8639687823ac44eb573af3b014b14116d1e223b4/src/configuration

Docs on it:

https://github.com/neoclide/coc.nvim/wiki/Using-configuration-file

olafurpg commented 5 years ago

One thing I am a bit worried about is potential confusion around exactly what can be configured through settings.json.

I expect settings.json to only be used for configuration that is sent to the server via workspace/didChangeConfiguration.

For example, in our VS Code extension we declare that the "metals" key in the JSON configuration should be forwarded to our language server.

  const clientOptions: LanguageClientOptions = {
    documentSelector: [{ scheme: "file", language: "scala" }],
    synchronize: {
+      configurationSection: "metals"
    },
    revealOutputChannelOn: RevealOutputChannelOn.Never,
    outputChannel: outputChannel
  };

In vim-lsc, this key could be declared in "server customizations". This key makes it possible to have configuration for multiple servers in the same JSON file.

{
  "metals": { ... },
  "rust": { ... }

Right after initialized and when the settings change (for example via manually triggered :LSCConfigurationChanged) the language server receives the following notification.

{
  "jsonrpc": "2.0",
  "method": "workspace/didChangeConfiguration",
  "params": {
    "settings": {
      "metals": {
        "javaHome": "/Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home",
        "sbtScript": "/usr/local/bin/sbt"
      }
    }
  }
}

In this particular case, the sbtScript setting was defined in my "workspace settings" and javaHome in "user settings".

screenshot 2019-01-11 at 11 07 40

In vim-lsc, the workspace setting should be a relative path (configurable as "server customization", not sure what is the best default) and one global path (could be hardcoded by vim-lsc). The workspace settings should override global settings.

you can use dots in the keys to flatten the nested

This is not critical in my opinion, it's OK to require users to nest the settings.

natebosch commented 5 years ago

https://github.com/natebosch/vim-lsc/pull/199 will add support for workspace/didChangeConfiguration as it's set in the server config key workspace_config. Next bit would be to locate and parse settings.json.