From 28eb0ea76b5d6f279b7fc46feb24d1a5f35865c0 Mon Sep 17 00:00:00 2001 From: MDeiml Date: Mon, 27 Feb 2023 13:06:59 +0100 Subject: [PATCH 1/2] Fix bug with positional encoding --- helix-term/src/application.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 95faa01b0a3e..e119a12cf3e0 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -959,6 +959,14 @@ impl Application { Call::MethodCall(helix_lsp::jsonrpc::MethodCall { method, params, id, .. }) => { + let offset_encoding = match self.editor.language_servers.get_by_id(server_id) { + Some(language_server) => language_server.offset_encoding(), + None => { + warn!("can't find language server with id `{}`", server_id); + return; + } + }; + let reply = match MethodCall::parse(&method, params) { Err(helix_lsp::Error::Unhandled) => { error!( @@ -999,11 +1007,7 @@ impl Application { Ok(serde_json::Value::Null) } Ok(MethodCall::ApplyWorkspaceEdit(params)) => { - let res = apply_workspace_edit( - &mut self.editor, - helix_lsp::OffsetEncoding::Utf8, - ¶ms.edit, - ); + apply_workspace_edit(&mut self.editor, offset_encoding, ¶ms.edit); Ok(json!(lsp::ApplyWorkspaceEditResponse { applied: res.is_ok(), From df11bdb2120c183233966a3d95147ddc3157c531 Mon Sep 17 00:00:00 2001 From: MDeiml Date: Mon, 27 Feb 2023 13:14:39 +0100 Subject: [PATCH 2/2] Implement LSP window/showDocument request --- helix-lsp/src/client.rs | 1 + helix-lsp/src/lib.rs | 5 +++ helix-term/src/application.rs | 73 +++++++++++++++++++++++++++++++---- 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index f93e582639a1..cac74859fb80 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -409,6 +409,7 @@ impl Client { }), window: Some(lsp::WindowClientCapabilities { work_done_progress: Some(true), + show_document: Some(lsp::ShowDocumentClientCapabilities { support: true }), ..Default::default() }), general: Some(lsp::GeneralClientCapabilities { diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index 5609a624fecc..ef112c6e84cc 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -527,6 +527,7 @@ pub enum MethodCall { WorkspaceFolders, WorkspaceConfiguration(lsp::ConfigurationParams), RegisterCapability(lsp::RegistrationParams), + ShowDocument(lsp::ShowDocumentParams), } impl MethodCall { @@ -550,6 +551,10 @@ impl MethodCall { let params: lsp::RegistrationParams = params.parse()?; Self::RegisterCapability(params) } + lsp::request::ShowDocument::METHOD => { + let params: lsp::ShowDocumentParams = params.parse()?; + Self::ShowDocument(params) + } _ => { return Err(Error::Unhandled); } diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index e119a12cf3e0..918ccee241e1 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -5,7 +5,11 @@ use helix_core::{ path::get_relative_path, pos_at_coords, syntax, Selection, }; -use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap}; +use helix_lsp::{ + lsp, + util::{lsp_pos_to_pos, lsp_range_to_range}, + LspProgressMap, +}; use helix_view::{ align_view, document::DocumentSavedEventResult, @@ -1007,7 +1011,8 @@ impl Application { Ok(serde_json::Value::Null) } Ok(MethodCall::ApplyWorkspaceEdit(params)) => { - apply_workspace_edit(&mut self.editor, offset_encoding, ¶ms.edit); + let res = + apply_workspace_edit(&mut self.editor, offset_encoding, ¶ms.edit); Ok(json!(lsp::ApplyWorkspaceEditResponse { applied: res.is_ok(), @@ -1063,16 +1068,68 @@ impl Application { Ok(serde_json::Value::Null) } - }; + Ok(MethodCall::ShowDocument(params)) => { + use helix_view::editor::Action; - let language_server = match self.editor.language_servers.get_by_id(server_id) { - Some(language_server) => language_server, - None => { - warn!("can't find language server with id `{}`", server_id); - return; + if params.external.unwrap_or(false) { + // TODO: Implement this + Ok(json!(lsp::ShowDocumentResult { success: false })) + } else { + match params.uri.to_file_path() { + Err(_) => { + let err = format!( + "unable to convert URI to filepath: {}", + params.uri + ); + self.editor.set_error(err); + Ok(json!(lsp::ShowDocumentResult { success: false })) + } + Ok(path) => { + match self.editor.open(&path, Action::Replace) { + Err(err) => { + let err = format!( + "failed to open path: {:?}: {:?}", + params.uri, err + ); + self.editor.set_error(err); + Ok(json!(lsp::ShowDocumentResult { success: false })) + } + Ok(_) => { + if let Some(range) = params.selection { + let (view, doc) = current!(self.editor); + // TODO: convert inside server + if let Some(new_range) = lsp_range_to_range( + doc.text(), + range, + offset_encoding, + ) { + let jump = + (doc.id(), doc.selection(view.id).clone()); + view.jumps.push(jump); + doc.set_selection( + view.id, + Selection::single( + new_range.anchor, + new_range.head, + ), + ); + align_view(doc, view, Align::Center); + } + } + + Ok(json!(lsp::ShowDocumentResult { success: true })) + } + } + } + } + } } }; + // We can `unwrap` here, because we would have already returned erlier if the + // resusult was `None`. + let language_server = self.editor.language_servers.get_by_id(server_id).unwrap(); + tokio::spawn(language_server.reply(id, reply)); } Call::Invalid { id } => log::error!("LSP invalid method call id={:?}", id),