diff options
author | Matouš Dzivjak | 2024-01-17 17:24:38 +0000 |
---|---|---|
committer | GitHub | 2024-01-17 17:24:38 +0000 |
commit | c60ba4ba04de56f37f4f4b19051bc4a1e68b3484 (patch) | |
tree | 724199349f239b9c646bc26639c60cbe18eb9b1b /helix-term/src/application.rs | |
parent | 6754acd83ff0f6edf837611679c5f4424e14492e (diff) |
feat(lsp): implement show document request (#8865)
* feat(lsp): implement show document request
Implement [window.showDocument](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#window_showDocument)
LSP server-sent request.
This PR builds on top of helix-editor#5820,
moves the external-URL opening functionality into shared crate-level
function that returns a callback that is now used by both the
`open_file` command as well as the window.showDocument handler if
the URL is marked as external.
* add return
* use vertical split
* refactor
---------
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Diffstat (limited to 'helix-term/src/application.rs')
-rw-r--r-- | helix-term/src/application.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 01c120d0..1b0a06dd 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -3,6 +3,7 @@ use futures_util::Stream; use helix_core::{path::get_relative_path, pos_at_coords, syntax, Selection}; use helix_lsp::{ lsp::{self, notification::Notification}, + util::lsp_range_to_range, LspProgressMap, }; use helix_view::{ @@ -1100,6 +1101,13 @@ impl Application { } Ok(serde_json::Value::Null) } + Ok(MethodCall::ShowDocument(params)) => { + let language_server = language_server!(); + let offset_encoding = language_server.offset_encoding(); + + let result = self.handle_show_document(params, offset_encoding); + Ok(json!(result)) + } }; tokio::spawn(language_server!().reply(id, reply)); @@ -1108,6 +1116,68 @@ impl Application { } } + fn handle_show_document( + &mut self, + params: lsp::ShowDocumentParams, + offset_encoding: helix_lsp::OffsetEncoding, + ) -> lsp::ShowDocumentResult { + if let lsp::ShowDocumentParams { + external: Some(true), + uri, + .. + } = params + { + self.jobs.callback(crate::open_external_url_callback(uri)); + return lsp::ShowDocumentResult { success: true }; + }; + + let lsp::ShowDocumentParams { + uri, + selection, + take_focus, + .. + } = params; + + let path = match uri.to_file_path() { + Ok(path) => path, + Err(err) => { + log::error!("unsupported file URI: {}: {:?}", uri, err); + return lsp::ShowDocumentResult { success: false }; + } + }; + + let action = match take_focus { + Some(true) => helix_view::editor::Action::Replace, + _ => helix_view::editor::Action::VerticalSplit, + }; + + let doc_id = match self.editor.open(&path, action) { + Ok(id) => id, + Err(err) => { + log::error!("failed to open path: {:?}: {:?}", uri, err); + return lsp::ShowDocumentResult { success: false }; + } + }; + + let doc = doc_mut!(self.editor, &doc_id); + if let Some(range) = selection { + // TODO: convert inside server + if let Some(new_range) = lsp_range_to_range(doc.text(), range, offset_encoding) { + let view = view_mut!(self.editor); + + // we flip the range so that the cursor sits on the start of the symbol + // (for example start of the function). + doc.set_selection(view.id, Selection::single(new_range.head, new_range.anchor)); + if action.align_view(view, doc.id()) { + align_view(doc, view, Align::Center); + } + } else { + log::warn!("lsp position out of bounds - {:?}", range); + }; + }; + lsp::ShowDocumentResult { success: true } + } + async fn claim_term(&mut self) -> std::io::Result<()> { let terminal_config = self.config.load().editor.clone().into(); self.terminal.claim(terminal_config) |