1use bitflags::bitflags;
2pub use buffer_search::BufferSearchBar;
3use gpui::{
4 actions,
5 elements::{Component, SafeStylable, TooltipStyle},
6 Action, AnyElement, AppContext, Element, View,
7};
8pub use mode::SearchMode;
9use project::search::SearchQuery;
10pub use project_search::{ProjectSearchBar, ProjectSearchView};
11use theme::components::{action_button::Button, svg::Svg, ComponentExt, ToggleIconButtonStyle};
12
13pub mod buffer_search;
14mod history;
15mod mode;
16pub mod project_search;
17pub(crate) mod search_bar;
18
19pub fn init(cx: &mut AppContext) {
20 buffer_search::init(cx);
21 project_search::init(cx);
22}
23
24actions!(
25 search,
26 [
27 CycleMode,
28 ToggleWholeWord,
29 ToggleCaseSensitive,
30 SelectNextMatch,
31 SelectPrevMatch,
32 SelectAllMatches,
33 NextHistoryQuery,
34 PreviousHistoryQuery,
35 ActivateTextMode,
36 ActivateSemanticMode,
37 ActivateRegexMode
38 ]
39);
40
41bitflags! {
42 #[derive(Default)]
43 pub struct SearchOptions: u8 {
44 const NONE = 0b000;
45 const WHOLE_WORD = 0b001;
46 const CASE_SENSITIVE = 0b010;
47 }
48}
49
50impl SearchOptions {
51 pub fn label(&self) -> &'static str {
52 match *self {
53 SearchOptions::WHOLE_WORD => "Match Whole Word",
54 SearchOptions::CASE_SENSITIVE => "Match Case",
55 _ => panic!("{:?} is not a named SearchOption", self),
56 }
57 }
58
59 pub fn icon(&self) -> &'static str {
60 match *self {
61 SearchOptions::WHOLE_WORD => "icons/word_search_12.svg",
62 SearchOptions::CASE_SENSITIVE => "icons/case_insensitive_12.svg",
63 _ => panic!("{:?} is not a named SearchOption", self),
64 }
65 }
66
67 pub fn to_toggle_action(&self) -> Box<dyn Action> {
68 match *self {
69 SearchOptions::WHOLE_WORD => Box::new(ToggleWholeWord),
70 SearchOptions::CASE_SENSITIVE => Box::new(ToggleCaseSensitive),
71 _ => panic!("{:?} is not a named SearchOption", self),
72 }
73 }
74
75 pub fn none() -> SearchOptions {
76 SearchOptions::NONE
77 }
78
79 pub fn from_query(query: &SearchQuery) -> SearchOptions {
80 let mut options = SearchOptions::NONE;
81 options.set(SearchOptions::WHOLE_WORD, query.whole_word());
82 options.set(SearchOptions::CASE_SENSITIVE, query.case_sensitive());
83 options
84 }
85
86 pub fn as_button<V: View>(
87 &self,
88 active: bool,
89 tooltip_style: TooltipStyle,
90 button_style: ToggleIconButtonStyle,
91 ) -> AnyElement<V> {
92 Button::dynamic_action(self.to_toggle_action())
93 .with_tooltip(format!("Toggle {}", self.label()), tooltip_style)
94 .with_contents(Svg::new(self.icon()))
95 .toggleable(active)
96 .with_style(button_style)
97 .element()
98 .into_any()
99 }
100}