Skip to content

Commit

Permalink
feat(lsp): codeAction commands
Browse files Browse the repository at this point in the history
  • Loading branch information
matoous committed Dec 19, 2021
1 parent 49e0678 commit b86781f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 5 deletions.
21 changes: 17 additions & 4 deletions helix-lsp/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,11 @@ impl Client {
}

/// Reply to a language server RPC call.
pub fn reply(
pub fn reply<R>(
&self,
id: jsonrpc::Id,
result: core::result::Result<Value, jsonrpc::Error>,
) -> impl Future<Output = Result<()>> {
result: core::result::Result<R, jsonrpc::Error>,
) -> impl Future<Output = Result<()>> where R: serde::Serialize {
use jsonrpc::{Failure, Output, Success, Version};

let server_tx = self.server_tx.clone();
Expand All @@ -202,7 +202,7 @@ impl Client {
Ok(result) => Output::Success(Success {
jsonrpc: Some(Version::V2),
id,
result,
result: serde_json::to_value(result)?,
}),
Err(error) => Output::Failure(Failure {
jsonrpc: Some(Version::V2),
Expand Down Expand Up @@ -800,4 +800,17 @@ impl Client {
let response = self.request::<lsp::request::Rename>(params).await?;
Ok(response.unwrap_or_default())
}

pub async fn command(&self, command: lsp::Command) -> anyhow::Result<Option<Value>> {
let params = lsp::ExecuteCommandParams {
command: command.command,
arguments: command.arguments.unwrap_or_default(),
work_done_progress_params: lsp::WorkDoneProgressParams {
work_done_token: None,
},
};

let response = self.call::<lsp::request::ExecuteCommand>(params).await?;
Ok(Some(response))
}
}
7 changes: 7 additions & 0 deletions helix-lsp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ pub mod util {
#[derive(Debug, PartialEq, Clone)]
pub enum MethodCall {
WorkDoneProgressCreate(lsp::WorkDoneProgressCreateParams),
ApplyWorkspaceEdit(lsp::ApplyWorkspaceEditParams),
}

impl MethodCall {
Expand All @@ -215,6 +216,12 @@ impl MethodCall {
.expect("Failed to parse WorkDoneCreate params");
Self::WorkDoneProgressCreate(params)
}
lsp::request::ApplyWorkspaceEdit::METHOD => {
let params: lsp::ApplyWorkspaceEditParams = params
.parse()
.expect("Failed to parse ApplyWorkspaceEdit params");
Self::ApplyWorkspaceEdit(params)
}
_ => {
log::warn!("unhandled lsp request: {}", method);
return None;
Expand Down
10 changes: 10 additions & 0 deletions helix-term/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,16 @@ impl Application {
}
tokio::spawn(language_server.reply(id, Ok(serde_json::Value::Null)));
}
MethodCall::ApplyWorkspaceEdit(params) => {
log::debug!("Received workspace/applyEdit from LSP: {:?}", params);
// TODO: handle the edits
let resp = lsp::ApplyWorkspaceEditResponse {
applied: true,
failure_reason: None,
failed_change: None,
};
tokio::spawn(language_server.reply(id, Ok(resp)));
}
}
}
e => unreachable!("{:?}", e),
Expand Down
26 changes: 25 additions & 1 deletion helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3282,7 +3282,31 @@ pub fn code_action(cx: &mut Context) {
lsp::CodeActionOrCommand::CodeAction(code_action) => {
log::debug!("code action: {:?}", code_action);
if let Some(ref workspace_edit) = code_action.edit {
apply_workspace_edit(editor, offset_encoding, workspace_edit)
log::debug!("edit: {:?}", workspace_edit);
apply_workspace_edit(editor, offset_encoding, workspace_edit);
}
// if code action provides both edit and command first the edit
// should be applied and then the command
if let Some(ref command) = code_action.command {
log::debug!("command: {:?}", command);
let (_, doc) = current!(editor);

let language_server = match doc.language_server() {
Some(language_server) => language_server,
None => return,
};

// command is executed on the server, in most cases the server
// creates workspace edit so we just block here and wait
// for the outbound workspace edit to resolve
match block_on(language_server.command(command.clone())) {
Ok(ref edit) => {
log::debug!("command edit: {:?}", edit);
},
Err(e) => {
log::error!("call LSP command: {:?}", e);
},
}
}
}
},
Expand Down

0 comments on commit b86781f

Please sign in to comment.