:art: Return an option task from confirm_completion

Max Brunsfeld created

Change summary

crates/editor/src/editor.rs       | 31 ++++++++++++------------
crates/editor/src/multi_buffer.rs | 16 ++++--------
crates/language/src/buffer.rs     | 41 +++++++++++---------------------
crates/snippet/src/snippet.rs     |  2 
4 files changed, 36 insertions(+), 54 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -297,7 +297,9 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
     cx.add_action(Editor::fold_selected_ranges);
     cx.add_action(Editor::show_completions);
     cx.add_action(|editor: &mut Editor, _: &ConfirmCompletion, cx| {
-        editor.confirm_completion(cx).detach_and_log_err(cx);
+        if let Some(task) = editor.confirm_completion(cx) {
+            task.detach_and_log_err(cx);
+        }
     });
 }
 
@@ -1648,20 +1650,17 @@ impl Editor {
         self.completion_state.take()
     }
 
-    fn confirm_completion(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
-        if let Some(completion_state) = self.hide_completions(cx) {
-            if let Some(completion) = completion_state
-                .matches
-                .get(completion_state.selected_item)
-                .and_then(|mat| completion_state.completions.get(mat.candidate_id))
-            {
-                return self.buffer.update(cx, |buffer, cx| {
-                    buffer.apply_completion(completion.clone(), cx)
-                });
-            }
-        }
-
-        Task::ready(Ok(()))
+    fn confirm_completion(&mut self, cx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
+        let completion_state = self.hide_completions(cx)?;
+        let mat = completion_state
+            .matches
+            .get(completion_state.selected_item)?;
+        let completion = completion_state.completions.get(mat.candidate_id)?;
+        self.buffer.update(cx, |buffer, cx| {
+            let mut completion = completion.clone();
+            // completion.
+            buffer.apply_completion(completion, cx)
+        })
     }
 
     pub fn has_completions(&self) -> bool {
@@ -6658,7 +6657,7 @@ mod tests {
 
         let apply_additional_edits = editor.update(&mut cx, |editor, cx| {
             editor.move_down(&MoveDown, cx);
-            let apply_additional_edits = editor.confirm_completion(cx);
+            let apply_additional_edits = editor.confirm_completion(cx).unwrap();
             assert_eq!(
                 editor.text(cx),
                 "

crates/editor/src/multi_buffer.rs 🔗

@@ -1,7 +1,7 @@
 mod anchor;
 
 pub use anchor::{Anchor, AnchorRangeExt};
-use anyhow::{anyhow, Result};
+use anyhow::Result;
 use clock::ReplicaId;
 use collections::{HashMap, HashSet};
 use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
@@ -933,17 +933,13 @@ impl MultiBuffer {
         &self,
         completion: Completion<Anchor>,
         cx: &mut ModelContext<Self>,
-    ) -> Task<Result<()>> {
-        let buffer = if let Some(buffer) = self
+    ) -> Option<Task<Result<()>>> {
+        let buffer = self
             .buffers
             .borrow()
-            .get(&completion.old_range.start.buffer_id)
-        {
-            buffer.buffer.clone()
-        } else {
-            return Task::ready(Err(anyhow!("completion cannot be applied to any buffer")));
-        };
-
+            .get(&completion.old_range.start.buffer_id)?
+            .buffer
+            .clone();
         buffer.update(cx, |buffer, cx| {
             buffer.apply_completion(
                 Completion {

crates/language/src/buffer.rs 🔗

@@ -1781,35 +1781,22 @@ impl Buffer {
         &mut self,
         completion: Completion<Anchor>,
         cx: &mut ModelContext<Self>,
-    ) -> Task<Result<()>> {
+    ) -> Option<Task<Result<()>>> {
         self.edit_with_autoindent([completion.old_range], completion.new_text.clone(), cx);
 
-        let file = if let Some(file) = self.file.as_ref() {
-            file
-        } else {
-            return Task::ready(Ok(Default::default()));
-        };
-        if file.is_local() {
-            let server = if let Some(lang) = self.language_server.as_ref() {
-                lang.server.clone()
-            } else {
-                return Task::ready(Ok(Default::default()));
-            };
-
-            cx.spawn(|this, mut cx| async move {
-                let resolved_completion = server
-                    .request::<lsp::request::ResolveCompletionItem>(completion.lsp_completion)
-                    .await?;
-                if let Some(additional_edits) = resolved_completion.additional_text_edits {
-                    this.update(&mut cx, |this, cx| {
-                        this.apply_lsp_edits(additional_edits, cx)
-                    })?;
-                }
-                Ok::<_, anyhow::Error>(())
-            })
-        } else {
-            return Task::ready(Ok(Default::default()));
-        }
+        self.file.as_ref()?.as_local()?;
+        let server = self.language_server.as_ref()?.server.clone();
+        Some(cx.spawn(|this, mut cx| async move {
+            let resolved_completion = server
+                .request::<lsp::request::ResolveCompletionItem>(completion.lsp_completion)
+                .await?;
+            if let Some(additional_edits) = resolved_completion.additional_text_edits {
+                this.update(&mut cx, |this, cx| {
+                    this.apply_lsp_edits(additional_edits, cx)
+                })?;
+            }
+            Ok::<_, anyhow::Error>(())
+        }))
     }
 }
 

crates/snippet/src/snippet.rs 🔗

@@ -12,7 +12,7 @@ type TabStop = SmallVec<[Range<usize>; 2]>;
 
 impl Snippet {
     pub fn parse(source: &str) -> Result<Self> {
-        let mut text = String::new();
+        let mut text = String::with_capacity(source.len());
         let mut tabstops = BTreeMap::new();
         parse_snippet(source, false, &mut text, &mut tabstops)
             .context("failed to parse snippet")?;