aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Mildenberger2023-04-05 16:50:05 +0000
committerPhilipp Mildenberger2023-05-18 20:04:47 +0000
commit39b9a4bba2a026844348886c9d9f2026a3d6f658 (patch)
tree5d940e2692d13faf949606aa5bb13267dad48547
parent521cdec5a1a53c61d38ce5a1df85f82857f59149 (diff)
Add function `Editor::language_server_by_id` and refactor/simplify related code, also don't 'crash' in completion menu if language_server somehow disappeared
-rw-r--r--helix-term/src/application.rs2
-rw-r--r--helix-term/src/commands/lsp.rs7
-rw-r--r--helix-term/src/ui/completion.rs47
-rw-r--r--helix-view/src/editor.rs7
4 files changed, 33 insertions, 30 deletions
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index dbb873e0..40c6d8c6 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -665,7 +665,7 @@ impl Application {
macro_rules! language_server {
() => {
- match self.editor.language_servers.get_by_id(server_id) {
+ match self.editor.language_server_by_id(server_id) {
Some(language_server) => language_server,
None => {
warn!("can't find language server with id `{}`", server_id);
diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs
index 38ba98d4..f7d35873 100644
--- a/helix-term/src/commands/lsp.rs
+++ b/helix-term/src/commands/lsp.rs
@@ -301,7 +301,7 @@ fn diag_picker(
flat_diag.reserve(diags.len());
for (diag, ls) in diags {
- if let Some(ls) = cx.editor.language_servers.get_by_id(ls) {
+ if let Some(ls) = cx.editor.language_server_by_id(ls) {
flat_diag.push(PickerDiagnostic {
url: url.clone(),
diag,
@@ -725,7 +725,7 @@ pub fn code_action(cx: &mut Context) {
// always present here
let action = action.unwrap();
- let Some(language_server) = editor.language_servers.get_by_id(action.language_server_id) else {
+ let Some(language_server) = editor.language_server_by_id(action.language_server_id) else {
editor.set_error("Language Server disappeared");
return;
};
@@ -772,8 +772,7 @@ pub fn execute_lsp_command(editor: &mut Editor, language_server_id: usize, cmd:
// the command is executed on the server and communicated back
// to the client asynchronously using workspace edits
let future = match editor
- .language_servers
- .get_by_id(language_server_id)
+ .language_server_by_id(language_server_id)
.and_then(|language_server| language_server.command(cmd))
{
Some(future) => future,
diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs
index e62efdac..28a5157c 100644
--- a/helix-term/src/ui/completion.rs
+++ b/helix-term/src/ui/completion.rs
@@ -212,6 +212,23 @@ impl Completion {
let (view, doc) = current!(editor);
+ macro_rules! language_server {
+ ($item:expr) => {
+ match editor
+ .language_servers
+ .get_by_id($item.language_server_id)
+ {
+ Some(ls) => ls,
+ None => {
+ editor.set_error("language server disappeared between completion request and application");
+ // TODO close the completion menu somehow,
+ // currently there is no trivial way to access the EditorView to close the completion menu
+ return;
+ }
+ }
+ };
+ }
+
match event {
PromptEvent::Abort => {}
PromptEvent::Update => {
@@ -236,17 +253,11 @@ impl Completion {
// always present here
let item = item.unwrap();
- let offset_encoding = editor
- .language_servers
- .get_by_id(item.language_server_id)
- .expect("language server disappeared between completion request and application")
- .offset_encoding();
-
let transaction = item_to_transaction(
doc,
view.id,
item,
- offset_encoding,
+ language_server!(item).offset_encoding(),
trigger_offset,
true,
replace_mode,
@@ -262,11 +273,8 @@ impl Completion {
// always present here
let mut item = item.unwrap().clone();
- let offset_encoding = editor
- .language_servers
- .get_by_id(item.language_server_id)
- .expect("language server disappeared between completion request and application")
- .offset_encoding();
+ let language_server = language_server!(item);
+ let offset_encoding = language_server.offset_encoding();
let language_server = editor
.language_servers
@@ -401,20 +409,11 @@ impl Completion {
Some(item) if !item.resolved => item.clone(),
_ => return false,
};
- let language_server = match cx
- .editor
- .language_servers
- .get_by_id(current_item.language_server_id)
- {
- Some(language_server) => language_server,
- None => return false,
- };
+
+ let Some(language_server) = cx.editor.language_server_by_id(current_item.language_server_id) else { return false; };
// This method should not block the compositor so we handle the response asynchronously.
- let future = match language_server.resolve_completion_item(current_item.item.clone()) {
- Some(future) => future,
- None => return false,
- };
+ let Some(future) = language_server.resolve_completion_item(current_item.item.clone()) else { return false; };
cx.callback(
future,
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index ca2144fd..afb8d91f 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -874,7 +874,7 @@ pub struct Editor {
/// times during rendering and should not be set by other functions.
pub cursor_cache: Cell<Option<Option<Position>>>,
/// When a new completion request is sent to the server old
- /// unifinished request must be dropped. Each completion
+ /// unfinished request must be dropped. Each completion
/// request is associated with a channel that cancels
/// when the channel is dropped. That channel is stored
/// here. When a new completion request is sent this
@@ -1093,6 +1093,11 @@ impl Editor {
self._refresh();
}
+ #[inline]
+ pub fn language_server_by_id(&self, language_server_id: usize) -> Option<&helix_lsp::Client> {
+ self.language_servers.get_by_id(language_server_id)
+ }
+
/// Refreshes the language server for a given document
pub fn refresh_language_servers(&mut self, doc_id: DocumentId) -> Option<()> {
self.launch_language_servers(doc_id)