-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HACK: Support eclipe.jdt.ls's break with the LSP spec #12
Conversation
This is obviously good specifically for Java's eclipse LSP but we should find a more generic way like proposed in this issue that allows package authors to "register" handlers for custom (or even generic) commands, and allow them to run a callback when such command is chosen by the user. |
Is there somewhere in the spec that allows for registering commands? or should we start there and update the spec first? I don't want to deviate from the spec too much.
No, which is why it is still a draft. |
I'm going to ignore the discussion that went on the bug I referenced, and the bugs referenced to it on the language-server-protocol repository, because things have changed and the specs look clearer now, and state this -
I'll take some time to research this and come back with conclusions and examples. |
After having done research (and in particular going over the progression made with what started all of this - the Eclipse language server) it seems that in many cases where the non-standard message made sense in the standard it was suggested to it and was often added, and in other cases we should allow it. For example - in the vscode java extension, the way they get project settings is by invoking I think it's fine for language servers to offer extra capabilities that enhance the experience of the developer. What happened in the ide-java case referenced here is that Eclipse returned a Code Action I think the most ideal thing we can do - and that should in turn help us handle many cases of having to override behaviors - is let the extension developer set a sort of "middleware" or register his own callback to any Some possible use cases -
Makes sense? I feel this will bring full control for extension developers on how |
I like it. Can you give me an example of what that would look like for a client? |
My proposal looks like this. I propose adding a A sample / gist of all of this - import { Command, ExecuteCommandParams } from "../languageclient";
import { LanguageClientConnection } from "../main";
export type CommandCustomCallbackFunction = (command: ExecuteCommandParams) => Promise<void>;
export default class CommandExecutionAdapter {
private static commandsCustomCallbacks: Map<string, CommandCustomCallbackFunction> = new Map<string, CommandCustomCallbackFunction>();
public static registerCustomCallbackForCommand(command: string, callback: CommandCustomCallbackFunction) {
this.commandsCustomCallbacks.set(command, callback);
}
public static async executeCommand(connection: LanguageClientConnection, command: string, commandArgs?: any[] | undefined): Promise<any | void> {
const executeCommandParams = CommandExecutionAdapter.createExecuteCommandParams(command, commandArgs);
const commandCustomCallback = this.commandsCustomCallbacks.get(command);
return commandCustomCallback != null ? await commandCustomCallback(executeCommandParams) : await connection.executeCommand(executeCommandParams);
}
public static createExecuteCommandParams(command: string, commandArgs?: any[] | undefined): ExecuteCommandParams {
return {
command: command,
arguments: commandArgs
};
}
} I think it is concise and rather clear, and also doesn't add a new convention rather than following the existing one where |
So the java client would look something like the following code instead of this PR? class JavaLanguageClient extends AutoLanguageClient {
...
constructor () {
...
this.registerCustomCallbackForCommand('java.apply.workspaceEdit', (command) => {
if (command.arguments) {
// Guaranteed only ever one element in the arguments array
const edit: WorkspaceEdit = command.arguments[0];
CodeActionAdapter.applyWorkspaceEdit(edit);
}
})
}
...
} |
Precisely. :) EDIT: |
LGTM Can you create a PR for that? |
done, added some tests, still gotta see this works well with ide-java as a testbed |
closing in favor of #117 |
moved from atom/atom-languageclient#268
see issue atom/atom-languageclient#183