Finished terminal search

This commit is contained in:
Mikayla Maki 2022-09-01 13:45:46 -07:00
parent 25aae1107b
commit ebae991cb2
8 changed files with 288 additions and 263 deletions

View file

@ -95,6 +95,12 @@ impl View for BufferSearchBar {
} else {
theme.search.editor.input.container
};
let supported_options = self
.active_searchable_item
.as_ref()
.map(|active_searchable_item| active_searchable_item.supported_options())
.unwrap_or_default();
Flex::row()
.with_child(
Flex::row()
@ -143,9 +149,24 @@ impl View for BufferSearchBar {
)
.with_child(
Flex::row()
.with_child(self.render_search_option("Case", SearchOption::CaseSensitive, cx))
.with_child(self.render_search_option("Word", SearchOption::WholeWord, cx))
.with_child(self.render_search_option("Regex", SearchOption::Regex, cx))
.with_children(self.render_search_option(
supported_options.case,
"Case",
SearchOption::CaseSensitive,
cx,
))
.with_children(self.render_search_option(
supported_options.word,
"Word",
SearchOption::WholeWord,
cx,
))
.with_children(self.render_search_option(
supported_options.regex,
"Regex",
SearchOption::Regex,
cx,
))
.contained()
.with_style(theme.search.option_button_group)
.aligned()
@ -234,7 +255,7 @@ impl BufferSearchBar {
if let Some(searchable_item) =
WeakSearchableItemHandle::upgrade(searchable_item.as_ref(), cx)
{
searchable_item.clear_highlights(cx);
searchable_item.clear_matches(cx);
}
}
if let Some(active_editor) = self.active_searchable_item.as_ref() {
@ -283,36 +304,43 @@ impl BufferSearchBar {
fn render_search_option(
&self,
option_supported: bool,
icon: &str,
option: SearchOption,
cx: &mut RenderContext<Self>,
) -> ElementBox {
) -> Option<ElementBox> {
if !option_supported {
return None;
}
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
let is_active = self.is_search_option_enabled(option);
MouseEventHandler::new::<Self, _, _>(option as usize, cx, |state, cx| {
let style = &cx
.global::<Settings>()
.theme
.search
.option_button
.style_for(state, is_active);
Label::new(icon.to_string(), style.text.clone())
.contained()
.with_style(style.container)
.boxed()
})
.on_click(MouseButton::Left, move |_, cx| {
cx.dispatch_any_action(option.to_toggle_action())
})
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<Self, _>(
option as usize,
format!("Toggle {}", option.label()),
Some(option.to_toggle_action()),
tooltip_style,
cx,
Some(
MouseEventHandler::new::<Self, _, _>(option as usize, cx, |state, cx| {
let style = &cx
.global::<Settings>()
.theme
.search
.option_button
.style_for(state, is_active);
Label::new(icon.to_string(), style.text.clone())
.contained()
.with_style(style.container)
.boxed()
})
.on_click(MouseButton::Left, move |_, cx| {
cx.dispatch_any_action(option.to_toggle_action())
})
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<Self, _>(
option as usize,
format!("Toggle {}", option.label()),
Some(option.to_toggle_action()),
tooltip_style,
cx,
)
.boxed(),
)
.boxed()
}
fn render_nav_button(
@ -422,8 +450,10 @@ impl BufferSearchBar {
.seachable_items_with_matches
.get(&searchable_item.downgrade())
{
searchable_item.select_next_match_in_direction(index, direction, matches, cx);
searchable_item.highlight_matches(matches, cx);
let new_match_index =
searchable_item.match_index_for_direction(matches, index, direction, cx);
searchable_item.update_matches(matches, cx);
searchable_item.activate_match(new_match_index, matches, cx);
}
}
}
@ -479,7 +509,7 @@ impl BufferSearchBar {
if Some(&searchable_item) == self.active_searchable_item.as_ref() {
active_item_matches = Some((searchable_item.downgrade(), matches));
} else {
searchable_item.clear_highlights(cx);
searchable_item.clear_matches(cx);
}
}
}
@ -494,7 +524,7 @@ impl BufferSearchBar {
if let Some(active_searchable_item) = self.active_searchable_item.as_ref() {
if query.is_empty() {
self.active_match_index.take();
active_searchable_item.clear_highlights(cx);
active_searchable_item.clear_matches(cx);
} else {
let query = if self.regex {
match SearchQuery::regex(query, self.whole_word, self.case_sensitive) {
@ -509,7 +539,7 @@ impl BufferSearchBar {
SearchQuery::text(query, self.whole_word, self.case_sensitive)
};
let matches = active_searchable_item.matches(query, cx);
let matches = active_searchable_item.find_matches(query, cx);
let active_searchable_item = active_searchable_item.downgrade();
self.pending_search = Some(cx.spawn_weak(|this, mut cx| async move {
@ -529,13 +559,13 @@ impl BufferSearchBar {
.seachable_items_with_matches
.get(&active_searchable_item.downgrade())
.unwrap();
active_searchable_item.update_matches(matches, cx);
if select_closest_match {
if let Some(match_ix) = this.active_match_index {
active_searchable_item
.select_match_by_index(match_ix, matches, cx);
.activate_match(match_ix, matches, cx);
}
}
active_searchable_item.highlight_matches(matches, cx);
}
cx.notify();
}

View file

@ -4,8 +4,8 @@ use crate::{
};
use collections::HashMap;
use editor::{
items::{active_match_index, match_index_for_direction},
Anchor, Autoscroll, Editor, MultiBuffer, SelectAll, MAX_TAB_TITLE_LEN,
items::active_match_index, Anchor, Autoscroll, Editor, MultiBuffer, SelectAll,
MAX_TAB_TITLE_LEN,
};
use gpui::{
actions, elements::*, platform::CursorStyle, Action, AnyViewHandle, AppContext, ElementBox,
@ -23,7 +23,7 @@ use std::{
};
use util::ResultExt as _;
use workspace::{
searchable::{Direction, SearchableItemHandle},
searchable::{Direction, SearchableItem, SearchableItemHandle},
Item, ItemHandle, ItemNavHistory, Pane, ToolbarItemLocation, ToolbarItemView, Workspace,
};
@ -486,16 +486,12 @@ impl ProjectSearchView {
fn select_match(&mut self, direction: Direction, cx: &mut ViewContext<Self>) {
if let Some(index) = self.active_match_index {
let model = self.model.read(cx);
let results_editor = self.results_editor.read(cx);
let new_index = match_index_for_direction(
&model.match_ranges,
&results_editor.selections.newest_anchor().head(),
index,
direction,
&results_editor.buffer().read(cx).snapshot(cx),
);
let range_to_select = model.match_ranges[new_index].clone();
let match_ranges = self.model.read(cx).match_ranges.clone();
let new_index = self.results_editor.update(cx, |editor, cx| {
editor.match_index_for_direction(&match_ranges, index, direction, cx)
});
let range_to_select = match_ranges[new_index].clone();
self.results_editor.update(cx, |editor, cx| {
editor.unfold_ranges([range_to_select.clone()], false, cx);
editor.change_selections(Some(Autoscroll::Fit), cx, |s| {