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)