-
Notifications
You must be signed in to change notification settings - Fork 4
Allow to disable selected capabilities by the client #58
base: master
Are you sure you want to change the base?
Allow to disable selected capabilities by the client #58
Conversation
I still do not understand why |
Is |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like some 7.3 issues with the build. Away from keyboard at the moment, but if the test is of a different category to the other test it's "fine" to have another test method, possibly the duplication could be reduced? But otherwise it is what it is.
bool $supportSnippets = true, | ||
): ClientCapabilities { | ||
$capabilities = new ClientCapabilities(); | ||
$capabilities->textDocument = new TextDocumentClientCapabilities(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can call Client capabilities::fromArray() or similar if it helps to generalize.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know about it but in this case building the array would look similar.
…rzepompownia:przepompownia/language-server-phpactor-extensions into allow-disable-selected-capabilities-by-the-client
/** | ||
* @var ClientCapabilities | ||
*/ | ||
private ClientCapabilities $clientCapabilities; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgotten that the whole project still depends on (unsupported) PHP 7.3 and typed properties are not allowed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, it would be good to bump it again. just a big PITA with 50 packages.
There is no reason. I think the CompletionHandler pre-dated the SignatureHelp handler. |
|
||
public function __construct(ClientCapabilities $clientCapabilities) | ||
{ | ||
$this->clientCapabilities = $clientCapabilities; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather avoid generalizing abstract classes. Not all handlers need to know the client capabilities, and chances are you need to override the constructor anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can move back those duplicates if you want.
Indeed, I forgotten to update some handlers to be depend on the client capabilities.
protected function clientCapabilities(Container $container): ClientCapabilities | ||
{ | ||
return $container->get(ClientCapabilities::class); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as below, i'd rather avoid this...
@@ -157,7 +161,7 @@ public function references( | |||
|
|||
public function registerCapabiltiies(ServerCapabilities $capabilities): void | |||
{ | |||
$capabilities->referencesProvider = true; | |||
$capabilities->referencesProvider = null !== $this->clientCapabilities->textDocument->references; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this correct? the server is still capable, the client is not? I would think this would only hide the fact the server supports it with no benefit to the client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not found any better solution to prevent the client from calling to phpactor's given method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah I see.
the goal here is f.e. disable completion and use another LS for that?
I don't think this is about client capabilities (I don't think that can necessarily be controlled by the user in every IDE?). I think this would then need to be a Phpactor level config, or mechanism to enable / disable extensions/handlers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still work on a legacy project mentioned in phpactor/phpactor#1125 Calling for completion or references still takes unacceptable time (with index on in-memory FS, JIT and ComposerAutoloaderExtension
) and warms up CPU.
It forces me to use intelephense instead for these costly requests.
This change allows me to use phpactor anywhere on that project (and then possibly learn it, find bugs etc.).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe not every IDE can make this selection but LSP seems to allow require it:
ClientCapabilities define capabilities for dynamic registration, workspace and text document features the client supports. The experimental can be used to pass experimental capabilities under development. For future compatibility a ClientCapabilities object literal can have more properties set than currently defined. Servers receiving a ClientCapabilities object literal with unknown properties should ignore these properties. A missing property should be interpreted as an absence of the capability. If a missing property normally defines sub properties, all missing sub properties should be interpreted as an absence of the corresponding capability.
(from https://microsoft.github.io/language-server-protocol/specification#initialize)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
text document features the client supports
but the client defines what the client supports not the user? in your case you want to disable (f.e.) text completion. the client still supports it.
in this PR the client determines what the server supports, which seems wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(i definitely support enabling/disabling functionality btw, there is a good use case for disabling completion and using another LS for that)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the client still supports it.
I understand the word "client" as a concrete instance (so it supports at most those capabilities which it declared at initialization) - not as a software able to create such (variously configured) instances. LSP-compliant server seems to know only about the declared set.
A missing property should be interpreted as an absence of the capability.
in this PR the client determines what the server supports
Yes, it (at this PR finish) would restrict the set according to the rule quoted above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$capabilities->referencesProvider = null !== $this->clientCapabilities->textDocument->references;
read literally, this says "I support references only if the client supports it". But that's a lie, it supports references regardless of if the client supports it.
As far as I understand it (and I can't see any contraditction in that spec extract). Capabilties braodcast what the server/client support. They do not intefere with eachother. We use the client capabilities to see if the client supports certain messages from the server. If the client doesn't support certain features, the server won't send those messages.
Unless I'm wrong I would rather we added explicit Phpactor configuration to enable/disable handlers somehow, as this would implicitly inform the ServerCapabilties (because they simply would not be registered, and the RPC methods would not be exposed) and the Client would then not use the server for f.e. text completion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the client doesn't support certain features, the server won't send those messages.
It's what I try to implement there. For example, client (understood as a configured instance) does not support textDocument/references
and then the server in the response says that it does not provide it to the client on its demand. Maybe, technically, in this PR the server can still response for textDocument/references
by some tricky way (is it mentioned lie?). Maybe we need to prevent from execution this method in such ways.
What else is the purpose of sending client LSP-defined capabilities than making an intersection with the server-provided set in the result?
See also
- https://www.reddit.com/r/neovim/comments/nvds8f/disable_single_capabilities_for_a_given_lsp_server/
- Add support for CodeAction.disabled microsoft/language-server-protocol#940
I still do not understand if dynamicRegistration
can be related to this issue:
https://medium.com/@malintha1996/understanding-the-language-server-protocol-5c0ba3ac83d2#6c58
So that the server knows what the client supports so it can avoid sending messages to the client that would result in an error I think. In that Reddit post the servers do not support the capabilities, it's a different problem I think and the goal is to stop the client sending messages. Would it not also make equal sense that the client could be configured to disable certain features and not request them? If you go to the trouble of disabling the Client Capabilty, surely the client can also simply not use that capability (although to me that also makes no sense, as capabilities are not, or do not have to be, user defined) |
I don't think it is. It's a way to say "from now on, I don't want the client to send me these messages" I think. Dynamic registration is sever => client. IIRC |
Yes, and if I understand you mean support as the set of possible client capabilities and I mean those chosen from them for a single instance. For example, nvim built-in client allows to start with Do you have concerns that this is LSP incompatible? In summary we have three possible independent solutions:
|
yes, it's an interpretation of the spec which is not specific on this (or I missed something). I would assume that other LS servers do not disable capabilities based on the client configuration, and then this is not a general solution, but a "hack" for Phpactor e.g. I would like to disable completion, but there is not a client capabiltiy for that, only a server one. interesting that the Sublime LSP server has the |
Neither of us seems to be 100% sure how it should be. I also would not like to propose a hack. The source is my understanding that this completes the missing protocol behavior. Maybe it's good moment to ask someone on https://github.com/microsoft/language-server-protocol before close or merge it.
I take into account that this client-side solution was implemented to workaround the lack of such feature ;-) |
Please look at microsoft/language-server-protocol#1403 |
Thanks for that. Given that behavior I would simply not register the handler rather than have the handler decide if it exposes that capability. But, at least in my case, it doesn't help with disabling completion or reference etc. (have to run now, will have a think) |
Initially I was wondering how to turn off the whole handler but I did not sure if we have one-to-one relation between handler and a corresponding LSP capability. |
Sorry for not getting back on this. I still think that deciding to support/not support a given feature is a client-side decision and should be incorporated there. The client makes the calls. If we were to implement this using the approach here, there would still be no way of f.e. disabling completion, and what's more not all clients will allow the capabilities to be overridden. Disabling the server side capabilities based on client capabilities in the referenced issue seems more about "not wasting unneeded resources". I think having Phpactor options to enable/disable a capability would still be beneficial, but I currently don't think that using the client capablities is a satisfactory way of doing that. |
No problem. While it works I simply use this branch and can focus on other things in the meantime. Independently of your choice and testing other approaches (including your propositions) there is also no problem for me to keep this branch up to date and, possibly, find some time to check how to free unused resources.
Lack of user access to restricting capabilities at a particular client side is an issue of such client. |
Closes #56