Finished terminal search
This commit is contained in:
parent
25aae1107b
commit
ebae991cb2
8 changed files with 288 additions and 263 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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| {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue