From 57ed5180e0e1af3b3ddcb478c4a6d6ecd969cd40 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Mon, 6 Sep 2021 11:00:33 +0900 Subject: lsp: Improve line ending handling when generating TextEdit --- helix-view/src/document.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'helix-view/src/document.rs') diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index e890a336..b2c02927 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -891,6 +891,40 @@ impl Default for Document { mod test { use super::*; + #[test] + fn changeset_to_changes_ignore_line_endings() { + use helix_lsp::{lsp, Client, OffsetEncoding}; + let text = Rope::from("hello\r\nworld"); + let mut doc = Document::from(text, None); + let view = ViewId::default(); + doc.set_selection(view, Selection::single(0, 0)); + + let transaction = + Transaction::change(doc.text(), vec![(5, 7, Some("\n".into()))].into_iter()); + let old_doc = doc.text().clone(); + doc.apply(&transaction, view); + let changes = Client::changeset_to_changes( + &old_doc, + doc.text(), + transaction.changes(), + OffsetEncoding::Utf8, + ); + + assert_eq!(doc.text(), "hello\nworld"); + + assert_eq!( + changes, + &[lsp::TextDocumentContentChangeEvent { + range: Some(lsp::Range::new( + lsp::Position::new(0, 5), + lsp::Position::new(1, 0) + )), + text: "\n".into(), + range_length: None, + }] + ); + } + #[test] fn changeset_to_changes() { use helix_lsp::{lsp, Client, OffsetEncoding}; -- cgit v1.2.3-70-g09d2 From 184637c55acca49380372ca118f13b3390bcb003 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Wed, 1 Sep 2021 14:49:48 +0900 Subject: lsp: refactor format so we stop cloning the language_server --- helix-lsp/src/client.rs | 14 +++++++++----- helix-view/src/document.rs | 23 +++++++++++++---------- 2 files changed, 22 insertions(+), 15 deletions(-) (limited to 'helix-view/src/document.rs') diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index ac6ae70a..fdff553f 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -583,19 +583,19 @@ impl Client { // formatting - pub async fn text_document_formatting( + pub fn text_document_formatting( &self, text_document: lsp::TextDocumentIdentifier, options: lsp::FormattingOptions, work_done_token: Option, - ) -> anyhow::Result> { + ) -> Option>>> { let capabilities = self.capabilities.get().unwrap(); // check if we're able to format match capabilities.document_formatting_provider { Some(lsp::OneOf::Left(true)) | Some(lsp::OneOf::Right(_)) => (), // None | Some(false) - _ => return Ok(Vec::new()), + _ => return None, }; // TODO: return err::unavailable so we can fall back to tree sitter formatting @@ -605,9 +605,13 @@ impl Client { work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token }, }; - let response = self.request::(params).await?; + let request = self.call::(params); - Ok(response.unwrap_or_default()) + Some(async move { + let json = request.await?; + let response: Vec = serde_json::from_value(json)?; + Ok(response) + }) } pub async fn text_document_range_formatting( diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index b2c02927..a27be8e6 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -386,21 +386,24 @@ impl Document { /// If supported, returns the changes that should be applied to this document in order /// to format it nicely. pub fn format(&self) -> Option + 'static> { - if let Some(language_server) = self.language_server.clone() { + if let Some(language_server) = self.language_server() { let text = self.text.clone(); - let id = self.identifier(); + let offset_encoding = language_server.offset_encoding(); + let request = language_server.text_document_formatting( + self.identifier(), + lsp::FormattingOptions::default(), + None, + )?; + let fut = async move { - let edits = language_server - .text_document_formatting(id, lsp::FormattingOptions::default(), None) - .await - .unwrap_or_else(|e| { - log::warn!("LSP formatting failed: {}", e); - Default::default() - }); + let edits = request.await.unwrap_or_else(|e| { + log::warn!("LSP formatting failed: {}", e); + Default::default() + }); LspFormatting { doc: text, edits, - offset_encoding: language_server.offset_encoding(), + offset_encoding, } }; Some(fut) -- cgit v1.2.3-70-g09d2 From 800d79b584cd09020488b8a614e5214b929d8f5d Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Wed, 1 Sep 2021 14:54:11 +0900 Subject: ls: Refactor textDocument/didSave in a similar vein --- helix-lsp/src/client.rs | 19 ++++++++++--------- helix-view/src/document.rs | 8 ++++---- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'helix-view/src/document.rs') diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index fdff553f..b8fbfddb 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -490,11 +490,11 @@ impl Client { // will_save / will_save_wait_until - pub async fn text_document_did_save( + pub fn text_document_did_save( &self, text_document: lsp::TextDocumentIdentifier, text: &Rope, - ) -> Result<()> { + ) -> Option>> { let capabilities = self.capabilities.get().unwrap(); let include_text = match &capabilities.text_document_sync { @@ -507,17 +507,18 @@ impl Client { include_text, }) => include_text.unwrap_or(false), // Supported(false) - _ => return Ok(()), + _ => return None, }, // unsupported - _ => return Ok(()), + _ => return None, }; - self.notify::(lsp::DidSaveTextDocumentParams { - text_document, - text: include_text.then(|| text.into()), - }) - .await + Some(self.notify::( + lsp::DidSaveTextDocumentParams { + text_document, + text: include_text.then(|| text.into()), + }, + )) } pub fn completion( diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index a27be8e6..5677eb44 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -471,10 +471,10 @@ impl Document { let mut file = File::create(path).await?; to_writer(&mut file, encoding, &text).await?; - if let Some(language_server) = language_server { - language_server - .text_document_did_save(identifier, &text) - .await?; + if let Some(notification) = language_server.and_then(|language_server| { + language_server.text_document_did_save(identifier, &text) + }) { + notification.await?; } Ok(()) -- cgit v1.2.3-70-g09d2 From 10b690b5bd5d3e9ee477782ebfe3f6ff8d11cb3f Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Thu, 2 Sep 2021 10:49:23 +0900 Subject: Drop some &mut bounds where & would have sufficed --- helix-term/src/job.rs | 4 ++-- helix-view/src/document.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'helix-view/src/document.rs') diff --git a/helix-term/src/job.rs b/helix-term/src/job.rs index 2ac41926..4fa38174 100644 --- a/helix-term/src/job.rs +++ b/helix-term/src/job.rs @@ -61,7 +61,7 @@ impl Jobs { } pub fn handle_callback( - &mut self, + &self, editor: &mut Editor, compositor: &mut Compositor, call: anyhow::Result>, @@ -84,7 +84,7 @@ impl Jobs { } } - pub fn add(&mut self, j: Job) { + pub fn add(&self, j: Job) { if j.wait { self.wait_futures.push(j.future); } else { diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 5677eb44..71f6680c 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -649,7 +649,7 @@ impl Document { // } // emit lsp notification - if let Some(language_server) = &self.language_server { + if let Some(language_server) = self.language_server() { let notify = language_server.text_document_did_change( self.versioned_identifier(), &old_doc, -- cgit v1.2.3-70-g09d2 From 37606bad47fe0e197cb34fc7d52856597c32ce33 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Thu, 2 Sep 2021 13:55:55 +0900 Subject: lsp: doc.language_server() is None until initialize completes --- helix-lsp/src/client.rs | 4 ++++ helix-view/src/document.rs | 13 +++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'helix-view/src/document.rs') diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 27e4697c..f2bb0059 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -93,6 +93,10 @@ impl Client { } } + pub fn is_initialized(&self) -> bool { + self.capabilities.get().is_some() + } + pub fn capabilities(&self) -> &lsp::ServerCapabilities { self.capabilities .get() diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 71f6680c..362a433e 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -798,9 +798,18 @@ impl Document { self.version } - #[inline] pub fn language_server(&self) -> Option<&helix_lsp::Client> { - self.language_server.as_deref() + let server = self.language_server.as_deref(); + let initialized = server + .map(|server| server.is_initialized()) + .unwrap_or(false); + + // only resolve language_server if it's initialized + if initialized { + server + } else { + None + } } #[inline] -- cgit v1.2.3-70-g09d2 From 64099af3f1f5957de8f4203c665063d02ba4bac9 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Thu, 2 Sep 2021 16:07:21 +0900 Subject: Don't panic on save if language_server isn't initialized --- helix-view/src/document.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'helix-view/src/document.rs') diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 362a433e..6de60995 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -471,10 +471,15 @@ impl Document { let mut file = File::create(path).await?; to_writer(&mut file, encoding, &text).await?; - if let Some(notification) = language_server.and_then(|language_server| { - language_server.text_document_did_save(identifier, &text) - }) { - notification.await?; + if let Some(language_server) = language_server { + if language_server.is_initialized() { + return Ok(()); + } + if let Some(notification) = + language_server.text_document_did_save(identifier, &text) + { + notification.await?; + } } Ok(()) -- cgit v1.2.3-70-g09d2 From 0b1bc566e4e3cfa88e23133fb018c998f2052c52 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Thu, 9 Sep 2021 11:54:01 +0900 Subject: fix: lsp: Regression with textDocument/didSave not getting sent --- helix-view/src/document.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'helix-view/src/document.rs') diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 6de60995..1f1b1f5f 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -472,7 +472,7 @@ impl Document { to_writer(&mut file, encoding, &text).await?; if let Some(language_server) = language_server { - if language_server.is_initialized() { + if !language_server.is_initialized() { return Ok(()); } if let Some(notification) = -- cgit v1.2.3-70-g09d2