From 533b710417a070531865078d817b2a903cfd1d70 Mon Sep 17 00:00:00 2001 From: "Aviv \"RustyStriker\" Romem" Date: Mon, 22 Nov 2021 19:14:09 +0200 Subject: [PATCH 1/9] fix issue #1136 --- helix-term/src/commands.rs | 9 ++++++++ helix-view/src/editor.rs | 47 ++++++++++++++++++++++++++++++++++++++ temp.rs | 4 ++++ 3 files changed, 60 insertions(+) create mode 100644 temp.rs diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index fde505fdc015..f5554a2eb367 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1816,9 +1816,13 @@ mod cmd { let jobs = &mut cx.jobs; let (_, doc) = current!(cx.editor); + // Should refresh lang server or not + let mut refresh_ls = false; + if let Some(path) = path { doc.set_path(Some(path.as_ref())) .context("invalid filepath")?; + refresh_ls = true; // we want to refresh the lang server } if doc.path().is_none() { bail!("cannot write a buffer without a filename"); @@ -1836,6 +1840,11 @@ mod cmd { }); let future = doc.format_and_save(fmt); cx.jobs.add(Job::new(future).wait_before_exiting()); + + if refresh_ls { + let id = doc.id(); + let _ = cx.editor.refresh_language_server(id); + } Ok(()) } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 1ce33760ed10..5ac177e5c426 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -271,6 +271,53 @@ impl Editor { Ok(()) } + /// Refreshes the language server for a given document + pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> { + // don' know why but it feels good using this pattern :) + let Editor { + documents, + language_servers, + theme, + syn_loader, + .. + } = self; + + let doc = documents.get_mut(&doc_id)?; + doc.detect_language(Some(&theme), &syn_loader); + let language_server = doc.language.as_ref().and_then(|language| { + language_servers + .get(language) + .map_err(|e| { + log::error!( + "Failed to initialize the LSP for `{}` {{ {} }}", + language.scope(), + e + ) + }) + .ok() + }); + + log::info!("ls is {:?}", language_server); + + if let Some(language_server) = language_server { + let language_id = doc + .language() + .and_then(|s| s.split('.').last()) // source.rust + .map(ToOwned::to_owned) + .unwrap_or_default(); + + // TODO: this now races with on_init code if the init happens too quickly + tokio::spawn(language_server.text_document_did_open( + doc.url().unwrap(), + doc.version(), + doc.text(), + language_id, + )); + + doc.set_language_server(Some(language_server)); + } + } + fn _refresh(&mut self) { for (view, _) in self.tree.views_mut() { let doc = &self.documents[&view.doc]; diff --git a/temp.rs b/temp.rs new file mode 100644 index 000000000000..162d0fe2eb53 --- /dev/null +++ b/temp.rs @@ -0,0 +1,4 @@ +fn main() { + let x : i32 = 0.1; +} + From 8e7e715372dff838f26cd41b41b6dc17f9fa3b39 Mon Sep 17 00:00:00 2001 From: "Aviv \"RustyStriker\" Romem" Date: Mon, 22 Nov 2021 19:18:06 +0200 Subject: [PATCH 2/9] removed a log::info --- helix-view/src/editor.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 5ac177e5c426..fe35e477f505 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -297,8 +297,6 @@ impl Editor { .ok() }); - log::info!("ls is {:?}", language_server); - if let Some(language_server) = language_server { let language_id = doc .language() From c12b61051494406b91556a4e241be20fe0c82e8d Mon Sep 17 00:00:00 2001 From: RustyStriker Date: Tue, 23 Nov 2021 10:12:09 +0200 Subject: [PATCH 3/9] removed temp.rs --- temp.rs | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 temp.rs diff --git a/temp.rs b/temp.rs deleted file mode 100644 index 162d0fe2eb53..000000000000 --- a/temp.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - let x : i32 = 0.1; -} - From 78ba859dfbdd6d9b95ad98237f06cc968b1edf19 Mon Sep 17 00:00:00 2001 From: RustyStriker Date: Tue, 23 Nov 2021 10:12:22 +0200 Subject: [PATCH 4/9] cargo clippy no longer complains --- helix-view/src/editor.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index fe35e477f505..97eb162ede93 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -273,19 +273,10 @@ impl Editor { /// Refreshes the language server for a given document pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> { - // don' know why but it feels good using this pattern :) - let Editor { - documents, - language_servers, - theme, - syn_loader, - .. - } = self; - - let doc = documents.get_mut(&doc_id)?; - doc.detect_language(Some(&theme), &syn_loader); + let doc = self.documents.get_mut(&doc_id)?; + doc.detect_language(Some(&self.theme), &self.syn_loader); let language_server = doc.language.as_ref().and_then(|language| { - language_servers + self.language_servers .get(language) .map_err(|e| { log::error!( @@ -314,6 +305,7 @@ impl Editor { doc.set_language_server(Some(language_server)); } + Some(()) } fn _refresh(&mut self) { From d48aa49fdbaefc97db87935c88e58fcd5ed3a1f9 Mon Sep 17 00:00:00 2001 From: RustyStriker Date: Tue, 23 Nov 2021 10:27:17 +0200 Subject: [PATCH 5/9] new get_lang_server function --- helix-view/src/editor.rs | 43 ++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 97eb162ede93..9f10fa03dcd2 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -275,18 +275,7 @@ impl Editor { pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> { let doc = self.documents.get_mut(&doc_id)?; doc.detect_language(Some(&self.theme), &self.syn_loader); - let language_server = doc.language.as_ref().and_then(|language| { - self.language_servers - .get(language) - .map_err(|e| { - log::error!( - "Failed to initialize the LSP for `{}` {{ {} }}", - language.scope(), - e - ) - }) - .ok() - }); + let language_server = Editor::get_lang_server(&mut self.language_servers, doc); if let Some(language_server) = language_server { let language_id = doc @@ -308,6 +297,23 @@ impl Editor { Some(()) } + fn get_lang_server( + ls: &mut helix_lsp::Registry, + doc: &mut Document, + ) -> Option> { + doc.language.as_ref().and_then(|language| { + ls.get(language) + .map_err(|e| { + log::error!( + "Failed to initialize the LSP for `{}` {{ {} }}", + language.scope(), + e + ) + }) + .ok() + }) + } + fn _refresh(&mut self) { for (view, _) in self.tree.views_mut() { let doc = &self.documents[&view.doc]; @@ -441,18 +447,7 @@ impl Editor { let mut doc = Document::open(&path, None, Some(&self.theme), Some(&self.syn_loader))?; // try to find a language server based on the language name - let language_server = doc.language.as_ref().and_then(|language| { - self.language_servers - .get(language) - .map_err(|e| { - log::error!( - "Failed to initialize the LSP for `{}` {{ {} }}", - language.scope(), - e - ) - }) - .ok() - }); + let language_server = Editor::get_lang_server(&mut self.language_servers, &mut doc); if let Some(language_server) = language_server { let language_id = doc From 24b237fdfb220856ab5311493d40bce28f3d8db3 Mon Sep 17 00:00:00 2001 From: "Aviv \"RustyStriker\" Romem" Date: Tue, 23 Nov 2021 16:33:28 +0200 Subject: [PATCH 6/9] get_lang_server is now launch_language_server --- helix-view/src/editor.rs | 52 ++++++++++++---------------------------- 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 9f10fa03dcd2..ff5d6803c257 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -275,8 +275,21 @@ impl Editor { pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> { let doc = self.documents.get_mut(&doc_id)?; doc.detect_language(Some(&self.theme), &self.syn_loader); - let language_server = Editor::get_lang_server(&mut self.language_servers, doc); + Editor::launch_language_server(&mut self.language_servers, doc) + } + fn launch_language_server(ls: &mut helix_lsp::Registry, doc: &mut Document) -> Option<()> { + let language_server = doc.language.as_ref().and_then(|language| { + ls.get(language) + .map_err(|e| { + log::error!( + "Failed to initialize the LSP for `{}` {{ {} }}", + language.scope(), + e + ) + }) + .ok() + }); if let Some(language_server) = language_server { let language_id = doc .language() @@ -297,23 +310,6 @@ impl Editor { Some(()) } - fn get_lang_server( - ls: &mut helix_lsp::Registry, - doc: &mut Document, - ) -> Option> { - doc.language.as_ref().and_then(|language| { - ls.get(language) - .map_err(|e| { - log::error!( - "Failed to initialize the LSP for `{}` {{ {} }}", - language.scope(), - e - ) - }) - .ok() - }) - } - fn _refresh(&mut self) { for (view, _) in self.tree.views_mut() { let doc = &self.documents[&view.doc]; @@ -447,25 +443,7 @@ impl Editor { let mut doc = Document::open(&path, None, Some(&self.theme), Some(&self.syn_loader))?; // try to find a language server based on the language name - let language_server = Editor::get_lang_server(&mut self.language_servers, &mut doc); - - if let Some(language_server) = language_server { - let language_id = doc - .language() - .and_then(|s| s.split('.').last()) // source.rust - .map(ToOwned::to_owned) - .unwrap_or_default(); - - // TODO: this now races with on_init code if the init happens too quickly - tokio::spawn(language_server.text_document_did_open( - doc.url().unwrap(), - doc.version(), - doc.text(), - language_id, - )); - - doc.set_language_server(Some(language_server)); - } + let _ = Editor::launch_language_server(&mut self.language_servers, &mut doc); let id = DocumentId(self.next_document_id); self.next_document_id += 1; From adec0a12c2f0c9c63fe2b927a42e12ebe861b063 Mon Sep 17 00:00:00 2001 From: "Aviv \"RustyStriker\" Romem" Date: Tue, 23 Nov 2021 17:04:16 +0200 Subject: [PATCH 7/9] launch_lang_server will now close the previous one --- helix-term/src/commands.rs | 3 +-- helix-view/src/editor.rs | 42 ++++++++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index f5554a2eb367..18db3f2f5c90 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1817,12 +1817,11 @@ mod cmd { let (_, doc) = current!(cx.editor); // Should refresh lang server or not - let mut refresh_ls = false; + let refresh_ls = path.is_some(); if let Some(path) = path { doc.set_path(Some(path.as_ref())) .context("invalid filepath")?; - refresh_ls = true; // we want to refresh the lang server } if doc.path().is_none() { bail!("cannot write a buffer without a filename"); diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index ff5d6803c257..baf68a625d13 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -291,21 +291,33 @@ impl Editor { .ok() }); if let Some(language_server) = language_server { - let language_id = doc - .language() - .and_then(|s| s.split('.').last()) // source.rust - .map(ToOwned::to_owned) - .unwrap_or_default(); - - // TODO: this now races with on_init code if the init happens too quickly - tokio::spawn(language_server.text_document_did_open( - doc.url().unwrap(), - doc.version(), - doc.text(), - language_id, - )); - - doc.set_language_server(Some(language_server)); + // only spawn a new lang server if the servers aren't the same + if language_server.id() + != doc + .language_server() + .map(|ls| ls.id()) + .unwrap_or(usize::MAX) + { + // we also want to kill the previous server + if let Some(ls) = doc.language_server() { + tokio::spawn(ls.text_document_did_close(doc.identifier())); + } + let language_id = doc + .language() + .and_then(|s| s.split('.').last()) // source.rust + .map(ToOwned::to_owned) + .unwrap_or_default(); + + // TODO: this now races with on_init code if the init happens too quickly + tokio::spawn(language_server.text_document_did_open( + doc.url().unwrap(), + doc.version(), + doc.text(), + language_id, + )); + + doc.set_language_server(Some(language_server)); + } } Some(()) } From 9d2a1ffb635384ab58612a8fa81c08d2b222b3c7 Mon Sep 17 00:00:00 2001 From: "Aviv \"RustyStriker\" Romem" Date: Wed, 24 Nov 2021 17:02:25 +0200 Subject: [PATCH 8/9] better code readability --- helix-view/src/editor.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index baf68a625d13..3f3960c3caa4 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -275,10 +275,12 @@ impl Editor { pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> { let doc = self.documents.get_mut(&doc_id)?; doc.detect_language(Some(&self.theme), &self.syn_loader); - Editor::launch_language_server(&mut self.language_servers, doc) + Self::launch_language_server(&mut self.language_servers, doc) } + /// Launch a language server for a given document fn launch_language_server(ls: &mut helix_lsp::Registry, doc: &mut Document) -> Option<()> { + // try to find a language server based on the language name let language_server = doc.language.as_ref().and_then(|language| { ls.get(language) .map_err(|e| { @@ -292,15 +294,10 @@ impl Editor { }); if let Some(language_server) = language_server { // only spawn a new lang server if the servers aren't the same - if language_server.id() - != doc - .language_server() - .map(|ls| ls.id()) - .unwrap_or(usize::MAX) - { + if Some(language_server.id()) != doc.language_server().map(|server| server.id()) { // we also want to kill the previous server - if let Some(ls) = doc.language_server() { - tokio::spawn(ls.text_document_did_close(doc.identifier())); + if let Some(language_server) = doc.language_server() { + tokio::spawn(language_server.text_document_did_close(doc.identifier())); } let language_id = doc .language() @@ -454,8 +451,7 @@ impl Editor { } else { let mut doc = Document::open(&path, None, Some(&self.theme), Some(&self.syn_loader))?; - // try to find a language server based on the language name - let _ = Editor::launch_language_server(&mut self.language_servers, &mut doc); + let _ = Self::launch_language_server(&mut self.language_servers, &mut doc); let id = DocumentId(self.next_document_id); self.next_document_id += 1; From ba8460c37cc6a6c0bc8ed93187444d4d965eaea8 Mon Sep 17 00:00:00 2001 From: "Aviv \"RustyStriker\" Romem" Date: Thu, 25 Nov 2021 16:24:27 +0200 Subject: [PATCH 9/9] remove resfresh_ls(and a wrong comment) --- helix-term/src/commands.rs | 7 ++----- helix-view/src/editor.rs | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 18db3f2f5c90..901ffbd84630 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1816,10 +1816,7 @@ mod cmd { let jobs = &mut cx.jobs; let (_, doc) = current!(cx.editor); - // Should refresh lang server or not - let refresh_ls = path.is_some(); - - if let Some(path) = path { + if let Some(ref path) = path { doc.set_path(Some(path.as_ref())) .context("invalid filepath")?; } @@ -1840,7 +1837,7 @@ mod cmd { let future = doc.format_and_save(fmt); cx.jobs.add(Job::new(future).wait_before_exiting()); - if refresh_ls { + if path.is_some() { let id = doc.id(); let _ = cx.editor.refresh_language_server(id); } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 3f3960c3caa4..d1b818bdb0a7 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -295,7 +295,6 @@ impl Editor { if let Some(language_server) = language_server { // only spawn a new lang server if the servers aren't the same if Some(language_server.id()) != doc.language_server().map(|server| server.id()) { - // we also want to kill the previous server if let Some(language_server) = doc.language_server() { tokio::spawn(language_server.text_document_did_close(doc.identifier())); }