From 37e6533b286c36372533c1d3ab7476d50a0c0a4c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 3 Jan 2024 10:38:23 -0800 Subject: [PATCH] Remove 2 suffix for project_symbols, theme_selector Co-authored-by: Mikayla --- Cargo.lock | 52 +-- Cargo.toml | 2 - crates/collab_ui/Cargo.toml | 2 +- crates/project_symbols/Cargo.toml | 34 +- crates/project_symbols/src/project_symbols.rs | 166 +++---- crates/project_symbols2/Cargo.toml | 37 -- .../project_symbols2/src/project_symbols.rs | 415 ------------------ crates/theme_selector/Cargo.toml | 23 +- crates/theme_selector/src/theme_selector.rs | 178 +++++--- crates/theme_selector2/Cargo.toml | 30 -- crates/theme_selector2/src/theme_selector.rs | 295 ------------- crates/welcome/Cargo.toml | 2 +- crates/zed/Cargo.toml | 4 +- 13 files changed, 245 insertions(+), 995 deletions(-) delete mode 100644 crates/project_symbols2/Cargo.toml delete mode 100644 crates/project_symbols2/src/project_symbols.rs delete mode 100644 crates/theme_selector2/Cargo.toml delete mode 100644 crates/theme_selector2/src/theme_selector.rs diff --git a/Cargo.lock b/Cargo.lock index 9e4815f153..8b14cf6da3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1864,7 +1864,7 @@ dependencies = [ "settings2", "smallvec", "theme2", - "theme_selector2", + "theme_selector", "time", "tree-sitter-markdown", "ui2", @@ -6763,29 +6763,6 @@ dependencies = [ [[package]] name = "project_symbols" version = "0.1.0" -dependencies = [ - "anyhow", - "editor", - "futures 0.3.28", - "fuzzy", - "gpui", - "language", - "lsp", - "ordered-float 2.10.0", - "picker", - "postage", - "project", - "settings", - "smol", - "text", - "theme", - "util", - "workspace", -] - -[[package]] -name = "project_symbols2" -version = "0.1.0" dependencies = [ "anyhow", "editor2", @@ -9464,27 +9441,6 @@ dependencies = [ [[package]] name = "theme_selector" version = "0.1.0" -dependencies = [ - "client", - "editor", - "feature_flags", - "fs", - "fuzzy", - "gpui", - "log", - "parking_lot 0.11.2", - "picker", - "postage", - "settings", - "smol", - "theme", - "util", - "workspace", -] - -[[package]] -name = "theme_selector2" -version = "0.1.0" dependencies = [ "client2", "editor2", @@ -11048,7 +11004,7 @@ dependencies = [ "serde", "settings2", "theme2", - "theme_selector2", + "theme_selector", "ui2", "util", "vim2", @@ -11511,7 +11467,7 @@ dependencies = [ "postage", "project2", "project_panel2", - "project_symbols2", + "project_symbols", "quick_action_bar", "rand 0.8.5", "recent_projects2", @@ -11536,7 +11492,7 @@ dependencies = [ "terminal_view2", "text2", "theme2", - "theme_selector2", + "theme_selector", "thiserror", "tiny_http", "toml 0.5.11", diff --git a/Cargo.toml b/Cargo.toml index 06e3f63522..0c3ec653fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,7 +89,6 @@ members = [ "crates/project_panel", "crates/project_panel2", "crates/project_symbols", - "crates/project_symbols2", "crates/quick_action_bar", "crates/recent_projects", "crates/recent_projects2", @@ -116,7 +115,6 @@ members = [ "crates/theme2", "crates/theme_importer", "crates/theme_selector", - "crates/theme_selector2", "crates/ui2", "crates/util", "crates/story", diff --git a/crates/collab_ui/Cargo.toml b/crates/collab_ui/Cargo.toml index fcce4fbfca..5f2f85c48f 100644 --- a/crates/collab_ui/Cargo.toml +++ b/crates/collab_ui/Cargo.toml @@ -46,7 +46,7 @@ rpc = { package ="rpc2", path = "../rpc2" } settings = { package = "settings2", path = "../settings2" } feature_flags = { package = "feature_flags2", path = "../feature_flags2"} theme = { package = "theme2", path = "../theme2" } -theme_selector = { package = "theme_selector2", path = "../theme_selector2" } +theme_selector = { path = "../theme_selector" } vcs_menu = { path = "../vcs_menu" } ui = { package = "ui2", path = "../ui2" } util = { path = "../util" } diff --git a/crates/project_symbols/Cargo.toml b/crates/project_symbols/Cargo.toml index 85939634ad..f24c7471c9 100644 --- a/crates/project_symbols/Cargo.toml +++ b/crates/project_symbols/Cargo.toml @@ -9,15 +9,15 @@ path = "src/project_symbols.rs" doctest = false [dependencies] -editor = { path = "../editor" } -fuzzy = { path = "../fuzzy" } -gpui = { path = "../gpui" } -picker = { path = "../picker" } -project = { path = "../project" } -text = { path = "../text" } -settings = { path = "../settings" } -workspace = { path = "../workspace" } -theme = { path = "../theme" } +editor = { package = "editor2", path = "../editor2" } +fuzzy = {package = "fuzzy2", path = "../fuzzy2" } +gpui = {package = "gpui2", path = "../gpui2" } +picker = {package = "picker2", path = "../picker2" } +project = { package = "project2", path = "../project2" } +text = {package = "text2", path = "../text2" } +settings = {package = "settings2", path = "../settings2" } +workspace = {package = "workspace2", path = "../workspace2" } +theme = { package = "theme2", path = "../theme2" } util = { path = "../util" } anyhow.workspace = true @@ -27,11 +27,11 @@ smol.workspace = true [dev-dependencies] futures.workspace = true -editor = { path = "../editor", features = ["test-support"] } -settings = { path = "../settings", features = ["test-support"] } -gpui = { path = "../gpui", features = ["test-support"] } -language = { path = "../language", features = ["test-support"] } -lsp = { path = "../lsp", features = ["test-support"] } -project = { path = "../project", features = ["test-support"] } -theme = { path = "../theme", features = ["test-support"] } -workspace = { path = "../workspace", features = ["test-support"] } +editor = { package = "editor2", path = "../editor2", features = ["test-support"] } +settings = { package = "settings2", path = "../settings2", features = ["test-support"] } +gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] } +language = { package = "language2", path = "../language2", features = ["test-support"] } +lsp = { package = "lsp2", path = "../lsp2", features = ["test-support"] } +project = { package = "project2", path = "../project2", features = ["test-support"] } +theme = { package = "theme2", path = "../theme2", features = ["test-support"] } +workspace = { package = "workspace2", path = "../workspace2", features = ["test-support"] } diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 3273d5c6e6..578a47f95a 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -1,38 +1,43 @@ -use editor::{ - combine_syntax_and_fuzzy_match_highlights, scroll::autoscroll::Autoscroll, - styled_runs_for_code_label, Bias, Editor, -}; +use editor::{scroll::autoscroll::Autoscroll, styled_runs_for_code_label, Bias, Editor}; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ - actions, elements::*, AppContext, ModelHandle, MouseState, Task, ViewContext, WeakViewHandle, + actions, rems, AppContext, DismissEvent, FontWeight, Model, ParentElement, StyledText, Task, + View, ViewContext, WeakView, }; use ordered_float::OrderedFloat; -use picker::{Picker, PickerDelegate, PickerEvent}; +use picker::{Picker, PickerDelegate}; use project::{Project, Symbol}; use std::{borrow::Cow, cmp::Reverse, sync::Arc}; +use theme::ActiveTheme; use util::ResultExt; -use workspace::Workspace; +use workspace::{ + ui::{v_stack, Color, Label, LabelCommon, LabelLike, ListItem, ListItemSpacing, Selectable}, + Workspace, +}; actions!(project_symbols, [Toggle]); pub fn init(cx: &mut AppContext) { - cx.add_action(toggle); - ProjectSymbols::init(cx); + cx.observe_new_views( + |workspace: &mut Workspace, _: &mut ViewContext| { + workspace.register_action(|workspace, _: &Toggle, cx| { + let project = workspace.project().clone(); + let handle = cx.view().downgrade(); + workspace.toggle_modal(cx, move |cx| { + let delegate = ProjectSymbolsDelegate::new(handle, project); + Picker::new(delegate, cx).width(rems(34.)) + }) + }); + }, + ) + .detach(); } -fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { - workspace.toggle_modal(cx, |workspace, cx| { - let project = workspace.project().clone(); - let workspace = cx.weak_handle(); - cx.add_view(|cx| ProjectSymbols::new(ProjectSymbolsDelegate::new(workspace, project), cx)) - }); -} - -pub type ProjectSymbols = Picker; +pub type ProjectSymbols = View>; pub struct ProjectSymbolsDelegate { - workspace: WeakViewHandle, - project: ModelHandle, + workspace: WeakView, + project: Model, selected_match_index: usize, symbols: Vec, visible_match_candidates: Vec, @@ -42,7 +47,7 @@ pub struct ProjectSymbolsDelegate { } impl ProjectSymbolsDelegate { - fn new(workspace: WeakViewHandle, project: ModelHandle) -> Self { + fn new(workspace: WeakView, project: Model) -> Self { Self { workspace, project, @@ -55,7 +60,7 @@ impl ProjectSymbolsDelegate { } } - fn filter(&mut self, query: &str, cx: &mut ViewContext) { + fn filter(&mut self, query: &str, cx: &mut ViewContext>) { const MAX_MATCHES: usize = 100; let mut visible_matches = cx.background_executor().block(fuzzy::match_strings( &self.visible_match_candidates, @@ -63,7 +68,7 @@ impl ProjectSymbolsDelegate { false, MAX_MATCHES, &Default::default(), - cx.background().clone(), + cx.background_executor().clone(), )); let mut external_matches = cx.background_executor().block(fuzzy::match_strings( &self.external_match_candidates, @@ -71,7 +76,7 @@ impl ProjectSymbolsDelegate { false, MAX_MATCHES - visible_matches.len().min(MAX_MATCHES), &Default::default(), - cx.background().clone(), + cx.background_executor().clone(), )); let sort_key_for_match = |mat: &StringMatch| { let symbol = &self.symbols[mat.candidate_id]; @@ -100,11 +105,12 @@ impl ProjectSymbolsDelegate { } impl PickerDelegate for ProjectSymbolsDelegate { + type ListItem = ListItem; fn placeholder_text(&self) -> Arc { "Search project symbols...".into() } - fn confirm(&mut self, secondary: bool, cx: &mut ViewContext) { + fn confirm(&mut self, secondary: bool, cx: &mut ViewContext>) { if let Some(symbol) = self .matches .get(self.selected_match_index) @@ -137,11 +143,11 @@ impl PickerDelegate for ProjectSymbolsDelegate { Ok::<_, anyhow::Error>(()) }) .detach_and_log_err(cx); - cx.emit(PickerEvent::Dismiss); + cx.emit(DismissEvent); } } - fn dismissed(&mut self, _cx: &mut ViewContext) {} + fn dismissed(&mut self, _cx: &mut ViewContext>) {} fn match_count(&self) -> usize { self.matches.len() @@ -151,11 +157,11 @@ impl PickerDelegate for ProjectSymbolsDelegate { self.selected_match_index } - fn set_selected_index(&mut self, ix: usize, _cx: &mut ViewContext) { + fn set_selected_index(&mut self, ix: usize, _cx: &mut ViewContext>) { self.selected_match_index = ix; } - fn update_matches(&mut self, query: String, cx: &mut ViewContext) -> Task<()> { + fn update_matches(&mut self, query: String, cx: &mut ViewContext>) -> Task<()> { self.filter(&query, cx); self.show_worktree_root_name = self.project.read(cx).visible_worktrees(cx).count() > 1; let symbols = self @@ -165,7 +171,7 @@ impl PickerDelegate for ProjectSymbolsDelegate { let symbols = symbols.await.log_err(); if let Some(symbols) = symbols { this.update(&mut cx, |this, cx| { - let delegate = this.delegate_mut(); + let delegate = &mut this.delegate; let project = delegate.project.read(cx); let (visible_match_candidates, external_match_candidates) = symbols .iter() @@ -195,17 +201,12 @@ impl PickerDelegate for ProjectSymbolsDelegate { fn render_match( &self, ix: usize, - mouse_state: &mut MouseState, selected: bool, - cx: &AppContext, - ) -> AnyElement> { - let theme = theme::current(cx); - let style = &theme.picker.item; - let current_style = style.in_state(selected).style_for(mouse_state); - + cx: &mut ViewContext>, + ) -> Option { let string_match = &self.matches[ix]; let symbol = &self.symbols[string_match.candidate_id]; - let syntax_runs = styled_runs_for_code_label(&symbol.label, &theme.editor.syntax); + let syntax_runs = styled_runs_for_code_label(&symbol.label, cx.theme().syntax()); let mut path = symbol.path.path.to_string_lossy(); if self.show_worktree_root_name { @@ -219,29 +220,39 @@ impl PickerDelegate for ProjectSymbolsDelegate { )); } } + let label = symbol.label.text.clone(); + let path = path.to_string().clone(); - Flex::column() - .with_child( - Text::new(symbol.label.text.clone(), current_style.label.text.clone()) - .with_soft_wrap(false) - .with_highlights(combine_syntax_and_fuzzy_match_highlights( - &symbol.label.text, - current_style.label.text.clone().into(), - syntax_runs, - &string_match.positions, - )), - ) - .with_child( - // Avoid styling the path differently when it is selected, since - // the symbol's syntax highlighting doesn't change when selected. - Label::new( - path.to_string(), - style.inactive_state().default.label.clone(), + let highlights = gpui::combine_highlights( + string_match + .positions + .iter() + .map(|pos| (*pos..pos + 1, FontWeight::BOLD.into())), + syntax_runs.map(|(range, mut highlight)| { + // Ignore font weight for syntax highlighting, as we'll use it + // for fuzzy matches. + highlight.font_weight = None; + (range, highlight) + }), + ); + + Some( + ListItem::new(ix) + .inset(true) + .spacing(ListItemSpacing::Sparse) + .selected(selected) + .child( + // todo!() combine_syntax_and_fuzzy_match_highlights() + v_stack() + .child( + LabelLike::new().child( + StyledText::new(label) + .with_highlights(&cx.text_style().clone(), highlights), + ), + ) + .child(Label::new(path).color(Color::Muted)), ), - ) - .contained() - .with_style(current_style.container) - .into_any() + ) } } @@ -249,7 +260,7 @@ impl PickerDelegate for ProjectSymbolsDelegate { mod tests { use super::*; use futures::StreamExt; - use gpui::{serde_json::json, TestAppContext}; + use gpui::{serde_json::json, TestAppContext, VisualContext}; use language::{FakeLspAdapter, Language, LanguageConfig}; use project::FakeFs; use settings::SettingsStore; @@ -271,7 +282,7 @@ mod tests { .set_fake_lsp_adapter(Arc::::default()) .await; - let fs = FakeFs::new(cx.background()); + let fs = FakeFs::new(cx.executor()); fs.insert_tree("/dir", json!({ "test.rs": "" })).await; let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; @@ -294,7 +305,7 @@ mod tests { let fake_server = fake_servers.next().await.unwrap(); fake_server.handle_request::( move |params: lsp::WorkspaceSymbolParams, cx| { - let executor = cx.background(); + let executor = cx.background_executor().clone(); let fake_symbols = fake_symbols.clone(); async move { let candidates = fake_symbols @@ -326,12 +337,11 @@ mod tests { }, ); - let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); - let workspace = window.root(cx); + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); // Create the project symbols view. - let symbols = window.add_view(cx, |cx| { - ProjectSymbols::new( + let symbols = cx.new_view(|cx| { + Picker::new( ProjectSymbolsDelegate::new(workspace.downgrade(), project.clone()), cx, ) @@ -346,9 +356,9 @@ mod tests { p.update_matches("onex".to_string(), cx); }); - cx.foreground().run_until_parked(); - symbols.read_with(cx, |symbols, _| { - assert_eq!(symbols.delegate().matches.len(), 0); + cx.run_until_parked(); + symbols.update(cx, |symbols, _| { + assert_eq!(symbols.delegate.matches.len(), 0); }); // Spawn more updates such that in the end, there are matches. @@ -357,9 +367,9 @@ mod tests { p.update_matches("on".to_string(), cx); }); - cx.foreground().run_until_parked(); - symbols.read_with(cx, |symbols, _| { - let delegate = symbols.delegate(); + cx.run_until_parked(); + symbols.update(cx, |symbols, _| { + let delegate = &symbols.delegate; assert_eq!(delegate.matches.len(), 2); assert_eq!(delegate.matches[0].string, "ton"); assert_eq!(delegate.matches[1].string, "one"); @@ -371,17 +381,17 @@ mod tests { p.update_matches("".to_string(), cx); }); - cx.foreground().run_until_parked(); - symbols.read_with(cx, |symbols, _| { - assert_eq!(symbols.delegate().matches.len(), 0); + cx.run_until_parked(); + symbols.update(cx, |symbols, _| { + assert_eq!(symbols.delegate.matches.len(), 0); }); } fn init_test(cx: &mut TestAppContext) { - cx.foreground().forbid_parking(); cx.update(|cx| { - cx.set_global(SettingsStore::test(cx)); - theme::init((), cx); + let store = SettingsStore::test(cx); + cx.set_global(store); + theme::init(theme::LoadThemes::JustBase, cx); language::init(cx); Project::init_settings(cx); workspace::init_settings(cx); diff --git a/crates/project_symbols2/Cargo.toml b/crates/project_symbols2/Cargo.toml deleted file mode 100644 index e11dd373a8..0000000000 --- a/crates/project_symbols2/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "project_symbols2" -version = "0.1.0" -edition = "2021" -publish = false - -[lib] -path = "src/project_symbols.rs" -doctest = false - -[dependencies] -editor = { package = "editor2", path = "../editor2" } -fuzzy = {package = "fuzzy2", path = "../fuzzy2" } -gpui = {package = "gpui2", path = "../gpui2" } -picker = {package = "picker2", path = "../picker2" } -project = { package = "project2", path = "../project2" } -text = {package = "text2", path = "../text2" } -settings = {package = "settings2", path = "../settings2" } -workspace = {package = "workspace2", path = "../workspace2" } -theme = { package = "theme2", path = "../theme2" } -util = { path = "../util" } - -anyhow.workspace = true -ordered-float.workspace = true -postage.workspace = true -smol.workspace = true - -[dev-dependencies] -futures.workspace = true -editor = { package = "editor2", path = "../editor2", features = ["test-support"] } -settings = { package = "settings2", path = "../settings2", features = ["test-support"] } -gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] } -language = { package = "language2", path = "../language2", features = ["test-support"] } -lsp = { package = "lsp2", path = "../lsp2", features = ["test-support"] } -project = { package = "project2", path = "../project2", features = ["test-support"] } -theme = { package = "theme2", path = "../theme2", features = ["test-support"] } -workspace = { package = "workspace2", path = "../workspace2", features = ["test-support"] } diff --git a/crates/project_symbols2/src/project_symbols.rs b/crates/project_symbols2/src/project_symbols.rs deleted file mode 100644 index 578a47f95a..0000000000 --- a/crates/project_symbols2/src/project_symbols.rs +++ /dev/null @@ -1,415 +0,0 @@ -use editor::{scroll::autoscroll::Autoscroll, styled_runs_for_code_label, Bias, Editor}; -use fuzzy::{StringMatch, StringMatchCandidate}; -use gpui::{ - actions, rems, AppContext, DismissEvent, FontWeight, Model, ParentElement, StyledText, Task, - View, ViewContext, WeakView, -}; -use ordered_float::OrderedFloat; -use picker::{Picker, PickerDelegate}; -use project::{Project, Symbol}; -use std::{borrow::Cow, cmp::Reverse, sync::Arc}; -use theme::ActiveTheme; -use util::ResultExt; -use workspace::{ - ui::{v_stack, Color, Label, LabelCommon, LabelLike, ListItem, ListItemSpacing, Selectable}, - Workspace, -}; - -actions!(project_symbols, [Toggle]); - -pub fn init(cx: &mut AppContext) { - cx.observe_new_views( - |workspace: &mut Workspace, _: &mut ViewContext| { - workspace.register_action(|workspace, _: &Toggle, cx| { - let project = workspace.project().clone(); - let handle = cx.view().downgrade(); - workspace.toggle_modal(cx, move |cx| { - let delegate = ProjectSymbolsDelegate::new(handle, project); - Picker::new(delegate, cx).width(rems(34.)) - }) - }); - }, - ) - .detach(); -} - -pub type ProjectSymbols = View>; - -pub struct ProjectSymbolsDelegate { - workspace: WeakView, - project: Model, - selected_match_index: usize, - symbols: Vec, - visible_match_candidates: Vec, - external_match_candidates: Vec, - show_worktree_root_name: bool, - matches: Vec, -} - -impl ProjectSymbolsDelegate { - fn new(workspace: WeakView, project: Model) -> Self { - Self { - workspace, - project, - selected_match_index: 0, - symbols: Default::default(), - visible_match_candidates: Default::default(), - external_match_candidates: Default::default(), - matches: Default::default(), - show_worktree_root_name: false, - } - } - - fn filter(&mut self, query: &str, cx: &mut ViewContext>) { - const MAX_MATCHES: usize = 100; - let mut visible_matches = cx.background_executor().block(fuzzy::match_strings( - &self.visible_match_candidates, - query, - false, - MAX_MATCHES, - &Default::default(), - cx.background_executor().clone(), - )); - let mut external_matches = cx.background_executor().block(fuzzy::match_strings( - &self.external_match_candidates, - query, - false, - MAX_MATCHES - visible_matches.len().min(MAX_MATCHES), - &Default::default(), - cx.background_executor().clone(), - )); - let sort_key_for_match = |mat: &StringMatch| { - let symbol = &self.symbols[mat.candidate_id]; - ( - Reverse(OrderedFloat(mat.score)), - &symbol.label.text[symbol.label.filter_range.clone()], - ) - }; - - visible_matches.sort_unstable_by_key(sort_key_for_match); - external_matches.sort_unstable_by_key(sort_key_for_match); - let mut matches = visible_matches; - matches.append(&mut external_matches); - - for mat in &mut matches { - let symbol = &self.symbols[mat.candidate_id]; - let filter_start = symbol.label.filter_range.start; - for position in &mut mat.positions { - *position += filter_start; - } - } - - self.matches = matches; - self.set_selected_index(0, cx); - } -} - -impl PickerDelegate for ProjectSymbolsDelegate { - type ListItem = ListItem; - fn placeholder_text(&self) -> Arc { - "Search project symbols...".into() - } - - fn confirm(&mut self, secondary: bool, cx: &mut ViewContext>) { - if let Some(symbol) = self - .matches - .get(self.selected_match_index) - .map(|mat| self.symbols[mat.candidate_id].clone()) - { - let buffer = self.project.update(cx, |project, cx| { - project.open_buffer_for_symbol(&symbol, cx) - }); - let symbol = symbol.clone(); - let workspace = self.workspace.clone(); - cx.spawn(|_, mut cx| async move { - let buffer = buffer.await?; - workspace.update(&mut cx, |workspace, cx| { - let position = buffer - .read(cx) - .clip_point_utf16(symbol.range.start, Bias::Left); - - let editor = if secondary { - workspace.split_project_item::(buffer, cx) - } else { - workspace.open_project_item::(buffer, cx) - }; - - editor.update(cx, |editor, cx| { - editor.change_selections(Some(Autoscroll::center()), cx, |s| { - s.select_ranges([position..position]) - }); - }); - })?; - Ok::<_, anyhow::Error>(()) - }) - .detach_and_log_err(cx); - cx.emit(DismissEvent); - } - } - - fn dismissed(&mut self, _cx: &mut ViewContext>) {} - - fn match_count(&self) -> usize { - self.matches.len() - } - - fn selected_index(&self) -> usize { - self.selected_match_index - } - - fn set_selected_index(&mut self, ix: usize, _cx: &mut ViewContext>) { - self.selected_match_index = ix; - } - - fn update_matches(&mut self, query: String, cx: &mut ViewContext>) -> Task<()> { - self.filter(&query, cx); - self.show_worktree_root_name = self.project.read(cx).visible_worktrees(cx).count() > 1; - let symbols = self - .project - .update(cx, |project, cx| project.symbols(&query, cx)); - cx.spawn(|this, mut cx| async move { - let symbols = symbols.await.log_err(); - if let Some(symbols) = symbols { - this.update(&mut cx, |this, cx| { - let delegate = &mut this.delegate; - let project = delegate.project.read(cx); - let (visible_match_candidates, external_match_candidates) = symbols - .iter() - .enumerate() - .map(|(id, symbol)| { - StringMatchCandidate::new( - id, - symbol.label.text[symbol.label.filter_range.clone()].to_string(), - ) - }) - .partition(|candidate| { - project - .entry_for_path(&symbols[candidate.id].path, cx) - .map_or(false, |e| !e.is_ignored) - }); - - delegate.visible_match_candidates = visible_match_candidates; - delegate.external_match_candidates = external_match_candidates; - delegate.symbols = symbols; - delegate.filter(&query, cx); - }) - .log_err(); - } - }) - } - - fn render_match( - &self, - ix: usize, - selected: bool, - cx: &mut ViewContext>, - ) -> Option { - let string_match = &self.matches[ix]; - let symbol = &self.symbols[string_match.candidate_id]; - let syntax_runs = styled_runs_for_code_label(&symbol.label, cx.theme().syntax()); - - let mut path = symbol.path.path.to_string_lossy(); - if self.show_worktree_root_name { - let project = self.project.read(cx); - if let Some(worktree) = project.worktree_for_id(symbol.path.worktree_id, cx) { - path = Cow::Owned(format!( - "{}{}{}", - worktree.read(cx).root_name(), - std::path::MAIN_SEPARATOR, - path.as_ref() - )); - } - } - let label = symbol.label.text.clone(); - let path = path.to_string().clone(); - - let highlights = gpui::combine_highlights( - string_match - .positions - .iter() - .map(|pos| (*pos..pos + 1, FontWeight::BOLD.into())), - syntax_runs.map(|(range, mut highlight)| { - // Ignore font weight for syntax highlighting, as we'll use it - // for fuzzy matches. - highlight.font_weight = None; - (range, highlight) - }), - ); - - Some( - ListItem::new(ix) - .inset(true) - .spacing(ListItemSpacing::Sparse) - .selected(selected) - .child( - // todo!() combine_syntax_and_fuzzy_match_highlights() - v_stack() - .child( - LabelLike::new().child( - StyledText::new(label) - .with_highlights(&cx.text_style().clone(), highlights), - ), - ) - .child(Label::new(path).color(Color::Muted)), - ), - ) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use futures::StreamExt; - use gpui::{serde_json::json, TestAppContext, VisualContext}; - use language::{FakeLspAdapter, Language, LanguageConfig}; - use project::FakeFs; - use settings::SettingsStore; - use std::{path::Path, sync::Arc}; - - #[gpui::test] - async fn test_project_symbols(cx: &mut TestAppContext) { - init_test(cx); - - let mut language = Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - ..Default::default() - }, - None, - ); - let mut fake_servers = language - .set_fake_lsp_adapter(Arc::::default()) - .await; - - let fs = FakeFs::new(cx.executor()); - fs.insert_tree("/dir", json!({ "test.rs": "" })).await; - - let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; - project.update(cx, |project, _| project.languages().add(Arc::new(language))); - - let _buffer = project - .update(cx, |project, cx| { - project.open_local_buffer("/dir/test.rs", cx) - }) - .await - .unwrap(); - - // Set up fake language server to return fuzzy matches against - // a fixed set of symbol names. - let fake_symbols = [ - symbol("one", "/external"), - symbol("ton", "/dir/test.rs"), - symbol("uno", "/dir/test.rs"), - ]; - let fake_server = fake_servers.next().await.unwrap(); - fake_server.handle_request::( - move |params: lsp::WorkspaceSymbolParams, cx| { - let executor = cx.background_executor().clone(); - let fake_symbols = fake_symbols.clone(); - async move { - let candidates = fake_symbols - .iter() - .enumerate() - .map(|(id, symbol)| StringMatchCandidate::new(id, symbol.name.clone())) - .collect::>(); - let matches = if params.query.is_empty() { - Vec::new() - } else { - fuzzy::match_strings( - &candidates, - ¶ms.query, - true, - 100, - &Default::default(), - executor.clone(), - ) - .await - }; - - Ok(Some(lsp::WorkspaceSymbolResponse::Flat( - matches - .into_iter() - .map(|mat| fake_symbols[mat.candidate_id].clone()) - .collect(), - ))) - } - }, - ); - - let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); - - // Create the project symbols view. - let symbols = cx.new_view(|cx| { - Picker::new( - ProjectSymbolsDelegate::new(workspace.downgrade(), project.clone()), - cx, - ) - }); - - // Spawn multiples updates before the first update completes, - // such that in the end, there are no matches. Testing for regression: - // https://github.com/zed-industries/zed/issues/861 - symbols.update(cx, |p, cx| { - p.update_matches("o".to_string(), cx); - p.update_matches("on".to_string(), cx); - p.update_matches("onex".to_string(), cx); - }); - - cx.run_until_parked(); - symbols.update(cx, |symbols, _| { - assert_eq!(symbols.delegate.matches.len(), 0); - }); - - // Spawn more updates such that in the end, there are matches. - symbols.update(cx, |p, cx| { - p.update_matches("one".to_string(), cx); - p.update_matches("on".to_string(), cx); - }); - - cx.run_until_parked(); - symbols.update(cx, |symbols, _| { - let delegate = &symbols.delegate; - assert_eq!(delegate.matches.len(), 2); - assert_eq!(delegate.matches[0].string, "ton"); - assert_eq!(delegate.matches[1].string, "one"); - }); - - // Spawn more updates such that in the end, there are again no matches. - symbols.update(cx, |p, cx| { - p.update_matches("o".to_string(), cx); - p.update_matches("".to_string(), cx); - }); - - cx.run_until_parked(); - symbols.update(cx, |symbols, _| { - assert_eq!(symbols.delegate.matches.len(), 0); - }); - } - - fn init_test(cx: &mut TestAppContext) { - cx.update(|cx| { - let store = SettingsStore::test(cx); - cx.set_global(store); - theme::init(theme::LoadThemes::JustBase, cx); - language::init(cx); - Project::init_settings(cx); - workspace::init_settings(cx); - }); - } - - fn symbol(name: &str, path: impl AsRef) -> lsp::SymbolInformation { - #[allow(deprecated)] - lsp::SymbolInformation { - name: name.to_string(), - kind: lsp::SymbolKind::FUNCTION, - tags: None, - deprecated: None, - container_name: None, - location: lsp::Location::new( - lsp::Url::from_file_path(path.as_ref()).unwrap(), - lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 0)), - ), - } - } -} diff --git a/crates/theme_selector/Cargo.toml b/crates/theme_selector/Cargo.toml index fb3feb8d38..07fee474ef 100644 --- a/crates/theme_selector/Cargo.toml +++ b/crates/theme_selector/Cargo.toml @@ -9,21 +9,22 @@ path = "src/theme_selector.rs" doctest = false [dependencies] -client = { path = "../client" } -editor = { path = "../editor" } -fuzzy = { path = "../fuzzy" } -fs = { path = "../fs" } -gpui = { path = "../gpui" } -picker = { path = "../picker" } -theme = { path = "../theme" } -settings = { path = "../settings" } -feature_flags = { path = "../feature_flags" } -workspace = { path = "../workspace" } +client = { package = "client2", path = "../client2" } +editor = { package = "editor2", path = "../editor2" } +feature_flags = { package = "feature_flags2", path = "../feature_flags2" } +fs = { package = "fs2", path = "../fs2" } +fuzzy = { package = "fuzzy2", path = "../fuzzy2" } +gpui = { package = "gpui2", path = "../gpui2" } +picker = { package = "picker2", path = "../picker2" } +settings = { package = "settings2", path = "../settings2" } +theme = { package = "theme2", path = "../theme2" } +ui = { package = "ui2", path = "../ui2" } util = { path = "../util" } +workspace = { package = "workspace2", path = "../workspace2" } log.workspace = true parking_lot.workspace = true postage.workspace = true smol.workspace = true [dev-dependencies] -editor = { path = "../editor", features = ["test-support"] } +editor = { package = "editor2", path = "../editor2", features = ["test-support"] } diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 4495413061..44f2069694 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -2,35 +2,48 @@ use client::{telemetry::Telemetry, TelemetrySettings}; use feature_flags::FeatureFlagAppExt; use fs::Fs; use fuzzy::{match_strings, StringMatch, StringMatchCandidate}; -use gpui::{actions, elements::*, AnyElement, AppContext, Element, MouseState, ViewContext}; -use picker::{Picker, PickerDelegate, PickerEvent}; -use settings::{update_settings_file, SettingsStore}; +use gpui::{ + actions, AppContext, DismissEvent, EventEmitter, FocusableView, Render, View, ViewContext, + VisualContext, WeakView, +}; +use picker::{Picker, PickerDelegate}; +use settings::{update_settings_file, Settings, SettingsStore}; use std::sync::Arc; use theme::{Theme, ThemeMeta, ThemeRegistry, ThemeSettings}; +use ui::{prelude::*, v_stack, ListItem, ListItemSpacing}; use util::ResultExt; -use workspace::Workspace; +use workspace::{ui::HighlightedLabel, ModalView, Workspace}; actions!(theme_selector, [Toggle, Reload]); pub fn init(cx: &mut AppContext) { - cx.add_action(toggle); - ThemeSelector::init(cx); + cx.observe_new_views( + |workspace: &mut Workspace, _cx: &mut ViewContext| { + workspace.register_action(toggle); + }, + ) + .detach(); } pub fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { - workspace.toggle_modal(cx, |workspace, cx| { - let fs = workspace.app_state().fs.clone(); - let telemetry = workspace.client().telemetry().clone(); - cx.add_view(|cx| ThemeSelector::new(ThemeSelectorDelegate::new(fs, telemetry, cx), cx)) + let fs = workspace.app_state().fs.clone(); + let telemetry = workspace.client().telemetry().clone(); + workspace.toggle_modal(cx, |cx| { + ThemeSelector::new( + ThemeSelectorDelegate::new(cx.view().downgrade(), fs, telemetry, cx), + cx, + ) }); } #[cfg(debug_assertions)] pub fn reload(cx: &mut AppContext) { - let current_theme_name = theme::current(cx).meta.name.clone(); - let registry = cx.global::>(); - registry.clear(); - match registry.get(¤t_theme_name) { + let current_theme_name = cx.theme().name.clone(); + let current_theme = cx.update_global(|registry: &mut ThemeRegistry, _cx| { + registry.clear(); + registry.get(¤t_theme_name) + }); + match current_theme { Ok(theme) => { ThemeSelectorDelegate::set_theme(theme, cx); log::info!("reloaded theme {}", current_theme_name); @@ -41,55 +54,88 @@ pub fn reload(cx: &mut AppContext) { } } -pub type ThemeSelector = Picker; +impl ModalView for ThemeSelector {} + +pub struct ThemeSelector { + picker: View>, +} + +impl EventEmitter for ThemeSelector {} + +impl FocusableView for ThemeSelector { + fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle { + self.picker.focus_handle(cx) + } +} + +impl Render for ThemeSelector { + fn render(&mut self, _cx: &mut ViewContext) -> impl IntoElement { + v_stack().w(rems(34.)).child(self.picker.clone()) + } +} + +impl ThemeSelector { + pub fn new(delegate: ThemeSelectorDelegate, cx: &mut ViewContext) -> Self { + let picker = cx.new_view(|cx| Picker::new(delegate, cx)); + Self { picker } + } +} pub struct ThemeSelectorDelegate { fs: Arc, - theme_data: Vec, + themes: Vec, matches: Vec, original_theme: Arc, selection_completed: bool, selected_index: usize, telemetry: Arc, + view: WeakView, } impl ThemeSelectorDelegate { fn new( + weak_view: WeakView, fs: Arc, telemetry: Arc, cx: &mut ViewContext, ) -> Self { - let original_theme = theme::current(cx).clone(); + let original_theme = cx.theme().clone(); let staff_mode = cx.is_staff(); - let registry = cx.global::>(); - let mut theme_names = registry.list(staff_mode).collect::>(); - theme_names.sort_unstable_by(|a, b| a.is_light.cmp(&b.is_light).then(a.name.cmp(&b.name))); - let matches = theme_names + let registry = cx.global::(); + let mut themes = registry.list(staff_mode).collect::>(); + themes.sort_unstable_by(|a, b| { + a.appearance + .is_light() + .cmp(&b.appearance.is_light()) + .then(a.name.cmp(&b.name)) + }); + let matches = themes .iter() .map(|meta| StringMatch { candidate_id: 0, score: 0.0, positions: Default::default(), - string: meta.name.clone(), + string: meta.name.to_string(), }) .collect(); let mut this = Self { fs, - theme_data: theme_names, + themes, matches, original_theme: original_theme.clone(), selected_index: 0, selection_completed: false, telemetry, + view: weak_view, }; - this.select_if_matching(&original_theme.meta.name); + this.select_if_matching(&original_theme.name); this } - fn show_selected_theme(&mut self, cx: &mut ViewContext) { + fn show_selected_theme(&mut self, cx: &mut ViewContext>) { if let Some(mat) = self.matches.get(self.selected_index) { - let registry = cx.global::>(); + let registry = cx.global::(); match registry.get(&mat.string) { Ok(theme) => { Self::set_theme(theme, cx); @@ -110,16 +156,18 @@ impl ThemeSelectorDelegate { } fn set_theme(theme: Arc, cx: &mut AppContext) { - cx.update_global::(|store, cx| { + cx.update_global(|store: &mut SettingsStore, cx| { let mut theme_settings = store.get::(None).clone(); - theme_settings.theme = theme; + theme_settings.active_theme = theme; store.override_global(theme_settings); - cx.refresh_windows(); + cx.refresh(); }); } } impl PickerDelegate for ThemeSelectorDelegate { + type ListItem = ui::ListItem; + fn placeholder_text(&self) -> Arc { "Select Theme...".into() } @@ -128,34 +176,46 @@ impl PickerDelegate for ThemeSelectorDelegate { self.matches.len() } - fn confirm(&mut self, _: bool, cx: &mut ViewContext) { + fn confirm(&mut self, _: bool, cx: &mut ViewContext>) { self.selection_completed = true; - let theme_name = theme::current(cx).meta.name.clone(); + let theme_name = cx.theme().name.clone(); - let telemetry_settings = *settings::get::(cx); + let telemetry_settings = TelemetrySettings::get_global(cx).clone(); self.telemetry .report_setting_event(telemetry_settings, "theme", theme_name.to_string()); - update_settings_file::(self.fs.clone(), cx, |settings| { - settings.theme = Some(theme_name); + update_settings_file::(self.fs.clone(), cx, move |settings| { + settings.theme = Some(theme_name.to_string()); }); - cx.emit(PickerEvent::Dismiss); + self.view + .update(cx, |_, cx| { + cx.emit(DismissEvent); + }) + .ok(); } - fn dismissed(&mut self, cx: &mut ViewContext) { + fn dismissed(&mut self, cx: &mut ViewContext>) { if !self.selection_completed { Self::set_theme(self.original_theme.clone(), cx); self.selection_completed = true; } + + self.view + .update(cx, |_, cx| cx.emit(DismissEvent)) + .log_err(); } fn selected_index(&self) -> usize { self.selected_index } - fn set_selected_index(&mut self, ix: usize, cx: &mut ViewContext) { + fn set_selected_index( + &mut self, + ix: usize, + cx: &mut ViewContext>, + ) { self.selected_index = ix; self.show_selected_theme(cx); } @@ -163,17 +223,17 @@ impl PickerDelegate for ThemeSelectorDelegate { fn update_matches( &mut self, query: String, - cx: &mut ViewContext, + cx: &mut ViewContext>, ) -> gpui::Task<()> { - let background = cx.background().clone(); + let background = cx.background_executor().clone(); let candidates = self - .theme_data + .themes .iter() .enumerate() .map(|(id, meta)| StringMatchCandidate { id, - char_bag: meta.name.as_str().into(), - string: meta.name.clone(), + char_bag: meta.name.as_ref().into(), + string: meta.name.to_string(), }) .collect::>(); @@ -202,12 +262,12 @@ impl PickerDelegate for ThemeSelectorDelegate { }; this.update(&mut cx, |this, cx| { - let delegate = this.delegate_mut(); - delegate.matches = matches; - delegate.selected_index = delegate + this.delegate.matches = matches; + this.delegate.selected_index = this + .delegate .selected_index - .min(delegate.matches.len().saturating_sub(1)); - delegate.show_selected_theme(cx); + .min(this.delegate.matches.len().saturating_sub(1)); + this.delegate.show_selected_theme(cx); }) .log_err(); }) @@ -216,18 +276,20 @@ impl PickerDelegate for ThemeSelectorDelegate { fn render_match( &self, ix: usize, - mouse_state: &mut MouseState, selected: bool, - cx: &AppContext, - ) -> AnyElement> { - let theme = theme::current(cx); - let style = theme.picker.item.in_state(selected).style_for(mouse_state); - + _cx: &mut ViewContext>, + ) -> Option { let theme_match = &self.matches[ix]; - Label::new(theme_match.string.clone(), style.label.clone()) - .with_highlights(theme_match.positions.clone()) - .contained() - .with_style(style.container) - .into_any() + + Some( + ListItem::new(ix) + .inset(true) + .spacing(ListItemSpacing::Sparse) + .selected(selected) + .child(HighlightedLabel::new( + theme_match.string.clone(), + theme_match.positions.clone(), + )), + ) } } diff --git a/crates/theme_selector2/Cargo.toml b/crates/theme_selector2/Cargo.toml deleted file mode 100644 index da9e3a4d16..0000000000 --- a/crates/theme_selector2/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "theme_selector2" -version = "0.1.0" -edition = "2021" -publish = false - -[lib] -path = "src/theme_selector.rs" -doctest = false - -[dependencies] -client = { package = "client2", path = "../client2" } -editor = { package = "editor2", path = "../editor2" } -feature_flags = { package = "feature_flags2", path = "../feature_flags2" } -fs = { package = "fs2", path = "../fs2" } -fuzzy = { package = "fuzzy2", path = "../fuzzy2" } -gpui = { package = "gpui2", path = "../gpui2" } -picker = { package = "picker2", path = "../picker2" } -settings = { package = "settings2", path = "../settings2" } -theme = { package = "theme2", path = "../theme2" } -ui = { package = "ui2", path = "../ui2" } -util = { path = "../util" } -workspace = { package = "workspace2", path = "../workspace2" } -log.workspace = true -parking_lot.workspace = true -postage.workspace = true -smol.workspace = true - -[dev-dependencies] -editor = { package = "editor2", path = "../editor2", features = ["test-support"] } diff --git a/crates/theme_selector2/src/theme_selector.rs b/crates/theme_selector2/src/theme_selector.rs deleted file mode 100644 index 44f2069694..0000000000 --- a/crates/theme_selector2/src/theme_selector.rs +++ /dev/null @@ -1,295 +0,0 @@ -use client::{telemetry::Telemetry, TelemetrySettings}; -use feature_flags::FeatureFlagAppExt; -use fs::Fs; -use fuzzy::{match_strings, StringMatch, StringMatchCandidate}; -use gpui::{ - actions, AppContext, DismissEvent, EventEmitter, FocusableView, Render, View, ViewContext, - VisualContext, WeakView, -}; -use picker::{Picker, PickerDelegate}; -use settings::{update_settings_file, Settings, SettingsStore}; -use std::sync::Arc; -use theme::{Theme, ThemeMeta, ThemeRegistry, ThemeSettings}; -use ui::{prelude::*, v_stack, ListItem, ListItemSpacing}; -use util::ResultExt; -use workspace::{ui::HighlightedLabel, ModalView, Workspace}; - -actions!(theme_selector, [Toggle, Reload]); - -pub fn init(cx: &mut AppContext) { - cx.observe_new_views( - |workspace: &mut Workspace, _cx: &mut ViewContext| { - workspace.register_action(toggle); - }, - ) - .detach(); -} - -pub fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { - let fs = workspace.app_state().fs.clone(); - let telemetry = workspace.client().telemetry().clone(); - workspace.toggle_modal(cx, |cx| { - ThemeSelector::new( - ThemeSelectorDelegate::new(cx.view().downgrade(), fs, telemetry, cx), - cx, - ) - }); -} - -#[cfg(debug_assertions)] -pub fn reload(cx: &mut AppContext) { - let current_theme_name = cx.theme().name.clone(); - let current_theme = cx.update_global(|registry: &mut ThemeRegistry, _cx| { - registry.clear(); - registry.get(¤t_theme_name) - }); - match current_theme { - Ok(theme) => { - ThemeSelectorDelegate::set_theme(theme, cx); - log::info!("reloaded theme {}", current_theme_name); - } - Err(error) => { - log::error!("failed to load theme {}: {:?}", current_theme_name, error) - } - } -} - -impl ModalView for ThemeSelector {} - -pub struct ThemeSelector { - picker: View>, -} - -impl EventEmitter for ThemeSelector {} - -impl FocusableView for ThemeSelector { - fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle { - self.picker.focus_handle(cx) - } -} - -impl Render for ThemeSelector { - fn render(&mut self, _cx: &mut ViewContext) -> impl IntoElement { - v_stack().w(rems(34.)).child(self.picker.clone()) - } -} - -impl ThemeSelector { - pub fn new(delegate: ThemeSelectorDelegate, cx: &mut ViewContext) -> Self { - let picker = cx.new_view(|cx| Picker::new(delegate, cx)); - Self { picker } - } -} - -pub struct ThemeSelectorDelegate { - fs: Arc, - themes: Vec, - matches: Vec, - original_theme: Arc, - selection_completed: bool, - selected_index: usize, - telemetry: Arc, - view: WeakView, -} - -impl ThemeSelectorDelegate { - fn new( - weak_view: WeakView, - fs: Arc, - telemetry: Arc, - cx: &mut ViewContext, - ) -> Self { - let original_theme = cx.theme().clone(); - - let staff_mode = cx.is_staff(); - let registry = cx.global::(); - let mut themes = registry.list(staff_mode).collect::>(); - themes.sort_unstable_by(|a, b| { - a.appearance - .is_light() - .cmp(&b.appearance.is_light()) - .then(a.name.cmp(&b.name)) - }); - let matches = themes - .iter() - .map(|meta| StringMatch { - candidate_id: 0, - score: 0.0, - positions: Default::default(), - string: meta.name.to_string(), - }) - .collect(); - let mut this = Self { - fs, - themes, - matches, - original_theme: original_theme.clone(), - selected_index: 0, - selection_completed: false, - telemetry, - view: weak_view, - }; - this.select_if_matching(&original_theme.name); - this - } - - fn show_selected_theme(&mut self, cx: &mut ViewContext>) { - if let Some(mat) = self.matches.get(self.selected_index) { - let registry = cx.global::(); - match registry.get(&mat.string) { - Ok(theme) => { - Self::set_theme(theme, cx); - } - Err(error) => { - log::error!("error loading theme {}: {}", mat.string, error) - } - } - } - } - - fn select_if_matching(&mut self, theme_name: &str) { - self.selected_index = self - .matches - .iter() - .position(|mat| mat.string == theme_name) - .unwrap_or(self.selected_index); - } - - fn set_theme(theme: Arc, cx: &mut AppContext) { - cx.update_global(|store: &mut SettingsStore, cx| { - let mut theme_settings = store.get::(None).clone(); - theme_settings.active_theme = theme; - store.override_global(theme_settings); - cx.refresh(); - }); - } -} - -impl PickerDelegate for ThemeSelectorDelegate { - type ListItem = ui::ListItem; - - fn placeholder_text(&self) -> Arc { - "Select Theme...".into() - } - - fn match_count(&self) -> usize { - self.matches.len() - } - - fn confirm(&mut self, _: bool, cx: &mut ViewContext>) { - self.selection_completed = true; - - let theme_name = cx.theme().name.clone(); - - let telemetry_settings = TelemetrySettings::get_global(cx).clone(); - self.telemetry - .report_setting_event(telemetry_settings, "theme", theme_name.to_string()); - - update_settings_file::(self.fs.clone(), cx, move |settings| { - settings.theme = Some(theme_name.to_string()); - }); - - self.view - .update(cx, |_, cx| { - cx.emit(DismissEvent); - }) - .ok(); - } - - fn dismissed(&mut self, cx: &mut ViewContext>) { - if !self.selection_completed { - Self::set_theme(self.original_theme.clone(), cx); - self.selection_completed = true; - } - - self.view - .update(cx, |_, cx| cx.emit(DismissEvent)) - .log_err(); - } - - fn selected_index(&self) -> usize { - self.selected_index - } - - fn set_selected_index( - &mut self, - ix: usize, - cx: &mut ViewContext>, - ) { - self.selected_index = ix; - self.show_selected_theme(cx); - } - - fn update_matches( - &mut self, - query: String, - cx: &mut ViewContext>, - ) -> gpui::Task<()> { - let background = cx.background_executor().clone(); - let candidates = self - .themes - .iter() - .enumerate() - .map(|(id, meta)| StringMatchCandidate { - id, - char_bag: meta.name.as_ref().into(), - string: meta.name.to_string(), - }) - .collect::>(); - - cx.spawn(|this, mut cx| async move { - let matches = if query.is_empty() { - candidates - .into_iter() - .enumerate() - .map(|(index, candidate)| StringMatch { - candidate_id: index, - string: candidate.string, - positions: Vec::new(), - score: 0.0, - }) - .collect() - } else { - match_strings( - &candidates, - &query, - false, - 100, - &Default::default(), - background, - ) - .await - }; - - this.update(&mut cx, |this, cx| { - this.delegate.matches = matches; - this.delegate.selected_index = this - .delegate - .selected_index - .min(this.delegate.matches.len().saturating_sub(1)); - this.delegate.show_selected_theme(cx); - }) - .log_err(); - }) - } - - fn render_match( - &self, - ix: usize, - selected: bool, - _cx: &mut ViewContext>, - ) -> Option { - let theme_match = &self.matches[ix]; - - Some( - ListItem::new(ix) - .inset(true) - .spacing(ListItemSpacing::Sparse) - .selected(selected) - .child(HighlightedLabel::new( - theme_match.string.clone(), - theme_match.positions.clone(), - )), - ) - } -} diff --git a/crates/welcome/Cargo.toml b/crates/welcome/Cargo.toml index c57689a916..15d7307775 100644 --- a/crates/welcome/Cargo.toml +++ b/crates/welcome/Cargo.toml @@ -22,7 +22,7 @@ install_cli = { package = "install_cli2", path = "../install_cli2" } project = { package = "project2", path = "../project2" } settings = { package = "settings2", path = "../settings2" } theme = { package = "theme2", path = "../theme2" } -theme_selector = { package = "theme_selector2", path = "../theme_selector2" } +theme_selector = { path = "../theme_selector" } util = { path = "../util" } picker = { package = "picker2", path = "../picker2" } workspace = { package = "workspace2", path = "../workspace2" } diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 1e4804d1c8..62687ec83c 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -55,7 +55,7 @@ outline = { package = "outline2", path = "../outline2" } # plugin_runtime = { path = "../plugin_runtime",optional = true } project = { package = "project2", path = "../project2" } project_panel = { package = "project_panel2", path = "../project_panel2" } -project_symbols = { package = "project_symbols2", path = "../project_symbols2" } +project_symbols = { path = "../project_symbols" } quick_action_bar = { path = "../quick_action_bar" } recent_projects = { package = "recent_projects2", path = "../recent_projects2" } rope = { package = "rope2", path = "../rope2"} @@ -67,7 +67,7 @@ shellexpand = "2.1.0" text = { package = "text2", path = "../text2" } terminal_view = { package = "terminal_view2", path = "../terminal_view2" } theme = { package = "theme2", path = "../theme2" } -theme_selector = { package = "theme_selector2", path = "../theme_selector2" } +theme_selector = { path = "../theme_selector" } util = { path = "../util" } semantic_index = { package = "semantic_index2", path = "../semantic_index2" } vim = { package = "vim2", path = "../vim2" }