Merge remote-tracking branch 'origin/main' into semantic-search-watch-worktrees

This commit is contained in:
Antonio Scandurra 2023-09-07 15:07:46 +02:00
commit 93b889a93b
154 changed files with 9047 additions and 5291 deletions

View file

@ -1,6 +1,6 @@
use crate::{
history::SearchHistory,
mode::{next_mode, SearchMode},
mode::{next_mode, SearchMode, Side},
search_bar::{render_nav_button, render_search_mode_button},
CycleMode, NextHistoryQuery, PreviousHistoryQuery, SearchOptions, SelectAllMatches,
SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleWholeWord,
@ -156,11 +156,12 @@ impl View for BufferSearchBar {
self.query_editor.update(cx, |editor, cx| {
editor.set_placeholder_text(new_placeholder_text, cx);
});
let search_button_for_mode = |mode, cx: &mut ViewContext<BufferSearchBar>| {
let search_button_for_mode = |mode, side, cx: &mut ViewContext<BufferSearchBar>| {
let is_active = self.current_mode == mode;
render_search_mode_button(
mode,
side,
is_active,
move |_, this, cx| {
this.activate_search_mode(mode, cx);
@ -212,20 +213,11 @@ impl View for BufferSearchBar {
)
};
let icon_style = theme.search.editor_icon.clone();
let nav_column = Flex::row()
.with_child(self.render_action_button("Select All", cx))
.with_child(nav_button_for_direction("<", Direction::Prev, cx))
.with_child(nav_button_for_direction(">", Direction::Next, cx))
.with_child(Flex::row().with_children(match_count))
.constrained()
.with_height(theme.search.search_bar_row_height);
let query = Flex::row()
let query_column = Flex::row()
.with_child(
Svg::for_style(icon_style.icon)
Svg::for_style(theme.search.editor_icon.clone().icon)
.contained()
.with_style(icon_style.container),
.with_style(theme.search.editor_icon.clone().container),
)
.with_child(ChildView::new(&self.query_editor, cx).flex(1., true))
.with_child(
@ -244,49 +236,45 @@ impl View for BufferSearchBar {
.contained(),
)
.align_children_center()
.flex(1., true);
let editor_column = Flex::row()
.with_child(
query
.contained()
.with_style(query_container_style)
.constrained()
.with_min_width(theme.search.editor.min_width)
.with_max_width(theme.search.editor.max_width)
.with_height(theme.search.search_bar_row_height)
.flex(1., false),
)
.contained()
.with_style(query_container_style)
.constrained()
.with_min_width(theme.search.editor.min_width)
.with_max_width(theme.search.editor.max_width)
.with_height(theme.search.search_bar_row_height)
.flex(1., false);
let mode_column = Flex::row()
.with_child(
Flex::row()
.with_child(search_button_for_mode(SearchMode::Text, cx))
.with_child(search_button_for_mode(SearchMode::Regex, cx))
.contained()
.with_style(theme.search.modes_container),
)
.with_child(super::search_bar::render_close_button(
"Dismiss Buffer Search",
&theme.search,
.with_child(search_button_for_mode(
SearchMode::Text,
Some(Side::Left),
cx,
|_, this, cx| this.dismiss(&Default::default(), cx),
Some(Box::new(Dismiss)),
))
.with_child(search_button_for_mode(
SearchMode::Regex,
Some(Side::Right),
cx,
))
.contained()
.with_style(theme.search.modes_container)
.constrained()
.with_height(theme.search.search_bar_row_height);
let nav_column = Flex::row()
.with_child(self.render_action_button("all", cx))
.with_child(Flex::row().with_children(match_count))
.with_child(nav_button_for_direction("<", Direction::Prev, cx))
.with_child(nav_button_for_direction(">", Direction::Next, cx))
.constrained()
.with_height(theme.search.search_bar_row_height)
.aligned()
.right()
.flex_float();
Flex::row()
.with_child(editor_column)
.with_child(nav_column)
.with_child(query_column)
.with_child(mode_column)
.with_child(nav_column)
.contained()
.with_style(theme.search.container)
.aligned()
.into_any_named("search bar")
}
}
@ -340,8 +328,9 @@ impl ToolbarItemView for BufferSearchBar {
ToolbarItemLocation::Hidden
}
}
fn row_count(&self, _: &ViewContext<Self>) -> usize {
2
1
}
}

View file

@ -48,41 +48,18 @@ impl SearchMode {
SearchMode::Regex => Box::new(ActivateRegexMode),
}
}
pub(crate) fn border_right(&self) -> bool {
match self {
SearchMode::Regex => true,
SearchMode::Text => true,
SearchMode::Semantic => true,
}
}
pub(crate) fn border_left(&self) -> bool {
match self {
SearchMode::Text => true,
_ => false,
}
}
pub(crate) fn button_side(&self) -> Option<Side> {
match self {
SearchMode::Text => Some(Side::Left),
SearchMode::Semantic => None,
SearchMode::Regex => Some(Side::Right),
}
}
}
pub(crate) fn next_mode(mode: &SearchMode, semantic_enabled: bool) -> SearchMode {
let next_text_state = if semantic_enabled {
SearchMode::Semantic
} else {
SearchMode::Regex
};
match mode {
SearchMode::Text => next_text_state,
SearchMode::Semantic => SearchMode::Regex,
SearchMode::Regex => SearchMode::Text,
SearchMode::Text => SearchMode::Regex,
SearchMode::Regex => {
if semantic_enabled {
SearchMode::Semantic
} else {
SearchMode::Text
}
}
SearchMode::Semantic => SearchMode::Text,
}
}

View file

@ -1,6 +1,6 @@
use crate::{
history::SearchHistory,
mode::SearchMode,
mode::{SearchMode, Side},
search_bar::{render_nav_button, render_option_button_icon, render_search_mode_button},
ActivateRegexMode, CycleMode, NextHistoryQuery, PreviousHistoryQuery, SearchOptions,
SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleWholeWord,
@ -1418,8 +1418,13 @@ impl View for ProjectSearchBar {
},
cx,
);
let search = _search.read(cx);
let is_semantic_available = SemanticIndex::enabled(cx);
let is_semantic_disabled = search.semantic_state.is_none();
let icon_style = theme.search.editor_icon.clone();
let is_active = search.active_match_index.is_some();
let render_option_button_icon = |path, option, cx: &mut ViewContext<Self>| {
crate::search_bar::render_option_button_icon(
self.is_option_enabled(option, cx),
@ -1445,28 +1450,23 @@ impl View for ProjectSearchBar {
render_option_button_icon("icons/word_search_12.svg", SearchOptions::WHOLE_WORD, cx)
});
let search = _search.read(cx);
let icon_style = theme.search.editor_icon.clone();
// Editor Functionality
let query = Flex::row()
.with_child(
Svg::for_style(icon_style.icon)
.contained()
.with_style(icon_style.container),
let search_button_for_mode = |mode, side, cx: &mut ViewContext<ProjectSearchBar>| {
let is_active = if let Some(search) = self.active_project_search.as_ref() {
let search = search.read(cx);
search.current_mode == mode
} else {
false
};
render_search_mode_button(
mode,
side,
is_active,
move |_, this, cx| {
this.activate_search_mode(mode, cx);
},
cx,
)
.with_child(ChildView::new(&search.query_editor, cx).flex(1., true))
.with_child(
Flex::row()
.with_child(filter_button)
.with_children(case_sensitive)
.with_children(whole_word)
.flex(1., false)
.constrained()
.contained(),
)
.align_children_center()
.flex(1., true);
};
let search = _search.read(cx);
@ -1484,50 +1484,6 @@ impl View for ProjectSearchBar {
theme.search.include_exclude_editor.input.container
};
let included_files_view = ChildView::new(&search.included_files_editor, cx)
.contained()
.flex(1., true);
let excluded_files_view = ChildView::new(&search.excluded_files_editor, cx)
.contained()
.flex(1., true);
let filters = search.filters_enabled.then(|| {
Flex::row()
.with_child(
included_files_view
.contained()
.with_style(include_container_style)
.constrained()
.with_height(theme.search.search_bar_row_height)
.with_min_width(theme.search.include_exclude_editor.min_width)
.with_max_width(theme.search.include_exclude_editor.max_width),
)
.with_child(
excluded_files_view
.contained()
.with_style(exclude_container_style)
.constrained()
.with_height(theme.search.search_bar_row_height)
.with_min_width(theme.search.include_exclude_editor.min_width)
.with_max_width(theme.search.include_exclude_editor.max_width),
)
.contained()
.with_padding_top(theme.workspace.toolbar.container.padding.bottom)
});
let editor_column = Flex::column()
.with_child(
query
.contained()
.with_style(query_container_style)
.constrained()
.with_min_width(theme.search.editor.min_width)
.with_max_width(theme.search.editor.max_width)
.with_height(theme.search.search_bar_row_height)
.flex(1., false),
)
.with_children(filters)
.flex(1., false);
let matches = search.active_match_index.map(|match_ix| {
Label::new(
format!(
@ -1542,25 +1498,81 @@ impl View for ProjectSearchBar {
.aligned()
});
let search_button_for_mode = |mode, cx: &mut ViewContext<ProjectSearchBar>| {
let is_active = if let Some(search) = self.active_project_search.as_ref() {
let search = search.read(cx);
search.current_mode == mode
} else {
false
};
render_search_mode_button(
mode,
is_active,
move |_, this, cx| {
this.activate_search_mode(mode, cx);
},
cx,
let query_column = Flex::column()
.with_spacing(theme.search.search_row_spacing)
.with_child(
Flex::row()
.with_child(
Svg::for_style(icon_style.icon)
.contained()
.with_style(icon_style.container),
)
.with_child(ChildView::new(&search.query_editor, cx).flex(1., true))
.with_child(
Flex::row()
.with_child(filter_button)
.with_children(case_sensitive)
.with_children(whole_word)
.flex(1., false)
.constrained()
.contained(),
)
.align_children_center()
.contained()
.with_style(query_container_style)
.constrained()
.with_min_width(theme.search.editor.min_width)
.with_max_width(theme.search.editor.max_width)
.with_height(theme.search.search_bar_row_height)
.flex(1., false),
)
};
let is_active = search.active_match_index.is_some();
let semantic_index = SemanticIndex::enabled(cx)
.then(|| search_button_for_mode(SearchMode::Semantic, cx));
.with_children(search.filters_enabled.then(|| {
Flex::row()
.with_child(
ChildView::new(&search.included_files_editor, cx)
.contained()
.with_style(include_container_style)
.constrained()
.with_height(theme.search.search_bar_row_height)
.flex(1., true),
)
.with_child(
ChildView::new(&search.excluded_files_editor, cx)
.contained()
.with_style(exclude_container_style)
.constrained()
.with_height(theme.search.search_bar_row_height)
.flex(1., true),
)
.constrained()
.with_min_width(theme.search.editor.min_width)
.with_max_width(theme.search.editor.max_width)
.flex(1., false)
}))
.flex(1., false);
let mode_column =
Flex::row()
.with_child(search_button_for_mode(
SearchMode::Text,
Some(Side::Left),
cx,
))
.with_child(search_button_for_mode(
SearchMode::Regex,
if is_semantic_available {
None
} else {
Some(Side::Right)
},
cx,
))
.with_children(is_semantic_available.then(|| {
search_button_for_mode(SearchMode::Semantic, Some(Side::Right), cx)
}))
.contained()
.with_style(theme.search.modes_container);
let nav_button_for_direction = |label, direction, cx: &mut ViewContext<Self>| {
render_nav_button(
label,
@ -1576,43 +1588,17 @@ impl View for ProjectSearchBar {
};
let nav_column = Flex::row()
.with_child(Flex::row().with_children(matches))
.with_child(nav_button_for_direction("<", Direction::Prev, cx))
.with_child(nav_button_for_direction(">", Direction::Next, cx))
.with_child(Flex::row().with_children(matches))
.constrained()
.with_height(theme.search.search_bar_row_height);
let mode_column = Flex::row()
.with_child(
Flex::row()
.with_child(search_button_for_mode(SearchMode::Text, cx))
.with_children(semantic_index)
.with_child(search_button_for_mode(SearchMode::Regex, cx))
.contained()
.with_style(theme.search.modes_container),
)
.with_child(super::search_bar::render_close_button(
"Dismiss Project Search",
&theme.search,
cx,
|_, this, cx| {
if let Some(search) = this.active_project_search.as_mut() {
search.update(cx, |_, cx| cx.emit(ViewEvent::Dismiss))
}
},
None,
))
.constrained()
.with_height(theme.search.search_bar_row_height)
.aligned()
.right()
.top()
.flex_float();
Flex::row()
.with_child(editor_column)
.with_child(nav_column)
.with_child(query_column)
.with_child(mode_column)
.with_child(nav_column)
.contained()
.with_style(theme.search.container)
.into_any_named("project search")
@ -1641,7 +1627,7 @@ impl ToolbarItemView for ProjectSearchBar {
self.subscription = Some(cx.observe(&search, |_, _, cx| cx.notify()));
self.active_project_search = Some(search);
ToolbarItemLocation::PrimaryLeft {
flex: Some((1., false)),
flex: Some((1., true)),
}
} else {
ToolbarItemLocation::Hidden
@ -1649,13 +1635,12 @@ impl ToolbarItemView for ProjectSearchBar {
}
fn row_count(&self, cx: &ViewContext<Self>) -> usize {
self.active_project_search
.as_ref()
.map(|search| {
let offset = search.read(cx).filters_enabled as usize;
2 + offset
})
.unwrap_or_else(|| 2)
if let Some(search) = self.active_project_search.as_ref() {
if search.read(cx).filters_enabled {
return 2;
}
}
1
}
}

View file

@ -13,34 +13,6 @@ use crate::{
SelectNextMatch, SelectPrevMatch,
};
pub(super) fn render_close_button<V: View>(
tooltip: &'static str,
theme: &theme::Search,
cx: &mut ViewContext<V>,
on_click: impl Fn(MouseClick, &mut V, &mut EventContext<V>) + 'static,
dismiss_action: Option<Box<dyn Action>>,
) -> AnyElement<V> {
let tooltip_style = theme::current(cx).tooltip.clone();
enum CloseButton {}
MouseEventHandler::new::<CloseButton, _>(0, cx, |state, _| {
let style = theme.dismiss_button.style_for(state);
Svg::new("icons/x_mark_8.svg")
.with_color(style.color)
.constrained()
.with_width(style.icon_width)
.aligned()
.contained()
.with_style(style.container)
.constrained()
.with_height(theme.search_bar_row_height)
})
.on_click(MouseButton::Left, on_click)
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<CloseButton>(0, tooltip.to_string(), dismiss_action, tooltip_style, cx)
.into_any()
}
pub(super) fn render_nav_button<V: View>(
icon: &'static str,
direction: Direction,
@ -111,6 +83,7 @@ pub(super) fn render_nav_button<V: View>(
pub(crate) fn render_search_mode_button<V: View>(
mode: SearchMode,
side: Option<Side>,
is_active: bool,
on_click: impl Fn(MouseClick, &mut V, &mut EventContext<V>) + 'static,
cx: &mut ViewContext<V>,
@ -119,41 +92,41 @@ pub(crate) fn render_search_mode_button<V: View>(
enum SearchModeButton {}
MouseEventHandler::new::<SearchModeButton, _>(mode.region_id(), cx, |state, cx| {
let theme = theme::current(cx);
let mut style = theme
let style = theme
.search
.mode_button
.in_state(is_active)
.style_for(state)
.clone();
style.container.border.left = mode.border_left();
style.container.border.right = mode.border_right();
let label = Label::new(mode.label(), style.text.clone())
.aligned()
.contained();
let mut container_style = style.container.clone();
if let Some(button_side) = mode.button_side() {
let mut container_style = style.container;
if let Some(button_side) = side {
if button_side == Side::Left {
container_style.border.left = true;
container_style.corner_radii = CornerRadii {
bottom_right: 0.,
top_right: 0.,
..container_style.corner_radii
};
label.with_style(container_style)
} else {
container_style.border.left = false;
container_style.corner_radii = CornerRadii {
bottom_left: 0.,
top_left: 0.,
..container_style.corner_radii
};
label.with_style(container_style)
}
} else {
container_style.border.left = false;
container_style.corner_radii = CornerRadii::default();
label.with_style(container_style)
}
.constrained()
.with_height(theme.search.search_bar_row_height)
Label::new(mode.label(), style.text)
.aligned()
.contained()
.with_style(container_style)
.constrained()
.with_height(theme.search.search_bar_row_height)
})
.on_click(MouseButton::Left, on_click)
.with_cursor_style(CursorStyle::PointingHand)