Fixed the easy search bugs

Mikayla Maki created

Change summary

crates/terminal/src/terminal_container_view.rs | 51 ++++++++++++++-----
crates/terminal/src/terminal_view.rs           |  2 
2 files changed, 37 insertions(+), 16 deletions(-)

Detailed changes

crates/terminal/src/terminal_container_view.rs 🔗

@@ -149,6 +149,13 @@ impl TerminalContainer {
             associated_directory: None,
         }
     }
+
+    fn connected(&self) -> Option<ViewHandle<TerminalView>> {
+        match &self.content {
+            TerminalContainerContent::Connected(vh) => Some(vh.clone()),
+            TerminalContainerContent::Error(_) => None,
+        }
+    }
 }
 
 impl View for TerminalContainer {
@@ -428,28 +435,42 @@ impl SearchableItem for TerminalContainer {
         matches: Vec<Self::Match>,
         cx: &mut ViewContext<Self>,
     ) -> Option<usize> {
-        if let TerminalContainerContent::Connected(connected) = &self.content {
-            if let Some(selection_head) = connected.read(cx).terminal().read(cx).selection_head {
+        let connected = self.connected();
+        // Selection head might have a value if there's a selection that isn't
+        // associated with a match. Therefore, if there are no matches, we should
+        // report None, no matter the state of the terminal
+        let res = if matches.len() > 0 && connected.is_some() {
+            if let Some(selection_head) = connected
+                .unwrap()
+                .read(cx)
+                .terminal()
+                .read(cx)
+                .selection_head
+            {
                 // If selection head is contained in a match. Return that match
-                for (ix, search_match) in matches.iter().enumerate() {
-                    if search_match.contains(&selection_head) {
-                        return Some(ix);
-                    }
-
-                    // If not contained, return the next match after the selection head
-                    if search_match.start() > &selection_head {
-                        return Some(ix);
-                    }
+                if let Some(ix) = matches
+                    .iter()
+                    .enumerate()
+                    .find(|(_, search_match)| {
+                        search_match.contains(&selection_head)
+                            || search_match.start() > &selection_head
+                    })
+                    .map(|(ix, _)| ix)
+                {
+                    Some(ix)
+                } else {
+                    // If no selection after selection head, return the last match
+                    Some(matches.len().saturating_sub(1))
                 }
-
-                // If no selection after selection head, return the last match
-                return Some(matches.len().saturating_sub(1));
             } else {
+                // Matches found but no active selection, return the first one
                 Some(0)
             }
         } else {
             None
-        }
+        };
+
+        res
     }
 }
 

crates/terminal/src/terminal_view.rs 🔗

@@ -91,8 +91,8 @@ impl TerminalView {
                 if !cx.is_self_focused() {
                     this.has_new_content = true;
                     cx.notify();
-                    cx.emit(Event::Wakeup);
                 }
+                cx.emit(Event::Wakeup);
             }
             Event::Bell => {
                 this.has_bell = true;