diff --git a/crates/terminal/src/terminal_container_view.rs b/crates/terminal/src/terminal_container_view.rs index 23f1b2ab16..5f5e1fb054 100644 --- a/crates/terminal/src/terminal_container_view.rs +++ b/crates/terminal/src/terminal_container_view.rs @@ -149,6 +149,13 @@ impl TerminalContainer { associated_directory: None, } } + + fn connected(&self) -> Option> { + 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, cx: &mut ViewContext, ) -> Option { - 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 } } diff --git a/crates/terminal/src/terminal_view.rs b/crates/terminal/src/terminal_view.rs index 1c49f8b3c2..ec35ba0a5c 100644 --- a/crates/terminal/src/terminal_view.rs +++ b/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;