From c0f042b39a595da6f93de2268e5990a3c5604912 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 17 Aug 2023 17:25:50 -0700 Subject: [PATCH] Remove semantic search UI --- crates/gpui/src/elements/component.rs | 51 +++-- crates/search/src/buffer_search.rs | 7 +- crates/search/src/mode.rs | 20 +- crates/search/src/project_search.rs | 296 ++++---------------------- crates/search/src/search.rs | 7 +- crates/settings/src/settings.rs | 2 + crates/theme/src/components.rs | 9 +- crates/workspace/src/pane.rs | 4 - 8 files changed, 89 insertions(+), 307 deletions(-) diff --git a/crates/gpui/src/elements/component.rs b/crates/gpui/src/elements/component.rs index 018dc644c6..a26355a539 100644 --- a/crates/gpui/src/elements/component.rs +++ b/crates/gpui/src/elements/component.rs @@ -1,5 +1,3 @@ -use std::marker::PhantomData; - use pathfinder_geometry::{rect::RectF, vector::Vector2F}; use crate::{ @@ -52,22 +50,26 @@ impl Component for C { } } -pub struct ComponentAdapter { +pub struct ComponentAdapter { component: Option, - phantom: PhantomData, + element: Option>, + #[cfg(debug_assertions)] + _component_name: &'static str, } -impl ComponentAdapter { +impl ComponentAdapter { pub fn new(e: E) -> Self { Self { component: Some(e), - phantom: PhantomData, + element: None, + #[cfg(debug_assertions)] + _component_name: std::any::type_name::(), } } } impl + 'static> Element for ComponentAdapter { - type LayoutState = AnyElement; + type LayoutState = (); type PaintState = (); @@ -77,10 +79,12 @@ impl + 'static> Element for ComponentAdapter { view: &mut V, cx: &mut LayoutContext, ) -> (Vector2F, Self::LayoutState) { - let component = self.component.take().unwrap(); - let mut element = component.render(view, cx.view_context()); - let constraint = element.layout(constraint, view, cx); - (constraint, element) + if self.element.is_none() { + let component = self.component.take().unwrap(); + self.element = Some(component.render(view, cx.view_context())); + } + let constraint = self.element.as_mut().unwrap().layout(constraint, view, cx); + (constraint, ()) } fn paint( @@ -88,11 +92,14 @@ impl + 'static> Element for ComponentAdapter { scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, - layout: &mut Self::LayoutState, + _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext, ) -> Self::PaintState { - layout.paint(scene, bounds.origin(), visible_bounds, view, cx) + self.element + .as_mut() + .unwrap() + .paint(scene, bounds.origin(), visible_bounds, view, cx) } fn rect_for_text_range( @@ -100,25 +107,35 @@ impl + 'static> Element for ComponentAdapter { range_utf16: std::ops::Range, _: RectF, _: RectF, - element: &Self::LayoutState, + _: &Self::LayoutState, _: &Self::PaintState, view: &V, cx: &ViewContext, ) -> Option { - element.rect_for_text_range(range_utf16, view, cx) + self.element + .as_ref() + .unwrap() + .rect_for_text_range(range_utf16, view, cx) } fn debug( &self, _: RectF, - element: &Self::LayoutState, + _: &Self::LayoutState, _: &Self::PaintState, view: &V, cx: &ViewContext, ) -> serde_json::Value { + #[cfg(debug_assertions)] + let component_name = self._component_name; + + #[cfg(not(debug_assertions))] + let component_name = "Unknown"; + serde_json::json!({ "type": "ComponentAdapter", - "child": element.debug(view, cx), + "child": self.element.as_ref().unwrap().debug(view, cx), + "component_name": component_name }) } } diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 4078cb572d..b65c7222a4 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -523,11 +523,6 @@ impl BufferSearchBar { } pub fn activate_search_mode(&mut self, mode: SearchMode, cx: &mut ViewContext) { - assert_ne!( - mode, - SearchMode::Semantic, - "Semantic search is not supported in buffer search" - ); if mode == self.current_mode { return; } @@ -802,7 +797,7 @@ impl BufferSearchBar { } } fn cycle_mode(&mut self, _: &CycleMode, cx: &mut ViewContext) { - self.activate_search_mode(next_mode(&self.current_mode, false), cx); + self.activate_search_mode(next_mode(&self.current_mode), cx); } fn cycle_mode_on_pane(pane: &mut Pane, action: &CycleMode, cx: &mut ViewContext) { let mut should_propagate = true; diff --git a/crates/search/src/mode.rs b/crates/search/src/mode.rs index 2c180be761..0163528951 100644 --- a/crates/search/src/mode.rs +++ b/crates/search/src/mode.rs @@ -1,12 +1,11 @@ use gpui::Action; -use crate::{ActivateRegexMode, ActivateSemanticMode, ActivateTextMode}; +use crate::{ActivateRegexMode, ActivateTextMode}; // TODO: Update the default search mode to get from config #[derive(Copy, Clone, Debug, Default, PartialEq)] pub enum SearchMode { #[default] Text, - Semantic, Regex, } @@ -20,7 +19,6 @@ impl SearchMode { pub(crate) fn label(&self) -> &'static str { match self { SearchMode::Text => "Text", - SearchMode::Semantic => "Semantic", SearchMode::Regex => "Regex", } } @@ -28,7 +26,6 @@ impl SearchMode { pub(crate) fn region_id(&self) -> usize { match self { SearchMode::Text => 3, - SearchMode::Semantic => 4, SearchMode::Regex => 5, } } @@ -36,7 +33,6 @@ impl SearchMode { pub(crate) fn tooltip_text(&self) -> &'static str { match self { SearchMode::Text => "Activate Text Search", - SearchMode::Semantic => "Activate Semantic Search", SearchMode::Regex => "Activate Regex Search", } } @@ -44,7 +40,6 @@ impl SearchMode { pub(crate) fn activate_action(&self) -> Box { match self { SearchMode::Text => Box::new(ActivateTextMode), - SearchMode::Semantic => Box::new(ActivateSemanticMode), SearchMode::Regex => Box::new(ActivateRegexMode), } } @@ -53,7 +48,6 @@ impl SearchMode { match self { SearchMode::Regex => true, SearchMode::Text => true, - SearchMode::Semantic => true, } } @@ -67,22 +61,14 @@ impl SearchMode { pub(crate) fn button_side(&self) -> Option { 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 - }; - +pub(crate) fn next_mode(mode: &SearchMode) -> SearchMode { match mode { - SearchMode::Text => next_text_state, - SearchMode::Semantic => SearchMode::Regex, + SearchMode::Text => SearchMode::Regex, SearchMode::Regex => SearchMode::Text, } } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index e15bd0e27a..abb7395e50 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -2,10 +2,10 @@ use crate::{ history::SearchHistory, mode::SearchMode, search_bar::{render_nav_button, render_option_button_icon, render_search_mode_button}, - ActivateRegexMode, CycleMode, NextHistoryQuery, PreviousHistoryQuery, SearchOptions, - SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleWholeWord, + CycleMode, NextHistoryQuery, PreviousHistoryQuery, SearchOptions, SelectNextMatch, + SelectPrevMatch, ToggleCaseSensitive, ToggleWholeWord, }; -use anyhow::{Context, Result}; +use anyhow::Context; use collections::HashMap; use editor::{ items::active_match_index, scroll::autoscroll::Autoscroll, Anchor, Editor, MultiBuffer, @@ -13,8 +13,6 @@ use editor::{ }; use futures::StreamExt; -use gpui::platform::PromptLevel; - use gpui::{ actions, elements::*, platform::MouseButton, Action, AnyElement, AnyViewHandle, AppContext, Entity, ModelContext, ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, @@ -22,12 +20,10 @@ use gpui::{ }; use menu::Confirm; -use postage::stream::Stream; use project::{ - search::{PathMatcher, SearchInputs, SearchQuery}, + search::{PathMatcher, SearchQuery}, Entry, Project, }; -use semantic_index::SemanticIndex; use smallvec::SmallVec; use std::{ any::{Any, TypeId}, @@ -118,8 +114,6 @@ pub struct ProjectSearchView { model: ModelHandle, query_editor: ViewHandle, results_editor: ViewHandle, - semantic_state: Option, - semantic_permissioned: Option, search_options: SearchOptions, panels_with_errors: HashSet, active_match_index: Option, @@ -131,12 +125,6 @@ pub struct ProjectSearchView { current_mode: SearchMode, } -struct SemanticSearchState { - file_count: usize, - outstanding_file_count: usize, - _progress_task: Task<()>, -} - pub struct ProjectSearchBar { active_project_search: Option>, subscription: Option, @@ -218,60 +206,6 @@ impl ProjectSearch { })); cx.notify(); } - - fn semantic_search(&mut self, inputs: &SearchInputs, cx: &mut ModelContext) { - let search = SemanticIndex::global(cx).map(|index| { - index.update(cx, |semantic_index, cx| { - semantic_index.search_project( - self.project.clone(), - inputs.as_str().to_owned(), - 10, - inputs.files_to_include().to_vec(), - inputs.files_to_exclude().to_vec(), - cx, - ) - }) - }); - self.search_id += 1; - self.match_ranges.clear(); - self.search_history.add(inputs.as_str().to_string()); - self.no_results = Some(true); - self.pending_search = Some(cx.spawn(|this, mut cx| async move { - let results = search?.await.log_err()?; - - let (_task, mut match_ranges) = this.update(&mut cx, |this, cx| { - this.excerpts.update(cx, |excerpts, cx| { - excerpts.clear(cx); - - let matches = results - .into_iter() - .map(|result| (result.buffer, vec![result.range.start..result.range.start])) - .collect(); - - excerpts.stream_excerpts_with_context_lines(matches, 3, cx) - }) - }); - - while let Some(match_range) = match_ranges.next().await { - this.update(&mut cx, |this, cx| { - this.match_ranges.push(match_range); - while let Ok(Some(match_range)) = match_ranges.try_next() { - this.match_ranges.push(match_range); - } - this.no_results = Some(false); - cx.notify(); - }); - } - - this.update(&mut cx, |this, cx| { - this.pending_search.take(); - cx.notify(); - }); - - None - })); - cx.notify(); - } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -311,27 +245,10 @@ impl View for ProjectSearchView { } else { match current_mode { SearchMode::Text => Cow::Borrowed("Text search all files and folders"), - SearchMode::Semantic => { - Cow::Borrowed("Search all code objects using Natural Language") - } SearchMode::Regex => Cow::Borrowed("Regex search all files and folders"), } }; - let semantic_status = if let Some(semantic) = &self.semantic_state { - if semantic.outstanding_file_count > 0 { - format!( - "Indexing: {} of {}...", - semantic.file_count - semantic.outstanding_file_count, - semantic.file_count - ) - } else { - "Indexing complete".to_string() - } - } else { - "Indexing: ...".to_string() - }; - let minor_text = if let Some(no_results) = model.no_results { if model.pending_search.is_none() && no_results { vec!["No results found in this project for the provided query".to_owned()] @@ -339,19 +256,11 @@ impl View for ProjectSearchView { vec![] } } else { - match current_mode { - SearchMode::Semantic => vec![ - "".to_owned(), - semantic_status, - "Simply explain the code you are looking to find.".to_owned(), - "ex. 'prompt user for permissions to index their project'".to_owned(), - ], - _ => vec![ - "".to_owned(), - "Include/exclude specific paths with the filter option.".to_owned(), - "Matching exact word and/or casing is available too.".to_owned(), - ], - } + vec![ + "".to_owned(), + "Include/exclude specific paths with the filter option.".to_owned(), + "Matching exact word and/or casing is available too.".to_owned(), + ] }; let previous_query_keystrokes = @@ -630,49 +539,6 @@ impl ProjectSearchView { self.search_options.toggle(option); } - fn index_project(&mut self, cx: &mut ViewContext) { - if let Some(semantic_index) = SemanticIndex::global(cx) { - // Semantic search uses no options - self.search_options = SearchOptions::none(); - - let project = self.model.read(cx).project.clone(); - let index_task = semantic_index.update(cx, |semantic_index, cx| { - semantic_index.index_project(project, cx) - }); - - cx.spawn(|search_view, mut cx| async move { - let (files_to_index, mut files_remaining_rx) = index_task.await?; - - search_view.update(&mut cx, |search_view, cx| { - cx.notify(); - search_view.semantic_state = Some(SemanticSearchState { - file_count: files_to_index, - outstanding_file_count: files_to_index, - _progress_task: cx.spawn(|search_view, mut cx| async move { - while let Some(count) = files_remaining_rx.recv().await { - search_view - .update(&mut cx, |search_view, cx| { - if let Some(semantic_search_state) = - &mut search_view.semantic_state - { - semantic_search_state.outstanding_file_count = count; - cx.notify(); - if count == 0 { - return; - } - } - }) - .ok(); - } - }), - }); - })?; - anyhow::Ok(()) - }) - .detach_and_log_err(cx); - } - } - fn clear_search(&mut self, cx: &mut ViewContext) { self.model.update(cx, |model, cx| { model.pending_search = None; @@ -696,56 +562,7 @@ impl ProjectSearchView { self.current_mode = mode; match mode { - SearchMode::Semantic => { - let has_permission = self.semantic_permissioned(cx); - self.active_match_index = None; - cx.spawn(|this, mut cx| async move { - let has_permission = has_permission.await?; - - if !has_permission { - let mut answer = this.update(&mut cx, |this, cx| { - let project = this.model.read(cx).project.clone(); - let project_name = project - .read(cx) - .worktree_root_names(cx) - .collect::>() - .join("/"); - let is_plural = - project_name.chars().filter(|letter| *letter == '/').count() > 0; - let prompt_text = format!("Would you like to index the '{}' project{} for semantic search? This requires sending code to the OpenAI API", project_name, - if is_plural { - "s" - } else {""}); - cx.prompt( - PromptLevel::Info, - prompt_text.as_str(), - &["Continue", "Cancel"], - ) - })?; - - if answer.next().await == Some(0) { - this.update(&mut cx, |this, _| { - this.semantic_permissioned = Some(true); - })?; - } else { - this.update(&mut cx, |this, cx| { - this.semantic_permissioned = Some(false); - debug_assert_ne!(previous_mode, SearchMode::Semantic, "Tried to re-enable semantic search mode after user modal was rejected"); - this.activate_search_mode(previous_mode, cx); - })?; - return anyhow::Ok(()); - } - } - - this.update(&mut cx, |this, cx| { - this.index_project(cx); - })?; - - anyhow::Ok(()) - }).detach_and_log_err(cx); - } SearchMode::Regex | SearchMode::Text => { - self.semantic_state = None; self.active_match_index = None; } } @@ -843,8 +660,6 @@ impl ProjectSearchView { model, query_editor, results_editor, - semantic_state: None, - semantic_permissioned: None, search_options: options, panels_with_errors: HashSet::new(), active_match_index: None, @@ -858,18 +673,6 @@ impl ProjectSearchView { this } - fn semantic_permissioned(&mut self, cx: &mut ViewContext) -> Task> { - if let Some(value) = self.semantic_permissioned { - return Task::ready(Ok(value)); - } - - SemanticIndex::global(cx) - .map(|semantic| { - let project = self.model.read(cx).project.clone(); - semantic.update(cx, |this, cx| this.project_previously_indexed(project, cx)) - }) - .unwrap_or(Task::ready(Ok(false))) - } pub fn new_search_in_directory( workspace: &mut Workspace, dir_entry: &Entry, @@ -945,26 +748,8 @@ impl ProjectSearchView { } fn search(&mut self, cx: &mut ViewContext) { - let mode = self.current_mode; - match mode { - SearchMode::Semantic => { - if let Some(semantic) = &mut self.semantic_state { - if semantic.outstanding_file_count > 0 { - return; - } - - if let Some(query) = self.build_search_query(cx) { - self.model - .update(cx, |model, cx| model.semantic_search(query.as_inner(), cx)); - } - } - } - - _ => { - if let Some(query) = self.build_search_query(cx) { - self.model.update(cx, |model, cx| model.search(query, cx)); - } - } + if let Some(query) = self.build_search_query(cx) { + self.model.update(cx, |model, cx| model.search(query, cx)); } } @@ -1164,8 +949,7 @@ impl ProjectSearchBar { .and_then(|item| item.downcast::()) { search_view.update(cx, |this, cx| { - let new_mode = - crate::mode::next_mode(&this.current_mode, SemanticIndex::enabled(cx)); + let new_mode = crate::mode::next_mode(&this.current_mode); this.activate_search_mode(new_mode, cx); }) } @@ -1288,18 +1072,18 @@ impl ProjectSearchBar { } } - fn activate_regex_mode(pane: &mut Pane, _: &ActivateRegexMode, cx: &mut ViewContext) { - if let Some(search_view) = pane - .active_item() - .and_then(|item| item.downcast::()) - { - search_view.update(cx, |view, cx| { - view.activate_search_mode(SearchMode::Regex, cx) - }); - } else { - cx.propagate_action(); - } - } + // fn activate_regex_mode(pane: &mut Pane, _: &ActivateRegexMode, cx: &mut ViewContext) { + // if let Some(search_view) = pane + // .active_item() + // .and_then(|item| item.downcast::()) + // { + // search_view.update(cx, |view, cx| { + // view.activate_search_mode(SearchMode::Regex, cx) + // }); + // } else { + // cx.propagate_action(); + // } + // } fn toggle_filters(&mut self, cx: &mut ViewContext) -> bool { if let Some(search_view) = self.active_project_search.as_ref() { @@ -1400,7 +1184,6 @@ impl View for ProjectSearchBar { theme.search.editor.input.container }; - let row_spacing = theme.workspace.toolbar.container.padding.bottom; let search = _search.read(cx); let filter_button = render_option_button_icon( search.filters_enabled, @@ -1413,8 +1196,7 @@ impl View for ProjectSearchBar { }, cx, ); - let search = _search.read(cx); - let is_semantic_disabled = search.semantic_state.is_none(); + let render_option_button_icon = |path, option, cx: &mut ViewContext| { crate::search_bar::render_option_button_icon( self.is_option_enabled(option, cx), @@ -1428,17 +1210,17 @@ impl View for ProjectSearchBar { cx, ) }; - let case_sensitive = is_semantic_disabled.then(|| { - render_option_button_icon( - "icons/case_insensitive_12.svg", - SearchOptions::CASE_SENSITIVE, - cx, - ) - }); + let case_sensitive = render_option_button_icon( + "icons/case_insensitive_12.svg", + SearchOptions::CASE_SENSITIVE, + cx, + ); - let whole_word = is_semantic_disabled.then(|| { - render_option_button_icon("icons/word_search_12.svg", SearchOptions::WHOLE_WORD, cx) - }); + let whole_word = 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(); @@ -1454,8 +1236,8 @@ impl View for ProjectSearchBar { .with_child( Flex::row() .with_child(filter_button) - .with_children(case_sensitive) - .with_children(whole_word) + .with_child(case_sensitive) + .with_child(whole_word) .flex(1., false) .constrained() .contained(), @@ -1554,8 +1336,7 @@ impl View for ProjectSearchBar { ) }; let is_active = search.active_match_index.is_some(); - let semantic_index = SemanticIndex::enabled(cx) - .then(|| search_button_for_mode(SearchMode::Semantic, cx)); + let nav_button_for_direction = |label, direction, cx: &mut ViewContext| { render_nav_button( label, @@ -1581,7 +1362,6 @@ impl View for ProjectSearchBar { .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), diff --git a/crates/search/src/search.rs b/crates/search/src/search.rs index c31ea6f2f8..7132efa5e3 100644 --- a/crates/search/src/search.rs +++ b/crates/search/src/search.rs @@ -8,7 +8,9 @@ use gpui::{ pub use mode::SearchMode; use project::search::SearchQuery; pub use project_search::{ProjectSearchBar, ProjectSearchView}; -use theme::components::{action_button::ActionButton, ComponentExt, ToggleIconButtonStyle}; +use theme::components::{ + action_button::ActionButton, svg::Svg, ComponentExt, ToggleIconButtonStyle, +}; pub mod buffer_search; mod history; @@ -33,7 +35,6 @@ actions!( NextHistoryQuery, PreviousHistoryQuery, ActivateTextMode, - ActivateSemanticMode, ActivateRegexMode ] ); @@ -94,7 +95,7 @@ impl SearchOptions { format!("Toggle {}", self.label()), tooltip_style, ) - .with_contents(theme::components::svg::Svg::new(self.icon())) + .with_contents(Svg::new(self.icon())) .toggleable(active) .with_style(button_style) .into_element() diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index 8c3587d942..5287c999e8 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -1,3 +1,5 @@ +#![allow(non_snake_case, non_upper_case_globals)] + mod keymap_file; mod settings_file; mod settings_store; diff --git a/crates/theme/src/components.rs b/crates/theme/src/components.rs index fce7ad825c..a74b9ed4a4 100644 --- a/crates/theme/src/components.rs +++ b/crates/theme/src/components.rs @@ -175,8 +175,13 @@ pub mod action_button { .on_click(MouseButton::Left, { let action = self.action.boxed_clone(); move |_, _, cx| { - cx.window() - .dispatch_action(cx.view_id(), action.as_ref(), cx); + let window = cx.window(); + let view = cx.view_id(); + let action = action.boxed_clone(); + cx.spawn(|_, mut cx| async move { + window.dispatch_action(view, action.as_ref(), &mut cx); + }) + .detach(); } }) .with_cursor_style(CursorStyle::PointingHand) diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 528b1e2029..60d22bbdae 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -286,10 +286,6 @@ impl Pane { context_menu.update(cx, |menu, _| { menu.set_position_mode(OverlayPositionMode::Local) }); - let theme = theme::current(cx).workspace.tab_bar.clone(); - - let nav_button_height = theme.height; - let button_style = theme.nav_button; Self { items: Vec::new(),