From cfc050e3fe2cd795941e50a246006834af372fc3 Mon Sep 17 00:00:00 2001 From: Julia Date: Wed, 13 Dec 2023 12:16:39 -0500 Subject: [PATCH 001/644] Fire focus handlers on draw to avoid timing with newly created item Co-Authored-By: Antonio Scandurra --- crates/gpui2/src/app.rs | 68 ++------------- crates/gpui2/src/elements/div.rs | 13 +-- crates/gpui2/src/interactive.rs | 8 +- crates/gpui2/src/key_dispatch.rs | 20 ++++- crates/gpui2/src/window.rs | 137 ++++++++++++------------------- 5 files changed, 84 insertions(+), 162 deletions(-) diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 62ce6305ea7303362a5b6fb8889e63e18ca3fd68..9b9a5921e17dca7fa3c22571ca6f6f0fdc9e5c55 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -17,11 +17,10 @@ use time::UtcOffset; use crate::{ current_platform, image_cache::ImageCache, init_app_menus, Action, ActionRegistry, Any, AnyView, AnyWindowHandle, AppMetadata, AssetSource, BackgroundExecutor, ClipboardItem, Context, - DispatchPhase, DisplayId, Entity, EventEmitter, FocusEvent, FocusHandle, FocusId, - ForegroundExecutor, KeyBinding, Keymap, Keystroke, LayoutId, Menu, PathPromptOptions, Pixels, - Platform, PlatformDisplay, Point, Render, SharedString, SubscriberSet, Subscription, - SvgRenderer, Task, TextStyle, TextStyleRefinement, TextSystem, View, ViewContext, Window, - WindowContext, WindowHandle, WindowId, + DispatchPhase, DisplayId, Entity, EventEmitter, ForegroundExecutor, KeyBinding, Keymap, + Keystroke, LayoutId, Menu, PathPromptOptions, Pixels, Platform, PlatformDisplay, Point, Render, + SharedString, SubscriberSet, Subscription, SvgRenderer, Task, TextStyle, TextStyleRefinement, + TextSystem, View, ViewContext, Window, WindowContext, WindowHandle, WindowId, }; use anyhow::{anyhow, Result}; use collections::{FxHashMap, FxHashSet, VecDeque}; @@ -577,23 +576,21 @@ impl AppContext { Effect::Notify { emitter } => { self.apply_notify_effect(emitter); } + Effect::Emit { emitter, event_type, event, } => self.apply_emit_effect(emitter, event_type, event), - Effect::FocusChanged { - window_handle, - focused, - } => { - self.apply_focus_changed_effect(window_handle, focused); - } + Effect::Refresh => { self.apply_refresh_effect(); } + Effect::NotifyGlobalObservers { global_type } => { self.apply_notify_global_observers_effect(global_type); } + Effect::Defer { callback } => { self.apply_defer_effect(callback); } @@ -693,51 +690,6 @@ impl AppContext { }); } - fn apply_focus_changed_effect( - &mut self, - window_handle: AnyWindowHandle, - focused: Option, - ) { - window_handle - .update(self, |_, cx| { - // The window might change focus multiple times in an effect cycle. - // We only honor effects for the most recently focused handle. - if cx.window.focus == focused { - // if someone calls focus multiple times in one frame with the same handle - // the first apply_focus_changed_effect will have taken the last blur already - // and run the rest of this, so we can return. - let Some(last_blur) = cx.window.last_blur.take() else { - return; - }; - - let focused = focused - .map(|id| FocusHandle::for_id(id, &cx.window.focus_handles).unwrap()); - - let blurred = - last_blur.and_then(|id| FocusHandle::for_id(id, &cx.window.focus_handles)); - - let focus_changed = focused.is_some() || blurred.is_some(); - let event = FocusEvent { focused, blurred }; - - let mut listeners = mem::take(&mut cx.window.rendered_frame.focus_listeners); - if focus_changed { - for listener in &mut listeners { - listener(&event, cx); - } - } - cx.window.rendered_frame.focus_listeners = listeners; - - if focus_changed { - cx.window - .focus_listeners - .clone() - .retain(&(), |listener| listener(&event, cx)); - } - } - }) - .ok(); - } - fn apply_refresh_effect(&mut self) { for window in self.windows.values_mut() { if let Some(window) = window.as_mut() { @@ -1246,10 +1198,6 @@ pub(crate) enum Effect { event_type: TypeId, event: Box, }, - FocusChanged { - window_handle: AnyWindowHandle, - focused: Option, - }, Refresh, NotifyGlobalObservers { global_type: TypeId, diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index a102c71a6fbc1d8d0dbc0b2d984efcbdbc677276..3ec0a46fcbfbe9caf0bd371741026a18a1345017 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1,10 +1,9 @@ use crate::{ point, px, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, BorrowAppContext, - BorrowWindow, Bounds, ClickEvent, DispatchPhase, Element, ElementId, FocusEvent, FocusHandle, - IntoElement, KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, MouseButton, MouseDownEvent, - MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, Render, ScrollWheelEvent, - SharedString, Size, StackingOrder, Style, StyleRefinement, Styled, Task, View, Visibility, - WindowContext, + BorrowWindow, Bounds, ClickEvent, DispatchPhase, Element, ElementId, FocusHandle, IntoElement, + KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, MouseButton, MouseDownEvent, MouseMoveEvent, + MouseUpEvent, ParentElement, Pixels, Point, Render, ScrollWheelEvent, SharedString, Size, + StackingOrder, Style, StyleRefinement, Styled, Task, View, Visibility, WindowContext, }; use collections::HashMap; use refineable::Refineable; @@ -462,10 +461,6 @@ pub trait FocusableElement: InteractiveElement { } } -pub type FocusListeners = Vec; - -pub type FocusListener = Box; - pub type MouseDownListener = Box; pub type MouseUpListener = diff --git a/crates/gpui2/src/interactive.rs b/crates/gpui2/src/interactive.rs index 1c6955111cd2f31870ff92fb2dfeff11db4b02ef..58ee849aad4a6d665c6ec14176f72eb457c9a82e 100644 --- a/crates/gpui2/src/interactive.rs +++ b/crates/gpui2/src/interactive.rs @@ -1,6 +1,5 @@ use crate::{ - div, point, Div, Element, FocusHandle, IntoElement, Keystroke, Modifiers, Pixels, Point, - Render, ViewContext, + div, point, Div, Element, IntoElement, Keystroke, Modifiers, Pixels, Point, Render, ViewContext, }; use smallvec::SmallVec; use std::{any::Any, fmt::Debug, marker::PhantomData, ops::Deref, path::PathBuf}; @@ -290,11 +289,6 @@ impl InputEvent { } } -pub struct FocusEvent { - pub blurred: Option, - pub focused: Option, -} - #[cfg(test)] mod test { use crate::{ diff --git a/crates/gpui2/src/key_dispatch.rs b/crates/gpui2/src/key_dispatch.rs index a44987aa39e65ecbabacbca40868fc27d61a3b49..ddb1f1e6ca8b4fd4db5d9c317144ca302519aa87 100644 --- a/crates/gpui2/src/key_dispatch.rs +++ b/crates/gpui2/src/key_dispatch.rs @@ -29,6 +29,7 @@ pub(crate) struct DispatchNode { pub key_listeners: Vec, pub action_listeners: Vec, pub context: Option, + focus_id: Option, parent: Option, } @@ -127,8 +128,9 @@ impl DispatchTree { } pub fn make_focusable(&mut self, focus_id: FocusId) { - self.focusable_node_ids - .insert(focus_id, self.active_node_id()); + let node_id = self.active_node_id(); + self.active_node().focus_id = Some(focus_id); + self.focusable_node_ids.insert(focus_id, node_id); } pub fn focus_contains(&self, parent: FocusId, child: FocusId) -> bool { @@ -247,6 +249,20 @@ impl DispatchTree { dispatch_path } + pub fn focus_path(&self, focus_id: FocusId) -> SmallVec<[FocusId; 8]> { + let mut focus_path: SmallVec<[FocusId; 8]> = SmallVec::new(); + let mut current_node_id = self.focusable_node_ids.get(&focus_id).copied(); + while let Some(node_id) = current_node_id { + let node = self.node(node_id); + if let Some(focus_id) = node.focus_id { + focus_path.push(focus_id); + } + current_node_id = node.parent; + } + focus_path.reverse(); // Reverse the path so it goes from the root to the focused node. + focus_path + } + pub fn node(&self, node_id: DispatchNodeId) -> &DispatchNode { &self.nodes[node_id.0] } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 77eb4e27be20bd734c27258a00fd05eaeff35caf..d2f48917112f5eda16c8a9a8a684bf47b036da09 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -2,10 +2,10 @@ use crate::{ key_dispatch::DispatchActionListener, px, size, Action, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle, DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, - EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla, - ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent, LayoutId, - Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent, - Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, + EventEmitter, FileDropEvent, Flatten, FontId, GlobalElementId, GlyphId, Hsla, ImageData, + InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent, LayoutId, Model, + ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent, Path, + Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, Scene, SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, @@ -74,9 +74,13 @@ impl DispatchPhase { type AnyObserver = Box bool + 'static>; type AnyMouseListener = Box; -type AnyFocusListener = Box; type AnyWindowFocusListener = Box bool + 'static>; +struct FocusEvent { + previous_focus_path: SmallVec<[FocusId; 8]>, + current_focus_path: SmallVec<[FocusId; 8]>, +} + slotmap::new_key_type! { pub struct FocusId; } impl FocusId { @@ -227,8 +231,8 @@ pub struct Window { pub(crate) rendered_frame: Frame, pub(crate) next_frame: Frame, pub(crate) focus_handles: Arc>>, - pub(crate) focus_listeners: SubscriberSet<(), AnyWindowFocusListener>, - pub(crate) blur_listeners: SubscriberSet<(), AnyObserver>, + focus_listeners: SubscriberSet<(), AnyWindowFocusListener>, + blur_listeners: SubscriberSet<(), AnyObserver>, default_prevented: bool, mouse_position: Point, requested_cursor_style: Option, @@ -238,7 +242,6 @@ pub struct Window { active: bool, pub(crate) dirty: bool, activation_observers: SubscriberSet<(), AnyObserver>, - pub(crate) last_blur: Option>, pub(crate) focus: Option, } @@ -250,10 +253,10 @@ pub(crate) struct ElementStateBox { // #[derive(Default)] pub(crate) struct Frame { + focus: Option, pub(crate) element_states: HashMap, mouse_listeners: HashMap>, pub(crate) dispatch_tree: DispatchTree, - pub(crate) focus_listeners: Vec, pub(crate) scene_builder: SceneBuilder, pub(crate) depth_map: Vec<(StackingOrder, Bounds)>, pub(crate) z_index_stack: StackingOrder, @@ -264,10 +267,10 @@ pub(crate) struct Frame { impl Frame { fn new(dispatch_tree: DispatchTree) -> Self { Frame { + focus: None, element_states: HashMap::default(), mouse_listeners: HashMap::default(), dispatch_tree, - focus_listeners: Vec::new(), scene_builder: SceneBuilder::default(), z_index_stack: StackingOrder::default(), depth_map: Default::default(), @@ -279,10 +282,15 @@ impl Frame { fn clear(&mut self) { self.element_states.clear(); self.mouse_listeners.values_mut().for_each(Vec::clear); - self.focus_listeners.clear(); self.dispatch_tree.clear(); self.depth_map.clear(); } + + fn focus_path(&self) -> SmallVec<[FocusId; 8]> { + self.focus + .map(|focus_id| self.dispatch_tree.focus_path(focus_id)) + .unwrap_or_default() + } } impl Window { @@ -372,7 +380,6 @@ impl Window { active: false, dirty: false, activation_observers: SubscriberSet::new(), - last_blur: None, focus: None, } } @@ -449,35 +456,17 @@ impl<'a> WindowContext<'a> { return; } - let focus_id = handle.id; - - if self.window.last_blur.is_none() { - self.window.last_blur = Some(self.window.focus); - } - - self.window.focus = Some(focus_id); + self.window.focus = Some(handle.id); self.window .rendered_frame .dispatch_tree .clear_pending_keystrokes(); - self.app.push_effect(Effect::FocusChanged { - window_handle: self.window.handle, - focused: Some(focus_id), - }); self.notify(); } /// Remove focus from all elements within this context's window. pub fn blur(&mut self) { - if self.window.last_blur.is_none() { - self.window.last_blur = Some(self.window.focus); - } - self.window.focus = None; - self.app.push_effect(Effect::FocusChanged { - window_handle: self.window.handle, - focused: None, - }); self.notify(); } @@ -1236,16 +1225,6 @@ impl<'a> WindowContext<'a> { /// Draw pixels to the display for this window based on the contents of its scene. pub(crate) fn draw(&mut self) -> Scene { - let window_was_focused = self - .window - .focus - .and_then(|focus_id| { - self.window - .rendered_frame - .dispatch_tree - .focusable_node_id(focus_id) - }) - .is_some(); self.text_system().start_frame(); self.window.platform_window.clear_input_handler(); self.window.layout_engine.as_mut().unwrap().clear(); @@ -1284,23 +1263,6 @@ impl<'a> WindowContext<'a> { }); } - let window_is_focused = self - .window - .focus - .and_then(|focus_id| { - self.window - .next_frame - .dispatch_tree - .focusable_node_id(focus_id) - }) - .is_some(); - if window_was_focused && !window_is_focused { - self.window - .blur_listeners - .clone() - .retain(&(), |listener| listener(self)); - } - self.window .next_frame .dispatch_tree @@ -1308,11 +1270,34 @@ impl<'a> WindowContext<'a> { &mut self.window.rendered_frame.dispatch_tree, self.window.focus, ); + self.window.next_frame.focus = self.window.focus; self.window.root_view = Some(root_view); + let previous_focus_path = self.window.rendered_frame.focus_path(); + let window = &mut self.window; mem::swap(&mut window.rendered_frame, &mut window.next_frame); + let current_focus_path = self.window.rendered_frame.focus_path(); + + if previous_focus_path != current_focus_path { + if !previous_focus_path.is_empty() && current_focus_path.is_empty() { + self.window + .blur_listeners + .clone() + .retain(&(), |listener| listener(self)); + } + + let event = FocusEvent { + previous_focus_path, + current_focus_path, + }; + self.window + .focus_listeners + .clone() + .retain(&(), |listener| listener(&event, self)); + } + let scene = self.window.rendered_frame.scene_builder.build(); // Set the cursor only if we're the active window. @@ -1699,22 +1684,6 @@ impl<'a> WindowContext<'a> { result } - /// Register a focus listener for the next frame only. It will be cleared - /// on the next frame render. You should use this method only from within elements, - /// and we may want to enforce that better via a different context type. - // todo!() Move this to `FrameContext` to emphasize its individuality? - pub fn on_focus_changed( - &mut self, - listener: impl Fn(&FocusEvent, &mut WindowContext) + 'static, - ) { - self.window - .next_frame - .focus_listeners - .push(Box::new(move |event, cx| { - listener(event, cx); - })); - } - /// Set an input handler, such as [ElementInputHandler], which interfaces with the /// platform to receive textual input with proper integration with concerns such /// as IME interactions. @@ -2389,7 +2358,9 @@ impl<'a, V: 'static> ViewContext<'a, V> { (), Box::new(move |event, cx| { view.update(cx, |view, cx| { - if event.focused.as_ref().map(|focused| focused.id) == Some(focus_id) { + if event.previous_focus_path.last() != Some(&focus_id) + && event.current_focus_path.last() == Some(&focus_id) + { listener(view, cx) } }) @@ -2414,10 +2385,8 @@ impl<'a, V: 'static> ViewContext<'a, V> { (), Box::new(move |event, cx| { view.update(cx, |view, cx| { - if event - .focused - .as_ref() - .map_or(false, |focused| focus_id.contains(focused.id, cx)) + if !event.previous_focus_path.contains(&focus_id) + && event.current_focus_path.contains(&focus_id) { listener(view, cx) } @@ -2443,7 +2412,9 @@ impl<'a, V: 'static> ViewContext<'a, V> { (), Box::new(move |event, cx| { view.update(cx, |view, cx| { - if event.blurred.as_ref().map(|blurred| blurred.id) == Some(focus_id) { + if event.previous_focus_path.last() == Some(&focus_id) + && event.current_focus_path.last() != Some(&focus_id) + { listener(view, cx) } }) @@ -2484,10 +2455,8 @@ impl<'a, V: 'static> ViewContext<'a, V> { (), Box::new(move |event, cx| { view.update(cx, |view, cx| { - if event - .blurred - .as_ref() - .map_or(false, |blurred| focus_id.contains(blurred.id, cx)) + if event.previous_focus_path.contains(&focus_id) + && !event.current_focus_path.contains(&focus_id) { listener(view, cx) } From 0e19da3107657fcdda07aa7145611a1f762dd126 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:53:53 +0100 Subject: [PATCH 002/644] Bring back semantic search UI --- crates/search2/src/project_search.rs | 340 ++++++++++----------------- 1 file changed, 128 insertions(+), 212 deletions(-) diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index 34cd2b98149d74d6064b0abc50c7e938ed1c82a4..875d2fe095a73495144182e14e5e4e4dd9959582 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -1,7 +1,8 @@ use crate::{ - history::SearchHistory, mode::SearchMode, ActivateRegexMode, ActivateTextMode, CycleMode, - NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext, SearchOptions, - SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleReplace, ToggleWholeWord, + history::SearchHistory, mode::SearchMode, ActivateRegexMode, ActivateSemanticMode, + ActivateTextMode, CycleMode, NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext, + SearchOptions, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleReplace, + ToggleWholeWord, }; use anyhow::{Context as _, Result}; use collections::HashMap; @@ -29,7 +30,7 @@ use std::{ mem, ops::{Not, Range}, path::PathBuf, - time::Duration, + time::{Duration, Instant}, }; use ui::{ @@ -283,196 +284,86 @@ impl Render for ProjectSearchView { let model = self.model.read(cx); let has_no_results = model.no_results.unwrap_or(false); let is_search_underway = model.pending_search.is_some(); - let major_text = if is_search_underway { + let mut major_text = if is_search_underway { Label::new("Searching...") } else if has_no_results { - Label::new("No results for a given query") + Label::new("No results") } else { Label::new(format!("{} search all files", self.current_mode.label())) }; + + let mut show_minor_text = true; + let semantic_status = self.semantic_state.as_ref().and_then(|semantic| { + let status = semantic.index_status; + match status { + SemanticIndexStatus::NotAuthenticated => { + major_text = Label::new("Not Authenticated"); + show_minor_text = false; + Some( + "API Key Missing: Please set 'OPENAI_API_KEY' in Environment Variables. If you authenticated using the Assistant Panel, please restart Zed to Authenticate.".to_string()) + } + SemanticIndexStatus::Indexed => Some("Indexing complete".to_string()), + SemanticIndexStatus::Indexing { + remaining_files, + rate_limit_expiry, + } => { + if remaining_files == 0 { + Some("Indexing...".to_string()) + } else { + if let Some(rate_limit_expiry) = rate_limit_expiry { + let remaining_seconds = + rate_limit_expiry.duration_since(Instant::now()); + if remaining_seconds > Duration::from_secs(0) { + Some(format!( + "Remaining files to index (rate limit resets in {}s): {}", + remaining_seconds.as_secs(), + remaining_files + )) + } else { + Some(format!("Remaining files to index: {}", remaining_files)) + } + } else { + Some(format!("Remaining files to index: {}", remaining_files)) + } + } + } + SemanticIndexStatus::NotIndexed => None, + } + }); let major_text = div().justify_center().max_w_96().child(major_text); - let middle_text = div() - .items_center() - .max_w_96() - .child(Label::new(self.landing_text_minor()).size(LabelSize::Small)); + + let minor_text: Option = if let Some(no_results) = model.no_results { + if model.pending_search.is_none() && no_results { + Some("No results found in this project for the provided query".into()) + } else { + None + } + } else { + if let Some(mut semantic_status) = semantic_status { + semantic_status.extend(self.landing_text_minor().chars()); + Some(semantic_status.into()) + } else { + Some(self.landing_text_minor()) + } + }; + let minor_text = minor_text.map(|text| { + div() + .items_center() + .max_w_96() + .child(Label::new(text).size(LabelSize::Small)) + }); v_stack().flex_1().size_full().justify_center().child( h_stack() .size_full() .justify_center() .child(h_stack().flex_1()) - .child(v_stack().child(major_text).child(middle_text)) + .child(v_stack().child(major_text).children(minor_text)) .child(h_stack().flex_1()), ) } } } -// impl Entity for ProjectSearchView { -// type Event = ViewEvent; -// } - -// impl View for ProjectSearchView { -// fn ui_name() -> &'static str { -// "ProjectSearchView" -// } - -// fn render(&mut self, cx: &mut ViewContext) -> AnyElement { -// let model = &self.model.read(cx); -// if model.match_ranges.is_empty() { -// enum Status {} - -// let theme = theme::current(cx).clone(); - -// // If Search is Active -> Major: Searching..., Minor: None -// // If Semantic -> Major: "Search using Natural Language", Minor: {Status}/n{ex...}/n{ex...} -// // If Regex -> Major: "Search using Regex", Minor: {ex...} -// // If Text -> Major: "Text search all files and folders", Minor: {...} - -// let current_mode = self.current_mode; -// let mut major_text = if model.pending_search.is_some() { -// Cow::Borrowed("Searching...") -// } else if model.no_results.is_some_and(|v| v) { -// Cow::Borrowed("No Results") -// } 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 mut show_minor_text = true; -// let semantic_status = self.semantic_state.as_ref().and_then(|semantic| { -// let status = semantic.index_status; -// match status { -// SemanticIndexStatus::NotAuthenticated => { -// major_text = Cow::Borrowed("Not Authenticated"); -// show_minor_text = false; -// Some(vec![ -// "API Key Missing: Please set 'OPENAI_API_KEY' in Environment Variables." -// .to_string(), "If you authenticated using the Assistant Panel, please restart Zed to Authenticate.".to_string()]) -// } -// SemanticIndexStatus::Indexed => Some(vec!["Indexing complete".to_string()]), -// SemanticIndexStatus::Indexing { -// remaining_files, -// rate_limit_expiry, -// } => { -// if remaining_files == 0 { -// Some(vec![format!("Indexing...")]) -// } else { -// if let Some(rate_limit_expiry) = rate_limit_expiry { -// let remaining_seconds = -// rate_limit_expiry.duration_since(Instant::now()); -// if remaining_seconds > Duration::from_secs(0) { -// Some(vec![format!( -// "Remaining files to index (rate limit resets in {}s): {}", -// remaining_seconds.as_secs(), -// remaining_files -// )]) -// } else { -// Some(vec![format!("Remaining files to index: {}", remaining_files)]) -// } -// } else { -// Some(vec![format!("Remaining files to index: {}", remaining_files)]) -// } -// } -// } -// SemanticIndexStatus::NotIndexed => None, -// } -// }); - -// 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()] -// } else { -// vec![] -// } -// } else { -// match current_mode { -// SearchMode::Semantic => { -// let mut minor_text: Vec = Vec::new(); -// minor_text.push("".into()); -// if let Some(semantic_status) = semantic_status { -// minor_text.extend(semantic_status); -// } -// if show_minor_text { -// minor_text -// .push("Simply explain the code you are looking to find.".into()); -// minor_text.push( -// "ex. 'prompt user for permissions to index their project'".into(), -// ); -// } -// minor_text -// } -// _ => vec![ -// "".to_owned(), -// "Include/exclude specific paths with the filter option.".to_owned(), -// "Matching exact word and/or casing is available too.".to_owned(), -// ], -// } -// }; - -// MouseEventHandler::new::(0, cx, |_, _| { -// Flex::column() -// .with_child(Flex::column().contained().flex(1., true)) -// .with_child( -// Flex::column() -// .align_children_center() -// .with_child(Label::new( -// major_text, -// theme.search.major_results_status.clone(), -// )) -// .with_children( -// minor_text.into_iter().map(|x| { -// Label::new(x, theme.search.minor_results_status.clone()) -// }), -// ) -// .aligned() -// .top() -// .contained() -// .flex(7., true), -// ) -// .contained() -// .with_background_color(theme.editor.background) -// }) -// .on_down(MouseButton::Left, |_, _, cx| { -// cx.focus_parent(); -// }) -// .into_any_named("project search view") -// } else { -// ChildView::new(&self.results_editor, cx) -// .flex(1., true) -// .into_any_named("project search view") -// } -// } - -// fn focus_in(&mut self, _: AnyView, cx: &mut ViewContext) { -// let handle = cx.weak_handle(); -// cx.update_global(|state: &mut ActiveSearches, cx| { -// state -// .0 -// .insert(self.model.read(cx).project.downgrade(), handle) -// }); - -// cx.update_global(|state: &mut ActiveSettings, cx| { -// state.0.insert( -// self.model.read(cx).project.downgrade(), -// self.current_settings(), -// ); -// }); - -// if cx.is_self_focused() { -// if self.query_editor_was_focused { -// cx.focus(&self.query_editor); -// } else { -// cx.focus(&self.results_editor); -// } -// } -// } -// } - impl FocusableView for ProjectSearchView { fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle { self.results_editor.focus_handle(cx) @@ -1256,7 +1147,7 @@ impl ProjectSearchView { fn landing_text_minor(&self) -> SharedString { match self.current_mode { SearchMode::Text | SearchMode::Regex => "Include/exclude specific paths with the filter option. Matching exact word and/or casing is available too.".into(), - SearchMode::Semantic => ".Simply explain the code you are looking to find. ex. 'prompt user for permissions to index their project'".into() + SearchMode::Semantic => "\nSimply explain the code you are looking to find. ex. 'prompt user for permissions to index their project'".into() } } } @@ -1277,8 +1168,8 @@ impl ProjectSearchBar { fn cycle_mode(&self, _: &CycleMode, cx: &mut ViewContext) { if let Some(view) = self.active_project_search.as_ref() { view.update(cx, |this, cx| { - // todo: po: 2nd argument of `next_mode` should be `SemanticIndex::enabled(cx))`, but we need to flesh out port of semantic_index first. - let new_mode = crate::mode::next_mode(&this.current_mode, false); + let new_mode = + crate::mode::next_mode(&this.current_mode, SemanticIndex::enabled(cx)); this.activate_search_mode(new_mode, cx); let editor_handle = this.query_editor.focus_handle(cx); cx.focus(&editor_handle); @@ -1548,7 +1439,7 @@ impl Render for ProjectSearchBar { }); } let search = search.read(cx); - + let semantic_is_available = SemanticIndex::enabled(cx); let query_column = v_stack() //.flex_1() .child( @@ -1578,42 +1469,51 @@ impl Render for ProjectSearchBar { .unwrap_or_default(), ), ) - .child( - IconButton::new( - "project-search-case-sensitive", - Icon::CaseSensitive, - ) - .tooltip(|cx| { - Tooltip::for_action( - "Toggle case sensitive", - &ToggleCaseSensitive, - cx, + .when(search.current_mode != SearchMode::Semantic, |this| { + this.child( + IconButton::new( + "project-search-case-sensitive", + Icon::CaseSensitive, ) - }) - .selected(self.is_option_enabled(SearchOptions::CASE_SENSITIVE, cx)) - .on_click(cx.listener( - |this, _, cx| { - this.toggle_search_option( - SearchOptions::CASE_SENSITIVE, - cx, - ); - }, - )), - ) - .child( - IconButton::new("project-search-whole-word", Icon::WholeWord) .tooltip(|cx| { Tooltip::for_action( - "Toggle whole word", - &ToggleWholeWord, + "Toggle case sensitive", + &ToggleCaseSensitive, cx, ) }) - .selected(self.is_option_enabled(SearchOptions::WHOLE_WORD, cx)) - .on_click(cx.listener(|this, _, cx| { - this.toggle_search_option(SearchOptions::WHOLE_WORD, cx); - })), - ), + .selected( + self.is_option_enabled(SearchOptions::CASE_SENSITIVE, cx), + ) + .on_click(cx.listener( + |this, _, cx| { + this.toggle_search_option( + SearchOptions::CASE_SENSITIVE, + cx, + ); + }, + )), + ) + .child( + IconButton::new("project-search-whole-word", Icon::WholeWord) + .tooltip(|cx| { + Tooltip::for_action( + "Toggle whole word", + &ToggleWholeWord, + cx, + ) + }) + .selected( + self.is_option_enabled(SearchOptions::WHOLE_WORD, cx), + ) + .on_click(cx.listener(|this, _, cx| { + this.toggle_search_option( + SearchOptions::WHOLE_WORD, + cx, + ); + })), + ) + }), ) .border_2() .bg(white()) @@ -1668,7 +1568,23 @@ impl Render for ProjectSearchBar { cx, ) }), - ), + ) + .when(semantic_is_available, |this| { + this.child( + Button::new("project-search-semantic-button", "Semantic") + .selected(search.current_mode == SearchMode::Semantic) + .on_click(cx.listener(|this, _, cx| { + this.activate_search_mode(SearchMode::Semantic, cx) + })) + .tooltip(|cx| { + Tooltip::for_action( + "Toggle semantic search", + &ActivateSemanticMode, + cx, + ) + }), + ) + }), ) .child( IconButton::new("project-search-toggle-replace", Icon::Replace) From ce1489f5dcb6471216d7a66924f880333afdddf4 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 13 Dec 2023 14:22:29 +0100 Subject: [PATCH 003/644] Add inclusion of ignored files --- crates/search2/src/project_search.rs | 75 ++++++++++++++++++---------- crates/search2/src/search.rs | 5 ++ 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index 875d2fe095a73495144182e14e5e4e4dd9959582..f1b0c16d5708241cd4421e9c7b88d762383ff532 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -1,8 +1,8 @@ use crate::{ history::SearchHistory, mode::SearchMode, ActivateRegexMode, ActivateSemanticMode, ActivateTextMode, CycleMode, NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext, - SearchOptions, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleReplace, - ToggleWholeWord, + SearchOptions, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleIncludeIgnored, + ToggleReplace, ToggleWholeWord, }; use anyhow::{Context as _, Result}; use collections::HashMap; @@ -1530,7 +1530,22 @@ impl Render for ProjectSearchBar { .flex_1() .border_1() .mr_2() - .child(search.included_files_editor.clone()), + .child(search.included_files_editor.clone()) + .when(search.current_mode != SearchMode::Semantic, |this| { + this.child( + SearchOptions::INCLUDE_IGNORED.as_button( + search + .search_options + .contains(SearchOptions::INCLUDE_IGNORED), + cx.listener(|this, _, cx| { + this.toggle_search_option( + SearchOptions::INCLUDE_IGNORED, + cx, + ); + }), + ), + ) + }), ) .child( h_stack() @@ -1671,34 +1686,14 @@ impl Render for ProjectSearchBar { .on_action(cx.listener(|this, _: &ToggleFilters, cx| { this.toggle_filters(cx); })) - .on_action(cx.listener(|this, _: &ToggleWholeWord, cx| { - this.toggle_search_option(SearchOptions::WHOLE_WORD, cx); - })) - .on_action(cx.listener(|this, _: &ToggleCaseSensitive, cx| { - this.toggle_search_option(SearchOptions::CASE_SENSITIVE, cx); - })) - .on_action(cx.listener(|this, action, cx| { - this.toggle_replace(action, cx); - })) .on_action(cx.listener(|this, _: &ActivateTextMode, cx| { this.activate_search_mode(SearchMode::Text, cx) })) .on_action(cx.listener(|this, _: &ActivateRegexMode, cx| { this.activate_search_mode(SearchMode::Regex, cx) })) - .on_action(cx.listener(|this, action, cx| { - if let Some(search) = this.active_project_search.as_ref() { - search.update(cx, |this, cx| { - this.replace_next(action, cx); - }) - } - })) - .on_action(cx.listener(|this, action, cx| { - if let Some(search) = this.active_project_search.as_ref() { - search.update(cx, |this, cx| { - this.replace_all(action, cx); - }) - } + .on_action(cx.listener(|this, _: &ActivateSemanticMode, cx| { + this.activate_search_mode(SearchMode::Semantic, cx) })) .on_action(cx.listener(|this, action, cx| { this.tab(action, cx); @@ -1709,6 +1704,36 @@ impl Render for ProjectSearchBar { .on_action(cx.listener(|this, action, cx| { this.cycle_mode(action, cx); })) + .when(search.current_mode != SearchMode::Semantic, |this| { + this.on_action(cx.listener(|this, action, cx| { + this.toggle_replace(action, cx); + })) + .on_action(cx.listener(|this, _: &ToggleWholeWord, cx| { + this.toggle_search_option(SearchOptions::WHOLE_WORD, cx); + })) + .on_action(cx.listener(|this, _: &ToggleCaseSensitive, cx| { + this.toggle_search_option(SearchOptions::CASE_SENSITIVE, cx); + })) + .on_action(cx.listener(|this, action, cx| { + if let Some(search) = this.active_project_search.as_ref() { + search.update(cx, |this, cx| { + this.replace_next(action, cx); + }) + } + })) + .on_action(cx.listener(|this, action, cx| { + if let Some(search) = this.active_project_search.as_ref() { + search.update(cx, |this, cx| { + this.replace_all(action, cx); + }) + } + })) + .when(search.filters_enabled, |this| { + this.on_action(cx.listener(|this, _: &ToggleIncludeIgnored, cx| { + this.toggle_search_option(SearchOptions::INCLUDE_IGNORED, cx); + })) + }) + }) .child(query_column) .child(mode_column) .child(replace_column) diff --git a/crates/search2/src/search.rs b/crates/search2/src/search.rs index 015c126aa1ef5abd37e67f6c169a3c7787ccf4b6..18fcc258f44497c8863f9000201238cebc1520ab 100644 --- a/crates/search2/src/search.rs +++ b/crates/search2/src/search.rs @@ -28,6 +28,7 @@ actions!( CycleMode, ToggleWholeWord, ToggleCaseSensitive, + ToggleIncludeIgnored, ToggleReplace, SelectNextMatch, SelectPrevMatch, @@ -57,6 +58,7 @@ impl SearchOptions { match *self { SearchOptions::WHOLE_WORD => "Match Whole Word", SearchOptions::CASE_SENSITIVE => "Match Case", + SearchOptions::INCLUDE_IGNORED => "Include ignored", _ => panic!("{:?} is not a named SearchOption", self), } } @@ -65,6 +67,7 @@ impl SearchOptions { match *self { SearchOptions::WHOLE_WORD => ui::Icon::WholeWord, SearchOptions::CASE_SENSITIVE => ui::Icon::CaseSensitive, + SearchOptions::INCLUDE_IGNORED => ui::Icon::FileGit, _ => panic!("{:?} is not a named SearchOption", self), } } @@ -73,6 +76,7 @@ impl SearchOptions { match *self { SearchOptions::WHOLE_WORD => Box::new(ToggleWholeWord), SearchOptions::CASE_SENSITIVE => Box::new(ToggleCaseSensitive), + SearchOptions::INCLUDE_IGNORED => Box::new(ToggleIncludeIgnored), _ => panic!("{:?} is not a named SearchOption", self), } } @@ -85,6 +89,7 @@ impl SearchOptions { let mut options = SearchOptions::NONE; options.set(SearchOptions::WHOLE_WORD, query.whole_word()); options.set(SearchOptions::CASE_SENSITIVE, query.case_sensitive()); + options.set(SearchOptions::INCLUDE_IGNORED, query.include_ignored()); options } From 85a1a8f777f4a8586d7adcd88863f6afeb086b2c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 11 Dec 2023 19:17:13 -0500 Subject: [PATCH 004/644] WIP --- docs/.gitignore | 2 + docs/book.toml | 6 + docs/src/CODE_OF_CONDUCT.md | 128 ++ docs/src/CONTRIBUTING.md | 3 + docs/src/SUMMARY.md | 18 + docs/src/configuring_zed.md | 1035 +++++++++++++++++ docs/src/configuring_zed__configuring_vim.md | 170 +++ docs/src/developing_zed__adding_languages.md | 83 ++ docs/src/developing_zed__building_zed.md | 107 ++ .../developing_zed__local_collaboration.md} | 0 docs/src/feedback.md | 29 + docs/src/getting_started.md | 15 + docs/src/system_requirements.md | 13 + docs/src/telemetry.md | 147 +++ {docs => docs_old}/backend-development.md | 0 {docs => docs_old}/building-zed.md | 0 {docs => docs_old}/company-and-vision.md | 0 {docs => docs_old}/design-tools.md | 0 {docs => docs_old}/index.md | 0 docs_old/local-collaboration.md | 22 + {docs => docs_old}/release-process.md | 0 .../theme/generating-theme-types.md | 0 {docs => docs_old}/tools.md | 0 {docs => docs_old}/zed/syntax-highlighting.md | 0 24 files changed, 1778 insertions(+) create mode 100644 docs/.gitignore create mode 100644 docs/book.toml create mode 100644 docs/src/CODE_OF_CONDUCT.md create mode 100644 docs/src/CONTRIBUTING.md create mode 100644 docs/src/SUMMARY.md create mode 100644 docs/src/configuring_zed.md create mode 100644 docs/src/configuring_zed__configuring_vim.md create mode 100644 docs/src/developing_zed__adding_languages.md create mode 100644 docs/src/developing_zed__building_zed.md rename docs/{local-collaboration.md => src/developing_zed__local_collaboration.md} (100%) create mode 100644 docs/src/feedback.md create mode 100644 docs/src/getting_started.md create mode 100644 docs/src/system_requirements.md create mode 100644 docs/src/telemetry.md rename {docs => docs_old}/backend-development.md (100%) rename {docs => docs_old}/building-zed.md (100%) rename {docs => docs_old}/company-and-vision.md (100%) rename {docs => docs_old}/design-tools.md (100%) rename {docs => docs_old}/index.md (100%) create mode 100644 docs_old/local-collaboration.md rename {docs => docs_old}/release-process.md (100%) rename {docs => docs_old}/theme/generating-theme-types.md (100%) rename {docs => docs_old}/tools.md (100%) rename {docs => docs_old}/zed/syntax-highlighting.md (100%) diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..eed3a3e0462ad6c1a85505fbedae8c76112571ba --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +book +.vercel diff --git a/docs/book.toml b/docs/book.toml new file mode 100644 index 0000000000000000000000000000000000000000..8062a76a4216ca248c786283bef9acf725fdee9d --- /dev/null +++ b/docs/book.toml @@ -0,0 +1,6 @@ +[book] +authors = ["Nate Butler"] +language = "en" +multilingual = false +src = "src" +title = "Zed App Docs" diff --git a/docs/src/CODE_OF_CONDUCT.md b/docs/src/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000000000000000000000000000000000..bc1d5522a0af5502dd8a428f8f3d28a9965b52be --- /dev/null +++ b/docs/src/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +hi@zed.dev. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/docs/src/CONTRIBUTING.md b/docs/src/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..d48c26844f2ee079fedcbdda70ac83704abb9747 --- /dev/null +++ b/docs/src/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing + +TBD diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md new file mode 100644 index 0000000000000000000000000000000000000000..4c6f5f9421dcb7e6b8517085e0c30374a216632b --- /dev/null +++ b/docs/src/SUMMARY.md @@ -0,0 +1,18 @@ +# Summary + +[Getting Started](./getting_started.md) +[Feedback](./feedback.md) + +# Configuring Zed +- [Settings](./configuring_zed.md) +- [Vim Mode](./configuring_zed__configuring_vim.md) + +# Developing Zed +- [Building from Source](./developing_zed__building_zed.md) +- [Local Collaboration](./developing_zed__local_collaboration.md) +- [Adding Languages](./developing_zed__adding_languages.md) + +# Other +- [Code of Conduct](./CODE_OF_CONDUCT.md) +- [Telemetry](./telemetry.md) +- [Contributing](./CONTRIBUTING.md) diff --git a/docs/src/configuring_zed.md b/docs/src/configuring_zed.md new file mode 100644 index 0000000000000000000000000000000000000000..9b9205f70ca7cac1cb587a2800de6af3f7bed956 --- /dev/null +++ b/docs/src/configuring_zed.md @@ -0,0 +1,1035 @@ +# Configuring Zed + +## Folder-specific settings + +Folder-specific settings are used to override Zed's global settings for files within a specific directory in the project panel. To get started, create a `.zed` subdirectory and add a `settings.json` within it. It should be noted that folder-specific settings don't need to live only a project's root, but can be defined at multiple levels in the project hierarchy. In setups like this, Zed will find the configuration nearest to the file you are working in and apply those settings to it. In most cases, this level of flexibility won't be needed and a single configuration for all files in a project is all that is required; the `Zed > Settings > Open Local Settings` menu action is built for this case. Running this action will look for a `.zed/settings.json` file at the root of the first top-level directory in your project panel. If it does not exist, it will create it. + +The following global settings can be overriden with a folder-specific configuration: + +- `copilot` +- `enable_language_server` +- `ensure_final_newline_on_save` +- `format_on_save` +- `formatter` +- `hard_tabs` +- `language_overrides` +- `preferred_line_length` +- `remove_trailing_whitespace_on_save` +- `soft_wrap` +- `tab_size` +- `show_copilot_suggestions` +- `show_whitespaces` + +*See the Global settings section for details about these settings* + +## Global settings + +To get started with editing Zed's global settings, open `~/.config/zed/settings.json` via `cmd-,`, the command palette (`zed: open settings`), or the `Zed > Settings > Open Settings` application menu item. + +Here are all the currently available settings. + +## Active Pane Magnification + +- Description: Scale by which to zoom the active pane. When set to `1.0`, the active pane has the same size as others, but when set to a larger value, the active pane takes up more space. +- Setting: `active_pane_magnification` +- Default: `1.0` + +**Options** + +`float` values + +## Autosave + +- Description: When to automatically save edited buffers. +- Setting: `autosave` +- Default: `off` + +**Options** + +1. To disable autosave, set it to `off` + +```json +{ + "autosave": "off" +} +``` + +2. To autosave when focus changes, use `on_focus_change`: + +```json +{ + "autosave": "on_focus_change" +} +``` + +3. To autosave when the active window changes, use `on_window_change`: + +```json +{ + "autosave": "on_window_change" +} +``` + +4. To autosave after an inactivity period, use `after_delay`: + +```json +{ + "autosave": { + "after_delay": { + "milliseconds": 1000 + } + } +} +``` + +## Auto Update + +- Description: Whether or not to automatically check for updates. +- Setting: `auto_update` +- Default: `true` + +**Options** + +`boolean` values + +## Buffer Font Family + +- Description: The name of a font to use for rendering text in the editor. +- Setting: `buffer_font_family` +- Default: `Zed Mono` + +**Options** + +The name of any font family installed on the user's system + +## Buffer Font Features + +- Description: The OpenType features to enable for text in the editor. +- Setting: `buffer_font_features` +- Default: `null` + +**Options** + +Zed supports a subset of OpenType features that can be enabled or disabled for a given buffer or terminal font. The following [OpenType features](https://en.wikipedia.org/wiki/List_of_typographic_features) can be enabled or disabled too: `calt`, `case`, `cpsp`, `frac`, `liga`, `onum`, `ordn`, `pnum`, `ss01`, `ss02`, `ss03`, `ss04`, `ss05`, `ss06`, `ss07`, `ss08`, `ss09`, `ss10`, `ss11`, `ss12`, `ss13`, `ss14`, `ss15`, `ss16`, `ss17`, `ss18`, `ss19`, `ss20`, `subs`, `sups`, `swsh`, `titl`, `tnum`, `zero`. + +For example, to disable ligatures for a given font you can add the following to your settings: + +```json +{ + "buffer_font_features": { + "calt": false + } +} +``` + +## Buffer Font Size + +- Description: The default font size for text in the editor. +- Setting: `buffer_font_size` +- Default: `15` + +**Options** + +`integer` values + +## Confirm Quit + +- Description: Whether or not to prompt the user to confirm before closing the application. +- Setting: `confirm_quit` +- Default: `false` + +**Options** + +`boolean` values + +## Copilot + +- Description: Copilot-specific settings. +- Setting: `copilot` +- Default: + +```json +"copilot": { + "disabled_globs": [ + ".env" + ] +} +``` + +**Options** + +### Disabled Globs + +- Description: The set of glob patterns for which Copilot should be disabled in any matching file. +- Setting: `disabled_globs` +- Default: [".env"] + +**Options** + +List of `string` values + +## Cursor Blink + +- Description: Whether or not the cursor blinks. +- Setting: `cursor_blink` +- Default: `true` + +**Options** + +`boolean` values + +## Default Dock Anchor + +- Description: The default anchor for new docks. +- Setting: `default_dock_anchor` +- Default: `bottom` + +**Options** + +1. Position the dock attached to the bottom of the workspace: `bottom` +2. Position the dock to the right of the workspace like a side panel: `right` +3. Position the dock full screen over the entire workspace: `expanded` + +## Enable Language Server + +- Description: Whether or not to use language servers to provide code intelligence. +- Setting: `enable_language_server` +- Default: `true` + +**Options** + +`boolean` values + +## Ensure Final Newline On Save + +- Description: Whether or not to ensure there's a single newline at the end of a buffer when saving it. +- Setting: `ensure_final_newline_on_save` +- Default: `true` + +**Options** + +`boolean` values + +## LSP + +- Description: Configuration for language servers. +- Setting: `lsp` +- Default: `null` + +**Options** + +The following settings can be overridden for specific language servers: + +- `initialization_options` + +To override settings for a language, add an entry for that language server's name to the `lsp` value. Example: + +```json +"lsp": { + "rust-analyzer": { + "initialization_options": { + "checkOnSave": { + "command": "clippy" // rust-analyzer.checkOnSave.command + } + } + } +} +``` + +## Format On Save + +- Description: Whether or not to perform a buffer format before saving. +- Setting: `format_on_save` +- Default: `on` + +**Options** + +1. `on`, enables format on save obeying `formatter` setting: + +```json +{ + "format_on_save": "on" +} +``` + +2. `off`, disables format on save: + +```json +{ + "format_on_save": "off" +} +``` + +## Formatter + +- Description: How to perform a buffer format. +- Setting: `formatter` +- Default: `language_server` + +**Options** + +1. To use the current language server, use `"language_server"`: + +```json +{ + "formatter": "language_server" +} +``` + +2. Or to use an external command, use `"external"`. Specify the name of the formatting program to run, and an array of arguments to pass to the program. The buffer's text will be passed to the program on stdin, and the formatted output should be written to stdout. For example, the following command would strip trailing spaces using [`sed(1)`](https://linux.die.net/man/1/sed): + +```json +{ + "formatter": { + "external": { + "command": "sed", + "arguments": ["-e", "s/ *$//"] + } + } +} +``` + +## Git + +- Description: Configuration for git-related features. +- Setting: `git` +- Default: + +```json +"git": { + "git_gutter": "tracked_files" +}, +``` + +### Git Gutter + +- Description: Whether or not to show the git gutter. +- Setting: `git_gutter` +- Default: `tracked_files` + +**Options** + +1. Show git gutter in tracked files + +```json +{ + "git_gutter": "tracked_files" +} +``` + +2. Hide git gutter + +```json +{ + "git_gutter": "hide" +} +``` + +## Hard Tabs + +- Description: Whether to indent lines using tab characters or multiple spaces. +- Setting: `hard_tabs` +- Default: `false` + +**Options** + +`boolean` values + +## Hover Popover Enabled + +- Description: Whether or not to show the informational hover box when moving the mouse over symbols in the editor. +- Setting: `hover_popover_enabled` +- Default: `true` + +**Options** + +`boolean` values + +## Inlay hints + +- Description: Configuration for displaying extra text with hints in the editor. +- Setting: `inlay_hints` +- Default: + +```json +"inlay_hints": { + "enabled": false, + "show_type_hints": true, + "show_parameter_hints": true, + "show_other_hints": true +} +``` + +**Options** + +Inlay hints querying consists of two parts: editor (client) and LSP server. +With the inlay settings above are changed to enable the hints, editor will start to query certain types of hints and react on LSP hint refresh request from the server. +At this point, the server may or may not return hints depending on its implementation, further configuration might be needed, refer to the corresponding LSP server documentation. + +Use `lsp` section for the server configuration, below are some examples for well known servers: + +### Rust + +```json +"lsp": { + "rust-analyzer": { + "initialization_options": { + "inlayHints": { + "maxLength": null, + "lifetimeElisionHints": { + "useParameterNames": true, + "enable": "skip_trivial" + }, + "closureReturnTypeHints": { + "enable": "always" + } + } + } + } +} +``` + +### Typescript + +```json +"lsp": { + "typescript-language-server": { + "initialization_options": { + "preferences": { + "includeInlayParameterNameHints": "all", + "includeInlayParameterNameHintsWhenArgumentMatchesName": true, + "includeInlayFunctionParameterTypeHints": true, + "includeInlayVariableTypeHints": true, + "includeInlayVariableTypeHintsWhenTypeMatchesName": false, + "includeInlayPropertyDeclarationTypeHints": true, + "includeInlayFunctionLikeReturnTypeHints": true, + "includeInlayEnumMemberValueHints": true + } + } + } +} +``` + +### Go + +```json +"lsp": { + "gopls": { + "initialization_options": { + "hints": { + "assignVariableTypes": true, + "compositeLiteralFields": true, + "compositeLiteralTypes": true, + "constantValues": true, + "functionTypeParameters": true, + "parameterNames": true, + "rangeVariableTypes": true + } + } + } +} +``` + +### Svelte + +```json +{ + "lsp": { + "typescript-language-server": { + "initialization_options": { + "preferences": { + "includeInlayParameterNameHints": "all", + "includeInlayParameterNameHintsWhenArgumentMatchesName": true, + "includeInlayFunctionParameterTypeHints": true, + "includeInlayVariableTypeHints": true, + "includeInlayVariableTypeHintsWhenTypeMatchesName": false, + "includeInlayPropertyDeclarationTypeHints": true, + "includeInlayFunctionLikeReturnTypeHints": true, + "includeInlayEnumMemberValueHints": true, + "includeInlayEnumMemberDeclarationTypes": true + } + } + } + } +} +``` + +## Journal + +- Description: Configuration for the journal. +- Setting: `journal` +- Default: + +```json +"journal": { + "path": "~", + "hour_format": "hour12" +} +``` + +### Path + +- Description: The path of the directory where journal entries are stored. +- Setting: `path` +- Default: `~` + +**Options** + +`string` values + +### Hour Format + +- Description: The format to use for displaying hours in the journal. +- Setting: `hour_format` +- Default: `hour12` + +**Options** + +1. 12-hour format: + +```json +{ + "hour_format": "hour12" +} +``` + +2. 24-hour format: + +```json +{ + "hour_format": "hour24" +} +``` + +## Language Overrides + +- Description: Configuration overrides for specific languages. +- Setting: `language_overrides` +- Default: `null` + +**Options** + +To override settings for a language, add an entry for that languages name to the `language_overrides` value. Example: + +```json +"language_overrides": { + "C": { + "format_on_save": "off", + "preferred_line_length": 64, + "soft_wrap": "preferred_line_length" + }, + "JSON": { + "tab_size": 4 + } +} +``` + +The following settings can be overridden for each specific language: + +- `enable_language_server` +- `ensure_final_newline_on_save` +- `format_on_save` +- `formatter` +- `hard_tabs` +- `preferred_line_length` +- `remove_trailing_whitespace_on_save` +- `show_copilot_suggestions` +- `show_whitespaces` +- `soft_wrap` +- `tab_size` + +These values take in the same options as the root-level settings with the same name. + +## Preferred Line Length + +- Description: The column at which to soft-wrap lines, for buffers where soft-wrap is enabled. +- Setting: `preferred_line_length` +- Default: `80` + +**Options** + +`integer` values + +## Projects Online By Default + +- Description: Whether or not to show the online projects view by default. +- Setting: `projects_online_by_default` +- Default: `true` + +**Options** + +`boolean` values + +## Remove Trailing Whitespace On Save + +- Description: Whether or not to remove any trailing whitespace from lines of a buffer before saving it. +- Setting: `remove_trailing_whitespace_on_save` +- Default: `true` + +**Options** + +`boolean` values + +## Semantic Index + +- Description: Settings related to semantic index. +- Setting: `semantic_index` +- Default: + +```json +"semantic_index": { + "enabled": false +}, +``` + +### Enabled + +- Description: Whether or not to display the `Semantic` mode in project search. +- Setting: `enabled` +- Default: `true` + +**Options** + +`boolean` values + +## Show Call Status Icon + +- Description: Whether or not to show the call status icon in the status bar. +- Setting: `show_call_status_icon` +- Default: `true` + +**Options** + +`boolean` values + +## Show Completions On Input + +- Description: Whether or not to show completions as you type. +- Setting: `show_completions_on_input` +- Default: `true` + +**Options** + +`boolean` values + +## Show Completion Documentation + +- Description: Whether to display inline and alongside documentation for items in the completions menu. +- Setting: `show_completion_documentation` +- Default: `true` + +**Options** + +`boolean` values + +## Show Copilot Suggestions + +- Description: Whether or not to show Copilot suggestions as you type or wait for a `copilot::Toggle`. +- Setting: `show_copilot_suggestions` +- Default: `true` + +**Options** + +`boolean` values + +## Show Whitespaces + +- Description: Whether or not to show render whitespace characters in the editor. +- Setting: `show_whitespaces` +- Default: `selection` + +**Options** + +1. `all` +2. `selection` +3. `none` + +## Soft Wrap + +- Description: Whether or not to automatically wrap lines of text to fit editor / preferred width. +- Setting: `soft_wrap` +- Default: `none` + +**Options** + +1. `editor_width` +2. `preferred_line_length` +3. `none` + +## Tab Size + +- Description: The number of spaces to use for each tab character. +- Setting: `tab_size` +- Default: `4` + +**Options** + +`integer` values + +## Telemetry + +- Description: Control what info is collected by Zed. +- Setting: `telemetry` +- Default: + +```json +"telemetry": { + "diagnostics": true, + "metrics": true +}, +``` + +**Options** + +### Diagnostics + +- Description: Setting for sending debug-related data, such as crash reports. +- Setting: `diagnostics` +- Default: `true` + +**Options** + +`boolean` values + +### Metrics + +- Description: Setting for sending anonymized usage data, such what languages you're using Zed with. +- Setting: `metrics` +- Default: `true` + +**Options** + +`boolean` values + +## Terminal + +- Description: Configuration for the terminal. +- Setting: `terminal` +- Default: + +```json +"terminal": { + "alternate_scroll": "off", + "blinking": "terminal_controlled", + "copy_on_select": false, + "env": {}, + "font_family": null, + "font_features": null, + "font_size": null, + "option_as_meta": false, + "shell": {}, + "working_directory": "current_project_directory" +} +``` + +### Alternate Scroll + +- Description: Set whether Alternate Scroll mode (DECSET code: `?1007`) is active by default. Alternate Scroll mode converts mouse scroll events into up / down key presses when in the alternate screen (e.g. when running applications like vim or less). The terminal can still set and unset this mode with ANSI escape codes. +- Setting: `alternate_scroll` +- Default: `off` + +**Options** + +1. Default alternate scroll mode to on + +```json +{ + "alternate_scroll": "on" +} +``` + +2. Default alternate scroll mode to off + +```json +{ + "alternate_scroll": "off" +} +``` + +### Blinking + +- Description: Set the cursor blinking behavior in the terminal +- Setting: `blinking` +- Default: `terminal_controlled` + +**Options** + +1. Never blink the cursor, ignore the terminal mode + +```json +{ + "blinking": "off" +} +``` + +2. Default the cursor blink to off, but allow the terminal to turn blinking on + +```json +{ + "blinking": "terminal_controlled" +} +``` + +3. Always blink the cursor, ignore the terminal mode + +```json +"blinking": "on", +``` + +### Copy On Select + +- Description: Whether or not selecting text in the terminal will automatically copy to the system clipboard. +- Setting: `copy_on_select` +- Default: `false` + +**Options** + +`boolean` values + +### Env + +- Description: Any key-value pairs added to this object will be added to the terminal's environment. Keys must be unique, use `:` to separate multiple values in a single variable +- Setting: `env` +- Default: `{}` + +**Example** + +```json +"env": { + "ZED": "1", + "KEY": "value1:value2" +} +``` + +### Font Size + +- Description: What font size to use for the terminal. When not set defaults to matching the editor's font size +- Setting: `font_size` +- Default: `null` + +**Options** + +`integer` values + +### Font Family + +- Description: What font to use for the terminal. When not set, defaults to matching the editor's font. +- Setting: `font_family` +- Default: `null` + +**Options** + +The name of any font family installed on the user's system + +### Font Features + +- Description: What font features to use for the terminal. When not set, defaults to matching the editor's font features. +- Setting: `font_features` +- Default: `null` + +**Options** + +See Buffer Font Features + +### Option As Meta + +- Description: Re-interprets the option keys to act like a 'meta' key, like in Emacs. +- Setting: `option_as_meta` +- Default: `true` + +**Options** + +`boolean` values + +### Shell + +- Description: What shell to use when launching the terminal. +- Setting: `shell` +- Default: `system` + +**Options** + +1. Use the system's default terminal configuration (usually the `/etc/passwd` file). + +```json +{ + "shell": "system" +} +``` + +2. A program to launch: + +```json +"shell": { + "program": "sh" +} +``` + +3. A program with arguments: + +```json +"shell": { + "with_arguments": { + "program": "/bin/bash", + "args": ["--login"] + } +} +``` + +### Working Directory + +- Description: What working directory to use when launching the terminal. +- Setting: `working_directory` +- Default: `"current_project_directory"` + +**Options** + +1. Use the current file's project directory. Will Fallback to the first project directory strategy if unsuccessful + +```json +{ + "working_directory": "current_project_directory" +} +``` + +2. Use the first project in this workspace's directory. Will fallback to using this platform's home directory. + +```json +{ + "working_directory": "first_project_directory" +} +``` + +3. Always use this platform's home directory (if we can find it) + +```json +{ + "working_directory": "always_home" +} +``` + +4. Always use a specific directory. This value will be shell expanded. If this path is not a valid directory the terminal will default to this platform's home directory. + +```json +"working_directory": { + "always": { + "directory": "~/zed/projects/" + } +} +``` + +## Theme + +- Description: The name of the Zed theme to use for the UI. +- Setting: `theme` +- Default: `One Dark` + +**Options** + +Run the `theme selector: toggle` action in the command palette to see a current list of valid themes names. + +## Vim + +- Description: Whether or not to enable vim mode (work in progress). +- Setting: `vim_mode` +- Default: `false` + +## Project Panel + +- Description: Customise project panel +- Setting: `project_panel` +- Default: + +```json +"project_panel": { + "dock": "left", + "git_status": true, + "default_width": "N/A - width in pixels" +}, +``` + +### Dock + +- Description: Control the position of the dock +- Setting: `dock` +- Default: `left` + +**Options** + +1. Default dock position to left + +```json +{ + "dock": "left" +} +``` + +2. Default dock position to right + +```json +{ + "dock": "right" +} +``` + +### Git Status + +- Description: Indicates newly created and updated files +- Setting: `git_status` +- Default: `true` + +1. Default enable git status + +```json +{ + "git_status": true +} +``` + +2. Default disable git status + +```json +{ + "git_status": false +} +``` + +### Default Width +- Description: Customise default width taken by project panel +- Setting: `default_width` +- Default: N/A width in pixels (eg: 420) + +**Options** + +`boolean` values + +## An example configuration: + +```json +// ~/.config/zed/settings.json +{ + "theme": "cave-light", + "tab_size": 2, + "preferred_line_length": 80, + "soft_wrap": "none", + + "buffer_font_size": 18, + "buffer_font_family": "Zed Mono", + + "autosave": "on_focus_change", + "format_on_save": "off", + "vim_mode": false, + "projects_online_by_default": true, + "terminal": { + "font_family": "FiraCode Nerd Font Mono", + "blinking": "off" + }, + "language_overrides": { + "C": { + "format_on_save": "language_server", + "preferred_line_length": 64, + "soft_wrap": "preferred_line_length" + } + } +} +``` diff --git a/docs/src/configuring_zed__configuring_vim.md b/docs/src/configuring_zed__configuring_vim.md new file mode 100644 index 0000000000000000000000000000000000000000..ddef07e3c28f8e2d2e3452d1e586f57656fbff91 --- /dev/null +++ b/docs/src/configuring_zed__configuring_vim.md @@ -0,0 +1,170 @@ +# Vim Mode + +Zed includes a vim emulation layer known as “vim mode”. This document aims to describe how it works, and how to make the most out of it. + +### Philosophy +Vim mode in Zed is supposed to primarily "do what you expect": it mostly tries to copy vim exactly, but will use Zed-specific functionality when available to make things smoother. + +This means Zed will never be 100% vim compatible, but should be 100% vim familiar! We expect that our vim mode already copes with 90% of your workflow, and we'd like to keep improving it. If you find things that you can’t yet do in vim mode, but which you rely on in your current workflow, please leave feedback in the editor itself (`:feedback`), or [file an issue](https://github.com/zed-industries/community). + +### Zed-specific features +Zed is built on a modern foundation that (among other things) uses tree-sitter to understand the content of the file you're editing, and supports multiple cursors out of the box. + +Vim mode has several "core Zed" key bindings, that will help you make the most of Zed's specific feature set. +``` +# Normal mode +g d Go to definition +g D Go to type definition +c d Rename (change definition) +g A Go to All references to the current word + +g Open the current search excerpt in its own tab + +g s Find symbol in current file +g S Find symbol in entire project + +g n Add a visual selection for the next copy of the current word +g N The same, but backwards +g > Skip latest word selection, and add next. +g < The same, but backwards +g a Add a visual selection for every copy of the current word + +g h Show inline error (hover) + +# Insert mode +ctrl-x ctrl-o Open the completion menu +ctrl-x ctrl-c Request Github Copilot suggestion (if configured) +ctrl-x ctrl-a Open the inline AI assistant (if configured) +ctrl-x ctrl-l Open the LSP code actions +ctrl-x ctrl-z Hides all suggestions +``` + +Vim mode uses Zed to define concepts like "brackets" (for the `%` key) and "words" (for motions like `w` and `e`). This does lead to some differences, but they are mostly positive. For example `%` considers `|` to be a bracket in languages like Rust; and `w` considers `$` to be a word-character in languages like Javascript. + +Vim mode emulates visual block mode using Zed's multiple cursor support. This again leads to some differences, but is much more powerful. + +Finally, Vim mode's search and replace functionality is backed by Zed's. This means that the pattern syntax is slightly different, see the section on [Regex differences](#regex-differences) for details. + +### Custom key bindings +Zed does not yet have an equivalent to vim’s `map` command to convert one set of keystrokes into another, however you can bind any sequence of keys to fire any Action documented in the [Key bindings documentation](https://docs.zed.dev/configuration/key-bindings). + +You can edit your personal key bindings with `:keymap`. +For vim-specific shortcuts, you may find the following template a good place to start: + +```json +[ + { + "context": "Editor && VimControl && !VimWaiting && !menu", + "bindings": { + // put key-bindings here if you want them to work in normal & visual mode + } + }, + { + "context": "Editor && vim_mode == normal && !VimWaiting && !menu", + "bindings": { + // put key-bindings here if you want them to work only in normal mode + } + }, + { + "context": "Editor && vim_mode == visual && !VimWaiting && !menu", + "bindings": { + // visual, visual line & visual block modes + } + }, + { + "context": "Editor && vim_mode == insert && !menu", + "bindings": { + // put key-bindings here if you want them to work in insert mode + } + } +] +``` + +You can see the bindings that are enabled by default in vim mode [here](https://zed.dev/ref/vim.json). + +The details of the context are a little out of scope for this doc, but suffice to say that `menu` is true when a menu is open (e.g. the completions menu), `VimWaiting` is true after you type `f` or `t` when we’re waiting for a new key (and you probably don’t want bindings to happen). Please reach out on [Github](https://github.com/zed-industries/community) if you want help making a key bindings work. + +### Command palette + +Vim mode allows you to enable Zed’s command palette with `:`. This means that you can use vim's command palette to run any action that Zed supports. + +Additionally vim mode contains a number of aliases for popular vim commands to ensure that muscle memory works. For example `:w` will save the file. + +We do not (yet) emulate the full power of vim’s command line, in particular we special case specific patterns instead of using vim's range selection syntax, and we do not support arguments to commands yet. Please reach out on [Github](https://github.com/zed-industries/community) as you find things that are missing from the command palette. + +As mentioned above, one thing to be aware of is that the regex engine is slightly different from vim's in `:%s/a/b`. + +Currently supported vim-specific commands (as of Zed 0.106): +``` +# window management +:w[rite][!], :wq[!], :q[uit][!], :wa[ll][!], :wqa[ll][!], :qa[ll][!], :[e]x[it][!], :up[date] + to save/close tab(s) and pane(s) (no filename is supported yet) +:cq + to quit completely. +:vs[plit], :sp[lit] + to split vertically/horizontally (no filename is supported yet) +:new, :vne[w] + to create a new file in a new pane above or to the left +:tabedit, :tabnew + to create a new file in a new tab. +:tabn[ext], :tabp[rev] + to go to previous/next tabs +:tabc[lose] + to close the current tab + +# navigating diagnostics +:cn[ext], :cp[rev], :ln[ext], :lp[rev] + to go to the next/prev diagnostics +:cc, :ll + to open the errors page + +# jump to position +: + to jump to a line number +:$ + to jump to the end of the file +:/foo and :?foo + to jump to next/prev line matching foo + +# replacement +:%s/foo/bar/ + to replace instances of foo with bar (/g is always assumed, the range must always be %, and Zed uses different regex syntax to vim) + +# editing +:j[oin] + to join the current line (no range is yet supported) +:d[elete][l][p] + to delete the current line (no range is yet supported) +:s[ort] [i] + to sort the current selection (with i, case-insensitively) +``` + + +### Related settings +There are a few Zed settings that you may also enjoy if you use vim mode: +``` +{ + // disable cursor blink + "cursor_blink": false + // use relative line numbers + "relative_line_numbers": true, + // hide the scroll bar + "scrollbar": {"show": "never"}, +} +``` + +### Regex differences + +Zed uses a different regular expression engine from Vim. This means that you will have to use a different syntax for some things. + +Notably: +* Vim uses `\(` and `\)` to represent capture groups, in Zed these are `(` and `)`. +* On the flip side, `(` and `)` represent literal parentheses, but in Zed these must be escaped to `\(` and `\)`. +* When replacing, Vim uses `\0` to represent the entire match, in Zed this is `$0`, same for numbered capture groups `\1` -> `$1`. +* Vim uses `\<` and `\>` to represent word boundaries, in Zed these are both handled by `\b` +* Vim uses `/g` to indicate "all matches on one line", in Zed this is implied +* Vim uses `/i` to indicate "case-insensitive", in Zed you can either use `(?i)` at the start of the pattern or toggle case-sensitivity with `cmd-option-c`. + +To help with the transition, the command palette will fix parentheses and replace groups for you when you run `:%s//`. So `%s:/\(a\)(b)/\1/` will be converted into a search for "(a)\(b\)" and a replacement of "$1". + +For the full syntax supported by Zed's regex engine see the [regex crate documentation](https://docs.rs/regex/latest/regex/#syntax). diff --git a/docs/src/developing_zed__adding_languages.md b/docs/src/developing_zed__adding_languages.md new file mode 100644 index 0000000000000000000000000000000000000000..2917b08422c1e2153a38f5c857a9318a9228c031 --- /dev/null +++ b/docs/src/developing_zed__adding_languages.md @@ -0,0 +1,83 @@ +# Adding New Languages to Zed + +## LSP + +Zed uses the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) to provide language support. This means, in theory, we can support any language that has an LSP server. + +## Syntax Highlighting + +### Defining syntax highlighting rules + +We use tree-sitter queries to match certian properties to highlight. + +#### Simple Example: + +```scheme +(property_identifier) @property +``` + +```ts +const font: FontFamily = { + weight: "normal", + underline: false, + italic: false, +} +``` + +Match a property identifier and highlight it using the identifier `@property`. In the above example, `weight`, `underline`, and `italic` would be highlighted. + +#### Complex example: + +```scheme +(_ + return_type: (type_annotation + [ + (type_identifier) @type.return + (generic_type + name: (type_identifier) @type.return) + ])) +``` + +```ts +function buildDefaultSyntax(colorScheme: Theme): Partial { + // ... +} +``` + +Match a function return type, and highlight the type using the identifier `@type.return`. In the above example, `Partial` would be highlighted. + +#### Example - Typescript + +Here is an example portion of our `highlights.scm` for TypeScript: + +```scheme +; crates/zed/src/languages/typescript/highlights.scm + +; Variables + +(identifier) @variable + +; Properties + +(property_identifier) @property + +; Function and method calls + +(call_expression + function: (identifier) @function) + +(call_expression + function: (member_expression + property: (property_identifier) @function.method)) + +; Function and method definitions + +(function + name: (identifier) @function) +(function_declaration + name: (identifier) @function) +(method_definition + name: (property_identifier) @function.method) + +; ... +``` diff --git a/docs/src/developing_zed__building_zed.md b/docs/src/developing_zed__building_zed.md new file mode 100644 index 0000000000000000000000000000000000000000..cb30051ffa19f551b46d6ddefdbf981077cb9fed --- /dev/null +++ b/docs/src/developing_zed__building_zed.md @@ -0,0 +1,107 @@ +# Building Zed + +🚧 TODO: +- [ ] Tidy up & update instructions +- [ ] Remove ZI-specific things +- [ ] Rework any steps that currently require a ZI-specific account + +How to build Zed from source for the first time. + +## Prerequisites + +- Be added to the GitHub organization +- Be added to the Vercel team + +## Process + +Expect this to take 30min to an hour! Some of these steps will take quite a while based on your connection speed, and how long your first build will be. + +1. Install the [GitHub CLI](https://cli.github.com/): + - `brew install gh` +1. Clone the `zed` repo + - `gh repo clone zed-industries/zed` +1. Install Xcode from the macOS App Store +1. Install Xcode command line tools + - `xcode-select --install` + - If xcode-select --print-path prints /Library/Developer/CommandLineTools… run `sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer.` +1. Install [Postgres](https://postgresapp.com) +1. Install rust/rustup + - `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh` +1. Install the wasm toolchain + - `rustup target add wasm32-wasi` +1. Install Livekit & Foreman + - `brew install livekit` + - `brew install foreman` +1. Generate an GitHub API Key + - Go to https://github.com/settings/tokens and Generate new token + - GitHub currently provides two kinds of tokens: + - Classic Tokens, where only `repo` (Full control of private repositories) OAuth scope has to be selected + Unfortunately, unselecting `repo` scope and selecting every its inner scope instead does not allow the token users to read from private repositories + - (not applicable) Fine-grained Tokens, at the moment of writing, did not allow any kind of access of non-owned private repos + - Keep the token in the browser tab/editor for the next two steps +1. (Optional but reccomended) Add your GITHUB_TOKEN to your `.zshrc` or `.bashrc` like this: `export GITHUB_TOKEN=yourGithubAPIToken` +1. Ensure the Zed.dev website is checked out in a sibling directory and install it's dependencies: + ``` + cd .. + git clone https://github.com/zed-industries/zed.dev + cd zed.dev && npm install + npm install -g vercel + ``` +1. Link your zed.dev project to Vercel + - `vercel link` + - Select the `zed-industries` team. If you don't have this get someone on the team to add you to it. + - Select the `zed.dev` project +1. Run `vercel pull` to pull down the environment variables and project info from Vercel +1. Open Postgres.app +1. From `./path/to/zed/`: + - Run: + - `GITHUB_TOKEN={yourGithubAPIToken} script/bootstrap` + - Replace `{yourGithubAPIToken}` with the API token you generated above. + - You don't need to include the GITHUB_TOKEN if you exported it above. + - Consider removing the token (if it's fine for you to recreate such tokens during occasional migrations) or store this token somewhere safe (like your Zed 1Password vault). + - If you get: + - ```bash + Error: Cannot install in Homebrew on ARM processor in Intel default prefix (/usr/local)! + Please create a new installation in /opt/homebrew using one of the + "Alternative Installs" from: + https://docs.brew.sh/Installation + ``` + - In that case try: + - `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"` + - If Homebrew is not in your PATH: + - Replace `{username}` with your home folder name (usually your login name) + - `echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/{username}/.zprofile` + - `eval "$(/opt/homebrew/bin/brew shellenv)"` +1. To run the Zed app: + - If you are working on zed: + - `cargo run` + - If you are just using the latest version, but not working on zed: + - `cargo run --release` + - If you need to run the collaboration server locally: + - `script/zed-local` + +## Troubleshooting + +### `error: failed to run custom build command for gpui v0.1.0 (/Users/path/to/zed)` + +- Try `xcode-select --switch /Applications/Xcode.app/Contents/Developer` + +### `xcrun: error: unable to find utility "metal", not a developer tool or in PATH` + +### Seeding errors during `script/bootstrap` runs + +``` +seeding database... +thread 'main' panicked at 'failed to deserialize github user from 'https://api.github.com/orgs/zed-industries/teams/staff/members': reqwest::Error { kind: Decode, source: Error("invalid type: map, expected a sequence", line: 1, column: 0) }', crates/collab/src/bin/seed.rs:111:10 +``` + +Wrong permissions for `GITHUB_TOKEN` token used, the token needs to be able to read from private repos. +For Classic GitHub Tokens, that required OAuth scope `repo` (seacrh the scope name above for more details) + +Same command + +`sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer` + +### If you experience errors that mention some dependency is using unstable features + +Try `cargo clean` and `cargo build` diff --git a/docs/local-collaboration.md b/docs/src/developing_zed__local_collaboration.md similarity index 100% rename from docs/local-collaboration.md rename to docs/src/developing_zed__local_collaboration.md diff --git a/docs/src/feedback.md b/docs/src/feedback.md new file mode 100644 index 0000000000000000000000000000000000000000..11ae444079c05d9b2573e4c691ef88848ddd2fd7 --- /dev/null +++ b/docs/src/feedback.md @@ -0,0 +1,29 @@ +# Giving feedback + +### Community repository + +We track our issues at [`zed-industries/community`](https://github.com/zed-industries/community/issues). + +#### Feature requests + +Try to focus on the things that are most critical to you rather than exhaustively listing all features another editor you have used has. + +Command palette: `request feature` + +#### Bug reports + +Try to add as much detail as possible, if it is not obvious to reproduce. Let us know how severe the problem is for you; is the issue more of a minor inconvenience or something that would prevent you from using Zed? + +Command palette: `file bug report` + +### In-app feedback + +Anonymous feedback can be submitted from within Zed via the feedback editor (command palette: `give feedback`). + +### Zed forum + +Use the [community forum](https://github.com/zed-industries/community/discussions) to ask questions and learn from one another. We will be present in the forum and answering questions as well. + +### Email + +If you prefer to write up your thoughts as an email, you can send them to [hi@zed.dev](mailto:hi@zed.dev). diff --git a/docs/src/getting_started.md b/docs/src/getting_started.md new file mode 100644 index 0000000000000000000000000000000000000000..236249d00abf339e0cd291e1b0ec82b5447f8419 --- /dev/null +++ b/docs/src/getting_started.md @@ -0,0 +1,15 @@ +# Getting Started + +Welcome to Zed! We are excited to have you. Here is a jumping-off point to getting started. + +### Download Zed + +You can obtain the release build via the [download page](https://zed.dev/download). After the first manual installation, Zed will periodically check for and install updates automatically for you. + +### Configure Zed + +Use `CMD + ,` to open your custom settings to set things like fonts, formatting settings, per-language settings and more. You can access the default configuration using the `Zed > Settings > Open Default Settings` menu item. See Configuring Zed for all available settings. + +### Set up your key bindings + +You can access the default key binding set using the `Zed > Settings > Open Default Key Bindings` menu item. Use `CMD + K`,`CMD + S` to open your custom keymap to add your own key bindings. See Key Bindings for more info., diff --git a/docs/src/system_requirements.md b/docs/src/system_requirements.md new file mode 100644 index 0000000000000000000000000000000000000000..debf7fa2998b262e9ad07746e3732e433b448fe6 --- /dev/null +++ b/docs/src/system_requirements.md @@ -0,0 +1,13 @@ +# System Requirements + +## macOS + +Supported versions: Catalina (10.15) - Ventura (13.x). + +{% hint style="info" %} +The implementation of our screen sharing feature makes use of [LiveKit](https://livekit.io). The LiveKit SDK requires macOS Catalina (10.15); consequently, in v0.62.4, we dropped support for earlier macOS versions that we were initially supporting. +{% endhint %} + +## Linux, Windows, and Web + +_Not supported at this time. See our_ [_Platform Support_](https://github.com/zed-industries/community/issues/174) _issue._ diff --git a/docs/src/telemetry.md b/docs/src/telemetry.md new file mode 100644 index 0000000000000000000000000000000000000000..834e02770aee030dcbf33c419ba6a8848de65024 --- /dev/null +++ b/docs/src/telemetry.md @@ -0,0 +1,147 @@ +# Telemetry in Zed + +**Up to date with v0.112.0** + +Zed collects anonymous telemetry data to help the team understand how people are using the application and to see what sort of issues they are experiencing. + +## Dataflow + +Telemetry is sent from the application to zed.dev. Data is proxied through our servers to enable us to easily switch analytics services; we never store this data. The data is then sent off to various services: + +- [Datadog](https://www.datadoghq.com): Cloud-monitoring service - stores diagnostic events +- [Clickhouse](https://clickhouse.com): Business Intelligence platform - stores both diagnostic and metric events +- [Metabase](https://www.metabase.com): Dashboards - dashboards built around data pulled from Clickhouse + +## Types of Telemetry + +### Diagnostics + +Diagnostic events include debug information (stack traces) from crash reports. Reports are sent on the first application launch after the crash occurred. We've built dashboards that allow us to visualize the frequency and severity of issues experienced by users. Having these reports sent automatically allows us to begin implementing fixes without the user needing to file a report in our issue tracker. The plots in the dashboards also give us an informal measurement of the stability of Zed. + +When a panic occurs, the following data is sent: + +#### PanicRequest + +- `panic`: The panic data +- `token`: An identifier that is used to authenticate the request on zed.dev + +#### Panic + +- `thread`: The name of the thread that panicked +- `payload`: The panic message +- `location_data`: The location of the panic + - `file` + - `line` +- `backtrace`: The backtrace of the panic +- `app_version`: Zed's app version +- `release_channel`: Zed's release channel + - `stable` + - `preview` + - `dev` +- `os_name`: The name of your operating system +- `os_version`: The version of your operating system +- `architecture`: The architecture of your CPU +- `panicked_on`: The time that the panic occurred +- `installation_id`: An identifier that is unique to each installation of Zed (this differs for stable, preview, and dev builds) +- `session_id`: An identifier that is unique to each Zed session (this differs for each time you open Zed) + +### Metrics + +Zed also collects metric information based on user actions. Metric events are reported over HTTPS, and requests are rate-limited to avoid using significant network bandwidth. All data remains anonymous, and can't be related to specific Zed users. + +The following data is sent: + +#### ClickhouseEventRequestBody + +- `token`: An identifier that is used to authenticate the request on zed.dev +- `installation_id`: An identifier that is unique to each installation of Zed (this differs for stable, preview, and dev builds) +- `session_id`: An identifier that is unique to each Zed session (this differs for each time you open Zed) +- `is_staff`: A boolean that indicates whether the user is a member of the Zed team or not +- `app_version`: Zed's app version +- `os_name`: The name of your operating system +- `os_version`: The version of your operating system +- `architecture`: The architecture of your CPU +- `release_channel`: Zed's release channel + - `stable` + - `preview` + - `dev` +- `events`: A vector of `ClickhouseEventWrapper`s + +#### ClickhouseEventWrapper + +- `signed_in`: A boolean that indicates whether the user is signed in or not +- `event`: An enum, where each variant can be one of the following `ClickhouseEvent` variants: + +#### ClickhouseEvent + +- `editor` + - `operation`: The editor operation that was performed + - `open` + - `save` + - `file_extension`: The extension of the file that was opened or saved + - `vim_mode`: A boolean that indicates whether the user is in vim mode or not + - `copilot_enabled`: A boolean that indicates whether the user has copilot enabled or not + - `copilot_enabled_for_language`: A boolean that indicates whether the user has copilot enabled for the language of the file that was opened or saved + - `milliseconds_since_first_event`: Duration of time between this event's timestamp and the timestamp of the first event in the current batch +- `copilot` + - `suggestion_id`: The ID of the suggestion + - `suggestion_accepted`: A boolean that indicates whether the suggestion was accepted or not + - `file_extension`: The file extension of the file that was opened or saved + - `milliseconds_since_first_event`: Same as above +- `call` + - `operation`: The call operation that was performed + - `accept incoming` + - `decline incoming` + - `disable microphone` + - `disable screen share` + - `enable microphone` + - `enable screen share` + - `hang up` + - `invite` + - `join channel` + - `open channel notes` + - `share project` + - `unshare project` + - `room_id`: The ID of the room + - `channel_id`: The ID of the channel + - `milliseconds_since_first_event`: Same as above +- `assistant` + - `conversation_id`: The ID of the conversation (for panel events only) + - `kind`: An enum with the following variants: + - `panel` + - `inline` + - `model`: The model that was used + - `milliseconds_since_first_event`: Same as above +- `cpu` + - `usage_as_percentage`: The CPU usage + - `core_count`: The number of cores on the CPU + - `milliseconds_since_first_event`: Same as above +- `memory` + - `memory_in_bytes`: The amount of memory used in bytes + - `virtual_memory_in_bytes`: The amount of virtual memory used in bytes + - `milliseconds_since_first_event`: Same as above +- `app` + - `operation`: The app operation that was performed + - `first open` + - `open` + - `close (only in GPUI2-powered Zed)` + - `milliseconds_since_first_event`: Same as above + +You can audit the metrics data that Zed has reported by running the command `zed: open telemetry log` from the command palette, or clicking `Help > View Telemetry Log` in the application menu. + +### Configuring Telemetry Settings + +You have full control over what data is sent out by Zed. To enable or disable some or all telemetry types, open your `settings.json` file via `zed: open settings` from the command palette. Insert and tweak the following: + +```json +"telemetry": { + "diagnostics": false, + "metrics": false +}, +``` + +The telemetry settings can also be configured via the `welcome` screen, which can be invoked via the `workspace: welcome` action in the command palette. + +### Concerns and Questions + +If you have concerns about telemetry, please feel free to open issues in our [community repository](https://github.com/zed-industries/community/issues/new/choose). diff --git a/docs/backend-development.md b/docs_old/backend-development.md similarity index 100% rename from docs/backend-development.md rename to docs_old/backend-development.md diff --git a/docs/building-zed.md b/docs_old/building-zed.md similarity index 100% rename from docs/building-zed.md rename to docs_old/building-zed.md diff --git a/docs/company-and-vision.md b/docs_old/company-and-vision.md similarity index 100% rename from docs/company-and-vision.md rename to docs_old/company-and-vision.md diff --git a/docs/design-tools.md b/docs_old/design-tools.md similarity index 100% rename from docs/design-tools.md rename to docs_old/design-tools.md diff --git a/docs/index.md b/docs_old/index.md similarity index 100% rename from docs/index.md rename to docs_old/index.md diff --git a/docs_old/local-collaboration.md b/docs_old/local-collaboration.md new file mode 100644 index 0000000000000000000000000000000000000000..4c059c0878b4df38a3450a5e4d44787ee10aaf0f --- /dev/null +++ b/docs_old/local-collaboration.md @@ -0,0 +1,22 @@ +# Local Collaboration + +## Setting up the local collaboration server + +### Setting up for the first time? + +1. Make sure you have livekit installed (`brew install livekit`) +1. Install [Postgres](https://postgresapp.com) and run it. +1. Then, from the root of the repo, run `script/bootstrap`. + +### Have a db that is out of date? / Need to migrate? + +1. Make sure you have livekit installed (`brew install livekit`) +1. Try `cd crates/collab && cargo run -- migrate` from the root of the repo. +1. Run `script/seed-db` + +## Testing collab locally + +1. Run `foreman start` from the root of the repo. +1. In another terminal run `script/zed-local -2`. +1. Two copies of Zed will open. Add yourself as a contact in the one that is not you. +1. Start a collaboration session as normal with any open project. diff --git a/docs/release-process.md b/docs_old/release-process.md similarity index 100% rename from docs/release-process.md rename to docs_old/release-process.md diff --git a/docs/theme/generating-theme-types.md b/docs_old/theme/generating-theme-types.md similarity index 100% rename from docs/theme/generating-theme-types.md rename to docs_old/theme/generating-theme-types.md diff --git a/docs/tools.md b/docs_old/tools.md similarity index 100% rename from docs/tools.md rename to docs_old/tools.md diff --git a/docs/zed/syntax-highlighting.md b/docs_old/zed/syntax-highlighting.md similarity index 100% rename from docs/zed/syntax-highlighting.md rename to docs_old/zed/syntax-highlighting.md From 5b3b15e95cb97553377e7cc0661fec145f9dd5a3 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 12 Dec 2023 09:10:12 -0500 Subject: [PATCH 005/644] Futher outline --- docs/src/CONTRIBUTING.md | 3 --- docs/src/SUMMARY.md | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) delete mode 100644 docs/src/CONTRIBUTING.md diff --git a/docs/src/CONTRIBUTING.md b/docs/src/CONTRIBUTING.md deleted file mode 100644 index d48c26844f2ee079fedcbdda70ac83704abb9747..0000000000000000000000000000000000000000 --- a/docs/src/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributing - -TBD diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 4c6f5f9421dcb7e6b8517085e0c30374a216632b..ad1cd6332c4a5200a66ff5767db3673abc88f921 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -7,12 +7,19 @@ - [Settings](./configuring_zed.md) - [Vim Mode](./configuring_zed__configuring_vim.md) -# Developing Zed +# Using Zed +- [Workflows]() +- [Collaboration]() +- [Using AI]() + +# Contributing to Zed +- [How to Contribute]() - [Building from Source](./developing_zed__building_zed.md) - [Local Collaboration](./developing_zed__local_collaboration.md) - [Adding Languages](./developing_zed__adding_languages.md) +- [Adding UI]() + +--- -# Other -- [Code of Conduct](./CODE_OF_CONDUCT.md) -- [Telemetry](./telemetry.md) -- [Contributing](./CONTRIBUTING.md) +[Telemetry](./telemetry.md) +[Code of Conduct](./CODE_OF_CONDUCT.md) From f9e7c796720834ec7c7da0622b5b8a4da34d8afe Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Wed, 13 Dec 2023 10:35:03 -0500 Subject: [PATCH 006/644] Add deploy note --- docs/how-to-deploy.md | 8 ++++++++ {docs_old => docs/old}/backend-development.md | 0 {docs_old => docs/old}/building-zed.md | 0 {docs_old => docs/old}/company-and-vision.md | 0 {docs_old => docs/old}/design-tools.md | 0 {docs_old => docs/old}/index.md | 0 {docs_old => docs/old}/local-collaboration.md | 0 {docs_old => docs/old}/release-process.md | 0 {docs_old => docs/old}/theme/generating-theme-types.md | 0 {docs_old => docs/old}/tools.md | 0 {docs_old => docs/old}/zed/syntax-highlighting.md | 0 11 files changed, 8 insertions(+) create mode 100644 docs/how-to-deploy.md rename {docs_old => docs/old}/backend-development.md (100%) rename {docs_old => docs/old}/building-zed.md (100%) rename {docs_old => docs/old}/company-and-vision.md (100%) rename {docs_old => docs/old}/design-tools.md (100%) rename {docs_old => docs/old}/index.md (100%) rename {docs_old => docs/old}/local-collaboration.md (100%) rename {docs_old => docs/old}/release-process.md (100%) rename {docs_old => docs/old}/theme/generating-theme-types.md (100%) rename {docs_old => docs/old}/tools.md (100%) rename {docs_old => docs/old}/zed/syntax-highlighting.md (100%) diff --git a/docs/how-to-deploy.md b/docs/how-to-deploy.md new file mode 100644 index 0000000000000000000000000000000000000000..b1222aac5cddc196add7ea8020f59641df3b39eb --- /dev/null +++ b/docs/how-to-deploy.md @@ -0,0 +1,8 @@ +1. `cd docs` from repo root +1. Install the vercel cli if you haven't already + - `pnpm i -g vercel` +1. `vercel` to deploy if you already have the project linked +1. Otherwise, `vercel login` and `vercel` to link + - Choose Zed Industries as the team, then `zed-app-docs` as the project + +Someone can write a script for this when they have time. diff --git a/docs_old/backend-development.md b/docs/old/backend-development.md similarity index 100% rename from docs_old/backend-development.md rename to docs/old/backend-development.md diff --git a/docs_old/building-zed.md b/docs/old/building-zed.md similarity index 100% rename from docs_old/building-zed.md rename to docs/old/building-zed.md diff --git a/docs_old/company-and-vision.md b/docs/old/company-and-vision.md similarity index 100% rename from docs_old/company-and-vision.md rename to docs/old/company-and-vision.md diff --git a/docs_old/design-tools.md b/docs/old/design-tools.md similarity index 100% rename from docs_old/design-tools.md rename to docs/old/design-tools.md diff --git a/docs_old/index.md b/docs/old/index.md similarity index 100% rename from docs_old/index.md rename to docs/old/index.md diff --git a/docs_old/local-collaboration.md b/docs/old/local-collaboration.md similarity index 100% rename from docs_old/local-collaboration.md rename to docs/old/local-collaboration.md diff --git a/docs_old/release-process.md b/docs/old/release-process.md similarity index 100% rename from docs_old/release-process.md rename to docs/old/release-process.md diff --git a/docs_old/theme/generating-theme-types.md b/docs/old/theme/generating-theme-types.md similarity index 100% rename from docs_old/theme/generating-theme-types.md rename to docs/old/theme/generating-theme-types.md diff --git a/docs_old/tools.md b/docs/old/tools.md similarity index 100% rename from docs_old/tools.md rename to docs/old/tools.md diff --git a/docs_old/zed/syntax-highlighting.md b/docs/old/zed/syntax-highlighting.md similarity index 100% rename from docs_old/zed/syntax-highlighting.md rename to docs/old/zed/syntax-highlighting.md From 70c6660ae4f7d0c2a70218022509bc4c1d77e4f1 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Wed, 13 Dec 2023 10:35:54 -0500 Subject: [PATCH 007/644] Add note --- docs/how-to-deploy.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/how-to-deploy.md b/docs/how-to-deploy.md index b1222aac5cddc196add7ea8020f59641df3b39eb..c32d3619a6d12657843b43ee9083291faed1c4e1 100644 --- a/docs/how-to-deploy.md +++ b/docs/how-to-deploy.md @@ -1,3 +1,5 @@ +These docs are intendended to replace both docs.zed.dev and introduce people to how to build Zed from source. + 1. `cd docs` from repo root 1. Install the vercel cli if you haven't already - `pnpm i -g vercel` From a874a96e76b8cced2bc0fe5e108f35b813814c7c Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 13 Dec 2023 11:44:51 -0500 Subject: [PATCH 008/644] Fix tab bar drop target sizing (#3627) This PR fixes an issue where the tab bar drop target was not receiving any size. The styling isn't 100% correct yet, as the updated background color has a gap around it. Release Notes: - N/A --- crates/workspace2/src/pane.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 20682451596f986e09665882014db6972ed68b19..afd7e665c4503e8492921206964d6a37b795b6f2 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1664,6 +1664,10 @@ impl Pane { ) .child( div() + .min_w_6() + // HACK: This empty child is currently necessary to force the drop traget to appear + // despite us setting a min width above. + .child("") .h_full() .flex_grow() .drag_over::(|bar| { From ab8d0abbc142052779a9968c4d64c2c26d335cab Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 13 Dec 2023 12:11:33 -0500 Subject: [PATCH 009/644] Wire up tooltips on tab bar actions (#3629) This PR wires up the tooltips on the actions in the tab bar. Release Notes: - N/A --- crates/workspace2/src/pane.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index afd7e665c4503e8492921206964d6a37b795b6f2..bcbadc4e532bcde153d4d70fc7044d51a490d44d 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1597,7 +1597,8 @@ impl Pane { let view = cx.view().clone(); move |_, cx| view.update(cx, Self::navigate_backward) }) - .disabled(!self.can_navigate_backward()), + .disabled(!self.can_navigate_backward()) + .tooltip(|cx| Tooltip::for_action("Go Back", &GoBack, cx)), ) .start_child( IconButton::new("navigate_forward", Icon::ArrowRight) @@ -1606,7 +1607,8 @@ impl Pane { let view = cx.view().clone(); move |_, cx| view.update(cx, Self::navigate_backward) }) - .disabled(!self.can_navigate_forward()), + .disabled(!self.can_navigate_forward()) + .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)), ) .end_child( div() @@ -1625,7 +1627,8 @@ impl Pane { }) .detach(); this.new_item_menu = Some(menu); - })), + })) + .tooltip(|cx| Tooltip::text("New...", cx)), ) .when_some(self.new_item_menu.as_ref(), |el, new_item_menu| { el.child(Self::render_menu_overlay(new_item_menu)) @@ -1649,7 +1652,8 @@ impl Pane { }) .detach(); this.split_item_menu = Some(menu); - })), + })) + .tooltip(|cx| Tooltip::text("Split Pane", cx)), ) .when_some(self.split_item_menu.as_ref(), |el, split_item_menu| { el.child(Self::render_menu_overlay(split_item_menu)) From 48faa171b53e252a07e1f95c10603c9d6dd196e6 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 13 Dec 2023 12:24:10 -0500 Subject: [PATCH 010/644] v0.118.x dev --- Cargo.lock | 2 +- crates/zed/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 033ff8b69c542ea96e5d3cac6d7d8320c4383946..cc4393bffa9e541330e6cf34c19b50b2e64e2a1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11882,7 +11882,7 @@ dependencies = [ [[package]] name = "zed" -version = "0.117.0" +version = "0.118.0" dependencies = [ "activity_indicator", "ai", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index f665cc36dbdc8f4b0fa8576768efb32388d07374..0c115fb2850a07afc1d26b348c80d9816418c232 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Nathan Sobo "] description = "The fast, collaborative code editor." edition = "2021" name = "zed" -version = "0.117.0" +version = "0.118.0" publish = false [lib] From a91a42763f8abd5426059dfb1206e0239deba099 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:56:49 +0100 Subject: [PATCH 011/644] collab_ui: Wire up project picker Co-authored-by: Conrad --- crates/collab_ui2/src/collab_titlebar_item.rs | 111 ++++++++++-------- crates/picker2/src/picker2.rs | 23 ++-- .../recent_projects2/src/recent_projects.rs | 21 +++- 3 files changed, 95 insertions(+), 60 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 2b931f7085b55d868a428453040e6a905b1628dd..f48a78fb1d87dd1d69db7011c70e3c726f48d733 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -2,11 +2,13 @@ use crate::face_pile::FacePile; use call::{ActiveCall, ParticipantLocation, Room}; use client::{proto::PeerId, Client, ParticipantIndex, User, UserStore}; use gpui::{ - actions, canvas, div, point, px, rems, AppContext, Div, Element, Hsla, InteractiveElement, - IntoElement, Model, ParentElement, Path, Render, Stateful, StatefulInteractiveElement, Styled, - Subscription, ViewContext, VisualContext, WeakView, WindowBounds, + actions, canvas, div, overlay, point, px, rems, AppContext, DismissEvent, Div, Element, + FocusableView, Hsla, InteractiveElement, IntoElement, Model, Overlay, ParentElement, Path, + Render, Stateful, StatefulInteractiveElement, Styled, Subscription, ViewContext, VisualContext, + WeakView, WindowBounds, }; use project::{Project, RepositoryEntry}; +use recent_projects::RecentProjects; use std::sync::Arc; use theme::{ActiveTheme, PlayerColors}; use ui::{ @@ -14,7 +16,7 @@ use ui::{ IconButton, IconElement, KeyBinding, Tooltip, }; use util::ResultExt; -use workspace::{notifications::NotifyResultExt, Workspace}; +use workspace::{notifications::NotifyResultExt, Workspace, WORKSPACE_DB}; const MAX_PROJECT_NAME_LENGTH: usize = 40; const MAX_BRANCH_NAME_LENGTH: usize = 40; @@ -49,7 +51,7 @@ pub struct CollabTitlebarItem { client: Arc, workspace: WeakView, //branch_popover: Option>, - //project_popover: Option>, + project_popover: Option, //user_menu: ViewHandle, _subscriptions: Vec, } @@ -328,7 +330,7 @@ impl CollabTitlebarItem { // menu // }), // branch_popover: None, - // project_popover: None, + project_popover: None, _subscriptions: subscriptions, } } @@ -366,11 +368,27 @@ impl CollabTitlebarItem { let name = util::truncate_and_trailoff(name, MAX_PROJECT_NAME_LENGTH); - div().border().border_color(gpui::red()).child( - Button::new("project_name_trigger", name) - .style(ButtonStyle::Subtle) - .tooltip(move |cx| Tooltip::text("Recent Projects", cx)), - ) + div() + .border() + .border_color(gpui::red()) + .child( + Button::new("project_name_trigger", name) + .style(ButtonStyle::Subtle) + .tooltip(move |cx| Tooltip::text("Recent Projects", cx)) + .on_click(cx.listener(|this, _, cx| { + this.toggle_project_menu(&ToggleProjectMenu, cx); + })), + ) + .children(self.project_popover.as_ref().map(|popover| { + overlay().child( + div() + .min_w_56() + .on_mouse_down_out(cx.listener_for(&popover.picker, |picker, _, cx| { + picker.cancel(&Default::default(), cx) + })) + .child(popover.picker.clone()), + ) + })) } pub fn render_project_branch(&self, cx: &mut ViewContext) -> Option { @@ -611,43 +629,40 @@ impl CollabTitlebarItem { // cx.notify(); // } - // pub fn toggle_project_menu(&mut self, _: &ToggleProjectMenu, cx: &mut ViewContext) { - // let workspace = self.workspace.clone(); - // if self.project_popover.take().is_none() { - // cx.spawn(|this, mut cx| async move { - // let workspaces = WORKSPACE_DB - // .recent_workspaces_on_disk() - // .await - // .unwrap_or_default() - // .into_iter() - // .map(|(_, location)| location) - // .collect(); - - // let workspace = workspace.clone(); - // this.update(&mut cx, move |this, cx| { - // let view = cx.add_view(|cx| build_recent_projects(workspace, workspaces, cx)); - - // cx.subscribe(&view, |this, _, event, cx| { - // match event { - // PickerEvent::Dismiss => { - // this.project_popover = None; - // } - // } - - // cx.notify(); - // }) - // .detach(); - // cx.focus(&view); - // this.branch_popover.take(); - // this.project_popover = Some(view); - // cx.notify(); - // }) - // .log_err(); - // }) - // .detach(); - // } - // cx.notify(); - // } + pub fn toggle_project_menu(&mut self, _: &ToggleProjectMenu, cx: &mut ViewContext) { + let workspace = self.workspace.clone(); + if self.project_popover.take().is_none() { + cx.spawn(|this, mut cx| async move { + let workspaces = WORKSPACE_DB + .recent_workspaces_on_disk() + .await + .unwrap_or_default() + .into_iter() + .map(|(_, location)| location) + .collect(); + + let workspace = workspace.clone(); + this.update(&mut cx, move |this, cx| { + let view = RecentProjects::open_popover(workspace, workspaces, cx); + + cx.subscribe(&view.picker, |this, _, _: &DismissEvent, cx| { + this.project_popover = None; + cx.notify(); + }) + .detach(); + let focus_handle = view.focus_handle(cx); + cx.focus(&focus_handle); + // todo!() + //this.branch_popover.take(); + this.project_popover = Some(view); + cx.notify(); + }) + .log_err(); + }) + .detach(); + } + cx.notify(); + } // fn render_user_menu_button( // &self, diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 98b6ce5ff099326943feb2009f9e7f27a9d43d62..db5eebff5389a1f3bd9f0561a017fcb109ec904e 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -1,8 +1,8 @@ use editor::Editor; use gpui::{ - div, prelude::*, rems, uniform_list, AnyElement, AppContext, Div, FocusHandle, FocusableView, - MouseButton, MouseDownEvent, Render, Task, UniformListScrollHandle, View, ViewContext, - WindowContext, + div, prelude::*, rems, uniform_list, AnyElement, AppContext, DismissEvent, Div, EventEmitter, + FocusHandle, FocusableView, MouseButton, MouseDownEvent, Render, Task, UniformListScrollHandle, + View, ViewContext, WindowContext, }; use std::{cmp, sync::Arc}; use ui::{prelude::*, v_stack, Color, Divider, Label}; @@ -113,8 +113,9 @@ impl Picker { cx.notify(); } - fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext) { + pub fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext) { self.delegate.dismissed(cx); + cx.emit(DismissEvent); } fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext) { @@ -146,9 +147,15 @@ impl Picker { event: &editor::EditorEvent, cx: &mut ViewContext, ) { - if let editor::EditorEvent::BufferEdited = event { - let query = self.editor.read(cx).text(cx); - self.update_matches(query, cx); + match event { + editor::EditorEvent::BufferEdited => { + let query = self.editor.read(cx).text(cx); + self.update_matches(query, cx); + } + editor::EditorEvent::Blurred => { + self.cancel(&menu::Cancel, cx); + } + _ => {} } } @@ -189,6 +196,8 @@ impl Picker { } } +impl EventEmitter for Picker {} + impl Render for Picker { type Element = Div; diff --git a/crates/recent_projects2/src/recent_projects.rs b/crates/recent_projects2/src/recent_projects.rs index e0147836876bf47a431fae5344911abd65d96292..dff6aa12ccc30f43766451d244619159c2a7c8bb 100644 --- a/crates/recent_projects2/src/recent_projects.rs +++ b/crates/recent_projects2/src/recent_projects.rs @@ -23,14 +23,15 @@ pub fn init(cx: &mut AppContext) { cx.observe_new_views(RecentProjects::register).detach(); } +#[derive(Clone)] pub struct RecentProjects { - picker: View>, + pub picker: View>, } impl ModalView for RecentProjects {} impl RecentProjects { - fn new(delegate: RecentProjectsDelegate, cx: &mut ViewContext) -> Self { + fn new(delegate: RecentProjectsDelegate, cx: &mut WindowContext<'_>) -> Self { Self { picker: cx.build_view(|cx| Picker::new(delegate, cx)), } @@ -86,6 +87,16 @@ impl RecentProjects { Ok(()) })) } + pub fn open_popover( + workspace: WeakView, + workspaces: Vec, + cx: &mut WindowContext<'_>, + ) -> Self { + Self::new( + RecentProjectsDelegate::new(workspace, workspaces, false), + cx, + ) + } } impl EventEmitter for RecentProjects {} @@ -127,7 +138,7 @@ impl RecentProjectsDelegate { } } } - +impl EventEmitter for RecentProjectsDelegate {} impl PickerDelegate for RecentProjectsDelegate { type ListItem = ListItem; @@ -202,11 +213,11 @@ impl PickerDelegate for RecentProjectsDelegate { .open_workspace_for_paths(workspace_location.paths().as_ref().clone(), cx) }) .detach_and_log_err(cx); - self.dismissed(cx); + cx.emit(DismissEvent); } } - fn dismissed(&mut self, _cx: &mut ViewContext>) {} + fn dismissed(&mut self, _: &mut ViewContext>) {} fn render_match( &self, From 72eef116c965f49ead482b1cc765a580c50cd191 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:58:17 +0100 Subject: [PATCH 012/644] fixup! collab_ui: Wire up project picker --- crates/collab_ui2/src/collab_titlebar_item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index f48a78fb1d87dd1d69db7011c70e3c726f48d733..3d8fedd06bb363c4efacd4e6458b6e796a366f94 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -3,8 +3,8 @@ use call::{ActiveCall, ParticipantLocation, Room}; use client::{proto::PeerId, Client, ParticipantIndex, User, UserStore}; use gpui::{ actions, canvas, div, overlay, point, px, rems, AppContext, DismissEvent, Div, Element, - FocusableView, Hsla, InteractiveElement, IntoElement, Model, Overlay, ParentElement, Path, - Render, Stateful, StatefulInteractiveElement, Styled, Subscription, ViewContext, VisualContext, + FocusableView, Hsla, InteractiveElement, IntoElement, Model, ParentElement, Path, Render, + Stateful, StatefulInteractiveElement, Styled, Subscription, ViewContext, VisualContext, WeakView, WindowBounds, }; use project::{Project, RepositoryEntry}; From 3094cb749ed1691a230b4bc037bd5e9676164c18 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Wed, 13 Dec 2023 14:12:59 -0700 Subject: [PATCH 013/644] Implement user menu --- Cargo.lock | 2 + crates/collab_ui2/Cargo.toml | 4 +- crates/collab_ui2/src/collab_titlebar_item.rs | 60 ++++++++++++++----- crates/zed2/src/zed2.rs | 3 +- crates/zed_actions2/src/lib.rs | 2 +- 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba868ebbae5a95b5faf4b90918a6d53f33e978d8..a6cc38ef6a8f22cd705aa0a8fd9d0283fb796fbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1957,6 +1957,7 @@ dependencies = [ "db2", "editor2", "feature_flags2", + "feedback2", "futures 0.3.28", "fuzzy2", "gpui2", @@ -1978,6 +1979,7 @@ dependencies = [ "settings2", "smallvec", "theme2", + "theme_selector2", "time", "tree-sitter-markdown", "ui2", diff --git a/crates/collab_ui2/Cargo.toml b/crates/collab_ui2/Cargo.toml index 65aced8e7edf1e522a97d44cd4dcbdf04536f348..88c27bc1657df28cb6ecbef07fbf856353a7d516 100644 --- a/crates/collab_ui2/Cargo.toml +++ b/crates/collab_ui2/Cargo.toml @@ -32,7 +32,7 @@ collections = { path = "../collections" } # context_menu = { path = "../context_menu" } # drag_and_drop = { path = "../drag_and_drop" } editor = { package="editor2", path = "../editor2" } -#feedback = { path = "../feedback" } +feedback = { package = "feedback2", path = "../feedback2" } fuzzy = { package = "fuzzy2", path = "../fuzzy2" } gpui = { package = "gpui2", path = "../gpui2" } language = { package = "language2", path = "../language2" } @@ -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 = { path = "../theme_selector" } +theme_selector = { package = "theme_selector2", path = "../theme_selector2" } # vcs_menu = { path = "../vcs_menu" } ui = { package = "ui2", path = "../ui2" } util = { path = "../util" } diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 3d8fedd06bb363c4efacd4e6458b6e796a366f94..d6de5a1565d82493c4bdec08544f63ad3370a7e2 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -1,8 +1,8 @@ use crate::face_pile::FacePile; use call::{ActiveCall, ParticipantLocation, Room}; -use client::{proto::PeerId, Client, ParticipantIndex, User, UserStore}; +use client::{proto::PeerId, Client, ParticipantIndex, SignOut, User, UserStore}; use gpui::{ - actions, canvas, div, overlay, point, px, rems, AppContext, DismissEvent, Div, Element, + actions, canvas, div, overlay, point, px, rems, Action, AppContext, DismissEvent, Div, Element, FocusableView, Hsla, InteractiveElement, IntoElement, Model, ParentElement, Path, Render, Stateful, StatefulInteractiveElement, Styled, Subscription, ViewContext, VisualContext, WeakView, WindowBounds, @@ -16,7 +16,7 @@ use ui::{ IconButton, IconElement, KeyBinding, Tooltip, }; use util::ResultExt; -use workspace::{notifications::NotifyResultExt, Workspace, WORKSPACE_DB}; +use workspace::{notifications::NotifyResultExt, Feedback, Workspace, WORKSPACE_DB}; const MAX_PROJECT_NAME_LENGTH: usize = 40; const MAX_BRANCH_NAME_LENGTH: usize = 40; @@ -239,7 +239,19 @@ impl Render for CollabTitlebarItem { this.child( popover_menu("user-menu") .menu(|cx| { - ContextMenu::build(cx, |menu, _| menu.header("ADADA")) + ContextMenu::build(cx, |menu, _| { + menu.action( + "Settings", + zed_actions::OpenSettings.boxed_clone(), + ) + .action("Theme", theme_selector::Toggle.boxed_clone()) + .separator() + .action( + "Share Feedback", + feedback::GiveFeedback.boxed_clone(), + ) + .action("Sign Out", client::SignOut.boxed_clone()) + }) }) .trigger( ButtonLike::new("user-menu") @@ -259,16 +271,6 @@ impl Render for CollabTitlebarItem { ) .anchor(gpui::AnchorCorner::TopRight), ) - // this.child( - // ButtonLike::new("user-menu") - // .child( - // h_stack().gap_0p5().child(Avatar::data(avatar)).child( - // IconElement::new(Icon::ChevronDown).color(Color::Muted), - // ), - // ) - // .style(ButtonStyle::Subtle) - // .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)), - // ) } else { this.child(Button::new("sign_in", "Sign in").on_click(move |_, cx| { let client = client.clone(); @@ -280,6 +282,36 @@ impl Render for CollabTitlebarItem { }) .detach(); })) + .child( + popover_menu("user-menu") + .menu(|cx| { + ContextMenu::build(cx, |menu, _| { + menu.action( + "Settings", + zed_actions::OpenSettings.boxed_clone(), + ) + .action("Theme", theme_selector::Toggle.boxed_clone()) + .separator() + .action( + "Share Feedback", + feedback::GiveFeedback.boxed_clone(), + ) + }) + }) + .trigger( + ButtonLike::new("user-menu") + .child( + h_stack().gap_0p5().child( + IconElement::new(Icon::ChevronDown) + .color(Color::Muted), + ), + ) + .style(ButtonStyle::Subtle) + .tooltip(move |cx| { + Tooltip::text("Toggle User Menu", cx) + }), + ), + ) } })), ) diff --git a/crates/zed2/src/zed2.rs b/crates/zed2/src/zed2.rs index 611cf645528039f7cff2a85412a79fce984f7146..45ef08fdcc1b9fafb03d51a850174f5db4fb24e4 100644 --- a/crates/zed2/src/zed2.rs +++ b/crates/zed2/src/zed2.rs @@ -41,7 +41,7 @@ use workspace::{ notifications::simple_message_notification::MessageNotification, open_new, AppState, NewFile, NewWindow, Workspace, WorkspaceSettings, }; -use zed_actions::{OpenBrowser, OpenZedURL, Quit}; +use zed_actions::{OpenBrowser, OpenSettings, OpenZedURL, Quit}; actions!( zed, @@ -59,7 +59,6 @@ actions!( OpenLicenses, OpenLocalSettings, OpenLog, - OpenSettings, OpenTelemetryLog, ResetBufferFontSize, ResetDatabase, diff --git a/crates/zed_actions2/src/lib.rs b/crates/zed_actions2/src/lib.rs index fa1a4a5ea961ce77ecd5d199a182c88c17166bbe..badf76a6e7b4bc84a81184b81fca33c413b61bfa 100644 --- a/crates/zed_actions2/src/lib.rs +++ b/crates/zed_actions2/src/lib.rs @@ -22,4 +22,4 @@ pub struct OpenZedURL { impl_actions!(zed, [OpenBrowser, OpenZedURL]); -actions!(zed, [Quit]); +actions!(zed, [OpenSettings, Quit]); From 26a31b41b96d56815c581b587d381d632e9cf85b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 13 Dec 2023 13:02:19 -0800 Subject: [PATCH 014/644] frame time --- crates/gpui2/src/window.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 77eb4e27be20bd734c27258a00fd05eaeff35caf..a0db7d6d9e8d26f6c7cc848860e3779d66ed0669 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1236,6 +1236,8 @@ impl<'a> WindowContext<'a> { /// Draw pixels to the display for this window based on the contents of its scene. pub(crate) fn draw(&mut self) -> Scene { + let t0 = std::time::Instant::now(); + let window_was_focused = self .window .focus @@ -1326,6 +1328,7 @@ impl<'a> WindowContext<'a> { } self.window.dirty = false; + eprintln!("frame: {:?}", t0.elapsed()); scene } From 7899833367ea3971dd87b014aec4e962d3ffce23 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Wed, 13 Dec 2023 15:44:27 -0700 Subject: [PATCH 015/644] Don't hang the app when signing in offline --- Cargo.lock | 1 + crates/auto_update2/src/auto_update.rs | 4 +- crates/client2/src/client2.rs | 177 ++++---- crates/collab_ui2/Cargo.toml | 2 +- crates/collab_ui2/src/collab_titlebar_item.rs | 390 ++++++------------ crates/ui2/src/components/icon.rs | 2 + 6 files changed, 229 insertions(+), 347 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6cc38ef6a8f22cd705aa0a8fd9d0283fb796fbc..3b0a8e57fdb63690eed560f4bedd97d9cd1b10a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1949,6 +1949,7 @@ name = "collab_ui2" version = "0.1.0" dependencies = [ "anyhow", + "auto_update2", "call2", "channel2", "client2", diff --git a/crates/auto_update2/src/auto_update.rs b/crates/auto_update2/src/auto_update.rs index 31e474242ac7fd9cf918a785b35620ae7764df0e..e1e1de0da4f8a343d3b9b50aa5790e0e970f9d22 100644 --- a/crates/auto_update2/src/auto_update.rs +++ b/crates/auto_update2/src/auto_update.rs @@ -6,7 +6,7 @@ use db::kvp::KEY_VALUE_STORE; use db::RELEASE_CHANNEL; use gpui::{ actions, AppContext, AsyncAppContext, Context as _, Model, ModelContext, SemanticVersion, Task, - ViewContext, VisualContext, + ViewContext, VisualContext, WindowContext, }; use isahc::AsyncBody; use serde::Deserialize; @@ -125,7 +125,7 @@ pub fn init(http_client: Arc, server_url: String, cx: &mut AppCo } } -pub fn check(_: &Check, cx: &mut ViewContext) { +pub fn check(_: &Check, cx: &mut WindowContext) { if let Some(updater) = AutoUpdater::get(cx) { updater.update(cx, |updater, cx| updater.poll(cx)); } else { diff --git a/crates/client2/src/client2.rs b/crates/client2/src/client2.rs index bf8d5dda771c3d9ddea8a3b8b3978318f051fdc3..2c9787298944cba3e49134ccb215768707f4c803 100644 --- a/crates/client2/src/client2.rs +++ b/crates/client2/src/client2.rs @@ -11,8 +11,8 @@ use async_tungstenite::tungstenite::{ http::{Request, StatusCode}, }; use futures::{ - future::LocalBoxFuture, AsyncReadExt, FutureExt, SinkExt, StreamExt, TryFutureExt as _, - TryStreamExt, + channel::oneshot, future::LocalBoxFuture, AsyncReadExt, FutureExt, SinkExt, StreamExt, + TryFutureExt as _, TryStreamExt, }; use gpui::{ actions, serde_json, AnyModel, AnyWeakModel, AppContext, AsyncAppContext, Model, @@ -1020,91 +1020,116 @@ impl Client { ) -> Task> { let http = self.http.clone(); cx.spawn(|cx| async move { - // Generate a pair of asymmetric encryption keys. The public key will be used by the - // zed server to encrypt the user's access token, so that it can'be intercepted by - // any other app running on the user's device. - let (public_key, private_key) = - rpc::auth::keypair().expect("failed to generate keypair for auth"); - let public_key_string = - String::try_from(public_key).expect("failed to serialize public key for auth"); - - if let Some((login, token)) = IMPERSONATE_LOGIN.as_ref().zip(ADMIN_API_TOKEN.as_ref()) { - return Self::authenticate_as_admin(http, login.clone(), token.clone()).await; - } - - // Start an HTTP server to receive the redirect from Zed's sign-in page. - let server = tiny_http::Server::http("127.0.0.1:0").expect("failed to find open port"); - let port = server.server_addr().port(); + let background = cx.background_executor().clone(); - // Open the Zed sign-in page in the user's browser, with query parameters that indicate - // that the user is signing in from a Zed app running on the same device. - let mut url = format!( - "{}/native_app_signin?native_app_port={}&native_app_public_key={}", - *ZED_SERVER_URL, port, public_key_string - ); + let (open_url_tx, open_url_rx) = oneshot::channel::(); + cx.update(|cx| { + cx.spawn(move |cx| async move { + let url = open_url_rx.await?; + cx.update(|cx| cx.open_url(&url)) + }) + .detach_and_log_err(cx); + }) + .log_err(); + + let credentials = background + .clone() + .spawn(async move { + // Generate a pair of asymmetric encryption keys. The public key will be used by the + // zed server to encrypt the user's access token, so that it can'be intercepted by + // any other app running on the user's device. + let (public_key, private_key) = + rpc::auth::keypair().expect("failed to generate keypair for auth"); + let public_key_string = String::try_from(public_key) + .expect("failed to serialize public key for auth"); + + if let Some((login, token)) = + IMPERSONATE_LOGIN.as_ref().zip(ADMIN_API_TOKEN.as_ref()) + { + return Self::authenticate_as_admin(http, login.clone(), token.clone()) + .await; + } - if let Some(impersonate_login) = IMPERSONATE_LOGIN.as_ref() { - log::info!("impersonating user @{}", impersonate_login); - write!(&mut url, "&impersonate={}", impersonate_login).unwrap(); - } + // Start an HTTP server to receive the redirect from Zed's sign-in page. + let server = + tiny_http::Server::http("127.0.0.1:0").expect("failed to find open port"); + let port = server.server_addr().port(); + + // Open the Zed sign-in page in the user's browser, with query parameters that indicate + // that the user is signing in from a Zed app running on the same device. + let mut url = format!( + "{}/native_app_signin?native_app_port={}&native_app_public_key={}", + *ZED_SERVER_URL, port, public_key_string + ); + + if let Some(impersonate_login) = IMPERSONATE_LOGIN.as_ref() { + log::info!("impersonating user @{}", impersonate_login); + write!(&mut url, "&impersonate={}", impersonate_login).unwrap(); + } - cx.update(|cx| cx.open_url(&url))?; - - // Receive the HTTP request from the user's browser. Retrieve the user id and encrypted - // access token from the query params. - // - // TODO - Avoid ever starting more than one HTTP server. Maybe switch to using a - // custom URL scheme instead of this local HTTP server. - let (user_id, access_token) = cx - .spawn(|_| async move { - for _ in 0..100 { - if let Some(req) = server.recv_timeout(Duration::from_secs(1))? { - let path = req.url(); - let mut user_id = None; - let mut access_token = None; - let url = Url::parse(&format!("http://example.com{}", path)) - .context("failed to parse login notification url")?; - for (key, value) in url.query_pairs() { - if key == "access_token" { - access_token = Some(value.to_string()); - } else if key == "user_id" { - user_id = Some(value.to_string()); + open_url_tx.send(url).log_err(); + + // Receive the HTTP request from the user's browser. Retrieve the user id and encrypted + // access token from the query params. + // + // TODO - Avoid ever starting more than one HTTP server. Maybe switch to using a + // custom URL scheme instead of this local HTTP server. + let (user_id, access_token) = background + .spawn(async move { + for _ in 0..100 { + if let Some(req) = server.recv_timeout(Duration::from_secs(1))? { + let path = req.url(); + let mut user_id = None; + let mut access_token = None; + let url = Url::parse(&format!("http://example.com{}", path)) + .context("failed to parse login notification url")?; + for (key, value) in url.query_pairs() { + if key == "access_token" { + access_token = Some(value.to_string()); + } else if key == "user_id" { + user_id = Some(value.to_string()); + } + } + + let post_auth_url = + format!("{}/native_app_signin_succeeded", *ZED_SERVER_URL); + req.respond( + tiny_http::Response::empty(302).with_header( + tiny_http::Header::from_bytes( + &b"Location"[..], + post_auth_url.as_bytes(), + ) + .unwrap(), + ), + ) + .context("failed to respond to login http request")?; + return Ok(( + user_id + .ok_or_else(|| anyhow!("missing user_id parameter"))?, + access_token.ok_or_else(|| { + anyhow!("missing access_token parameter") + })?, + )); } } - let post_auth_url = - format!("{}/native_app_signin_succeeded", *ZED_SERVER_URL); - req.respond( - tiny_http::Response::empty(302).with_header( - tiny_http::Header::from_bytes( - &b"Location"[..], - post_auth_url.as_bytes(), - ) - .unwrap(), - ), - ) - .context("failed to respond to login http request")?; - return Ok(( - user_id.ok_or_else(|| anyhow!("missing user_id parameter"))?, - access_token - .ok_or_else(|| anyhow!("missing access_token parameter"))?, - )); - } - } + Err(anyhow!("didn't receive login redirect")) + }) + .await?; - Err(anyhow!("didn't receive login redirect")) + let access_token = private_key + .decrypt_string(&access_token) + .context("failed to decrypt access token")?; + + Ok(Credentials { + user_id: user_id.parse()?, + access_token, + }) }) .await?; - let access_token = private_key - .decrypt_string(&access_token) - .context("failed to decrypt access token")?; cx.update(|cx| cx.activate(true))?; - - Ok(Credentials { - user_id: user_id.parse()?, - access_token, - }) + Ok(credentials) }) } diff --git a/crates/collab_ui2/Cargo.toml b/crates/collab_ui2/Cargo.toml index 88c27bc1657df28cb6ecbef07fbf856353a7d516..6249e9fdaff495c1d36e6dc56a35c718a53b3bd0 100644 --- a/crates/collab_ui2/Cargo.toml +++ b/crates/collab_ui2/Cargo.toml @@ -22,7 +22,7 @@ test-support = [ ] [dependencies] -# auto_update = { path = "../auto_update" } +auto_update = { package = "auto_update2", path = "../auto_update2" } db = { package = "db2", path = "../db2" } call = { package = "call2", path = "../call2" } client = { package = "client2", path = "../client2" } diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index d6de5a1565d82493c4bdec08544f63ad3370a7e2..276455151e0a203edfae2a825b884247c8138015 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -1,10 +1,11 @@ use crate::face_pile::FacePile; +use auto_update::AutoUpdateStatus; use call::{ActiveCall, ParticipantLocation, Room}; -use client::{proto::PeerId, Client, ParticipantIndex, SignOut, User, UserStore}; +use client::{proto::PeerId, Client, ParticipantIndex, User, UserStore}; use gpui::{ - actions, canvas, div, overlay, point, px, rems, Action, AppContext, DismissEvent, Div, Element, - FocusableView, Hsla, InteractiveElement, IntoElement, Model, ParentElement, Path, Render, - Stateful, StatefulInteractiveElement, Styled, Subscription, ViewContext, VisualContext, + actions, canvas, div, overlay, point, px, rems, Action, AnyElement, AppContext, DismissEvent, + Div, Element, FocusableView, Hsla, InteractiveElement, IntoElement, Model, ParentElement, Path, + Render, Stateful, StatefulInteractiveElement, Styled, Subscription, ViewContext, VisualContext, WeakView, WindowBounds, }; use project::{Project, RepositoryEntry}; @@ -16,7 +17,7 @@ use ui::{ IconButton, IconElement, KeyBinding, Tooltip, }; use util::ResultExt; -use workspace::{notifications::NotifyResultExt, Feedback, Workspace, WORKSPACE_DB}; +use workspace::{notifications::NotifyResultExt, Workspace, WORKSPACE_DB}; const MAX_PROJECT_NAME_LENGTH: usize = 40; const MAX_BRANCH_NAME_LENGTH: usize = 40; @@ -52,7 +53,6 @@ pub struct CollabTitlebarItem { workspace: WeakView, //branch_popover: Option>, project_popover: Option, - //user_menu: ViewHandle, _subscriptions: Vec, } @@ -232,88 +232,17 @@ impl Render for CollabTitlebarItem { }), ) }) - .child(h_stack().px_1p5().map(|this| { - if let Some(user) = current_user { - // TODO: Finish implementing user menu popover - // - this.child( - popover_menu("user-menu") - .menu(|cx| { - ContextMenu::build(cx, |menu, _| { - menu.action( - "Settings", - zed_actions::OpenSettings.boxed_clone(), - ) - .action("Theme", theme_selector::Toggle.boxed_clone()) - .separator() - .action( - "Share Feedback", - feedback::GiveFeedback.boxed_clone(), - ) - .action("Sign Out", client::SignOut.boxed_clone()) - }) - }) - .trigger( - ButtonLike::new("user-menu") - .child( - h_stack() - .gap_0p5() - .child(Avatar::new(user.avatar_uri.clone())) - .child( - IconElement::new(Icon::ChevronDown) - .color(Color::Muted), - ), - ) - .style(ButtonStyle::Subtle) - .tooltip(move |cx| { - Tooltip::text("Toggle User Menu", cx) - }), - ) - .anchor(gpui::AnchorCorner::TopRight), - ) + .map(|el| { + let status = self.client.status(); + let status = &*status.borrow(); + if matches!(status, client::Status::Connected { .. }) { + el.child(self.render_user_menu_button(cx)) } else { - this.child(Button::new("sign_in", "Sign in").on_click(move |_, cx| { - let client = client.clone(); - cx.spawn(move |mut cx| async move { - client - .authenticate_and_connect(true, &cx) - .await - .notify_async_err(&mut cx); - }) - .detach(); - })) - .child( - popover_menu("user-menu") - .menu(|cx| { - ContextMenu::build(cx, |menu, _| { - menu.action( - "Settings", - zed_actions::OpenSettings.boxed_clone(), - ) - .action("Theme", theme_selector::Toggle.boxed_clone()) - .separator() - .action( - "Share Feedback", - feedback::GiveFeedback.boxed_clone(), - ) - }) - }) - .trigger( - ButtonLike::new("user-menu") - .child( - h_stack().gap_0p5().child( - IconElement::new(Icon::ChevronDown) - .color(Color::Muted), - ), - ) - .style(ButtonStyle::Subtle) - .tooltip(move |cx| { - Tooltip::text("Toggle User Menu", cx) - }), - ), - ) + el.children(self.render_connection_status(status, cx)) + .child(self.render_sign_in_button(cx)) + .child(self.render_user_menu_button(cx)) } - })), + }), ) } } @@ -355,12 +284,6 @@ impl CollabTitlebarItem { project, user_store, client, - // user_menu: cx.add_view(|cx| { - // let view_id = cx.view_id(); - // let mut menu = ContextMenu::new(view_id, cx); - // menu.set_position_mode(OverlayPositionMode::Local); - // menu - // }), // branch_popover: None, project_popover: None, _subscriptions: subscriptions, @@ -535,34 +458,6 @@ impl CollabTitlebarItem { .log_err(); } - // pub fn toggle_user_menu(&mut self, _: &ToggleUserMenu, cx: &mut ViewContext) { - // self.user_menu.update(cx, |user_menu, cx| { - // let items = if let Some(_) = self.user_store.read(cx).current_user() { - // vec![ - // ContextMenuItem::action("Settings", zed_actions::OpenSettings), - // ContextMenuItem::action("Theme", theme_selector::Toggle), - // ContextMenuItem::separator(), - // ContextMenuItem::action( - // "Share Feedback", - // feedback::feedback_editor::GiveFeedback, - // ), - // ContextMenuItem::action("Sign Out", SignOut), - // ] - // } else { - // vec![ - // ContextMenuItem::action("Settings", zed_actions::OpenSettings), - // ContextMenuItem::action("Theme", theme_selector::Toggle), - // ContextMenuItem::separator(), - // ContextMenuItem::action( - // "Share Feedback", - // feedback::feedback_editor::GiveFeedback, - // ), - // ] - // }; - // user_menu.toggle(Default::default(), AnchorCorner::TopRight, items, cx); - // }); - // } - // fn render_branches_popover_host<'a>( // &'a self, // _theme: &'a theme::Titlebar, @@ -696,154 +591,113 @@ impl CollabTitlebarItem { cx.notify(); } - // fn render_user_menu_button( - // &self, - // theme: &Theme, - // avatar: Option>, - // cx: &mut ViewContext, - // ) -> AnyElement { - // let tooltip = theme.tooltip.clone(); - // let user_menu_button_style = if avatar.is_some() { - // &theme.titlebar.user_menu.user_menu_button_online - // } else { - // &theme.titlebar.user_menu.user_menu_button_offline - // }; - - // let avatar_style = &user_menu_button_style.avatar; - // Stack::new() - // .with_child( - // MouseEventHandler::new::(0, cx, |state, _| { - // let style = user_menu_button_style - // .user_menu - // .inactive_state() - // .style_for(state); - - // let mut dropdown = Flex::row().align_children_center(); - - // if let Some(avatar_img) = avatar { - // dropdown = dropdown.with_child(Self::render_face( - // avatar_img, - // *avatar_style, - // Color::transparent_black(), - // None, - // )); - // }; - - // dropdown - // .with_child( - // Svg::new("icons/caret_down.svg") - // .with_color(user_menu_button_style.icon.color) - // .constrained() - // .with_width(user_menu_button_style.icon.width) - // .contained() - // .into_any(), - // ) - // .aligned() - // .constrained() - // .with_height(style.width) - // .contained() - // .with_style(style.container) - // .into_any() - // }) - // .with_cursor_style(CursorStyle::PointingHand) - // .on_down(MouseButton::Left, move |_, this, cx| { - // this.user_menu.update(cx, |menu, _| menu.delay_cancel()); - // }) - // .on_click(MouseButton::Left, move |_, this, cx| { - // this.toggle_user_menu(&Default::default(), cx) - // }) - // .with_tooltip::( - // 0, - // "Toggle User Menu".to_owned(), - // Some(Box::new(ToggleUserMenu)), - // tooltip, - // cx, - // ) - // .contained(), - // ) - // .with_child( - // ChildView::new(&self.user_menu, cx) - // .aligned() - // .bottom() - // .right(), - // ) - // .into_any() - // } - - // fn render_sign_in_button(&self, theme: &Theme, cx: &mut ViewContext) -> AnyElement { - // let titlebar = &theme.titlebar; - // MouseEventHandler::new::(0, cx, |state, _| { - // let style = titlebar.sign_in_button.inactive_state().style_for(state); - // Label::new("Sign In", style.text.clone()) - // .contained() - // .with_style(style.container) - // }) - // .with_cursor_style(CursorStyle::PointingHand) - // .on_click(MouseButton::Left, move |_, this, cx| { - // let client = this.client.clone(); - // cx.app_context() - // .spawn(|cx| async move { client.authenticate_and_connect(true, &cx).await }) - // .detach_and_log_err(cx); - // }) - // .into_any() - // } + fn render_connection_status( + &self, + status: &client::Status, + cx: &mut ViewContext, + ) -> Option { + match status { + client::Status::ConnectionError + | client::Status::ConnectionLost + | client::Status::Reauthenticating { .. } + | client::Status::Reconnecting { .. } + | client::Status::ReconnectionError { .. } => Some( + div() + .id("disconnected") + .bg(gpui::red()) // todo!() @nate + .child(IconElement::new(Icon::Disconnected)) + .tooltip(|cx| Tooltip::text("Disconnected", cx)) + .into_any_element(), + ), + client::Status::UpgradeRequired => { + let auto_updater = auto_update::AutoUpdater::get(cx); + let label = match auto_updater.map(|auto_update| auto_update.read(cx).status()) { + Some(AutoUpdateStatus::Updated) => "Please restart Zed to Collaborate", + Some(AutoUpdateStatus::Installing) + | Some(AutoUpdateStatus::Downloading) + | Some(AutoUpdateStatus::Checking) => "Updating...", + Some(AutoUpdateStatus::Idle) | Some(AutoUpdateStatus::Errored) | None => { + "Please update Zed to Collaborate" + } + }; + + Some( + div() + .bg(gpui::red()) // todo!() @nate + .child(Button::new("connection-status", label).on_click(|_, cx| { + if let Some(auto_updater) = auto_update::AutoUpdater::get(cx) { + if auto_updater.read(cx).status() == AutoUpdateStatus::Updated { + workspace::restart(&Default::default(), cx); + return; + } + } + auto_update::check(&Default::default(), cx); + })) + .into_any_element(), + ) + } + _ => None, + } + } - // fn render_connection_status( - // &self, - // status: &client::Status, - // cx: &mut ViewContext, - // ) -> Option> { - // enum ConnectionStatusButton {} - - // let theme = &theme::current(cx).clone(); - // match status { - // client::Status::ConnectionError - // | client::Status::ConnectionLost - // | client::Status::Reauthenticating { .. } - // | client::Status::Reconnecting { .. } - // | client::Status::ReconnectionError { .. } => Some( - // Svg::new("icons/disconnected.svg") - // .with_color(theme.titlebar.offline_icon.color) - // .constrained() - // .with_width(theme.titlebar.offline_icon.width) - // .aligned() - // .contained() - // .with_style(theme.titlebar.offline_icon.container) - // .into_any(), - // ), - // client::Status::UpgradeRequired => { - // let auto_updater = auto_update::AutoUpdater::get(cx); - // let label = match auto_updater.map(|auto_update| auto_update.read(cx).status()) { - // Some(AutoUpdateStatus::Updated) => "Please restart Zed to Collaborate", - // Some(AutoUpdateStatus::Installing) - // | Some(AutoUpdateStatus::Downloading) - // | Some(AutoUpdateStatus::Checking) => "Updating...", - // Some(AutoUpdateStatus::Idle) | Some(AutoUpdateStatus::Errored) | None => { - // "Please update Zed to Collaborate" - // } - // }; + pub fn render_sign_in_button(&mut self, _: &mut ViewContext) -> Button { + let client = self.client.clone(); + Button::new("sign_in", "Sign in").on_click(move |_, cx| { + let client = client.clone(); + cx.spawn(move |mut cx| async move { + client + .authenticate_and_connect(true, &cx) + .await + .notify_async_err(&mut cx); + }) + .detach(); + }) + } - // Some( - // MouseEventHandler::new::(0, cx, |_, _| { - // Label::new(label, theme.titlebar.outdated_warning.text.clone()) - // .contained() - // .with_style(theme.titlebar.outdated_warning.container) - // .aligned() - // }) - // .with_cursor_style(CursorStyle::PointingHand) - // .on_click(MouseButton::Left, |_, _, cx| { - // if let Some(auto_updater) = auto_update::AutoUpdater::get(cx) { - // if auto_updater.read(cx).status() == AutoUpdateStatus::Updated { - // workspace::restart(&Default::default(), cx); - // return; - // } - // } - // auto_update::check(&Default::default(), cx); - // }) - // .into_any(), - // ) - // } - // _ => None, - // } - // } + pub fn render_user_menu_button(&mut self, cx: &mut ViewContext) -> impl Element { + if let Some(user) = self.user_store.read(cx).current_user() { + popover_menu("user-menu") + .menu(|cx| { + ContextMenu::build(cx, |menu, _| { + menu.action("Settings", zed_actions::OpenSettings.boxed_clone()) + .action("Theme", theme_selector::Toggle.boxed_clone()) + .separator() + .action("Share Feedback", feedback::GiveFeedback.boxed_clone()) + .action("Sign Out", client::SignOut.boxed_clone()) + }) + }) + .trigger( + ButtonLike::new("user-menu") + .child( + h_stack() + .gap_0p5() + .child(Avatar::new(user.avatar_uri.clone())) + .child(IconElement::new(Icon::ChevronDown).color(Color::Muted)), + ) + .style(ButtonStyle::Subtle) + .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)), + ) + .anchor(gpui::AnchorCorner::TopRight) + } else { + popover_menu("user-menu") + .menu(|cx| { + ContextMenu::build(cx, |menu, _| { + menu.action("Settings", zed_actions::OpenSettings.boxed_clone()) + .action("Theme", theme_selector::Toggle.boxed_clone()) + .separator() + .action("Share Feedback", feedback::GiveFeedback.boxed_clone()) + }) + }) + .trigger( + ButtonLike::new("user-menu") + .child( + h_stack() + .gap_0p5() + .child(IconElement::new(Icon::ChevronDown).color(Color::Muted)), + ) + .style(ButtonStyle::Subtle) + .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)), + ) + } + } } diff --git a/crates/ui2/src/components/icon.rs b/crates/ui2/src/components/icon.rs index b68aa579c026d518f33e9eabc94824270c8104e7..6876630100e95d3ec23252e80787642263783d56 100644 --- a/crates/ui2/src/components/icon.rs +++ b/crates/ui2/src/components/icon.rs @@ -50,6 +50,7 @@ pub enum Icon { CopilotError, CopilotDisabled, Dash, + Disconnected, Envelope, ExternalLink, ExclamationTriangle, @@ -129,6 +130,7 @@ impl Icon { Icon::CopilotError => "icons/copilot_error.svg", Icon::CopilotDisabled => "icons/copilot_disabled.svg", Icon::Dash => "icons/dash.svg", + Icon::Disconnected => "icons/disconnected.svg", Icon::Envelope => "icons/feedback.svg", Icon::ExclamationTriangle => "icons/warning.svg", Icon::ExternalLink => "icons/external_link.svg", From 1e4a7e6ef18e765fc30303e2ec7176a61a1d8b72 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 13 Dec 2023 16:01:49 -0700 Subject: [PATCH 016/644] Don't notify when drawing --- crates/gpui2/src/window.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index a0db7d6d9e8d26f6c7cc848860e3779d66ed0669..d0056617edea93099a40e2f1df30921eae867497 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -237,6 +237,7 @@ pub struct Window { bounds_observers: SubscriberSet<(), AnyObserver>, active: bool, pub(crate) dirty: bool, + pub(crate) drawing: bool, activation_observers: SubscriberSet<(), AnyObserver>, pub(crate) last_blur: Option>, pub(crate) focus: Option, @@ -371,6 +372,7 @@ impl Window { bounds_observers: SubscriberSet::new(), active: false, dirty: false, + drawing: false, activation_observers: SubscriberSet::new(), last_blur: None, focus: None, @@ -422,7 +424,9 @@ impl<'a> WindowContext<'a> { /// Mark the window as dirty, scheduling it to be redrawn on the next frame. pub fn notify(&mut self) { - self.window.dirty = true; + if !self.window.drawing { + self.window.dirty = true; + } } /// Close this window. @@ -1237,6 +1241,8 @@ impl<'a> WindowContext<'a> { /// Draw pixels to the display for this window based on the contents of its scene. pub(crate) fn draw(&mut self) -> Scene { let t0 = std::time::Instant::now(); + self.window.dirty = false; + self.window.drawing = true; let window_was_focused = self .window @@ -1327,7 +1333,7 @@ impl<'a> WindowContext<'a> { self.platform.set_cursor_style(cursor_style); } - self.window.dirty = false; + self.window.drawing = false; eprintln!("frame: {:?}", t0.elapsed()); scene @@ -2346,10 +2352,12 @@ impl<'a, V: 'static> ViewContext<'a, V> { } pub fn notify(&mut self) { - self.window_cx.notify(); - self.window_cx.app.push_effect(Effect::Notify { - emitter: self.view.model.entity_id, - }); + if !self.window.drawing { + self.window_cx.notify(); + self.window_cx.app.push_effect(Effect::Notify { + emitter: self.view.model.entity_id, + }); + } } pub fn observe_window_bounds( From c863227dc2f84a7bd6285963d8377b3772c70322 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 13 Dec 2023 18:44:21 -0700 Subject: [PATCH 017/644] Log frame timings --- crates/gpui2/src/platform/mac/metal_renderer.rs | 6 ++++++ crates/gpui2/src/view.rs | 6 ++++++ crates/gpui2/src/window.rs | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/crates/gpui2/src/platform/mac/metal_renderer.rs b/crates/gpui2/src/platform/mac/metal_renderer.rs index c477440df5d888658e96c8e9d4d3f7e70d214679..3210a53c634e81e5410e732c2971c86a553c808f 100644 --- a/crates/gpui2/src/platform/mac/metal_renderer.rs +++ b/crates/gpui2/src/platform/mac/metal_renderer.rs @@ -187,6 +187,8 @@ impl MetalRenderer { } pub fn draw(&mut self, scene: &Scene) { + let start = std::time::Instant::now(); + let layer = self.layer.clone(); let viewport_size = layer.drawable_size(); let viewport_size: Size = size( @@ -303,6 +305,10 @@ impl MetalRenderer { command_buffer.commit(); self.sprite_atlas.clear_textures(AtlasTextureKind::Path); + + let duration_since_start = start.elapsed(); + println!("renderer draw: {:?}", duration_since_start); + command_buffer.wait_until_completed(); drawable.present(); } diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index 280c52df2afad19af029a75e336222eae82aa74e..46a90864783b0e8933731a275704cd1ce9dd4d32 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -209,8 +209,14 @@ impl AnyView { ) { cx.with_absolute_element_offset(origin, |cx| { let (layout_id, rendered_element) = (self.layout)(self, cx); + let start_time = std::time::Instant::now(); cx.compute_layout(layout_id, available_space); + let duration = start_time.elapsed(); + println!("compute layout: {:?}", duration); + let start_time = std::time::Instant::now(); (self.paint)(self, rendered_element, cx); + let duration = start_time.elapsed(); + println!("paint: {:?}", duration); }) } } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index d0056617edea93099a40e2f1df30921eae867497..4624bcf20bbc1829c0f6d0cde24c1948d88d1ce0 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1334,7 +1334,7 @@ impl<'a> WindowContext<'a> { } self.window.drawing = false; - eprintln!("frame: {:?}", t0.elapsed()); + eprintln!("window draw: {:?}", t0.elapsed()); scene } From cd08d349a5410970b919bb0d3f0f57182ee649c2 Mon Sep 17 00:00:00 2001 From: Julia Date: Wed, 13 Dec 2023 21:48:05 -0500 Subject: [PATCH 018/644] Quick and dirty attempt to immediately apply focus change in tests Doesn't quite work yet --- crates/gpui2/src/app.rs | 4 +++- crates/gpui2/src/window.rs | 22 ++++++++++++++++++---- crates/project_panel2/src/project_panel.rs | 1 + 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 9b9a5921e17dca7fa3c22571ca6f6f0fdc9e5c55..deb03498bc7d1783aac36acdd8bb88428d7c5c64 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -571,6 +571,7 @@ impl AppContext { loop { self.release_dropped_entities(); self.release_dropped_focus_handles(); + if let Some(effect) = self.pending_effects.pop_front() { match effect { Effect::Notify { emitter } => { @@ -610,7 +611,8 @@ impl AppContext { .values() .filter_map(|window| { let window = window.as_ref()?; - window.dirty.then_some(window.handle) + dbg!(window.focus_invalidated); + (window.dirty || window.focus_invalidated).then_some(window.handle) }) .collect::>() { diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index d2f48917112f5eda16c8a9a8a684bf47b036da09..895ae788627aa7d608762cef2ca0c4b6b4bbd15e 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -243,6 +243,9 @@ pub struct Window { pub(crate) dirty: bool, activation_observers: SubscriberSet<(), AnyObserver>, pub(crate) focus: Option, + + #[cfg(any(test, feature = "test-support"))] + pub(crate) focus_invalidated: bool, } pub(crate) struct ElementStateBox { @@ -381,6 +384,9 @@ impl Window { dirty: false, activation_observers: SubscriberSet::new(), focus: None, + + #[cfg(any(test, feature = "test-support"))] + focus_invalidated: false, } } } @@ -461,6 +467,12 @@ impl<'a> WindowContext<'a> { .rendered_frame .dispatch_tree .clear_pending_keystrokes(); + + #[cfg(any(test, feature = "test-support"))] + { + self.window.focus_invalidated = true; + } + self.notify(); } @@ -1274,13 +1286,15 @@ impl<'a> WindowContext<'a> { self.window.root_view = Some(root_view); let previous_focus_path = self.window.rendered_frame.focus_path(); - - let window = &mut self.window; - mem::swap(&mut window.rendered_frame, &mut window.next_frame); - + mem::swap(&mut self.window.rendered_frame, &mut self.window.next_frame); let current_focus_path = self.window.rendered_frame.focus_path(); if previous_focus_path != current_focus_path { + #[cfg(any(test, feature = "test-support"))] + { + self.window.focus_invalidated = false; + } + if !previous_focus_path.is_empty() && current_focus_path.is_empty() { self.window .blur_listeners diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index adcd21cac6d35f2a00f24938184122d7c7d842c1..5e71266c2177c857d6d5fbd6f34c1d3f59ef68da 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -739,6 +739,7 @@ impl ProjectPanel { }); self.filename_editor.update(cx, |editor, cx| { editor.clear(cx); + println!("focusing"); editor.focus(cx); }); self.update_visible_entries(Some((worktree_id, NEW_ENTRY_ID)), cx); From 6f17cf73370c4482ff7a0ad63bac00ffce45d5b0 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 14 Dec 2023 09:25:09 -0700 Subject: [PATCH 019/644] WIP --- crates/gpui2/src/elements/div.rs | 16 +++++++-------- crates/gpui2/src/view.rs | 5 +++++ crates/gpui2/src/window.rs | 34 ++++++++++++++++++++++++-------- debug.plist | 8 ++++++++ 4 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 debug.plist diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index a102c71a6fbc1d8d0dbc0b2d984efcbdbc677276..5ae051644af2212f28ab4b6aaea8bed4f2789d0b 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -778,28 +778,28 @@ impl Interactivity { }); } - for listener in self.mouse_down_listeners.drain(..) { + for listener in self.mouse_down_listeners { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| { listener(event, &*interactive_bounds, phase, cx); }) } - for listener in self.mouse_up_listeners.drain(..) { + for listener in self.mouse_up_listeners { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { listener(event, &*interactive_bounds, phase, cx); }) } - for listener in self.mouse_move_listeners.drain(..) { + for listener in self.mouse_move_listeners { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { listener(event, &*interactive_bounds, phase, cx); }) } - for listener in self.scroll_wheel_listeners.drain(..) { + for listener in self.scroll_wheel_listeners { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { listener(event, &*interactive_bounds, phase, cx); @@ -868,8 +868,8 @@ impl Interactivity { } } - let click_listeners = mem::take(&mut self.click_listeners); - let drag_listener = mem::take(&mut self.drag_listener); + let click_listeners = self.click_listeners; + let drag_listener = self.drag_listener; if !click_listeners.is_empty() || drag_listener.is_some() { let pending_mouse_down = element_state.pending_mouse_down.clone(); @@ -1086,13 +1086,13 @@ impl Interactivity { self.key_context.clone(), element_state.focus_handle.clone(), |_, cx| { - for listener in self.key_down_listeners.drain(..) { + for listener in self.key_down_listeners { cx.on_key_event(move |event: &KeyDownEvent, phase, cx| { listener(event, phase, cx); }) } - for listener in self.key_up_listeners.drain(..) { + for listener in self.key_up_listeners { cx.on_key_event(move |event: &KeyUpEvent, phase, cx| { listener(event, phase, cx); }) diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index 46a90864783b0e8933731a275704cd1ce9dd4d32..d3506e93fa1f4630d620258b77c8995c1c4cc0c3 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -208,11 +208,16 @@ impl AnyView { cx: &mut WindowContext, ) { cx.with_absolute_element_offset(origin, |cx| { + let start_time = std::time::Instant::now(); let (layout_id, rendered_element) = (self.layout)(self, cx); + let duration = start_time.elapsed(); + println!("request layout: {:?}", duration); + let start_time = std::time::Instant::now(); cx.compute_layout(layout_id, available_space); let duration = start_time.elapsed(); println!("compute layout: {:?}", duration); + let start_time = std::time::Instant::now(); (self.paint)(self, rendered_element, cx); let duration = start_time.elapsed(); diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 4624bcf20bbc1829c0f6d0cde24c1948d88d1ce0..a6e738db54ea9650417944bec0c15a62e64dc714 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -42,8 +42,26 @@ const ACTIVE_DRAG_Z_INDEX: u32 = 1; /// A global stacking order, which is created by stacking successive z-index values. /// Each z-index will always be interpreted in the context of its parent z-index. -#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Default, Debug)] -pub struct StackingOrder(pub(crate) SmallVec<[u32; 16]>); +#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Debug)] +pub struct StackingOrder(pub(crate) Arc>); + +impl Default for StackingOrder { + fn default() -> Self { + StackingOrder(Arc::new(Vec::new())) + } +} + +impl StackingOrder { + /// Pushes a new z-index onto the stacking order. + pub fn push(&mut self, z_index: u32) { + Arc::make_mut(&mut self.0).push(z_index); + } + + /// Pops the last z-index off the stacking order. + pub fn pop(&mut self) { + Arc::make_mut(&mut self.0).pop(); + } +} /// Represents the two different phases when dispatching events. #[derive(Default, Copy, Clone, Debug, Eq, PartialEq)] @@ -2892,12 +2910,12 @@ impl AnyWindowHandle { } } -#[cfg(any(test, feature = "test-support"))] -impl From> for StackingOrder { - fn from(small_vec: SmallVec<[u32; 16]>) -> Self { - StackingOrder(small_vec) - } -} +// #[cfg(any(test, feature = "test-support"))] +// impl From> for StackingOrder { +// fn from(small_vec: SmallVec<[u32; 16]>) -> Self { +// StackingOrder(small_vec) +// } +// } #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub enum ElementId { diff --git a/debug.plist b/debug.plist new file mode 100644 index 0000000000000000000000000000000000000000..e09573c9d1c1499f8b1357d3a86bd90d306bded3 --- /dev/null +++ b/debug.plist @@ -0,0 +1,8 @@ + + + + + com.apple.security.get-task-allow + + + From 4ace342cf0d47946b26f22c71cdbd67590856cc1 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 14 Dec 2023 11:59:24 -0500 Subject: [PATCH 020/644] Fix typo --- crates/storybook2/src/stories/text.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/storybook2/src/stories/text.rs b/crates/storybook2/src/stories/text.rs index ccd13cb4d80b1e739cef0671a3bfd54b78264fea..b279e004c7b37bc3c1d626028d86239df6e14d65 100644 --- a/crates/storybook2/src/stories/text.rs +++ b/crates/storybook2/src/stories/text.rs @@ -50,7 +50,7 @@ impl Render for TextStory { )))) // NOTE: When rendering text in a horizonal flex container, // Taffy will not pass width constraints down from the parent. - // To fix this, render text in a praent with overflow: hidden, which + // To fix this, render text in a parent with overflow: hidden .child(div().h_5()) .child(div().flex().w_96().bg(red()).child(concat!( "flex-row. width 96. The quick brown fox jumps over the lazy dog. ", From 1ae25f52a114919abe9062e3ea3506473164345f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 14 Dec 2023 10:31:45 -0700 Subject: [PATCH 021/644] WIP --- crates/collab_ui2/src/face_pile.rs | 2 +- crates/gpui2/src/elements/div.rs | 65 ++++++++++++++++++------ crates/gpui2/src/style.rs | 2 +- crates/gpui2/src/styled.rs | 2 +- crates/gpui2/src/window.rs | 24 +++++---- crates/storybook2/src/stories/z_index.rs | 4 +- crates/ui2/src/styles/elevation.rs | 12 ++--- crates/workspace2/src/modal_layer.rs | 2 +- 8 files changed, 77 insertions(+), 36 deletions(-) diff --git a/crates/collab_ui2/src/face_pile.rs b/crates/collab_ui2/src/face_pile.rs index d181509c46f1e568460b935f6d403dd6b15a1fff..fd675127e4a0786da76f3f5eb044d836652f7fab 100644 --- a/crates/collab_ui2/src/face_pile.rs +++ b/crates/collab_ui2/src/face_pile.rs @@ -17,7 +17,7 @@ impl RenderOnce for FacePile { let isnt_last = ix < player_count - 1; div() - .z_index((player_count - ix) as u32) + .z_index((player_count - ix) as u8) .when(isnt_last, |div| div.neg_mr_1()) .child(player) }); diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 5ae051644af2212f28ab4b6aaea8bed4f2789d0b..cc82ff3cb09dbba6c5b5fff18795f27ef3b8c77a 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -646,7 +646,10 @@ pub struct DivState { impl DivState { pub fn is_active(&self) -> bool { - self.interactive_state.pending_mouse_down.borrow().is_some() + self.interactive_state + .pending_mouse_down + .as_ref() + .map_or(false, |pending| pending.borrow().is_some()) } } @@ -872,11 +875,17 @@ impl Interactivity { let drag_listener = self.drag_listener; if !click_listeners.is_empty() || drag_listener.is_some() { - let pending_mouse_down = element_state.pending_mouse_down.clone(); + let pending_mouse_down = element_state + .pending_mouse_down + .get_or_insert_with(Default::default) + .clone(); let mouse_down = pending_mouse_down.borrow().clone(); if let Some(mouse_down) = mouse_down { if let Some(drag_listener) = drag_listener { - let active_state = element_state.clicked_state.clone(); + let active_state = element_state + .clicked_state + .get_or_insert_with(Default::default) + .clone(); let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { @@ -929,8 +938,14 @@ impl Interactivity { } if let Some(hover_listener) = self.hover_listener.take() { - let was_hovered = element_state.hover_state.clone(); - let has_mouse_down = element_state.pending_mouse_down.clone(); + let was_hovered = element_state + .hover_state + .get_or_insert_with(Default::default) + .clone(); + let has_mouse_down = element_state + .pending_mouse_down + .get_or_insert_with(Default::default) + .clone(); let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { @@ -951,8 +966,14 @@ impl Interactivity { } if let Some(tooltip_builder) = self.tooltip_builder.take() { - let active_tooltip = element_state.active_tooltip.clone(); - let pending_mouse_down = element_state.pending_mouse_down.clone(); + let active_tooltip = element_state + .active_tooltip + .get_or_insert_with(Default::default) + .clone(); + let pending_mouse_down = element_state + .pending_mouse_down + .get_or_insert_with(Default::default) + .clone(); let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { @@ -994,19 +1015,30 @@ impl Interactivity { } }); - let active_tooltip = element_state.active_tooltip.clone(); + let active_tooltip = element_state + .active_tooltip + .get_or_insert_with(Default::default) + .clone(); cx.on_mouse_event(move |_: &MouseDownEvent, _, _| { active_tooltip.borrow_mut().take(); }); - if let Some(active_tooltip) = element_state.active_tooltip.borrow().as_ref() { + if let Some(active_tooltip) = element_state + .active_tooltip + .get_or_insert_with(Default::default) + .borrow() + .as_ref() + { if active_tooltip.tooltip.is_some() { cx.active_tooltip = active_tooltip.tooltip.clone() } } } - let active_state = element_state.clicked_state.clone(); + let active_state = element_state + .clicked_state + .get_or_insert_with(Default::default) + .clone(); if active_state.borrow().is_clicked() { cx.on_mouse_event(move |_: &MouseUpEvent, phase, cx| { if phase == DispatchPhase::Capture { @@ -1180,7 +1212,10 @@ impl Interactivity { } } - let clicked_state = element_state.clicked_state.borrow(); + let clicked_state = element_state + .clicked_state + .get_or_insert_with(Default::default) + .borrow(); if clicked_state.group { if let Some(group) = self.group_active_style.as_ref() { style.refine(&group.style) @@ -1235,11 +1270,11 @@ impl Default for Interactivity { #[derive(Default)] pub struct InteractiveElementState { pub focus_handle: Option, - pub clicked_state: Rc>, - pub hover_state: Rc>, - pub pending_mouse_down: Rc>>, + pub clicked_state: Option>>, + pub hover_state: Option>>, + pub pending_mouse_down: Option>>>, pub scroll_offset: Option>>>, - pub active_tooltip: Rc>>, + pub active_tooltip: Option>>>, } pub struct ActiveTooltip { diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index 04f247d07627ac6572fe55724f1eb7b29c76463a..d330e73585c5cf31046c782a55c19d570e991194 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -107,7 +107,7 @@ pub struct Style { /// The mouse cursor style shown when the mouse pointer is over an element. pub mouse_cursor: Option, - pub z_index: Option, + pub z_index: Option, } impl Styled for StyleRefinement { diff --git a/crates/gpui2/src/styled.rs b/crates/gpui2/src/styled.rs index a39e5f9cf955883405437347af5220d6dff6ab40..c7312da7ac4bafc3edc800ebe3222f50971581ee 100644 --- a/crates/gpui2/src/styled.rs +++ b/crates/gpui2/src/styled.rs @@ -12,7 +12,7 @@ pub trait Styled: Sized { gpui2_macros::style_helpers!(); - fn z_index(mut self, z_index: u32) -> Self { + fn z_index(mut self, z_index: u8) -> Self { self.style().z_index = Some(z_index); self } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index a6e738db54ea9650417944bec0c15a62e64dc714..31e9afc695378b4dfe974173a02ea1a2a371113b 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -38,28 +38,34 @@ use std::{ }; use util::ResultExt; -const ACTIVE_DRAG_Z_INDEX: u32 = 1; +const ACTIVE_DRAG_Z_INDEX: u8 = 1; /// A global stacking order, which is created by stacking successive z-index values. /// Each z-index will always be interpreted in the context of its parent z-index. -#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Debug)] -pub struct StackingOrder(pub(crate) Arc>); +#[derive(Deref, DerefMut, Clone, Debug, Ord, PartialOrd, PartialEq, Eq)] +pub struct StackingOrder { + #[deref] + #[deref_mut] + z_indices: Arc>, +} impl Default for StackingOrder { fn default() -> Self { - StackingOrder(Arc::new(Vec::new())) + StackingOrder { + z_indices: Arc::new(SmallVec::new()), + } } } impl StackingOrder { /// Pushes a new z-index onto the stacking order. - pub fn push(&mut self, z_index: u32) { - Arc::make_mut(&mut self.0).push(z_index); + pub fn push(&mut self, z_index: u8) { + Arc::make_mut(&mut self.z_indices).push(z_index); } /// Pops the last z-index off the stacking order. pub fn pop(&mut self) { - Arc::make_mut(&mut self.0).pop(); + Arc::make_mut(&mut self.z_indices).pop(); } } @@ -905,7 +911,7 @@ impl<'a> WindowContext<'a> { /// Called during painting to invoke the given closure in a new stacking context. The given /// z-index is interpreted relative to the previous call to `stack`. - pub fn with_z_index(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R { + pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { self.window.next_frame.z_index_stack.push(z_index); let result = f(self); self.window.next_frame.z_index_stack.pop(); @@ -2233,7 +2239,7 @@ impl<'a, V: 'static> ViewContext<'a, V> { &mut self.window_cx } - pub fn with_z_index(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R { + pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { self.window.next_frame.z_index_stack.push(z_index); let result = f(self); self.window.next_frame.z_index_stack.pop(); diff --git a/crates/storybook2/src/stories/z_index.rs b/crates/storybook2/src/stories/z_index.rs index c6a4b68cc369f4e0bf409f714e585c2bde6f47f4..9579b8c7fcf891c4fcda7ef691d37f583b2bd77a 100644 --- a/crates/storybook2/src/stories/z_index.rs +++ b/crates/storybook2/src/stories/z_index.rs @@ -78,7 +78,7 @@ impl Styles for Div {} #[derive(IntoElement)] struct ZIndexExample { - z_index: u32, + z_index: u8, } impl RenderOnce for ZIndexExample { @@ -170,7 +170,7 @@ impl RenderOnce for ZIndexExample { } impl ZIndexExample { - pub fn new(z_index: u32) -> Self { + pub fn new(z_index: u8) -> Self { Self { z_index } } } diff --git a/crates/ui2/src/styles/elevation.rs b/crates/ui2/src/styles/elevation.rs index 88b2ff2e56aeaf5d2e212fca7218afa3940a4742..7b3835c2e54b3e60528ab212311d245dfd7223d3 100644 --- a/crates/ui2/src/styles/elevation.rs +++ b/crates/ui2/src/styles/elevation.rs @@ -20,14 +20,14 @@ pub enum ElevationIndex { } impl ElevationIndex { - pub fn z_index(self) -> u32 { + pub fn z_index(self) -> u8 { match self { ElevationIndex::Background => 0, - ElevationIndex::Surface => 100, - ElevationIndex::ElevatedSurface => 200, - ElevationIndex::Wash => 250, - ElevationIndex::ModalSurface => 300, - ElevationIndex::DraggedElement => 900, + ElevationIndex::Surface => 42, + ElevationIndex::ElevatedSurface => 84, + ElevationIndex::Wash => 126, + ElevationIndex::ModalSurface => 168, + ElevationIndex::DraggedElement => 210, } } diff --git a/crates/workspace2/src/modal_layer.rs b/crates/workspace2/src/modal_layer.rs index a428ba3e18352ec7750f13ecd19289b5682a75be..e0a6395f31a7024eff0cfe3d62a37e8d7f577a2c 100644 --- a/crates/workspace2/src/modal_layer.rs +++ b/crates/workspace2/src/modal_layer.rs @@ -116,7 +116,7 @@ impl Render for ModalLayer { .size_full() .top_0() .left_0() - .z_index(400) + .z_index(169) .child( v_stack() .h(px(0.0)) From 0d30b698a493f92b774ae70675f4d5e825c98d65 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 14 Dec 2023 11:28:52 -0700 Subject: [PATCH 022/644] Don't allocate interactive bounds --- crates/gpui2/src/elements/div.rs | 12 ++++++------ crates/gpui2/src/window.rs | 16 ++-------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index cc82ff3cb09dbba6c5b5fff18795f27ef3b8c77a..fa8ef50bbb749a0430887e62139f71438e74b2d3 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -748,10 +748,10 @@ impl Interactivity { cx.with_z_index(style.z_index.unwrap_or(0), |cx| cx.add_opaque_layer(bounds)) } - let interactive_bounds = Rc::new(InteractiveBounds { + let interactive_bounds = InteractiveBounds { bounds: bounds.intersect(&cx.content_mask().bounds), stacking_order: cx.stacking_order().clone(), - }); + }; if let Some(mouse_cursor) = style.mouse_cursor { let mouse_position = &cx.mouse_position(); @@ -784,28 +784,28 @@ impl Interactivity { for listener in self.mouse_down_listeners { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| { - listener(event, &*interactive_bounds, phase, cx); + listener(event, &interactive_bounds, phase, cx); }) } for listener in self.mouse_up_listeners { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { - listener(event, &*interactive_bounds, phase, cx); + listener(event, &interactive_bounds, phase, cx); }) } for listener in self.mouse_move_listeners { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - listener(event, &*interactive_bounds, phase, cx); + listener(event, &interactive_bounds, phase, cx); }) } for listener in self.scroll_wheel_listeners { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { - listener(event, &*interactive_bounds, phase, cx); + listener(event, &interactive_bounds, phase, cx); }) } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 31e9afc695378b4dfe974173a02ea1a2a371113b..d43263f815749eb66d55760e935721bb1d781c88 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -46,29 +46,17 @@ const ACTIVE_DRAG_Z_INDEX: u8 = 1; pub struct StackingOrder { #[deref] #[deref_mut] - z_indices: Arc>, + z_indices: SmallVec<[u8; 32]>, } impl Default for StackingOrder { fn default() -> Self { StackingOrder { - z_indices: Arc::new(SmallVec::new()), + z_indices: SmallVec::new(), } } } -impl StackingOrder { - /// Pushes a new z-index onto the stacking order. - pub fn push(&mut self, z_index: u8) { - Arc::make_mut(&mut self.z_indices).push(z_index); - } - - /// Pops the last z-index off the stacking order. - pub fn pop(&mut self) { - Arc::make_mut(&mut self.z_indices).pop(); - } -} - /// Represents the two different phases when dispatching events. #[derive(Default, Copy, Clone, Debug, Eq, PartialEq)] pub enum DispatchPhase { From 3d1dae9a0610c4b023cd348e01c57001c04d8396 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 14 Dec 2023 11:37:48 -0700 Subject: [PATCH 023/644] Make z_indices bigger in StackingOrder --- crates/gpui2/src/window.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index d43263f815749eb66d55760e935721bb1d781c88..e3b1cb4eb523cbdca8df63e96a47024f60958e50 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -46,7 +46,7 @@ const ACTIVE_DRAG_Z_INDEX: u8 = 1; pub struct StackingOrder { #[deref] #[deref_mut] - z_indices: SmallVec<[u8; 32]>, + z_indices: SmallVec<[u8; 64]>, } impl Default for StackingOrder { From c041799c6ad32c046ac51b5233cdfe227958bd7c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 14 Dec 2023 15:55:17 -0500 Subject: [PATCH 024/644] Extend Story components, allow linking to story file Co-Authored-By: Marshall Bowers <1486634+maxdeviant@users.noreply.github.com> --- Cargo.lock | 2 + crates/story/Cargo.toml | 1 + crates/story/src/story.rs | 274 ++++++++++++++++++++++++-- crates/storybook2/Cargo.toml | 1 + crates/storybook2/src/stories/text.rs | 137 +++++++------ 5 files changed, 344 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4281553aff5f7100dc91be770eeda88bad9825ac..c5ec126de5934615c09f1e494b46b4f70808763e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9211,6 +9211,7 @@ name = "story" version = "0.1.0" dependencies = [ "gpui2", + "smallvec", ] [[package]] @@ -9224,6 +9225,7 @@ dependencies = [ "editor2", "fuzzy2", "gpui2", + "indoc", "itertools 0.11.0", "language2", "log", diff --git a/crates/story/Cargo.toml b/crates/story/Cargo.toml index 384447af8fe51472a7da9b614e23b364bb664d25..b042cbab807702b77610e885c997444ba5465fb8 100644 --- a/crates/story/Cargo.toml +++ b/crates/story/Cargo.toml @@ -8,3 +8,4 @@ publish = false [dependencies] gpui = { package = "gpui2", path = "../gpui2" } +smallvec.workspace = true diff --git a/crates/story/src/story.rs b/crates/story/src/story.rs index d95c879ce0068c00fd24ffb64179d4e3d46a5c7a..c656f3729db4c679ae81292f1ccaea10cb7eacaf 100644 --- a/crates/story/src/story.rs +++ b/crates/story/src/story.rs @@ -1,22 +1,109 @@ -use gpui::prelude::*; -use gpui::{div, hsla, Div, SharedString}; +use gpui::{div, hsla, AnyElement, Div, ElementId, Hsla, SharedString, Stateful, WindowContext}; +use gpui::{prelude::*, px}; +use smallvec::SmallVec; + +use std::path::PathBuf; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::time::{SystemTime, UNIX_EPOCH}; + +static COUNTER: AtomicUsize = AtomicUsize::new(0); + +pub fn reasonably_unique_id() -> String { + let now = SystemTime::now(); + let timestamp = now.duration_since(UNIX_EPOCH).unwrap(); + + let cnt = COUNTER.fetch_add(1, Ordering::Relaxed); + + let id = format!("{}_{}", timestamp.as_nanos(), cnt); + + id +} + +pub struct StoryColor { + pub primary: Hsla, + pub secondary: Hsla, + pub border: Hsla, + pub background: Hsla, + pub card_background: Hsla, + pub divider: Hsla, + pub link: Hsla, +} + +impl StoryColor { + pub fn new() -> Self { + Self { + primary: hsla(216. / 360., 11. / 100., 0. / 100., 1.), + secondary: hsla(216. / 360., 11. / 100., 16. / 100., 1.), + border: hsla(216. / 360., 11. / 100., 91. / 100., 1.), + background: hsla(0. / 360., 0. / 100., 100. / 100., 1.), + card_background: hsla(0. / 360., 0. / 100., 96. / 100., 1.), + divider: hsla(216. / 360., 11. / 100., 91. / 100., 1.), + link: hsla(206. / 360., 100. / 100., 50. / 100., 1.), + } + } +} + +pub fn story_color() -> StoryColor { + StoryColor::new() +} pub struct Story {} impl Story { pub fn container() -> Div { - div().size_full().flex().flex_col().pt_2().px_4().bg(hsla( - 0. / 360., - 0. / 100., - 100. / 100., - 1., - )) + div() + .size_full() + .flex() + .flex_col() + .bg(story_color().background) + } + + // TODO: Move all stories to container2, then rename + pub fn container2(relative_path: &'static str) -> Div { + div() + .size_full() + .flex() + .flex_col() + .bg(story_color().background) + .child( + div() + .flex() + .justify_between() + .p_2() + .border_b() + .border_color(story_color().border) + .child(Story::title_for::()) + .child( + div() + .text_xs() + .text_color(story_color().primary) + .child(Story::open_story_link(relative_path)), + ), + ) + } + + pub fn open_story_link(relative_path: &'static str) -> impl Element { + let path = PathBuf::from_iter([relative_path]); + div() + .id(SharedString::from(format!("id_{}", relative_path))) + .text_xs() + .text_color(story_color().primary) + .on_click({ + let path = path.clone(); + + move |_event, _cx| { + let path = format!("{}:0:0", path.to_string_lossy()); + + std::process::Command::new("zed").arg(path).spawn().ok(); + } + }) + .child(Story::link(path.to_string_lossy().to_string())) } pub fn title(title: impl Into) -> impl Element { div() - .text_xl() - .text_color(hsla(0. / 360., 0. / 100., 0. / 100., 1.)) + .text_xs() + .text_color(story_color().primary) .child(title.into()) } @@ -24,12 +111,173 @@ impl Story { Self::title(std::any::type_name::()) } + pub fn section() -> Div { + div().mt_4().mb_2() + } + + pub fn section_title() -> Div { + div().text_lg().text_color(story_color().primary) + } + + pub fn group() -> Div { + div().my_2().bg(story_color().background) + } + + pub fn code_block(code: impl Into) -> Div { + div() + .size_full() + .p_2() + .bg(gpui::black()) + .border() + .border_color(story_color().border) + .rounded_md() + .text_sm() + .text_color(gpui::white()) + .child(code.into()) + } + + pub fn divider() -> Div { + div().my_2().h(px(1.)).bg(story_color().divider) + } + + pub fn link(link: impl Into) -> impl Element { + div() + .id(ElementId::from(SharedString::from(reasonably_unique_id()))) + .text_xs() + .text_color(story_color().link) + .cursor(gpui::CursorStyle::PointingHand) + .child(link.into()) + } + + pub fn description(description: impl Into) -> impl Element { + div() + .text_sm() + .text_color(story_color().secondary) + .min_w_96() + .child(description.into()) + } + pub fn label(label: impl Into) -> impl Element { div() - .mt_4() - .mb_2() .text_xs() - .text_color(hsla(0. / 360., 0. / 100., 0. / 100., 1.)) + .text_color(story_color().primary) .child(label.into()) } + + /// Note: Not ui::v_stack() as the story crate doesn't depend on the ui crate. + pub fn v_stack() -> Div { + div().flex().flex_col().gap_1() + } +} + +#[derive(IntoElement)] +pub struct StoryItem { + label: SharedString, + item: AnyElement, + description: Option, + usage: Option, +} + +impl StoryItem { + pub fn new(label: impl Into, item: impl IntoElement) -> Self { + Self { + label: label.into(), + item: item.into_any_element(), + description: None, + usage: None, + } + } + + pub fn description(mut self, description: impl Into) -> Self { + self.description = Some(description.into()); + self + } + + pub fn usage(mut self, code: impl Into) -> Self { + self.usage = Some(code.into()); + self + } +} + +impl RenderOnce for StoryItem { + type Rendered = Div; + + fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + div() + .my_2() + .flex() + .w_full() + .child( + Story::v_stack() + .px_2() + .flex_none() + .w_1_2() + .min_h_px() + .child(Story::label(self.label)) + .child( + div() + .rounded_sm() + .bg(story_color().card_background) + .border() + .border_color(story_color().border) + .child(self.item), + ) + .when_some(self.description, |this, description| { + this.child(Story::description(description)) + }), + ) + .child( + Story::v_stack() + .px_2() + .flex_none() + .w_1_2() + .min_h_px() + .when_some(self.usage, |this, usage| { + this.child(Story::label("Usage")) + .child(Story::code_block(usage)) + }), + ) + } +} + +#[derive(IntoElement)] +pub struct StorySection { + description: Option, + children: SmallVec<[AnyElement; 2]>, +} + +impl StorySection { + pub fn new() -> Self { + Self { + description: None, + children: SmallVec::new(), + } + } + + pub fn description(mut self, description: impl Into) -> Self { + self.description = Some(description.into()); + self + } +} + +impl RenderOnce for StorySection { + type Rendered = Div; + + fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + Story::section() + // Section title + .py_2() + // Section description + .when_some(self.description.clone(), |section, description| { + section.child(Story::description(description)) + }) + .child(div().flex().flex_col().gap_2().children(self.children)) + .child(Story::divider()) + } +} + +impl ParentElement for StorySection { + fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> { + &mut self.children + } } diff --git a/crates/storybook2/Cargo.toml b/crates/storybook2/Cargo.toml index 949d07b06f83bc4b18aaa7faa6b6c4ebfa2899d0..672bebe20e1ea59124833c00615c4da44cc65057 100644 --- a/crates/storybook2/Cargo.toml +++ b/crates/storybook2/Cargo.toml @@ -22,6 +22,7 @@ editor = { package = "editor2", path = "../editor2" } chrono = "0.4" fuzzy = { package = "fuzzy2", path = "../fuzzy2" } gpui = { package = "gpui2", path = "../gpui2" } +indoc.workspace = true itertools = "0.11.0" language = { package = "language2", path = "../language2" } log.workspace = true diff --git a/crates/storybook2/src/stories/text.rs b/crates/storybook2/src/stories/text.rs index b279e004c7b37bc3c1d626028d86239df6e14d65..279a2dbf4d24051aca3ec82263ea8821bb24ae7b 100644 --- a/crates/storybook2/src/stories/text.rs +++ b/crates/storybook2/src/stories/text.rs @@ -1,8 +1,6 @@ -use gpui::{ - blue, div, green, red, white, Div, HighlightStyle, InteractiveText, ParentElement, Render, - Styled, StyledText, View, VisualContext, WindowContext, -}; -use ui::v_stack; +use gpui::{div, Div, ParentElement, Render, Styled, View, VisualContext, WindowContext}; +use indoc::indoc; +use story::*; pub struct TextStory; @@ -16,59 +14,82 @@ impl Render for TextStory { type Element = Div; fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { - v_stack() - .bg(blue()) - .child( - div() - .flex() - .child(div().max_w_96().bg(white()).child(concat!( - "max-width: 96. The quick brown fox jumps over the lazy dog. ", - "Meanwhile, the lazy dog decided it was time for a change. ", - "He started daily workout routines, ate healthier and became the fastest dog in town.", - ))), - ) - .child(div().h_5()) - .child(div().flex().flex_col().w_96().bg(white()).child(concat!( - "flex-col. width: 96; The quick brown fox jumps over the lazy dog. ", - "Meanwhile, the lazy dog decided it was time for a change. ", - "He started daily workout routines, ate healthier and became the fastest dog in town.", - ))) - .child(div().h_5()) - .child( - div() - .flex() - .child(div().min_w_96().bg(white()).child(concat!( - "min-width: 96. The quick brown fox jumps over the lazy dog. ", - "Meanwhile, the lazy dog decided it was time for a change. ", - "He started daily workout routines, ate healthier and became the fastest dog in town.", -)))) - .child(div().h_5()) - .child(div().flex().w_96().bg(white()).child(div().overflow_hidden().child(concat!( - "flex-row. width 96. overflow-hidden. The quick brown fox jumps over the lazy dog. ", - "Meanwhile, the lazy dog decided it was time for a change. ", - "He started daily workout routines, ate healthier and became the fastest dog in town.", - )))) - // NOTE: When rendering text in a horizonal flex container, - // Taffy will not pass width constraints down from the parent. - // To fix this, render text in a parent with overflow: hidden - .child(div().h_5()) - .child(div().flex().w_96().bg(red()).child(concat!( - "flex-row. width 96. The quick brown fox jumps over the lazy dog. ", - "Meanwhile, the lazy dog decided it was time for a change. ", - "He started daily workout routines, ate healthier and became the fastest dog in town.", - ))).child( - InteractiveText::new( - "interactive", - StyledText::new("Hello world, how is it going?").with_highlights(&cx.text_style(), [ - (6..11, HighlightStyle { - background_color: Some(green()), - ..Default::default() - }), - ]), + // let # = "The quick brown fox jumps over the lazy dog. Meanwhile, the lazy dog decided it was time for a change. He started daily workout routines, ate healthier and became the fastest dog in town."; + + Story::container2::("crates/storybook2/src/stories/text.rs").child( + StorySection::new().child( + StoryItem::new( + "Default Text", + div().flex().child(div().max_w_96().child("foo")), ) - .on_click(vec![2..4, 1..3, 7..9], |range_ix, _cx| { - println!("Clicked range {range_ix}"); - }) - ) + .description("Text with a max-width. Wraps based on set max-width.") + .usage(indoc! {r##" + div().max_w_96() + .child("Some text that you want to wrap.") + "## + }), + ), + ) } } + +// impl Render for TextStory { +// type Element = Div; + +// fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { +// v_stack() +// .bg(blue()) +// .child( +// div() +// .flex() +// .child(div().max_w_96().bg(white()).child(concat!( +// "max-width: 96. The quick brown fox jumps over the lazy dog. ", +// "Meanwhile, the lazy dog decided it was time for a change. ", +// "He started daily workout routines, ate healthier and became the fastest dog in town.", +// ))), +// ) +// .child(div().h_5()) +// .child(div().flex().flex_col().w_96().bg(white()).child(concat!( +// "flex-col. width: 96; The quick brown fox jumps over the lazy dog. ", +// "Meanwhile, the lazy dog decided it was time for a change. ", +// "He started daily workout routines, ate healthier and became the fastest dog in town.", +// ))) +// .child(div().h_5()) +// .child( +// div() +// .flex() +// .child(div().min_w_96().bg(white()).child(concat!( +// "min-width: 96. The quick brown fox jumps over the lazy dog. ", +// "Meanwhile, the lazy dog decided it was time for a change. ", +// "He started daily workout routines, ate healthier and became the fastest dog in town.", +// )))) +// .child(div().h_5()) +// .child(div().flex().w_96().bg(white()).child(div().overflow_hidden().child(concat!( +// "flex-row. width 96. overflow-hidden. The quick brown fox jumps over the lazy dog. ", +// "Meanwhile, the lazy dog decided it was time for a change. ", +// "He started daily workout routines, ate healthier and became the fastest dog in town.", +// )))) +// // NOTE: When rendering text in a horizonal flex container, +// // Taffy will not pass width constraints down from the parent. +// // To fix this, render text in a parent with overflow: hidden +// .child(div().h_5()) +// .child(div().flex().w_96().bg(red()).child(concat!( +// "flex-row. width 96. The quick brown fox jumps over the lazy dog. ", +// "Meanwhile, the lazy dog decided it was time for a change. ", +// "He started daily workout routines, ate healthier and became the fastest dog in town.", +// ))).child( +// InteractiveText::new( +// "interactive", +// StyledText::new("Hello world, how is it going?").with_highlights(&cx.text_style(), [ +// (6..11, HighlightStyle { +// background_color: Some(green()), +// ..Default::default() +// }), +// ]), +// ) +// .on_click(vec![2..4, 1..3, 7..9], |range_ix, _cx| { +// println!("Clicked range {range_ix}"); +// }) +// ) +// } +// } From 2484a6969a96794e5ccc2c3821e20d9acf3bc341 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 14 Dec 2023 15:57:06 -0500 Subject: [PATCH 025/644] Fix toolbar flex sizing --- crates/workspace2/src/toolbar.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index b6d7b3e2cbf3d0a25a9513dc5884924262791fff..a6c8f9d0bff03ec3edd42779b49bdf4382a15a25 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -109,8 +109,22 @@ impl Render for Toolbar { .child( h_stack() .justify_between() - .child(h_stack().children(self.left_items().map(|item| item.to_any()))) - .child(h_stack().children(self.right_items().map(|item| item.to_any()))), + .when(self.left_items().count() > 0, |this| { + this.child( + h_stack() + .flex_1() + .justify_start() + .children(self.left_items().map(|item| item.to_any())), + ) + }) + .when(self.right_items().count() > 0, |this| { + this.child( + h_stack() + .flex_1() + .justify_end() + .children(self.right_items().map(|item| item.to_any())), + ) + }), ) .children(secondary_item) } From c166311c06669839710e2d14e4c2506d8fc1f62d Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 14 Dec 2023 15:58:17 -0500 Subject: [PATCH 026/644] Style "Replace in project" input --- crates/search2/src/project_search.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index 6e71253b1c9f17174aa7a441b668fb4a20f6b162..059003e909c7ac0ca2b64f78236e4c90d1f8b620 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -1606,12 +1606,16 @@ impl Render for ProjectSearchBar { ); let replace_column = if search.replace_enabled { h_stack() - .p_1() .flex_1() - .border_2() + .h_full() + .gap_2() + .px_2() + .py_1() + .border_1() + .border_color(cx.theme().colors().border) .rounded_lg() .child(IconElement::new(Icon::Replace).size(ui::IconSize::Small)) - .child(search.replacement_editor.clone()) + .child(self.render_text_input(&search.replacement_editor, cx)) } else { // Fill out the space if we don't have a replacement editor. h_stack().flex_1() @@ -1674,10 +1678,10 @@ impl Render for ProjectSearchBar { ]); v_stack() .key_context(key_context) + .flex_grow() .p_1() .m_2() .gap_2() - .justify_between() .on_action(cx.listener(|this, _: &ToggleFilters, cx| { this.toggle_filters(cx); })) @@ -1731,6 +1735,7 @@ impl Render for ProjectSearchBar { }) .child( h_stack() + .justify_between() .child(query_column) .child(mode_column) .child(replace_column) From 0dd6c50a200bdc3b1cad2d48b8f38b85f9f5a458 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 14 Dec 2023 14:06:19 -0700 Subject: [PATCH 027/644] Use FxHashMap for element state --- crates/gpui2/src/window.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index e3b1cb4eb523cbdca8df63e96a47024f60958e50..fc8754afefbc7b628603cf9973ee2ee6720f39ff 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -12,7 +12,7 @@ use crate::{ VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS, }; use anyhow::{anyhow, Context as _, Result}; -use collections::HashMap; +use collections::FxHashMap; use derive_more::{Deref, DerefMut}; use futures::{ channel::{mpsc, oneshot}, @@ -263,8 +263,8 @@ pub(crate) struct ElementStateBox { // #[derive(Default)] pub(crate) struct Frame { - pub(crate) element_states: HashMap, - mouse_listeners: HashMap>, + pub(crate) element_states: FxHashMap, + mouse_listeners: FxHashMap>, pub(crate) dispatch_tree: DispatchTree, pub(crate) focus_listeners: Vec, pub(crate) scene_builder: SceneBuilder, @@ -277,8 +277,8 @@ pub(crate) struct Frame { impl Frame { fn new(dispatch_tree: DispatchTree) -> Self { Frame { - element_states: HashMap::default(), - mouse_listeners: HashMap::default(), + element_states: FxHashMap::default(), + mouse_listeners: FxHashMap::default(), dispatch_tree, focus_listeners: Vec::new(), scene_builder: SceneBuilder::default(), From 8791f7cefccc84982c2cc4e0516ea44cca0e35a3 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 14 Dec 2023 12:03:17 -0800 Subject: [PATCH 028/644] Enable dragging from project panel to panes Rework gpui2 drag API so that receivers need not specify the dragged view type. co-authored-by: Max co-authored-by: Conrad --- crates/collab_ui2/src/collab_panel.rs | 11 +- crates/gpui2/src/app.rs | 7 +- crates/gpui2/src/elements/div.rs | 89 +++++++----- crates/gpui2/src/window.rs | 3 +- crates/project_panel2/src/project_panel.rs | 37 +++-- crates/terminal_view2/src/terminal_element.rs | 1 - crates/workspace2/src/dock.rs | 4 +- crates/workspace2/src/pane.rs | 134 +++++++++++++----- crates/workspace2/src/workspace2.rs | 4 +- 9 files changed, 190 insertions(+), 100 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 298c7682eb663bdd470e80826de26f30d83ed807..65a994e6d94326e19245cb68120c1fdb35ea335b 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2552,12 +2552,11 @@ impl CollabPanel { .group("") .flex() .w_full() - .on_drag({ - let channel = channel.clone(); - move |cx| { - let channel = channel.clone(); - cx.build_view(|cx| DraggedChannelView { channel, width }) - } + .on_drag(channel.clone(), move |channel, cx| { + cx.build_view(|cx| DraggedChannelView { + channel: channel.clone(), + width, + }) }) .drag_over::(|style| { style.bg(cx.theme().colors().ghost_element_hover) diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 18f688f179e34c6a272351a7bcf7cae9e5dc7bd3..bfbdc6b4a69421605d0ced7c54280fe84e890293 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -1139,8 +1139,10 @@ impl AppContext { self.active_drag.is_some() } - pub fn active_drag(&self) -> Option { - self.active_drag.as_ref().map(|drag| drag.view.clone()) + pub fn active_drag(&self) -> Option<&T> { + self.active_drag + .as_ref() + .and_then(|drag| drag.value.downcast_ref()) } } @@ -1296,6 +1298,7 @@ impl DerefMut for GlobalLease { /// within the window or by dragging into the app from the underlying platform. pub struct AnyDrag { pub view: AnyView, + pub value: Box, pub cursor_offset: Point, } diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 1954e3086c6b8f2c2b7bd3ea705a76e33c895d6f..4eed40f2ebf2be8e69a8514f2487be3166cfb4ca 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -15,6 +15,7 @@ use std::{ cell::RefCell, cmp::Ordering, fmt::Debug, + marker::PhantomData, mem, rc::Rc, time::Duration, @@ -30,9 +31,18 @@ pub struct GroupStyle { pub style: Box, } -pub struct DragMoveEvent { +pub struct DragMoveEvent { pub event: MouseMoveEvent, - pub drag: View, + drag: PhantomData, +} + +impl DragMoveEvent { + pub fn drag<'b>(&self, cx: &'b AppContext) -> &'b T { + cx.active_drag + .as_ref() + .and_then(|drag| drag.value.downcast_ref::()) + .expect("DragMoveEvent is only valid when the stored active drag is of the same type.") + } } pub trait InteractiveElement: Sized { @@ -198,24 +208,27 @@ pub trait InteractiveElement: Sized { self } - fn on_drag_move( + fn on_drag_move( mut self, - listener: impl Fn(&DragMoveEvent, &mut WindowContext) + 'static, + listener: impl Fn(&DragMoveEvent, &mut WindowContext) + 'static, ) -> Self where - W: Render, + T: Render, { self.interactivity().mouse_move_listeners.push(Box::new( move |event, bounds, phase, cx| { if phase == DispatchPhase::Capture && bounds.drag_target_contains(&event.position, cx) { - if let Some(view) = cx.active_drag().and_then(|view| view.downcast::().ok()) + if cx + .active_drag + .as_ref() + .is_some_and(|drag| drag.value.type_id() == TypeId::of::()) { (listener)( &DragMoveEvent { event: event.clone(), - drag: view, + drag: PhantomData, }, cx, ); @@ -363,14 +376,11 @@ pub trait InteractiveElement: Sized { self } - fn on_drop( - mut self, - listener: impl Fn(&View, &mut WindowContext) + 'static, - ) -> Self { + fn on_drop(mut self, listener: impl Fn(&T, &mut WindowContext) + 'static) -> Self { self.interactivity().drop_listeners.push(( - TypeId::of::(), - Box::new(move |dragged_view, cx| { - listener(&dragged_view.downcast().unwrap(), cx); + TypeId::of::(), + Box::new(move |dragged_value, cx| { + listener(dragged_value.downcast_ref().unwrap(), cx); }), )); self @@ -437,19 +447,24 @@ pub trait StatefulInteractiveElement: InteractiveElement { self } - fn on_drag(mut self, constructor: impl Fn(&mut WindowContext) -> View + 'static) -> Self + fn on_drag( + mut self, + value: T, + constructor: impl Fn(&T, &mut WindowContext) -> View + 'static, + ) -> Self where Self: Sized, + T: 'static, W: 'static + Render, { debug_assert!( self.interactivity().drag_listener.is_none(), "calling on_drag more than once on the same element is not supported" ); - self.interactivity().drag_listener = Some(Box::new(move |cursor_offset, cx| AnyDrag { - view: constructor(cx).into(), - cursor_offset, - })); + self.interactivity().drag_listener = Some(( + Box::new(value), + Box::new(move |value, cx| constructor(value.downcast_ref().unwrap(), cx).into()), + )); self } @@ -513,9 +528,9 @@ pub type ScrollWheelListener = pub type ClickListener = Box; -pub type DragListener = Box, &mut WindowContext) -> AnyDrag + 'static>; +pub type DragListener = Box AnyView + 'static>; -type DropListener = dyn Fn(AnyView, &mut WindowContext) + 'static; +type DropListener = Box; pub type TooltipBuilder = Rc AnyView + 'static>; @@ -712,9 +727,9 @@ pub struct Interactivity { pub key_down_listeners: Vec, pub key_up_listeners: Vec, pub action_listeners: Vec<(TypeId, ActionListener)>, - pub drop_listeners: Vec<(TypeId, Box)>, + pub drop_listeners: Vec<(TypeId, DropListener)>, pub click_listeners: Vec, - pub drag_listener: Option, + pub drag_listener: Option<(Box, DragListener)>, pub hover_listener: Option>, pub tooltip_builder: Option, @@ -998,8 +1013,10 @@ impl Interactivity { if phase == DispatchPhase::Bubble && interactive_bounds.drag_target_contains(&event.position, cx) { - if let Some(drag_state_type) = - cx.active_drag.as_ref().map(|drag| drag.view.entity_type()) + if let Some(drag_state_type) = cx + .active_drag + .as_ref() + .map(|drag| drag.value.as_ref().type_id()) { for (drop_state_type, listener) in &drop_listeners { if *drop_state_type == drag_state_type { @@ -1008,7 +1025,7 @@ impl Interactivity { .take() .expect("checked for type drag state type above"); - listener(drag.view.clone(), cx); + listener(drag.value.as_ref(), cx); cx.notify(); cx.stop_propagation(); } @@ -1022,13 +1039,13 @@ impl Interactivity { } let click_listeners = mem::take(&mut self.click_listeners); - let drag_listener = mem::take(&mut self.drag_listener); + let mut drag_listener = mem::take(&mut self.drag_listener); if !click_listeners.is_empty() || drag_listener.is_some() { let pending_mouse_down = element_state.pending_mouse_down.clone(); let mouse_down = pending_mouse_down.borrow().clone(); if let Some(mouse_down) = mouse_down { - if let Some(drag_listener) = drag_listener { + if drag_listener.is_some() { let active_state = element_state.clicked_state.clone(); let interactive_bounds = interactive_bounds.clone(); @@ -1041,10 +1058,18 @@ impl Interactivity { && interactive_bounds.visibly_contains(&event.position, cx) && (event.position - mouse_down.position).magnitude() > DRAG_THRESHOLD { + let (drag_value, drag_listener) = drag_listener + .take() + .expect("The notify below should invalidate this callback"); + *active_state.borrow_mut() = ElementClickedState::default(); let cursor_offset = event.position - bounds.origin; - let drag = drag_listener(cursor_offset, cx); - cx.active_drag = Some(drag); + let drag = (drag_listener)(drag_value.as_ref(), cx); + cx.active_drag = Some(AnyDrag { + view: drag, + value: drag_value, + cursor_offset, + }); cx.notify(); cx.stop_propagation(); } @@ -1312,7 +1337,7 @@ impl Interactivity { if let Some(drag) = cx.active_drag.take() { for (state_type, group_drag_style) in &self.group_drag_over_styles { if let Some(group_bounds) = GroupBounds::get(&group_drag_style.group, cx) { - if *state_type == drag.view.entity_type() + if *state_type == drag.value.as_ref().type_id() && group_bounds.contains(&mouse_position) { style.refine(&group_drag_style.style); @@ -1321,7 +1346,7 @@ impl Interactivity { } for (state_type, drag_over_style) in &self.drag_over_styles { - if *state_type == drag.view.entity_type() + if *state_type == drag.value.as_ref().type_id() && bounds .intersect(&cx.content_mask().bounds) .contains(&mouse_position) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 585db90c6fe8bc6da15e250e14cf89ab4e8b8802..fd297419868e699c78231e058261b06b67368eb4 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -806,7 +806,7 @@ impl<'a> WindowContext<'a> { /// a specific need to register a global listener. pub fn on_mouse_event( &mut self, - handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static, + mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { let order = self.window.next_frame.z_index_stack.clone(); self.window @@ -1379,6 +1379,7 @@ impl<'a> WindowContext<'a> { self.window.mouse_position = position; if self.active_drag.is_none() { self.active_drag = Some(AnyDrag { + value: Box::new(files.clone()), view: self.build_view(|_| files).into(), cursor_offset: position, }); diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index adcd21cac6d35f2a00f24938184122d7c7d842c1..417b351df761afd6e094165e1b580524218a710d 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -1377,33 +1377,28 @@ impl ProjectPanel { }) .unwrap_or(theme.status().info); + let file_name = details.filename.clone(); + let icon = details.icon.clone(); + let depth = details.depth; div() .id(entry_id.to_proto() as usize) - .on_drag({ - let details = details.clone(); - move |cx| { - let details = details.clone(); - cx.build_view(|_| DraggedProjectEntryView { - details, - width, - entry_id, - }) - } - }) - .drag_over::(|style| { - style.bg(cx.theme().colors().ghost_element_hover) + .on_drag(entry_id, move |entry_id, cx| { + cx.build_view(|_| DraggedProjectEntryView { + details: details.clone(), + width, + entry_id: *entry_id, + }) }) - .on_drop(cx.listener( - move |this, dragged_view: &View, cx| { - this.move_entry(dragged_view.read(cx).entry_id, entry_id, kind.is_file(), cx); - }, - )) + .drag_over::(|style| style.bg(cx.theme().colors().ghost_element_hover)) + .on_drop(cx.listener(move |this, dragged_id: &ProjectEntryId, cx| { + this.move_entry(*dragged_id, entry_id, kind.is_file(), cx); + })) .child( ListItem::new(entry_id.to_proto() as usize) - .indent_level(details.depth) + .indent_level(depth) .indent_step_size(px(settings.indent_size)) .selected(is_selected) - .child(if let Some(icon) = &details.icon { + .child(if let Some(icon) = &icon { div().child(IconElement::from_path(icon.to_string())) } else { div() @@ -1414,7 +1409,7 @@ impl ProjectPanel { } else { div() .text_color(filename_text_color) - .child(Label::new(details.filename.clone())) + .child(Label::new(file_name)) } .ml_1(), ) diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index 7358f2e1d735bd9170ab2815035d4232c3e4f933..bced03e7eabd263ea8b74ff8fe29d7ac361e2719 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -792,7 +792,6 @@ impl Element for TerminalElement { .on_drop::(move |external_paths, cx| { cx.focus(&terminal_focus_handle); let mut new_text = external_paths - .read(cx) .paths() .iter() .map(|path| format!(" {path:?}")) diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index f9e294763b3314cfb0b01930c0d4581c76be000e..6a4740b6e270e5ef4e813ef6ca44081bfbc3f07c 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -493,7 +493,9 @@ impl Render for Dock { let handler = div() .id("resize-handle") .bg(cx.theme().colors().border) - .on_drag(move |cx| cx.build_view(|_| DraggedDock(position))) + .on_drag(DraggedDock(position), |dock, cx| { + cx.build_view(|_| dock.clone()) + }) .on_click(cx.listener(|v, e: &ClickEvent, cx| { if e.down.button == MouseButton::Left && e.down.click_count == 2 { v.resize_active_panel(None, cx) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index a55469fbadd096bc3a041b3ebb3cc12614be871d..2f6dec5bc493dce504486044cb52424b841ca345 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -231,6 +231,7 @@ pub struct NavigationEntry { pub timestamp: usize, } +#[derive(Clone)] struct DraggedTab { pub pane: View, pub ix: usize, @@ -1514,24 +1515,25 @@ impl Pane { .on_click(cx.listener(move |pane: &mut Self, event, cx| { pane.activate_item(ix, true, true, cx) })) - .on_drag({ - let pane = cx.view().clone(); - move |cx| { - cx.build_view(|cx| DraggedTab { - pane: pane.clone(), - detail, - item_id, - is_active, - ix, - }) - } - }) - .drag_over::(|tab| tab.bg(cx.theme().colors().tab_active_background)) - .on_drop( - cx.listener(move |this, dragged_tab: &View, cx| { - this.handle_tab_drop(dragged_tab, ix, cx) - }), + .on_drag( + DraggedTab { + pane: cx.view().clone(), + detail, + item_id, + is_active, + ix, + }, + |tab, cx| cx.build_view(|cx| tab.clone()), ) + .drag_over::(|tab| tab.bg(cx.theme().colors().tab_active_background)) + .drag_over::(|tab| tab.bg(gpui::red())) + .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { + this.handle_tab_drop(dragged_tab, ix, cx) + })) + .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { + dbg!(entry_id); + this.handle_project_entry_drop(entry_id, ix, cx) + })) .when_some(item.tab_tooltip_text(cx), |tab, text| { tab.tooltip(move |cx| Tooltip::text(text.clone(), cx)) }) @@ -1677,11 +1679,13 @@ impl Pane { .drag_over::(|bar| { bar.bg(cx.theme().colors().tab_active_background) }) - .on_drop( - cx.listener(move |this, dragged_tab: &View, cx| { - this.handle_tab_drop(dragged_tab, this.items.len(), cx) - }), - ), + .drag_over::(|bar| bar.bg(gpui::red())) + .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { + this.handle_tab_drop(dragged_tab, this.items.len(), cx) + })) + .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { + this.handle_project_entry_drop(entry_id, this.items.len(), cx) + })), ) } @@ -1743,11 +1747,10 @@ impl Pane { fn handle_tab_drop( &mut self, - dragged_tab: &View, + dragged_tab: &DraggedTab, ix: usize, cx: &mut ViewContext<'_, Pane>, ) { - let dragged_tab = dragged_tab.read(cx); let item_id = dragged_tab.item_id; let from_pane = dragged_tab.pane.clone(); let to_pane = cx.view().clone(); @@ -1760,13 +1763,37 @@ impl Pane { .log_err(); } + fn handle_project_entry_drop( + &mut self, + project_entry_id: &ProjectEntryId, + ix: usize, + cx: &mut ViewContext<'_, Pane>, + ) { + let to_pane = cx.view().downgrade(); + let project_entry_id = *project_entry_id; + self.workspace + .update(cx, |workspace, cx| { + cx.defer(move |workspace, cx| { + if let Some(path) = workspace + .project() + .read(cx) + .path_for_entry(project_entry_id, cx) + { + workspace + .open_path(path, Some(to_pane), true, cx) + .detach_and_log_err(cx); + } + }); + }) + .log_err(); + } + fn handle_split_tab_drop( &mut self, - dragged_tab: &View, + dragged_tab: &DraggedTab, split_direction: SplitDirection, cx: &mut ViewContext<'_, Pane>, ) { - let dragged_tab = dragged_tab.read(cx); let item_id = dragged_tab.item_id; let from_pane = dragged_tab.pane.clone(); let to_pane = cx.view().clone(); @@ -1780,13 +1807,40 @@ impl Pane { .map(|item| item.boxed_clone()); if let Some(item) = item { if let Some(item) = item.clone_on_split(workspace.database_id(), cx) { - workspace.split_item(split_direction, item, cx); + let pane = workspace.split_pane(to_pane, split_direction, cx); + workspace.move_item(from_pane, pane, item_id, 0, cx); } } }); }) .log_err(); } + + fn handle_split_project_entry_drop( + &mut self, + project_entry_id: &ProjectEntryId, + split_direction: SplitDirection, + cx: &mut ViewContext<'_, Pane>, + ) { + let project_entry_id = *project_entry_id; + let current_pane = cx.view().clone(); + self.workspace + .update(cx, |workspace, cx| { + cx.defer(move |workspace, cx| { + if let Some(path) = workspace + .project() + .read(cx) + .path_for_entry(project_entry_id, cx) + { + let pane = workspace.split_pane(current_pane, split_direction, cx); + workspace + .open_path(path, Some(pane.downgrade()), true, cx) + .detach_and_log_err(cx); + } + }); + }) + .log_err(); + } } impl FocusableView for Pane { @@ -1894,11 +1948,17 @@ impl Render for Pane { .full() .z_index(1) .drag_over::(|style| style.bg(drag_target_color)) - .on_drop(cx.listener( - move |this, dragged_tab: &View, cx| { - this.handle_tab_drop(dragged_tab, this.active_item_index(), cx) - }, - )), + .drag_over::(|style| style.bg(gpui::red())) + .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { + this.handle_tab_drop(dragged_tab, this.active_item_index(), cx) + })) + .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { + this.handle_project_entry_drop( + entry_id, + this.active_item_index(), + cx, + ) + })), ) .children( [ @@ -1915,9 +1975,15 @@ impl Render for Pane { .invisible() .bg(drag_target_color) .drag_over::(|style| style.visible()) + .drag_over::(|style| style.visible()) + .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { + this.handle_split_tab_drop(dragged_tab, direction, cx) + })) .on_drop(cx.listener( - move |this, dragged_tab: &View, cx| { - this.handle_split_tab_drop(dragged_tab, direction, cx) + move |this, entry_id: &ProjectEntryId, cx| { + this.handle_split_project_entry_drop( + entry_id, direction, cx, + ) }, )); match direction { diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index a07c5818a0d0ce7fca252882ca43f41a32732c02..87083b09292dfca85bd20264bf8148d81f815b6f 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -3580,7 +3580,7 @@ impl FocusableView for Workspace { struct WorkspaceBounds(Bounds); -#[derive(Render)] +#[derive(Clone, Render)] struct DraggedDock(DockPosition); impl Render for Workspace { @@ -3636,7 +3636,7 @@ impl Render for Workspace { ) .on_drag_move( cx.listener(|workspace, e: &DragMoveEvent, cx| { - match e.drag.read(cx).0 { + match e.drag(cx).0 { DockPosition::Left => { let size = workspace.bounds.left() + e.event.position.x; workspace.left_dock.update(cx, |left_dock, cx| { From 6b06bb4ffe924a54f939f0c6825c566c8ff540a4 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 14 Dec 2023 13:30:11 -0800 Subject: [PATCH 029/644] Re-enable cmd- key bindings for activating panes co-authored-by: Conrad --- crates/workspace2/src/workspace2.rs | 45 +++++------------------------ 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index a07c5818a0d0ce7fca252882ca43f41a32732c02..991a124693527eab8f2943e274ec4f0546845a1f 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -3,13 +3,12 @@ pub mod dock; pub mod item; +mod modal_layer; pub mod notifications; pub mod pane; pub mod pane_group; mod persistence; pub mod searchable; -// todo!() -mod modal_layer; pub mod shared_screen; mod status_bar; mod toolbar; @@ -3313,42 +3312,12 @@ impl Workspace { ) .on_action(cx.listener(Workspace::open)) .on_action(cx.listener(Workspace::close_window)) - - // cx.add_action(Workspace::activate_pane_at_index); - // cx.add_action(|workspace: &mut Workspace, _: &ReopenClosedItem, cx| { - // workspace.reopen_closed_item(cx).detach(); - // }); - // cx.add_action(|workspace: &mut Workspace, _: &GoBack, cx| { - // workspace - // .go_back(workspace.active_pane().downgrade(), cx) - // .detach(); - // }); - // cx.add_action(|workspace: &mut Workspace, _: &GoForward, cx| { - // workspace - // .go_forward(workspace.active_pane().downgrade(), cx) - // .detach(); - // }); - - // cx.add_action(|_: &mut Workspace, _: &install_cli::Install, cx| { - // cx.spawn(|workspace, mut cx| async move { - // let err = install_cli::install_cli(&cx) - // .await - // .context("Failed to create CLI symlink"); - - // workspace.update(&mut cx, |workspace, cx| { - // if matches!(err, Err(_)) { - // err.notify_err(workspace, cx); - // } else { - // workspace.show_notification(1, cx, |cx| { - // cx.build_view(|_| { - // MessageNotification::new("Successfully installed the `zed` binary") - // }) - // }); - // } - // }) - // }) - // .detach(); - // }); + .on_action(cx.listener(Workspace::activate_pane_at_index)) + .on_action( + cx.listener(|workspace: &mut Workspace, _: &ReopenClosedItem, cx| { + workspace.reopen_closed_item(cx).detach(); + }), + ) } #[cfg(any(test, feature = "test-support"))] From 63c3edfb83a223c0822a160fc60e7a7de9c0d155 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 14 Dec 2023 16:52:05 -0500 Subject: [PATCH 030/644] Continue styling new story components --- Cargo.lock | 1 + crates/story/Cargo.toml | 1 + crates/story/src/story.rs | 34 +++++++++---- crates/storybook2/src/stories/text.rs | 72 +++++++++++++++++++++------ 4 files changed, 83 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5ec126de5934615c09f1e494b46b4f70808763e..1c74b49738e5703537ea5e43d0e0d067695b89c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9211,6 +9211,7 @@ name = "story" version = "0.1.0" dependencies = [ "gpui2", + "itertools 0.10.5", "smallvec", ] diff --git a/crates/story/Cargo.toml b/crates/story/Cargo.toml index b042cbab807702b77610e885c997444ba5465fb8..9c195f77f05f591474e739834a8b8965c3822fb4 100644 --- a/crates/story/Cargo.toml +++ b/crates/story/Cargo.toml @@ -9,3 +9,4 @@ publish = false [dependencies] gpui = { package = "gpui2", path = "../gpui2" } smallvec.workspace = true +itertools = {package = "itertools", version = "0.10"} diff --git a/crates/story/src/story.rs b/crates/story/src/story.rs index c656f3729db4c679ae81292f1ccaea10cb7eacaf..4985fb1961c3e4957d8ad9b8947929fee996fe52 100644 --- a/crates/story/src/story.rs +++ b/crates/story/src/story.rs @@ -1,5 +1,7 @@ -use gpui::{div, hsla, AnyElement, Div, ElementId, Hsla, SharedString, Stateful, WindowContext}; -use gpui::{prelude::*, px}; +use gpui::{ + div, hsla, prelude::*, px, rems, AnyElement, Div, ElementId, Hsla, SharedString, WindowContext, +}; +use itertools::Itertools; use smallvec::SmallVec; use std::path::PathBuf; @@ -37,7 +39,7 @@ impl StoryColor { border: hsla(216. / 360., 11. / 100., 91. / 100., 1.), background: hsla(0. / 360., 0. / 100., 100. / 100., 1.), card_background: hsla(0. / 360., 0. / 100., 96. / 100., 1.), - divider: hsla(216. / 360., 11. / 100., 91. / 100., 1.), + divider: hsla(216. / 360., 11. / 100., 86. / 100., 1.), link: hsla(206. / 360., 100. / 100., 50. / 100., 1.), } } @@ -112,7 +114,11 @@ impl Story { } pub fn section() -> Div { - div().mt_4().mb_2() + div() + .p_4() + .m_4() + .border() + .border_color(story_color().border) } pub fn section_title() -> Div { @@ -127,12 +133,12 @@ impl Story { div() .size_full() .p_2() + .max_w(rems(36.)) .bg(gpui::black()) - .border() - .border_color(story_color().border) .rounded_md() .text_sm() .text_color(gpui::white()) + .overflow_hidden() .child(code.into()) } @@ -206,20 +212,23 @@ impl RenderOnce for StoryItem { div() .my_2() .flex() + .gap_4() .w_full() .child( Story::v_stack() .px_2() - .flex_none() .w_1_2() .min_h_px() .child(Story::label(self.label)) .child( div() - .rounded_sm() + .rounded_md() .bg(story_color().card_background) .border() .border_color(story_color().border) + .py_1() + .px_2() + .overflow_hidden() .child(self.item), ) .when_some(self.description, |this, description| { @@ -233,7 +242,7 @@ impl RenderOnce for StoryItem { .w_1_2() .min_h_px() .when_some(self.usage, |this, usage| { - this.child(Story::label("Usage")) + this.child(Story::label("Example Usage")) .child(Story::code_block(usage)) }), ) @@ -264,6 +273,11 @@ impl RenderOnce for StorySection { type Rendered = Div; fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + let children: SmallVec<[AnyElement; 2]> = SmallVec::from_iter(Itertools::intersperse_with( + self.children.into_iter(), + || Story::divider().into_any_element(), + )); + Story::section() // Section title .py_2() @@ -271,7 +285,7 @@ impl RenderOnce for StorySection { .when_some(self.description.clone(), |section, description| { section.child(Story::description(description)) }) - .child(div().flex().flex_col().gap_2().children(self.children)) + .child(div().flex().flex_col().gap_2().children(children)) .child(Story::divider()) } } diff --git a/crates/storybook2/src/stories/text.rs b/crates/storybook2/src/stories/text.rs index 279a2dbf4d24051aca3ec82263ea8821bb24ae7b..b48b9dd4b5ea438564499ec80654e6f052aa4396 100644 --- a/crates/storybook2/src/stories/text.rs +++ b/crates/storybook2/src/stories/text.rs @@ -1,4 +1,4 @@ -use gpui::{div, Div, ParentElement, Render, Styled, View, VisualContext, WindowContext}; +use gpui::{div, red, Div, ParentElement, Render, Styled, View, VisualContext, WindowContext}; use indoc::indoc; use story::*; @@ -13,22 +13,64 @@ impl TextStory { impl Render for TextStory { type Element = Div; - fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { - // let # = "The quick brown fox jumps over the lazy dog. Meanwhile, the lazy dog decided it was time for a change. He started daily workout routines, ate healthier and became the fastest dog in town."; - + fn render(&mut self, _cx: &mut gpui::ViewContext) -> Self::Element { Story::container2::("crates/storybook2/src/stories/text.rs").child( - StorySection::new().child( - StoryItem::new( - "Default Text", - div().flex().child(div().max_w_96().child("foo")), + StorySection::new() + .child( + StoryItem::new("Default", div().bg(gpui::blue()).child("Hello World!")) + .usage(indoc! {r##" + div() + .child("Hello World!") + "## + }), + ) + .child( + StoryItem::new("Wrapping Text", + div().max_w_96() + .child( + concat!( + "The quick brown fox jumps over the lazy dog. ", + "Meanwhile, the lazy dog decided it was time for a change. ", + "He started daily workout routines, ate healthier and became the fastest dog in town.", + ) + ) + ) + .description("Set a width or max-width to enable text wrapping.") + .usage(indoc! {r##" + div() + .max_w_96() + .child("Some text that you want to wrap.") + "## + }) + ) + .child( + StoryItem::new("tbd", + div().flex().w_96().child(div().overflow_hidden().child(concat!( + "flex-row. width 96. overflow-hidden. The quick brown fox jumps over the lazy dog. ", + "Meanwhile, the lazy dog decided it was time for a change. ", + "He started daily workout routines, ate healthier and became the fastest dog in town.", + ))) + ) + ) + .child( + StoryItem::new("Text in Horizontal Flex", + div().flex().w_96().bg(red()).child(concat!( + "flex-row. width 96. The quick brown fox jumps over the lazy dog. ", + "Meanwhile, the lazy dog decided it was time for a change. ", + "He started daily workout routines, ate healthier and became the fastest dog in town.", + )) + ) + .usage(indoc! {r##" + // NOTE: When rendering text in a horizonal flex container, + // Taffy will not pass width constraints down from the parent. + // To fix this, render text in a parent with overflow: hidden + + div() + .max_w_96() + .child("Some text that you want to wrap.") + "## + }) ) - .description("Text with a max-width. Wraps based on set max-width.") - .usage(indoc! {r##" - div().max_w_96() - .child("Some text that you want to wrap.") - "## - }), - ), ) } } From bbbdb9ff3e6cc90cf35c823e255cd694aa135af8 Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 14 Dec 2023 17:11:00 -0500 Subject: [PATCH 031/644] Render panel in this test to make sure it can receive focus --- crates/gpui2/src/app.rs | 1 - crates/gpui2/src/window.rs | 11 ++++++----- crates/project_panel2/src/project_panel.rs | 10 +++++++--- crates/workspace2/src/workspace2.rs | 1 + 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index deb03498bc7d1783aac36acdd8bb88428d7c5c64..771b56115198441d4f14506639d391cb7897747f 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -611,7 +611,6 @@ impl AppContext { .values() .filter_map(|window| { let window = window.as_ref()?; - dbg!(window.focus_invalidated); (window.dirty || window.focus_invalidated).then_some(window.handle) }) .collect::>() diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 895ae788627aa7d608762cef2ca0c4b6b4bbd15e..557b2155f86caa58f3509c8120eda6bf223c28e7 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -470,6 +470,7 @@ impl<'a> WindowContext<'a> { #[cfg(any(test, feature = "test-support"))] { + println!("invalidating focus"); self.window.focus_invalidated = true; } @@ -1237,6 +1238,11 @@ impl<'a> WindowContext<'a> { /// Draw pixels to the display for this window based on the contents of its scene. pub(crate) fn draw(&mut self) -> Scene { + #[cfg(any(test, feature = "test-support"))] + { + self.window.focus_invalidated = false; + } + self.text_system().start_frame(); self.window.platform_window.clear_input_handler(); self.window.layout_engine.as_mut().unwrap().clear(); @@ -1290,11 +1296,6 @@ impl<'a> WindowContext<'a> { let current_focus_path = self.window.rendered_frame.focus_path(); if previous_focus_path != current_focus_path { - #[cfg(any(test, feature = "test-support"))] - { - self.window.focus_invalidated = false; - } - if !previous_focus_path.is_empty() && current_focus_path.is_empty() { self.window .blur_listeners diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index 5e71266c2177c857d6d5fbd6f34c1d3f59ef68da..f7789c1a62af282840bc53acdcf5758a6257dd8c 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -739,7 +739,6 @@ impl ProjectPanel { }); self.filename_editor.update(cx, |editor, cx| { editor.clear(cx); - println!("focusing"); editor.focus(cx); }); self.update_visible_entries(Some((worktree_id, NEW_ENTRY_ID)), cx); @@ -1672,7 +1671,7 @@ mod tests { path::{Path, PathBuf}, sync::atomic::{self, AtomicUsize}, }; - use workspace::AppState; + use workspace::{dock::PanelHandle, AppState}; #[gpui::test] async fn test_visible_list(cx: &mut gpui::TestAppContext) { @@ -2281,7 +2280,12 @@ mod tests { let workspace = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let cx = &mut VisualTestContext::from_window(*workspace, cx); let panel = workspace - .update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)) + .update(cx, |workspace, cx| { + let panel = ProjectPanel::new(workspace, cx); + workspace.add_panel(panel.clone(), cx); + workspace.toggle_dock(panel.read(cx).position(cx), cx); + panel + }) .unwrap(); select_path(&panel, "root1", cx); diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index a7dc76f41da49fe4bf9139ed2bf7b0ae8b6f4b23..3cfb1f2458dfb2cfd90a3aa28790c457642ce3a6 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -532,6 +532,7 @@ impl Workspace { cx.notify() }) .detach(); + cx.on_blur_window(|this, cx| { let focus_handle = this.focus_handle(cx); cx.focus(&focus_handle); From d13a21c2388c6507ec66775529ccaa7ac1783e2b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 14 Dec 2023 15:15:18 -0700 Subject: [PATCH 032/644] Don't move in paint --- crates/editor2/src/element.rs | 9 +- crates/gpui2/src/element.rs | 24 +- crates/gpui2/src/elements/canvas.rs | 8 +- crates/gpui2/src/elements/div.rs | 516 +++++++++++------- crates/gpui2/src/elements/img.rs | 5 +- crates/gpui2/src/elements/list.rs | 4 +- crates/gpui2/src/elements/overlay.rs | 4 +- crates/gpui2/src/elements/svg.rs | 8 +- crates/gpui2/src/elements/text.rs | 15 +- crates/gpui2/src/elements/uniform_list.rs | 6 +- crates/gpui2/src/view.rs | 16 +- crates/terminal_view2/src/terminal_element.rs | 299 +++++----- crates/ui2/src/components/popover_menu.rs | 6 +- crates/ui2/src/components/right_click_menu.rs | 8 +- crates/workspace2/src/pane_group.rs | 4 +- 15 files changed, 538 insertions(+), 394 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 9b95e256a65e0342a6b4191f8b300b98166232f8..831b6cd35ae8c80282ba312bc965fb8577e99bd3 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -933,7 +933,7 @@ impl EditorElement { cx.stop_propagation(); }, )) - .draw( + .draw2( fold_bounds.origin, fold_bounds.size, cx, @@ -1199,11 +1199,10 @@ impl EditorElement { .child(mouse_context_menu.context_menu.clone()) .anchor(AnchorCorner::TopLeft) .snap_to_window(); - element.draw( + element.into_any().draw( gpui::Point::default(), size(AvailableSpace::MinContent, AvailableSpace::MinContent), cx, - |_, _| {}, ); } } @@ -1496,7 +1495,7 @@ impl EditorElement { let scroll_left = scroll_position.x * layout.position_map.em_width; let scroll_top = scroll_position.y * layout.position_map.line_height; - for block in layout.blocks.drain(..) { + for mut block in layout.blocks.drain(..) { let mut origin = bounds.origin + point( Pixels::ZERO, @@ -2781,7 +2780,7 @@ impl Element for EditorElement { } fn paint( - mut self, + &mut self, bounds: Bounds, element_state: &mut Self::State, cx: &mut gpui::WindowContext, diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index e5ecd195baa14694bc65a15e9102d5cbd56be10a..f4bcb17f3c8180be4bef821092d6ef7ea1b0f88d 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -23,7 +23,7 @@ pub trait IntoElement: Sized { self.into_element().into_any() } - fn draw( + fn draw2( self, origin: Point, available_space: Size, @@ -92,7 +92,7 @@ pub trait Element: 'static + IntoElement { cx: &mut WindowContext, ) -> (LayoutId, Self::State); - fn paint(self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext); + fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext); fn into_any(self) -> AnyElement { AnyElement::new(self) @@ -150,8 +150,8 @@ impl Element for Component { } } - fn paint(self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { - let element = state.rendered_element.take().unwrap(); + fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { + let mut element = state.rendered_element.take().unwrap(); if let Some(element_id) = element.element_id() { cx.with_element_state(element_id, |element_state, cx| { let mut element_state = element_state.unwrap(); @@ -420,7 +420,7 @@ impl AnyElement { self.0.layout(cx) } - pub fn paint(mut self, cx: &mut WindowContext) { + pub fn paint(&mut self, cx: &mut WindowContext) { self.0.paint(cx) } @@ -435,7 +435,7 @@ impl AnyElement { /// Initializes this element and performs layout in the available space, then paints it at the given origin. pub fn draw( - mut self, + &mut self, origin: Point, available_space: Size, cx: &mut WindowContext, @@ -465,8 +465,8 @@ impl Element for AnyElement { (layout_id, ()) } - fn paint(self, _: Bounds, _: &mut Self::State, cx: &mut WindowContext) { - self.paint(cx); + fn paint(&mut self, _: Bounds, _: &mut Self::State, cx: &mut WindowContext) { + self.paint(cx) } } @@ -508,5 +508,11 @@ impl Element for () { (cx.request_layout(&crate::Style::default(), None), ()) } - fn paint(self, _bounds: Bounds, _state: &mut Self::State, _cx: &mut WindowContext) {} + fn paint( + &mut self, + _bounds: Bounds, + _state: &mut Self::State, + _cx: &mut WindowContext, + ) { + } } diff --git a/crates/gpui2/src/elements/canvas.rs b/crates/gpui2/src/elements/canvas.rs index b3afd335d41d4544267a9453e8ffedea5c990b18..56cfef4553470a146913d4664e862f4dab3ec328 100644 --- a/crates/gpui2/src/elements/canvas.rs +++ b/crates/gpui2/src/elements/canvas.rs @@ -4,13 +4,13 @@ use crate::{Bounds, Element, IntoElement, Pixels, Style, StyleRefinement, Styled pub fn canvas(callback: impl 'static + FnOnce(&Bounds, &mut WindowContext)) -> Canvas { Canvas { - paint_callback: Box::new(callback), + paint_callback: Some(Box::new(callback)), style: StyleRefinement::default(), } } pub struct Canvas { - paint_callback: Box, &mut WindowContext)>, + paint_callback: Option, &mut WindowContext)>>, style: StyleRefinement, } @@ -40,8 +40,8 @@ impl Element for Canvas { (layout_id, ()) } - fn paint(self, bounds: Bounds, _: &mut (), cx: &mut WindowContext) { - (self.paint_callback)(&bounds, cx) + fn paint(&mut self, bounds: Bounds, _: &mut (), cx: &mut WindowContext) { + (self.paint_callback.take().unwrap())(&bounds, cx) } } diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index c24b5617d5d9e795de212e9e42cfae27e82d35e3..ff2e87e8e7f15aeff8b8157a0c689765b5105efc 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -35,6 +35,281 @@ pub struct DragMoveEvent { pub drag: View, } +impl Interactivity { + pub fn on_mouse_down( + &mut self, + button: MouseButton, + listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, + ) { + self.mouse_down_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Bubble + && event.button == button + && bounds.visibly_contains(&event.position, cx) + { + (listener)(event, cx) + } + })); + } + + pub fn on_any_mouse_down( + &mut self, + listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, + ) { + self.mouse_down_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) { + (listener)(event, cx) + } + })); + } + + pub fn on_mouse_up( + &mut self, + button: MouseButton, + listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static, + ) { + self.mouse_up_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Bubble + && event.button == button + && bounds.visibly_contains(&event.position, cx) + { + (listener)(event, cx) + } + })); + } + + pub fn on_any_mouse_up( + &mut self, + listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static, + ) { + self.mouse_up_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) { + (listener)(event, cx) + } + })); + } + + pub fn on_mouse_down_out( + &mut self, + listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, + ) { + self.mouse_down_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Capture && !bounds.visibly_contains(&event.position, cx) + { + (listener)(event, cx) + } + })); + } + + pub fn on_mouse_up_out( + &mut self, + button: MouseButton, + listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static, + ) { + self.mouse_up_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Capture + && event.button == button + && !bounds.visibly_contains(&event.position, cx) + { + (listener)(event, cx); + } + })); + } + + pub fn on_mouse_move( + &mut self, + listener: impl Fn(&MouseMoveEvent, &mut WindowContext) + 'static, + ) { + self.mouse_move_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) { + (listener)(event, cx); + } + })); + } + + pub fn on_drag_move( + &mut self, + listener: impl Fn(&DragMoveEvent, &mut WindowContext) + 'static, + ) where + W: Render, + { + self.mouse_move_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Capture + && bounds.drag_target_contains(&event.position, cx) + { + if let Some(view) = cx.active_drag().and_then(|view| view.downcast::().ok()) + { + (listener)( + &DragMoveEvent { + event: event.clone(), + drag: view, + }, + cx, + ); + } + } + })); + } + + pub fn on_scroll_wheel( + &mut self, + listener: impl Fn(&ScrollWheelEvent, &mut WindowContext) + 'static, + ) { + self.scroll_wheel_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) { + (listener)(event, cx); + } + })); + } + + pub fn capture_action( + &mut self, + listener: impl Fn(&A, &mut WindowContext) + 'static, + ) { + self.action_listeners.push(( + TypeId::of::(), + Box::new(move |action, phase, cx| { + let action = action.downcast_ref().unwrap(); + if phase == DispatchPhase::Capture { + (listener)(action, cx) + } + }), + )); + } + + pub fn on_action(&mut self, listener: impl Fn(&A, &mut WindowContext) + 'static) { + self.action_listeners.push(( + TypeId::of::(), + Box::new(move |action, phase, cx| { + let action = action.downcast_ref().unwrap(); + if phase == DispatchPhase::Bubble { + (listener)(action, cx) + } + }), + )); + } + + pub fn on_boxed_action( + &mut self, + action: &Box, + listener: impl Fn(&Box, &mut WindowContext) + 'static, + ) { + let action = action.boxed_clone(); + self.action_listeners.push(( + (*action).type_id(), + Box::new(move |_, phase, cx| { + if phase == DispatchPhase::Bubble { + (listener)(&action, cx) + } + }), + )); + } + + pub fn on_key_down(&mut self, listener: impl Fn(&KeyDownEvent, &mut WindowContext) + 'static) { + self.key_down_listeners + .push(Box::new(move |event, phase, cx| { + if phase == DispatchPhase::Bubble { + (listener)(event, cx) + } + })); + } + + pub fn capture_key_down( + &mut self, + listener: impl Fn(&KeyDownEvent, &mut WindowContext) + 'static, + ) { + self.key_down_listeners + .push(Box::new(move |event, phase, cx| { + if phase == DispatchPhase::Capture { + listener(event, cx) + } + })); + } + + pub fn on_key_up(&mut self, listener: impl Fn(&KeyUpEvent, &mut WindowContext) + 'static) { + self.key_up_listeners + .push(Box::new(move |event, phase, cx| { + if phase == DispatchPhase::Bubble { + listener(event, cx) + } + })); + } + + pub fn capture_key_up(&mut self, listener: impl Fn(&KeyUpEvent, &mut WindowContext) + 'static) { + self.key_up_listeners + .push(Box::new(move |event, phase, cx| { + if phase == DispatchPhase::Capture { + listener(event, cx) + } + })); + } + + pub fn on_drop( + &mut self, + listener: impl Fn(&View, &mut WindowContext) + 'static, + ) { + self.drop_listeners.push(( + TypeId::of::(), + Box::new(move |dragged_view, cx| { + listener(&dragged_view.downcast().unwrap(), cx); + }), + )); + } + + pub fn on_click(&mut self, listener: impl Fn(&ClickEvent, &mut WindowContext) + 'static) + where + Self: Sized, + { + self.click_listeners + .push(Box::new(move |event, cx| listener(event, cx))); + } + + pub fn on_drag(&mut self, constructor: impl Fn(&mut WindowContext) -> View + 'static) + where + Self: Sized, + W: 'static + Render, + { + debug_assert!( + self.drag_listener.is_none(), + "calling on_drag more than once on the same element is not supported" + ); + self.drag_listener = Some(Box::new(move |cursor_offset, cx| AnyDrag { + view: constructor(cx).into(), + cursor_offset, + })); + } + + pub fn on_hover(&mut self, listener: impl Fn(&bool, &mut WindowContext) + 'static) + where + Self: Sized, + { + debug_assert!( + self.hover_listener.is_none(), + "calling on_hover more than once on the same element is not supported" + ); + self.hover_listener = Some(Box::new(listener)); + } + + pub fn tooltip(&mut self, build_tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) + where + Self: Sized, + { + debug_assert!( + self.tooltip_builder.is_none(), + "calling tooltip more than once on the same element is not supported" + ); + self.tooltip_builder = Some(Rc::new(build_tooltip)); + } +} + pub trait InteractiveElement: Sized { fn interactivity(&mut self) -> &mut Interactivity; @@ -92,16 +367,7 @@ pub trait InteractiveElement: Sized { button: MouseButton, listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity().mouse_down_listeners.push(Box::new( - move |event, bounds, phase, cx| { - if phase == DispatchPhase::Bubble - && event.button == button - && bounds.visibly_contains(&event.position, cx) - { - (listener)(event, cx) - } - }, - )); + self.interactivity().on_mouse_down(button, listener); self } @@ -109,13 +375,7 @@ pub trait InteractiveElement: Sized { mut self, listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity().mouse_down_listeners.push(Box::new( - move |event, bounds, phase, cx| { - if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) { - (listener)(event, cx) - } - }, - )); + self.interactivity().on_any_mouse_down(listener); self } @@ -124,30 +384,7 @@ pub trait InteractiveElement: Sized { button: MouseButton, listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity() - .mouse_up_listeners - .push(Box::new(move |event, bounds, phase, cx| { - if phase == DispatchPhase::Bubble - && event.button == button - && bounds.visibly_contains(&event.position, cx) - { - (listener)(event, cx) - } - })); - self - } - - fn on_any_mouse_up( - mut self, - listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static, - ) -> Self { - self.interactivity() - .mouse_up_listeners - .push(Box::new(move |event, bounds, phase, cx| { - if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) { - (listener)(event, cx) - } - })); + self.interactivity().on_mouse_up(button, listener); self } @@ -155,14 +392,7 @@ pub trait InteractiveElement: Sized { mut self, listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity().mouse_down_listeners.push(Box::new( - move |event, bounds, phase, cx| { - if phase == DispatchPhase::Capture && !bounds.visibly_contains(&event.position, cx) - { - (listener)(event, cx) - } - }, - )); + self.interactivity().on_mouse_down_out(listener); self } @@ -171,16 +401,7 @@ pub trait InteractiveElement: Sized { button: MouseButton, listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity() - .mouse_up_listeners - .push(Box::new(move |event, bounds, phase, cx| { - if phase == DispatchPhase::Capture - && event.button == button - && !bounds.visibly_contains(&event.position, cx) - { - (listener)(event, cx); - } - })); + self.interactivity().on_mouse_up_out(button, listener); self } @@ -188,13 +409,7 @@ pub trait InteractiveElement: Sized { mut self, listener: impl Fn(&MouseMoveEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity().mouse_move_listeners.push(Box::new( - move |event, bounds, phase, cx| { - if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) { - (listener)(event, cx); - } - }, - )); + self.interactivity().on_mouse_move(listener); self } @@ -205,24 +420,7 @@ pub trait InteractiveElement: Sized { where W: Render, { - self.interactivity().mouse_move_listeners.push(Box::new( - move |event, bounds, phase, cx| { - if phase == DispatchPhase::Capture - && bounds.drag_target_contains(&event.position, cx) - { - if let Some(view) = cx.active_drag().and_then(|view| view.downcast::().ok()) - { - (listener)( - &DragMoveEvent { - event: event.clone(), - drag: view, - }, - cx, - ); - } - } - }, - )); + self.interactivity().on_drag_move(listener); self } @@ -230,13 +428,7 @@ pub trait InteractiveElement: Sized { mut self, listener: impl Fn(&ScrollWheelEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity().scroll_wheel_listeners.push(Box::new( - move |event, bounds, phase, cx| { - if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) { - (listener)(event, cx); - } - }, - )); + self.interactivity().on_scroll_wheel(listener); self } @@ -245,29 +437,13 @@ pub trait InteractiveElement: Sized { mut self, listener: impl Fn(&A, &mut WindowContext) + 'static, ) -> Self { - self.interactivity().action_listeners.push(( - TypeId::of::(), - Box::new(move |action, phase, cx| { - let action = action.downcast_ref().unwrap(); - if phase == DispatchPhase::Capture { - (listener)(action, cx) - } - }), - )); + self.interactivity().capture_action(listener); self } /// Add a listener for the given action, fires during the bubble event phase fn on_action(mut self, listener: impl Fn(&A, &mut WindowContext) + 'static) -> Self { - self.interactivity().action_listeners.push(( - TypeId::of::(), - Box::new(move |action, phase, cx| { - let action = action.downcast_ref().unwrap(); - if phase == DispatchPhase::Bubble { - (listener)(action, cx) - } - }), - )); + self.interactivity().on_action(listener); self } @@ -276,15 +452,7 @@ pub trait InteractiveElement: Sized { action: &Box, listener: impl Fn(&Box, &mut WindowContext) + 'static, ) -> Self { - let action = action.boxed_clone(); - self.interactivity().action_listeners.push(( - (*action).type_id(), - Box::new(move |_, phase, cx| { - if phase == DispatchPhase::Bubble { - (listener)(&action, cx) - } - }), - )); + self.interactivity().on_boxed_action(action, listener); self } @@ -292,13 +460,7 @@ pub trait InteractiveElement: Sized { mut self, listener: impl Fn(&KeyDownEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity() - .key_down_listeners - .push(Box::new(move |event, phase, cx| { - if phase == DispatchPhase::Bubble { - (listener)(event, cx) - } - })); + self.interactivity().on_key_down(listener); self } @@ -306,24 +468,12 @@ pub trait InteractiveElement: Sized { mut self, listener: impl Fn(&KeyDownEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity() - .key_down_listeners - .push(Box::new(move |event, phase, cx| { - if phase == DispatchPhase::Capture { - listener(event, cx) - } - })); + self.interactivity().capture_key_down(listener); self } fn on_key_up(mut self, listener: impl Fn(&KeyUpEvent, &mut WindowContext) + 'static) -> Self { - self.interactivity() - .key_up_listeners - .push(Box::new(move |event, phase, cx| { - if phase == DispatchPhase::Bubble { - listener(event, cx) - } - })); + self.interactivity().on_key_up(listener); self } @@ -331,13 +481,15 @@ pub trait InteractiveElement: Sized { mut self, listener: impl Fn(&KeyUpEvent, &mut WindowContext) + 'static, ) -> Self { - self.interactivity() - .key_up_listeners - .push(Box::new(move |event, phase, cx| { - if phase == DispatchPhase::Capture { - listener(event, cx) - } - })); + self.interactivity().capture_key_up(listener); + self + } + + fn on_drop( + mut self, + listener: impl Fn(&View, &mut WindowContext) + 'static, + ) -> Self { + self.interactivity().on_drop(listener); self } @@ -362,19 +514,6 @@ pub trait InteractiveElement: Sized { )); self } - - fn on_drop( - mut self, - listener: impl Fn(&View, &mut WindowContext) + 'static, - ) -> Self { - self.interactivity().drop_listeners.push(( - TypeId::of::(), - Box::new(move |dragged_view, cx| { - listener(&dragged_view.downcast().unwrap(), cx); - }), - )); - self - } } pub trait StatefulInteractiveElement: InteractiveElement { @@ -431,9 +570,7 @@ pub trait StatefulInteractiveElement: InteractiveElement { where Self: Sized, { - self.interactivity() - .click_listeners - .push(Box::new(move |event, cx| listener(event, cx))); + self.interactivity().on_click(listener); self } @@ -442,14 +579,7 @@ pub trait StatefulInteractiveElement: InteractiveElement { Self: Sized, W: 'static + Render, { - debug_assert!( - self.interactivity().drag_listener.is_none(), - "calling on_drag more than once on the same element is not supported" - ); - self.interactivity().drag_listener = Some(Box::new(move |cursor_offset, cx| AnyDrag { - view: constructor(cx).into(), - cursor_offset, - })); + self.interactivity().on_drag(constructor); self } @@ -457,11 +587,7 @@ pub trait StatefulInteractiveElement: InteractiveElement { where Self: Sized, { - debug_assert!( - self.interactivity().hover_listener.is_none(), - "calling on_hover more than once on the same element is not supported" - ); - self.interactivity().hover_listener = Some(Box::new(listener)); + self.interactivity().on_hover(listener); self } @@ -469,11 +595,7 @@ pub trait StatefulInteractiveElement: InteractiveElement { where Self: Sized, { - debug_assert!( - self.interactivity().tooltip_builder.is_none(), - "calling tooltip more than once on the same element is not supported" - ); - self.interactivity().tooltip_builder = Some(Rc::new(build_tooltip)); + self.interactivity().tooltip(build_tooltip); self } } @@ -529,6 +651,7 @@ pub type ActionListener = Box Div { + #[allow(unused_mut)] let mut div = Div { interactivity: Interactivity::default(), children: SmallVec::default(), @@ -598,7 +721,7 @@ impl Element for Div { } fn paint( - self, + &mut self, bounds: Bounds, element_state: &mut Self::State, cx: &mut WindowContext, @@ -649,7 +772,7 @@ impl Element for Div { cx.with_text_style(style.text_style().cloned(), |cx| { cx.with_content_mask(style.overflow_mask(bounds), |cx| { cx.with_element_offset(scroll_offset, |cx| { - for child in self.children { + for child in &mut self.children { child.paint(cx); } }) @@ -769,7 +892,7 @@ impl Interactivity { } pub fn paint( - mut self, + &mut self, bounds: Bounds, content_size: Size, element_state: &mut InteractiveElementState, @@ -788,7 +911,7 @@ impl Interactivity { && bounds.contains(&cx.mouse_position()) { const FONT_SIZE: crate::Pixels = crate::Pixels(10.); - let element_id = format!("{:?}", self.element_id.unwrap()); + let element_id = format!("{:?}", self.element_id.as_ref().unwrap()); let str_len = element_id.len(); let render_debug_text = |cx: &mut WindowContext| { @@ -934,28 +1057,28 @@ impl Interactivity { }); } - for listener in self.mouse_down_listeners { + for listener in self.mouse_down_listeners.drain(..) { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| { listener(event, &interactive_bounds, phase, cx); }) } - for listener in self.mouse_up_listeners { + for listener in self.mouse_up_listeners.drain(..) { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { listener(event, &interactive_bounds, phase, cx); }) } - for listener in self.mouse_move_listeners { + for listener in self.mouse_move_listeners.drain(..) { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { listener(event, &interactive_bounds, phase, cx); }) } - for listener in self.scroll_wheel_listeners { + for listener in self.scroll_wheel_listeners.drain(..) { let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { listener(event, &interactive_bounds, phase, cx); @@ -1024,8 +1147,8 @@ impl Interactivity { } } - let click_listeners = self.click_listeners; - let drag_listener = self.drag_listener; + let click_listeners = mem::take(&mut self.click_listeners); + let drag_listener = mem::take(&mut self.drag_listener); if !click_listeners.is_empty() || drag_listener.is_some() { let pending_mouse_down = element_state @@ -1267,23 +1390,26 @@ impl Interactivity { .as_ref() .map(|scroll_offset| *scroll_offset.borrow()); + let key_down_listeners = mem::take(&mut self.key_down_listeners); + let key_up_listeners = mem::take(&mut self.key_up_listeners); + let action_listeners = mem::take(&mut self.action_listeners); cx.with_key_dispatch( self.key_context.clone(), element_state.focus_handle.clone(), |_, cx| { - for listener in self.key_down_listeners { + for listener in key_down_listeners { cx.on_key_event(move |event: &KeyDownEvent, phase, cx| { listener(event, phase, cx); }) } - for listener in self.key_up_listeners { + for listener in key_up_listeners { cx.on_key_event(move |event: &KeyUpEvent, phase, cx| { listener(event, phase, cx); }) } - for (action_type, listener) in self.action_listeners { + for (action_type, listener) in action_listeners { cx.on_action(action_type, listener) } @@ -1522,7 +1648,7 @@ where self.element.layout(state, cx) } - fn paint(self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { + fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { self.element.paint(bounds, state, cx) } } @@ -1596,7 +1722,7 @@ where self.element.layout(state, cx) } - fn paint(self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { + fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { self.element.paint(bounds, state, cx) } } diff --git a/crates/gpui2/src/elements/img.rs b/crates/gpui2/src/elements/img.rs index f6aae2de66aebb7bc894bd63a8d9a85a6e74e089..4f81f604c8d3799923b9fb76742019cb1724c0b5 100644 --- a/crates/gpui2/src/elements/img.rs +++ b/crates/gpui2/src/elements/img.rs @@ -81,11 +81,12 @@ impl Element for Img { } fn paint( - self, + &mut self, bounds: Bounds, element_state: &mut Self::State, cx: &mut WindowContext, ) { + let source = self.source.clone(); self.interactivity.paint( bounds, bounds.size, @@ -94,7 +95,7 @@ impl Element for Img { |style, _scroll_offset, cx| { let corner_radii = style.corner_radii.to_pixels(bounds.size, cx.rem_size()); cx.with_z_index(1, |cx| { - match self.source { + match source { ImageSource::Uri(uri) => { let image_future = cx.image_cache.get(uri.clone()); if let Some(data) = image_future diff --git a/crates/gpui2/src/elements/list.rs b/crates/gpui2/src/elements/list.rs index ba479e1ea8f460ecf5915661f877a89f132f288d..6818c5c7a2e62baab27aad701dfa27cfa80dbce4 100644 --- a/crates/gpui2/src/elements/list.rs +++ b/crates/gpui2/src/elements/list.rs @@ -257,7 +257,7 @@ impl Element for List { } fn paint( - self, + &mut self, bounds: crate::Bounds, _state: &mut Self::State, cx: &mut crate::WindowContext, @@ -385,7 +385,7 @@ impl Element for List { // Paint the visible items let mut item_origin = bounds.origin; item_origin.y -= scroll_top.offset_in_item; - for mut item_element in item_elements { + for item_element in &mut item_elements { let item_height = item_element.measure(available_item_space, cx).height; item_element.draw(item_origin, available_item_space, cx); item_origin.y += item_height; diff --git a/crates/gpui2/src/elements/overlay.rs b/crates/gpui2/src/elements/overlay.rs index e925d03d275ea75d40633b1add4228b3c1ffce38..5b72019f177f899f886a375fe4468bcf403c336c 100644 --- a/crates/gpui2/src/elements/overlay.rs +++ b/crates/gpui2/src/elements/overlay.rs @@ -81,7 +81,7 @@ impl Element for Overlay { } fn paint( - self, + &mut self, bounds: crate::Bounds, element_state: &mut Self::State, cx: &mut WindowContext, @@ -149,7 +149,7 @@ impl Element for Overlay { cx.with_element_offset(desired.origin - bounds.origin, |cx| { cx.break_content_mask(|cx| { - for child in self.children { + for child in &mut self.children { child.paint(cx); } }) diff --git a/crates/gpui2/src/elements/svg.rs b/crates/gpui2/src/elements/svg.rs index aba31686f588fbfca2d9aabf2e04e52daa15d5bd..9ca9baf470e6c3bdeec2fafb1806d34430c44aea 100644 --- a/crates/gpui2/src/elements/svg.rs +++ b/crates/gpui2/src/elements/svg.rs @@ -36,8 +36,12 @@ impl Element for Svg { }) } - fn paint(self, bounds: Bounds, element_state: &mut Self::State, cx: &mut WindowContext) - where + fn paint( + &mut self, + bounds: Bounds, + element_state: &mut Self::State, + cx: &mut WindowContext, + ) where Self: Sized, { self.interactivity diff --git a/crates/gpui2/src/elements/text.rs b/crates/gpui2/src/elements/text.rs index b8fe5e68666d7abe3e7f07b90feb4e7cdc7a5354..175a79c19a512832c7c70571780adb6268b91ab2 100644 --- a/crates/gpui2/src/elements/text.rs +++ b/crates/gpui2/src/elements/text.rs @@ -6,7 +6,7 @@ use crate::{ use anyhow::anyhow; use parking_lot::{Mutex, MutexGuard}; use smallvec::SmallVec; -use std::{cell::Cell, ops::Range, rc::Rc, sync::Arc}; +use std::{cell::Cell, mem, ops::Range, rc::Rc, sync::Arc}; use util::ResultExt; impl Element for &'static str { @@ -22,7 +22,7 @@ impl Element for &'static str { (layout_id, state) } - fn paint(self, bounds: Bounds, state: &mut TextState, cx: &mut WindowContext) { + fn paint(&mut self, bounds: Bounds, state: &mut TextState, cx: &mut WindowContext) { state.paint(bounds, self, cx) } } @@ -52,7 +52,7 @@ impl Element for SharedString { (layout_id, state) } - fn paint(self, bounds: Bounds, state: &mut TextState, cx: &mut WindowContext) { + fn paint(&mut self, bounds: Bounds, state: &mut TextState, cx: &mut WindowContext) { let text_str: &str = self.as_ref(); state.paint(bounds, text_str, cx) } @@ -128,7 +128,7 @@ impl Element for StyledText { (layout_id, state) } - fn paint(self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { + fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { state.paint(bounds, &self.text, cx) } } @@ -356,8 +356,8 @@ impl Element for InteractiveText { } } - fn paint(self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { - if let Some(click_listener) = self.click_listener { + fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { + if let Some(click_listener) = self.click_listener.take() { if let Some(ix) = state .text_state .index_for_position(bounds, cx.mouse_position()) @@ -374,13 +374,14 @@ impl Element for InteractiveText { let text_state = state.text_state.clone(); let mouse_down = state.mouse_down_index.clone(); if let Some(mouse_down_index) = mouse_down.get() { + let clickable_ranges = mem::take(&mut self.clickable_ranges); cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { if phase == DispatchPhase::Bubble { if let Some(mouse_up_index) = text_state.index_for_position(bounds, event.position) { click_listener( - &self.clickable_ranges, + &clickable_ranges, InteractiveTextClickEvent { mouse_down_index, mouse_up_index, diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index debd365c87da2da4fbf402dc6bf4188267c191ee..9fedbad41c580b767d5c4425be1aa7a5c5f3b9b9 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -155,7 +155,7 @@ impl Element for UniformList { } fn paint( - self, + &mut self, bounds: Bounds, element_state: &mut Self::State, cx: &mut WindowContext, @@ -220,11 +220,11 @@ impl Element for UniformList { let visible_range = first_visible_element_ix ..cmp::min(last_visible_element_ix, self.item_count); - let items = (self.render_items)(visible_range.clone(), cx); + let mut items = (self.render_items)(visible_range.clone(), cx); cx.with_z_index(1, |cx| { let content_mask = ContentMask { bounds }; cx.with_content_mask(Some(content_mask), |cx| { - for (item, ix) in items.into_iter().zip(visible_range) { + for (item, ix) in items.iter_mut().zip(visible_range) { let item_origin = padded_bounds.origin + point(px(0.), item_height * ix + scroll_offset.y); let available_space = size( diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index d3506e93fa1f4630d620258b77c8995c1c4cc0c3..7657ae25120c526d6581fb8be8709bdb2e2024bb 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -90,7 +90,7 @@ impl Element for View { (layout_id, Some(element)) } - fn paint(self, _: Bounds, element: &mut Self::State, cx: &mut WindowContext) { + fn paint(&mut self, _: Bounds, element: &mut Self::State, cx: &mut WindowContext) { element.take().unwrap().paint(cx); } } @@ -170,7 +170,7 @@ impl Eq for WeakView {} pub struct AnyView { model: AnyModel, layout: fn(&AnyView, &mut WindowContext) -> (LayoutId, AnyElement), - paint: fn(&AnyView, AnyElement, &mut WindowContext), + paint: fn(&AnyView, &mut AnyElement, &mut WindowContext), } impl AnyView { @@ -209,7 +209,7 @@ impl AnyView { ) { cx.with_absolute_element_offset(origin, |cx| { let start_time = std::time::Instant::now(); - let (layout_id, rendered_element) = (self.layout)(self, cx); + let (layout_id, mut rendered_element) = (self.layout)(self, cx); let duration = start_time.elapsed(); println!("request layout: {:?}", duration); @@ -219,7 +219,7 @@ impl AnyView { println!("compute layout: {:?}", duration); let start_time = std::time::Instant::now(); - (self.paint)(self, rendered_element, cx); + (self.paint)(self, &mut rendered_element, cx); let duration = start_time.elapsed(); println!("paint: {:?}", duration); }) @@ -248,12 +248,12 @@ impl Element for AnyView { (layout_id, Some(state)) } - fn paint(self, _: Bounds, state: &mut Self::State, cx: &mut WindowContext) { + fn paint(&mut self, _: Bounds, state: &mut Self::State, cx: &mut WindowContext) { debug_assert!( state.is_some(), "state is None. Did you include an AnyView twice in the tree?" ); - (self.paint)(&self, state.take().unwrap(), cx) + (self.paint)(&self, state.as_mut().unwrap(), cx) } } @@ -284,7 +284,7 @@ impl IntoElement for AnyView { pub struct AnyWeakView { model: AnyWeakModel, layout: fn(&AnyView, &mut WindowContext) -> (LayoutId, AnyElement), - paint: fn(&AnyView, AnyElement, &mut WindowContext), + paint: fn(&AnyView, &mut AnyElement, &mut WindowContext), } impl AnyWeakView { @@ -335,7 +335,7 @@ mod any_view { pub(crate) fn paint( _view: &AnyView, - element: AnyElement, + element: &mut AnyElement, cx: &mut WindowContext, ) { element.paint(cx); diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index 7358f2e1d735bd9170ab2815035d4232c3e4f933..7f221129f03009115be75c2f405990cc228be7a3 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -2,8 +2,8 @@ use editor::{Cursor, HighlightedRange, HighlightedRangeLine}; use gpui::{ black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, FontStyle, - FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, IntoElement, - LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels, + FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, Interactivity, + IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels, PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled, TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, }; @@ -145,11 +145,11 @@ pub struct TerminalElement { focused: bool, cursor_visible: bool, can_navigate_to_selected_word: bool, - interactivity: gpui::Interactivity, + interactivity: Interactivity, } impl InteractiveElement for TerminalElement { - fn interactivity(&mut self) -> &mut gpui::Interactivity { + fn interactivity(&mut self) -> &mut Interactivity { &mut self.interactivity } } @@ -605,141 +605,157 @@ impl TerminalElement { } fn register_mouse_listeners( - self, + &mut self, origin: Point, mode: TermMode, bounds: Bounds, cx: &mut WindowContext, - ) -> Self { + ) { let focus = self.focus.clone(); - let connection = self.terminal.clone(); - - let mut this = self - .on_mouse_down(MouseButton::Left, { - let connection = connection.clone(); - let focus = focus.clone(); - move |e, cx| { - cx.focus(&focus); - //todo!(context menu) - // v.context_menu.update(cx, |menu, _cx| menu.delay_cancel()); - connection.update(cx, |terminal, cx| { - terminal.mouse_down(&e, origin); + let terminal = self.terminal.clone(); + + self.interactivity.on_mouse_down(MouseButton::Left, { + let terminal = terminal.clone(); + let focus = focus.clone(); + move |e, cx| { + cx.focus(&focus); + //todo!(context menu) + // v.context_menu.update(cx, |menu, _cx| menu.delay_cancel()); + terminal.update(cx, |terminal, cx| { + terminal.mouse_down(&e, origin); + cx.notify(); + }) + } + }); + self.interactivity.on_mouse_move({ + let terminal = terminal.clone(); + let focus = focus.clone(); + move |e, cx| { + if e.pressed_button.is_some() && focus.is_focused(cx) && !cx.has_active_drag() { + terminal.update(cx, |terminal, cx| { + terminal.mouse_drag(e, origin, bounds); cx.notify(); }) } - }) - .on_mouse_move({ - let connection = connection.clone(); - let focus = focus.clone(); - move |e, cx| { - if e.pressed_button.is_some() && focus.is_focused(cx) && !cx.has_active_drag() { - connection.update(cx, |terminal, cx| { - terminal.mouse_drag(e, origin, bounds); - cx.notify(); - }) - } - } - }) - .on_mouse_up( - MouseButton::Left, - TerminalElement::generic_button_handler( - connection.clone(), - origin, - focus.clone(), - move |terminal, origin, e, cx| { - terminal.mouse_up(&e, origin, cx); - }, - ), - ) - .on_click({ - let connection = connection.clone(); - move |e, cx| { - if e.down.button == MouseButton::Right { - let mouse_mode = connection.update(cx, |terminal, _cx| { - terminal.mouse_mode(e.down.modifiers.shift) - }); - - if !mouse_mode { - //todo!(context menu) - // view.deploy_context_menu(e.position, cx); - } - } - } - }) - .on_mouse_move({ - let connection = connection.clone(); - let focus = focus.clone(); - move |e, cx| { - if focus.is_focused(cx) { - connection.update(cx, |terminal, cx| { - terminal.mouse_move(&e, origin); - cx.notify(); - }) + } + }); + self.interactivity.on_mouse_up( + MouseButton::Left, + TerminalElement::generic_button_handler( + terminal.clone(), + origin, + focus.clone(), + move |terminal, origin, e, cx| { + terminal.mouse_up(&e, origin, cx); + }, + ), + ); + self.interactivity.on_click({ + let terminal = terminal.clone(); + move |e, cx| { + if e.down.button == MouseButton::Right { + let mouse_mode = terminal.update(cx, |terminal, _cx| { + terminal.mouse_mode(e.down.modifiers.shift) + }); + + if !mouse_mode { + //todo!(context menu) + // view.deploy_context_menu(e.position, cx); } } - }) - .on_scroll_wheel({ - let connection = connection.clone(); - move |e, cx| { - connection.update(cx, |terminal, cx| { - terminal.scroll_wheel(e, origin); + } + }); + + self.interactivity.on_mouse_move({ + let terminal = terminal.clone(); + let focus = focus.clone(); + move |e, cx| { + if focus.is_focused(cx) { + terminal.update(cx, |terminal, cx| { + terminal.mouse_move(&e, origin); cx.notify(); }) } - }); + } + }); + self.interactivity.on_scroll_wheel({ + let terminal = terminal.clone(); + move |e, cx| { + terminal.update(cx, |terminal, cx| { + terminal.scroll_wheel(e, origin); + cx.notify(); + }) + } + }); + + self.interactivity.on_drop::({ + let focus = focus.clone(); + let terminal = terminal.clone(); + move |external_paths, cx| { + cx.focus(&focus); + let mut new_text = external_paths + .read(cx) + .paths() + .iter() + .map(|path| format!(" {path:?}")) + .join(""); + new_text.push(' '); + terminal.update(cx, |terminal, _| { + // todo!() long paths are not displayed properly albeit the text is there + terminal.paste(&new_text); + }); + } + }); // Mouse mode handlers: // All mouse modes need the extra click handlers if mode.intersects(TermMode::MOUSE_MODE) { - this = this - .on_mouse_down( - MouseButton::Right, - TerminalElement::generic_button_handler( - connection.clone(), - origin, - focus.clone(), - move |terminal, origin, e, _cx| { - terminal.mouse_down(&e, origin); - }, - ), - ) - .on_mouse_down( - MouseButton::Middle, - TerminalElement::generic_button_handler( - connection.clone(), - origin, - focus.clone(), - move |terminal, origin, e, _cx| { - terminal.mouse_down(&e, origin); - }, - ), - ) - .on_mouse_up( - MouseButton::Right, - TerminalElement::generic_button_handler( - connection.clone(), - origin, - focus.clone(), - move |terminal, origin, e, cx| { - terminal.mouse_up(&e, origin, cx); - }, - ), - ) - .on_mouse_up( - MouseButton::Middle, - TerminalElement::generic_button_handler( - connection, - origin, - focus, - move |terminal, origin, e, cx| { - terminal.mouse_up(&e, origin, cx); - }, - ), - ) + self.interactivity.on_mouse_down( + MouseButton::Right, + TerminalElement::generic_button_handler( + terminal.clone(), + origin, + focus.clone(), + move |terminal, origin, e, _cx| { + terminal.mouse_down(&e, origin); + }, + ), + ); + self.interactivity.on_mouse_down( + MouseButton::Middle, + TerminalElement::generic_button_handler( + terminal.clone(), + origin, + focus.clone(), + move |terminal, origin, e, _cx| { + terminal.mouse_down(&e, origin); + }, + ), + ); + self.interactivity.on_mouse_up( + MouseButton::Right, + TerminalElement::generic_button_handler( + terminal.clone(), + origin, + focus.clone(), + move |terminal, origin, e, cx| { + terminal.mouse_up(&e, origin, cx); + }, + ), + ); + self.interactivity.on_mouse_up( + MouseButton::Middle, + TerminalElement::generic_button_handler( + terminal, + origin, + focus, + move |terminal, origin, e, cx| { + terminal.mouse_up(&e, origin, cx); + }, + ), + ); } - - this } } @@ -764,7 +780,12 @@ impl Element for TerminalElement { (layout_id, interactive_state) } - fn paint(self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext<'_>) { + fn paint( + &mut self, + bounds: Bounds, + state: &mut Self::State, + cx: &mut WindowContext<'_>, + ) { let mut layout = self.compute_layout(bounds, cx); let theme = cx.theme(); @@ -783,33 +804,19 @@ impl Element for TerminalElement { let terminal_focus_handle = self.focus.clone(); let terminal_handle = self.terminal.clone(); - let mut this: TerminalElement = self - .register_mouse_listeners(origin, layout.mode, bounds, cx) - .drag_over::(|style| { - // todo!() why does not it work? z-index of elements? - style.bg(cx.theme().colors().ghost_element_hover) - }) - .on_drop::(move |external_paths, cx| { - cx.focus(&terminal_focus_handle); - let mut new_text = external_paths - .read(cx) - .paths() - .iter() - .map(|path| format!(" {path:?}")) - .join(""); - new_text.push(' '); - terminal_handle.update(cx, |terminal, _| { - // todo!() long paths are not displayed properly albeit the text is there - terminal.paste(&new_text); - }); - }); + self.register_mouse_listeners(origin, layout.mode, bounds, cx); - let interactivity = mem::take(&mut this.interactivity); + // todo!(change this to work in terms of on_drag_move or some such) + // .drag_over::(|style| { + // // todo!() why does not it work? z-index of elements? + // style.bg(cx.theme().colors().ghost_element_hover) + // }) + let mut interactivity = mem::take(&mut self.interactivity); interactivity.paint(bounds, bounds.size, state, cx, |_, _, cx| { - cx.handle_input(&this.focus, terminal_input_handler); + cx.handle_input(&self.focus, terminal_input_handler); - this.register_key_listeners(cx); + self.register_key_listeners(cx); for rect in &layout.rects { rect.paint(origin, &layout, cx); @@ -840,7 +847,7 @@ impl Element for TerminalElement { } }); - if this.cursor_visible { + if self.cursor_visible { cx.with_z_index(3, |cx| { if let Some(cursor) = &layout.cursor { cursor.paint(origin, cx); @@ -848,7 +855,7 @@ impl Element for TerminalElement { }); } - if let Some(element) = layout.hyperlink_tooltip.take() { + if let Some(mut element) = layout.hyperlink_tooltip.take() { let width: AvailableSpace = bounds.size.width.into(); let height: AvailableSpace = bounds.size.height.into(); element.draw(origin, Size { width, height }, cx) diff --git a/crates/ui2/src/components/popover_menu.rs b/crates/ui2/src/components/popover_menu.rs index 4b5144e7c7de468e823cd7e60d062083ea065386..0f2fa6d23f147ba846695d1177ca5189f9130b3e 100644 --- a/crates/ui2/src/components/popover_menu.rs +++ b/crates/ui2/src/components/popover_menu.rs @@ -182,12 +182,12 @@ impl Element for PopoverMenu { } fn paint( - self, + &mut self, _: Bounds, element_state: &mut Self::State, cx: &mut WindowContext, ) { - if let Some(child) = element_state.child_element.take() { + if let Some(mut child) = element_state.child_element.take() { child.paint(cx); } @@ -195,7 +195,7 @@ impl Element for PopoverMenu { element_state.child_bounds = Some(cx.layout_bounds(child_layout_id)); } - if let Some(menu) = element_state.menu_element.take() { + if let Some(mut menu) = element_state.menu_element.take() { menu.paint(cx); if let Some(child_bounds) = element_state.child_bounds { diff --git a/crates/ui2/src/components/right_click_menu.rs b/crates/ui2/src/components/right_click_menu.rs index 19031b2be70f7953e21a1305dd8957912ddfb63a..a3a454d652fa4dcbea48a6c8114c7c83e390c555 100644 --- a/crates/ui2/src/components/right_click_menu.rs +++ b/crates/ui2/src/components/right_click_menu.rs @@ -112,21 +112,21 @@ impl Element for RightClickMenu { } fn paint( - self, + &mut self, bounds: Bounds, element_state: &mut Self::State, cx: &mut WindowContext, ) { - if let Some(child) = element_state.child_element.take() { + if let Some(mut child) = element_state.child_element.take() { child.paint(cx); } - if let Some(menu) = element_state.menu_element.take() { + if let Some(mut menu) = element_state.menu_element.take() { menu.paint(cx); return; } - let Some(builder) = self.menu_builder else { + let Some(builder) = self.menu_builder.take() else { return; }; let menu = element_state.menu.clone(); diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index 5f14df833d1dfd5df8b83edf52dd0f1fce8ad2eb..5d79109dee817d9b35558904bd8497fa5f4ea364 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -896,7 +896,7 @@ mod element { } fn paint( - self, + &mut self, bounds: gpui::Bounds, state: &mut Self::State, cx: &mut ui::prelude::WindowContext, @@ -912,7 +912,7 @@ mod element { let mut bounding_boxes = self.bounding_boxes.lock(); bounding_boxes.clear(); - for (ix, child) in self.children.into_iter().enumerate() { + for (ix, mut child) in self.children.iter_mut().enumerate() { //todo!(active_pane_magnification) // If usign active pane magnification, need to switch to using // 1 for all non-active panes, and then the magnification for the From 23d5f3f3e832ba68e0a191e7139c2e48a81445eb Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 14 Dec 2023 14:15:56 -0800 Subject: [PATCH 033/644] Enable all warnings in workspace, fix all warnings Bring back some workspace tests Co-authored-by: Conrad --- crates/gpui2/src/view.rs | 15 + crates/workspace2/src/dock.rs | 179 +----- crates/workspace2/src/item.rs | 6 +- crates/workspace2/src/modal_layer.rs | 6 +- crates/workspace2/src/notifications.rs | 43 +- crates/workspace2/src/pane.rs | 170 ++---- crates/workspace2/src/pane_group.rs | 416 +------------ crates/workspace2/src/searchable.rs | 4 +- crates/workspace2/src/status_bar.rs | 4 +- crates/workspace2/src/workspace2.rs | 779 ++++++++++++------------- 10 files changed, 499 insertions(+), 1123 deletions(-) diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index 280c52df2afad19af029a75e336222eae82aa74e..351eb0ad06fbe9ac66855870156afa1834a1a7c2 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -7,6 +7,7 @@ use crate::{ use anyhow::{Context, Result}; use std::{ any::TypeId, + fmt, hash::{Hash, Hasher}, }; @@ -297,6 +298,20 @@ impl From> for AnyWeakView { } } +impl PartialEq for AnyWeakView { + fn eq(&self, other: &Self) -> bool { + self.model == other.model + } +} + +impl std::fmt::Debug for AnyWeakView { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("AnyWeakView") + .field("entity_id", &self.model.entity_id) + .finish_non_exhaustive() + } +} + impl Render for T where T: 'static + FnMut(&mut WindowContext) -> E, diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 6a4740b6e270e5ef4e813ef6ca44081bfbc3f07c..54480f0b68748870530425f7b6d7910a065f2a0e 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -41,7 +41,7 @@ pub trait Panel: FocusableView + EventEmitter { } pub trait PanelHandle: Send + Sync { - fn entity_id(&self) -> EntityId; + fn panel_id(&self) -> EntityId; fn persistent_name(&self) -> &'static str; fn position(&self, cx: &WindowContext) -> DockPosition; fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool; @@ -62,7 +62,7 @@ impl PanelHandle for View where T: Panel, { - fn entity_id(&self) -> EntityId { + fn panel_id(&self) -> EntityId { Entity::entity_id(self) } @@ -135,7 +135,7 @@ pub struct Dock { is_open: bool, active_panel_index: usize, focus_handle: FocusHandle, - focus_subscription: Subscription, + _focus_subscription: Subscription, } impl FocusableView for Dock { @@ -187,7 +187,6 @@ struct PanelEntry { pub struct PanelButtons { dock: View, - workspace: WeakView, } impl Dock { @@ -204,7 +203,7 @@ impl Dock { active_panel_index: 0, is_open: false, focus_handle, - focus_subscription, + _focus_subscription: focus_subscription, } } @@ -261,7 +260,7 @@ impl Dock { pub fn set_panel_zoomed(&mut self, panel: &AnyView, zoomed: bool, cx: &mut ViewContext) { for entry in &mut self.panel_entries { - if entry.panel.entity_id() == panel.entity_id() { + if entry.panel.panel_id() == panel.entity_id() { if zoomed != entry.panel.is_zoomed(cx) { entry.panel.set_zoomed(zoomed, cx); } @@ -309,7 +308,7 @@ impl Dock { let was_visible = this.is_open() && this.visible_panel().map_or(false, |active_panel| { - active_panel.entity_id() == Entity::entity_id(&panel) + active_panel.panel_id() == Entity::entity_id(&panel) }); this.remove_panel(&panel, cx); @@ -351,7 +350,7 @@ impl Dock { if let Some(ix) = this .panel_entries .iter() - .position(|entry| entry.panel.entity_id() == Entity::entity_id(&panel)) + .position(|entry| entry.panel.panel_id() == Entity::entity_id(&panel)) { this.set_open(true, cx); this.activate_panel(ix, cx); @@ -361,7 +360,7 @@ impl Dock { PanelEvent::Close => { if this .visible_panel() - .map_or(false, |p| p.entity_id() == Entity::entity_id(&panel)) + .map_or(false, |p| p.panel_id() == Entity::entity_id(&panel)) { this.set_open(false, cx); } @@ -389,7 +388,7 @@ impl Dock { if let Some(panel_ix) = self .panel_entries .iter() - .position(|entry| entry.panel.entity_id() == Entity::entity_id(panel)) + .position(|entry| entry.panel.panel_id() == Entity::entity_id(panel)) { if panel_ix == self.active_panel_index { self.active_panel_index = 0; @@ -450,7 +449,7 @@ impl Dock { pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option { self.panel_entries .iter() - .find(|entry| entry.panel.entity_id() == panel.entity_id()) + .find(|entry| entry.panel.panel_id() == panel.panel_id()) .map(|entry| entry.panel.size(cx)) } @@ -549,166 +548,12 @@ impl Render for Dock { } impl PanelButtons { - pub fn new( - dock: View, - workspace: WeakView, - cx: &mut ViewContext, - ) -> Self { + pub fn new(dock: View, cx: &mut ViewContext) -> Self { cx.observe(&dock, |_, _, cx| cx.notify()).detach(); - Self { dock, workspace } + Self { dock } } } -// impl Render for PanelButtons { -// type Element = (); - -// fn render(&mut self, cx: &mut ViewContext) -> Self::Element { -// todo!("") -// } - -// fn ui_name() -> &'static str { -// "PanelButtons" -// } - -// fn render(&mut self, cx: &mut ViewContext) -> AnyElement { -// let theme = &settings::get::(cx).theme; -// let tooltip_style = theme.tooltip.clone(); -// let theme = &theme.workspace.status_bar.panel_buttons; -// let button_style = theme.button.clone(); -// let dock = self.dock.read(cx); -// let active_ix = dock.active_panel_index; -// let is_open = dock.is_open; -// let dock_position = dock.position; -// let group_style = match dock_position { -// DockPosition::Left => theme.group_left, -// DockPosition::Bottom => theme.group_bottom, -// DockPosition::Right => theme.group_right, -// }; -// let menu_corner = match dock_position { -// DockPosition::Left => AnchorCorner::BottomLeft, -// DockPosition::Bottom | DockPosition::Right => AnchorCorner::BottomRight, -// }; - -// let panels = dock -// .panel_entries -// .iter() -// .map(|item| (item.panel.clone(), item.context_menu.clone())) -// .collect::>(); -// Flex::row() -// .with_children(panels.into_iter().enumerate().filter_map( -// |(panel_ix, (view, context_menu))| { -// let icon_path = view.icon_path(cx)?; -// let is_active = is_open && panel_ix == active_ix; -// let (tooltip, tooltip_action) = if is_active { -// ( -// format!("Close {} dock", dock_position.to_label()), -// Some(match dock_position { -// DockPosition::Left => crate::ToggleLeftDock.boxed_clone(), -// DockPosition::Bottom => crate::ToggleBottomDock.boxed_clone(), -// DockPosition::Right => crate::ToggleRightDock.boxed_clone(), -// }), -// ) -// } else { -// view.icon_tooltip(cx) -// }; -// Some( -// Stack::new() -// .with_child( -// MouseEventHandler::new::(panel_ix, cx, |state, cx| { -// let style = button_style.in_state(is_active); - -// let style = style.style_for(state); -// Flex::row() -// .with_child( -// Svg::new(icon_path) -// .with_color(style.icon_color) -// .constrained() -// .with_width(style.icon_size) -// .aligned(), -// ) -// .with_children(if let Some(label) = view.icon_label(cx) { -// Some( -// Label::new(label, style.label.text.clone()) -// .contained() -// .with_style(style.label.container) -// .aligned(), -// ) -// } else { -// None -// }) -// .constrained() -// .with_height(style.icon_size) -// .contained() -// .with_style(style.container) -// }) -// .with_cursor_style(CursorStyle::PointingHand) -// .on_click(MouseButton::Left, { -// let tooltip_action = -// tooltip_action.as_ref().map(|action| action.boxed_clone()); -// move |_, this, cx| { -// if let Some(tooltip_action) = &tooltip_action { -// let window = cx.window(); -// let view_id = this.workspace.id(); -// let tooltip_action = tooltip_action.boxed_clone(); -// cx.spawn(|_, mut cx| async move { -// window.dispatch_action( -// view_id, -// &*tooltip_action, -// &mut cx, -// ); -// }) -// .detach(); -// } -// } -// }) -// .on_click(MouseButton::Right, { -// let view = view.clone(); -// let menu = context_menu.clone(); -// move |_, _, cx| { -// const POSITIONS: [DockPosition; 3] = [ -// DockPosition::Left, -// DockPosition::Right, -// DockPosition::Bottom, -// ]; - -// menu.update(cx, |menu, cx| { -// let items = POSITIONS -// .into_iter() -// .filter(|position| { -// *position != dock_position -// && view.position_is_valid(*position, cx) -// }) -// .map(|position| { -// let view = view.clone(); -// ContextMenuItem::handler( -// format!("Dock {}", position.to_label()), -// move |cx| view.set_position(position, cx), -// ) -// }) -// .collect(); -// menu.show(Default::default(), menu_corner, items, cx); -// }) -// } -// }) -// .with_tooltip::( -// panel_ix, -// tooltip, -// tooltip_action, -// tooltip_style.clone(), -// cx, -// ), -// ) -// .with_child(ChildView::new(&context_menu, cx)), -// ) -// }, -// )) -// .contained() -// .with_style(group_style) -// .into_any() -// } -// } - -// here be kittens impl Render for PanelButtons { type Element = Div; diff --git a/crates/workspace2/src/item.rs b/crates/workspace2/src/item.rs index c0242ffa170aedfd00516a0ef031988bee16cdcd..43597f21a79a0cc2b178a429fe28b4736a895c5f 100644 --- a/crates/workspace2/src/item.rs +++ b/crates/workspace2/src/item.rs @@ -919,7 +919,7 @@ pub mod test { impl EventEmitter for TestItem {} impl FocusableView for TestItem { - fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle { + fn focus_handle(&self, _: &AppContext) -> gpui::FocusHandle { self.focus_handle.clone() } } @@ -941,8 +941,8 @@ pub mod test { fn tab_content( &self, detail: Option, - selected: bool, - cx: &ui::prelude::WindowContext, + _selected: bool, + _cx: &ui::prelude::WindowContext, ) -> AnyElement { self.tab_detail.set(detail); gpui::div().into_any_element() diff --git a/crates/workspace2/src/modal_layer.rs b/crates/workspace2/src/modal_layer.rs index a428ba3e18352ec7750f13ecd19289b5682a75be..8c1af48667789e3cd072611778e83de601455468 100644 --- a/crates/workspace2/src/modal_layer.rs +++ b/crates/workspace2/src/modal_layer.rs @@ -5,7 +5,7 @@ use gpui::{ use ui::{h_stack, v_stack}; pub trait ModalView: ManagedView { - fn on_before_dismiss(&mut self, cx: &mut ViewContext) -> bool { + fn on_before_dismiss(&mut self, _: &mut ViewContext) -> bool { true } } @@ -27,7 +27,7 @@ impl ModalViewHandle for View { pub struct ActiveModal { modal: Box, - subscription: Subscription, + _subscription: Subscription, previous_focus_handle: Option, focus_handle: FocusHandle, } @@ -63,7 +63,7 @@ impl ModalLayer { { self.active_modal = Some(ActiveModal { modal: Box::new(new_modal.clone()), - subscription: cx.subscribe(&new_modal, |this, modal, _: &DismissEvent, cx| { + _subscription: cx.subscribe(&new_modal, |this, _, _: &DismissEvent, cx| { this.hide_modal(cx); }), previous_focus_handle: cx.focused(), diff --git a/crates/workspace2/src/notifications.rs b/crates/workspace2/src/notifications.rs index 63475c2aba64100155311136630f6e7d57537950..a692388a06afe1eb4f88eb063d37b1a4e4e333d1 100644 --- a/crates/workspace2/src/notifications.rs +++ b/crates/workspace2/src/notifications.rs @@ -104,12 +104,9 @@ impl Workspace { }) { let notification = build_notification(cx); - cx.subscribe( - ¬ification, - move |this, handle, event: &DismissEvent, cx| { - this.dismiss_notification_internal(type_id, id, cx); - }, - ) + cx.subscribe(¬ification, move |this, _, _: &DismissEvent, cx| { + this.dismiss_notification_internal(type_id, id, cx); + }) .detach(); self.notifications .push((type_id, id, Box::new(notification))); @@ -173,21 +170,15 @@ impl Workspace { pub mod simple_message_notification { use gpui::{ - div, AnyElement, AppContext, DismissEvent, Div, EventEmitter, InteractiveElement, - ParentElement, Render, SharedString, StatefulInteractiveElement, Styled, TextStyle, - ViewContext, + div, DismissEvent, Div, EventEmitter, InteractiveElement, ParentElement, Render, + SharedString, StatefulInteractiveElement, Styled, ViewContext, }; use std::sync::Arc; use ui::prelude::*; use ui::{h_stack, v_stack, Button, Icon, IconElement, Label, StyledExt}; - enum NotificationMessage { - Text(SharedString), - Element(fn(TextStyle, &AppContext) -> AnyElement), - } - pub struct MessageNotification { - message: NotificationMessage, + message: SharedString, on_click: Option)>>, click_message: Option, } @@ -200,23 +191,12 @@ pub mod simple_message_notification { S: Into, { Self { - message: NotificationMessage::Text(message.into()), + message: message.into(), on_click: None, click_message: None, } } - // not needed I think (only for the "new panel" toast, which is outdated now) - // pub fn new_element( - // message: fn(TextStyle, &AppContext) -> AnyElement, - // ) -> MessageNotification { - // Self { - // message: NotificationMessage::Element(message), - // on_click: None, - // click_message: None, - // } - // } - pub fn with_click_message(mut self, message: S) -> Self where S: Into, @@ -248,18 +228,13 @@ pub mod simple_message_notification { .child( h_stack() .justify_between() - .child(div().max_w_80().child(match &self.message { - NotificationMessage::Text(text) => Label::new(text.clone()), - NotificationMessage::Element(element) => { - todo!() - } - })) + .child(div().max_w_80().child(Label::new(self.message.clone()))) .child( div() .id("cancel") .child(IconElement::new(Icon::Close)) .cursor_pointer() - .on_click(cx.listener(|this, event, cx| this.dismiss(cx))), + .on_click(cx.listener(|this, _, cx| this.dismiss(cx))), ), ) .children(self.click_message.iter().map(|message| { diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 2f6dec5bc493dce504486044cb52424b841ca345..4c436daada47625f8db784f11978129b3b4082c6 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -7,7 +7,7 @@ use crate::{ use anyhow::Result; use collections::{HashMap, HashSet, VecDeque}; use gpui::{ - actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AnyWeakView, AppContext, + actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AppContext, AsyncWindowContext, DismissEvent, Div, EntityId, EventEmitter, FocusHandle, Focusable, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel, Render, ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext, @@ -164,11 +164,6 @@ impl fmt::Debug for Event { } } -struct FocusedView { - view: AnyWeakView, - focus_handle: FocusHandle, -} - pub struct Pane { focus_handle: FocusHandle, items: Vec>, @@ -187,7 +182,7 @@ pub struct Pane { // can_drop: Rc, &WindowContext) -> bool>, can_split: bool, // render_tab_bar_buttons: Rc) -> AnyElement>, - subscriptions: Vec, + _subscriptions: Vec, tab_bar_scroll_handle: ScrollHandle, } @@ -432,14 +427,10 @@ impl Pane { // }) // .into_any() // }), - subscriptions, + _subscriptions: subscriptions, } } - pub(crate) fn workspace(&self) -> &WeakView { - &self.workspace - } - pub fn has_focus(&self, cx: &WindowContext) -> bool { // todo!(); // inline this manually self.focus_handle.contains_focused(cx) @@ -1468,21 +1459,6 @@ impl Pane { let label = item.tab_content(Some(detail), is_active, cx); let close_side = &ItemSettings::get_global(cx).close_position; - let (text_color, tab_bg, tab_hover_bg, tab_active_bg) = match ix == self.active_item_index { - false => ( - cx.theme().colors().text_muted, - cx.theme().colors().tab_inactive_background, - cx.theme().colors().ghost_element_hover, - cx.theme().colors().ghost_element_active, - ), - true => ( - cx.theme().colors().text, - cx.theme().colors().tab_active_background, - cx.theme().colors().element_hover, - cx.theme().colors().element_active, - ), - }; - let indicator = maybe!({ let indicator_color = match (item.has_conflict(cx), item.is_dirty(cx)) { (true, _) => Color::Warning, @@ -1498,57 +1474,55 @@ impl Pane { let is_last_item = ix == self.items.len() - 1; let position_relative_to_active_item = ix.cmp(&self.active_item_index); - let tab = - Tab::new(ix) - .position(if is_first_item { - TabPosition::First - } else if is_last_item { - TabPosition::Last - } else { - TabPosition::Middle(position_relative_to_active_item) - }) - .close_side(match close_side { - ClosePosition::Left => ui::TabCloseSide::Start, - ClosePosition::Right => ui::TabCloseSide::End, - }) - .selected(is_active) - .on_click(cx.listener(move |pane: &mut Self, event, cx| { - pane.activate_item(ix, true, true, cx) - })) - .on_drag( - DraggedTab { - pane: cx.view().clone(), - detail, - item_id, - is_active, - ix, - }, - |tab, cx| cx.build_view(|cx| tab.clone()), - ) - .drag_over::(|tab| tab.bg(cx.theme().colors().tab_active_background)) - .drag_over::(|tab| tab.bg(gpui::red())) - .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { - this.handle_tab_drop(dragged_tab, ix, cx) - })) - .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { - dbg!(entry_id); - this.handle_project_entry_drop(entry_id, ix, cx) - })) - .when_some(item.tab_tooltip_text(cx), |tab, text| { - tab.tooltip(move |cx| Tooltip::text(text.clone(), cx)) - }) - .start_slot::(indicator) - .end_slot( - IconButton::new("close tab", Icon::Close) - .icon_color(Color::Muted) - .size(ButtonSize::None) - .icon_size(IconSize::XSmall) - .on_click(cx.listener(move |pane, _, cx| { - pane.close_item_by_id(item_id, SaveIntent::Close, cx) - .detach_and_log_err(cx); - })), - ) - .child(label); + let tab = Tab::new(ix) + .position(if is_first_item { + TabPosition::First + } else if is_last_item { + TabPosition::Last + } else { + TabPosition::Middle(position_relative_to_active_item) + }) + .close_side(match close_side { + ClosePosition::Left => ui::TabCloseSide::Start, + ClosePosition::Right => ui::TabCloseSide::End, + }) + .selected(is_active) + .on_click( + cx.listener(move |pane: &mut Self, _, cx| pane.activate_item(ix, true, true, cx)), + ) + .on_drag( + DraggedTab { + pane: cx.view().clone(), + detail, + item_id, + is_active, + ix, + }, + |tab, cx| cx.build_view(|_| tab.clone()), + ) + .drag_over::(|tab| tab.bg(cx.theme().colors().tab_active_background)) + .drag_over::(|tab| tab.bg(gpui::red())) + .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { + this.handle_tab_drop(dragged_tab, ix, cx) + })) + .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { + this.handle_project_entry_drop(entry_id, cx) + })) + .when_some(item.tab_tooltip_text(cx), |tab, text| { + tab.tooltip(move |cx| Tooltip::text(text.clone(), cx)) + }) + .start_slot::(indicator) + .end_slot( + IconButton::new("close tab", Icon::Close) + .icon_color(Color::Muted) + .size(ButtonSize::None) + .icon_size(IconSize::XSmall) + .on_click(cx.listener(move |pane, _, cx| { + pane.close_item_by_id(item_id, SaveIntent::Close, cx) + .detach_and_log_err(cx); + })), + ) + .child(label); let single_entry_to_resolve = { let item_entries = self.items[ix].project_entry_ids(cx); @@ -1618,12 +1592,12 @@ impl Pane { IconButton::new("plus", Icon::Plus) .icon_size(IconSize::Small) .on_click(cx.listener(|this, _, cx| { - let menu = ContextMenu::build(cx, |menu, cx| { + let menu = ContextMenu::build(cx, |menu, _| { menu.action("New File", NewFile.boxed_clone()) .action("New Terminal", NewCenterTerminal.boxed_clone()) .action("New Search", NewSearch.boxed_clone()) }); - cx.subscribe(&menu, |this, _, event: &DismissEvent, cx| { + cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| { this.focus(cx); this.new_item_menu = None; }) @@ -1642,13 +1616,13 @@ impl Pane { IconButton::new("split", Icon::Split) .icon_size(IconSize::Small) .on_click(cx.listener(|this, _, cx| { - let menu = ContextMenu::build(cx, |menu, cx| { + let menu = ContextMenu::build(cx, |menu, _| { menu.action("Split Right", SplitRight.boxed_clone()) .action("Split Left", SplitLeft.boxed_clone()) .action("Split Up", SplitUp.boxed_clone()) .action("Split Down", SplitDown.boxed_clone()) }); - cx.subscribe(&menu, |this, _, event: &DismissEvent, cx| { + cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| { this.focus(cx); this.split_item_menu = None; }) @@ -1684,7 +1658,7 @@ impl Pane { this.handle_tab_drop(dragged_tab, this.items.len(), cx) })) .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { - this.handle_project_entry_drop(entry_id, this.items.len(), cx) + this.handle_project_entry_drop(entry_id, cx) })), ) } @@ -1755,7 +1729,7 @@ impl Pane { let from_pane = dragged_tab.pane.clone(); let to_pane = cx.view().clone(); self.workspace - .update(cx, |workspace, cx| { + .update(cx, |_, cx| { cx.defer(move |workspace, cx| { workspace.move_item(from_pane, to_pane, item_id, ix, cx); }); @@ -1766,13 +1740,12 @@ impl Pane { fn handle_project_entry_drop( &mut self, project_entry_id: &ProjectEntryId, - ix: usize, cx: &mut ViewContext<'_, Pane>, ) { let to_pane = cx.view().downgrade(); let project_entry_id = *project_entry_id; self.workspace - .update(cx, |workspace, cx| { + .update(cx, |_, cx| { cx.defer(move |workspace, cx| { if let Some(path) = workspace .project() @@ -1798,19 +1771,10 @@ impl Pane { let from_pane = dragged_tab.pane.clone(); let to_pane = cx.view().clone(); self.workspace - .update(cx, |workspace, cx| { + .update(cx, |_, cx| { cx.defer(move |workspace, cx| { - let item = from_pane - .read(cx) - .items() - .find(|item| item.item_id() == item_id) - .map(|item| item.boxed_clone()); - if let Some(item) = item { - if let Some(item) = item.clone_on_split(workspace.database_id(), cx) { - let pane = workspace.split_pane(to_pane, split_direction, cx); - workspace.move_item(from_pane, pane, item_id, 0, cx); - } - } + let pane = workspace.split_pane(to_pane, split_direction, cx); + workspace.move_item(from_pane, pane, item_id, 0, cx); }); }) .log_err(); @@ -1825,7 +1789,7 @@ impl Pane { let project_entry_id = *project_entry_id; let current_pane = cx.view().clone(); self.workspace - .update(cx, |workspace, cx| { + .update(cx, |_, cx| { cx.defer(move |workspace, cx| { if let Some(path) = workspace .project() @@ -1853,8 +1817,6 @@ impl Render for Pane { type Element = Focusable
; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - let this = cx.view().downgrade(); - v_stack() .key_context("Pane") .track_focus(&self.focus_handle) @@ -1953,11 +1915,7 @@ impl Render for Pane { this.handle_tab_drop(dragged_tab, this.active_item_index(), cx) })) .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { - this.handle_project_entry_drop( - entry_id, - this.active_item_index(), - cx, - ) + this.handle_project_entry_drop(entry_id, cx) })), ) .children( diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index 5f14df833d1dfd5df8b83edf52dd0f1fce8ad2eb..72466d9ce41ef96f838cdc50cd0d4813beef37d5 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -16,7 +16,7 @@ const HANDLE_HITBOX_SIZE: f32 = 10.0; //todo!(change this back to 4) const HORIZONTAL_MIN_SIZE: f32 = 80.; const VERTICAL_MIN_SIZE: f32 = 100.; -#[derive(Clone, PartialEq)] +#[derive(Clone)] pub struct PaneGroup { pub(crate) root: Member, } @@ -121,7 +121,7 @@ impl PaneGroup { } } -#[derive(Clone, PartialEq)] +#[derive(Clone)] pub(crate) enum Member { Axis(PaneAxis), Pane(View), @@ -426,12 +426,6 @@ pub(crate) struct PaneAxis { pub bounding_boxes: Arc>>>>, } -impl PartialEq for PaneAxis { - fn eq(&self, other: &Self) -> bool { - todo!() - } -} - impl PaneAxis { pub fn new(axis: Axis, members: Vec) -> Self { let flexes = Arc::new(Mutex::new(vec![1.; members.len()])); @@ -816,7 +810,7 @@ mod element { proposed_current_pixel_change -= current_pixel_change; } - // todo!(reserialize workspace) + // todo!(schedule serialize) // workspace.schedule_serialize(cx); cx.notify(); } @@ -851,7 +845,7 @@ mod element { cx.on_mouse_event({ let dragged_handle = dragged_handle.clone(); - move |e: &MouseDownEvent, phase, cx| { + move |e: &MouseDownEvent, phase, _cx| { if phase.bubble() && handle_bounds.contains(&e.position) { dragged_handle.replace(Some(ix)); } @@ -859,7 +853,7 @@ mod element { }); cx.on_mouse_event(move |e: &MouseMoveEvent, phase, cx| { let dragged_handle = dragged_handle.borrow(); - if *dragged_handle == Some(ix) { + if phase.bubble() && *dragged_handle == Some(ix) { Self::compute_resize(&flexes, e, ix, axis, axis_bounds, cx) } }); @@ -949,7 +943,7 @@ mod element { cx.with_z_index(1, |cx| { cx.on_mouse_event({ let state = state.clone(); - move |e: &MouseUpEvent, phase, cx| { + move |_: &MouseUpEvent, phase, _cx| { if phase.bubble() { state.replace(None); } @@ -968,402 +962,4 @@ mod element { fn flex_values_in_bounds(flexes: &[f32]) -> bool { (flexes.iter().copied().sum::() - flexes.len() as f32).abs() < 0.001 } - // // use std::{cell::RefCell, iter::from_fn, ops::Range, rc::Rc}; - - // // use gpui::{ - // // geometry::{ - // // rect::Bounds, - // // vector::{vec2f, Vector2F}, - // // }, - // // json::{self, ToJson}, - // // platform::{CursorStyle, MouseButton}, - // // scene::MouseDrag, - // // AnyElement, Axis, CursorRegion, Element, EventContext, MouseRegion, BoundsExt, - // // SizeConstraint, Vector2FExt, ViewContext, - // // }; - - // use crate::{ - // pane_group::{HANDLE_HITBOX_SIZE, HORIZONTAL_MIN_SIZE, VERTICAL_MIN_SIZE}, - // Workspace, WorkspaceSettings, - // }; - - // pub struct PaneAxisElement { - // axis: Axis, - // basis: usize, - // active_pane_ix: Option, - // flexes: Rc>>, - // children: Vec>, - // bounding_boxes: Rc>>>>, - // } - - // impl PaneAxisElement { - // pub fn new( - // axis: Axis, - // basis: usize, - // flexes: Rc>>, - // bounding_boxes: Rc>>>>, - // ) -> Self { - // Self { - // axis, - // basis, - // flexes, - // bounding_boxes, - // active_pane_ix: None, - // children: Default::default(), - // } - // } - - // pub fn set_active_pane(&mut self, active_pane_ix: Option) { - // self.active_pane_ix = active_pane_ix; - // } - - // fn layout_children( - // &mut self, - // active_pane_magnification: f32, - // constraint: SizeConstraint, - // remaining_space: &mut f32, - // remaining_flex: &mut f32, - // cross_axis_max: &mut f32, - // view: &mut Workspace, - // cx: &mut ViewContext, - // ) { - // let flexes = self.flexes.borrow(); - // let cross_axis = self.axis.invert(); - // for (ix, child) in self.children.iter_mut().enumerate() { - // let flex = if active_pane_magnification != 1. { - // if let Some(active_pane_ix) = self.active_pane_ix { - // if ix == active_pane_ix { - // active_pane_magnification - // } else { - // 1. - // } - // } else { - // 1. - // } - // } else { - // flexes[ix] - // }; - - // let child_size = if *remaining_flex == 0.0 { - // *remaining_space - // } else { - // let space_per_flex = *remaining_space / *remaining_flex; - // space_per_flex * flex - // }; - - // let child_constraint = match self.axis { - // Axis::Horizontal => SizeConstraint::new( - // vec2f(child_size, constraint.min.y()), - // vec2f(child_size, constraint.max.y()), - // ), - // Axis::Vertical => SizeConstraint::new( - // vec2f(constraint.min.x(), child_size), - // vec2f(constraint.max.x(), child_size), - // ), - // }; - // let child_size = child.layout(child_constraint, view, cx); - // *remaining_space -= child_size.along(self.axis); - // *remaining_flex -= flex; - // *cross_axis_max = cross_axis_max.max(child_size.along(cross_axis)); - // } - // } - - // fn handle_resize( - // flexes: Rc>>, - // axis: Axis, - // preceding_ix: usize, - // child_start: Vector2F, - // drag_bounds: Bounds, - // ) -> impl Fn(MouseDrag, &mut Workspace, &mut EventContext) { - // let size = move |ix, flexes: &[f32]| { - // drag_bounds.length_along(axis) * (flexes[ix] / flexes.len() as f32) - // }; - - // move |drag, workspace: &mut Workspace, cx| { - // if drag.end { - // // TODO: Clear cascading resize state - // return; - // } - // let min_size = match axis { - // Axis::Horizontal => HORIZONTAL_MIN_SIZE, - // Axis::Vertical => VERTICAL_MIN_SIZE, - // }; - // let mut flexes = flexes.borrow_mut(); - - // // Don't allow resizing to less than the minimum size, if elements are already too small - // if min_size - 1. > size(preceding_ix, flexes.as_slice()) { - // return; - // } - - // let mut proposed_current_pixel_change = (drag.position - child_start).along(axis) - // - size(preceding_ix, flexes.as_slice()); - - // let flex_changes = |pixel_dx, target_ix, next: isize, flexes: &[f32]| { - // let flex_change = pixel_dx / drag_bounds.length_along(axis); - // let current_target_flex = flexes[target_ix] + flex_change; - // let next_target_flex = - // flexes[(target_ix as isize + next) as usize] - flex_change; - // (current_target_flex, next_target_flex) - // }; - - // let mut successors = from_fn({ - // let forward = proposed_current_pixel_change > 0.; - // let mut ix_offset = 0; - // let len = flexes.len(); - // move || { - // let result = if forward { - // (preceding_ix + 1 + ix_offset < len).then(|| preceding_ix + ix_offset) - // } else { - // (preceding_ix as isize - ix_offset as isize >= 0) - // .then(|| preceding_ix - ix_offset) - // }; - - // ix_offset += 1; - - // result - // } - // }); - - // while proposed_current_pixel_change.abs() > 0. { - // let Some(current_ix) = successors.next() else { - // break; - // }; - - // let next_target_size = f32::max( - // size(current_ix + 1, flexes.as_slice()) - proposed_current_pixel_change, - // min_size, - // ); - - // let current_target_size = f32::max( - // size(current_ix, flexes.as_slice()) - // + size(current_ix + 1, flexes.as_slice()) - // - next_target_size, - // min_size, - // ); - - // let current_pixel_change = - // current_target_size - size(current_ix, flexes.as_slice()); - - // let (current_target_flex, next_target_flex) = - // flex_changes(current_pixel_change, current_ix, 1, flexes.as_slice()); - - // flexes[current_ix] = current_target_flex; - // flexes[current_ix + 1] = next_target_flex; - - // proposed_current_pixel_change -= current_pixel_change; - // } - - // workspace.schedule_serialize(cx); - // cx.notify(); - // } - // } - // } - - // impl Extend> for PaneAxisElement { - // fn extend>>(&mut self, children: T) { - // self.children.extend(children); - // } - // } - - // impl Element for PaneAxisElement { - // type LayoutState = f32; - // type PaintState = (); - - // fn layout( - // &mut self, - // constraint: SizeConstraint, - // view: &mut Workspace, - // cx: &mut ViewContext, - // ) -> (Vector2F, Self::LayoutState) { - // debug_assert!(self.children.len() == self.flexes.borrow().len()); - - // let active_pane_magnification = - // settings::get::(cx).active_pane_magnification; - - // let mut remaining_flex = 0.; - - // if active_pane_magnification != 1. { - // let active_pane_flex = self - // .active_pane_ix - // .map(|_| active_pane_magnification) - // .unwrap_or(1.); - // remaining_flex += self.children.len() as f32 - 1. + active_pane_flex; - // } else { - // for flex in self.flexes.borrow().iter() { - // remaining_flex += flex; - // } - // } - - // let mut cross_axis_max: f32 = 0.0; - // let mut remaining_space = constraint.max_along(self.axis); - - // if remaining_space.is_infinite() { - // panic!("flex contains flexible children but has an infinite constraint along the flex axis"); - // } - - // self.layout_children( - // active_pane_magnification, - // constraint, - // &mut remaining_space, - // &mut remaining_flex, - // &mut cross_axis_max, - // view, - // cx, - // ); - - // let mut size = match self.axis { - // Axis::Horizontal => vec2f(constraint.max.x() - remaining_space, cross_axis_max), - // Axis::Vertical => vec2f(cross_axis_max, constraint.max.y() - remaining_space), - // }; - - // if constraint.min.x().is_finite() { - // size.set_x(size.x().max(constraint.min.x())); - // } - // if constraint.min.y().is_finite() { - // size.set_y(size.y().max(constraint.min.y())); - // } - - // if size.x() > constraint.max.x() { - // size.set_x(constraint.max.x()); - // } - // if size.y() > constraint.max.y() { - // size.set_y(constraint.max.y()); - // } - - // (size, remaining_space) - // } - - // fn paint( - // &mut self, - // bounds: Bounds, - // visible_bounds: Bounds, - // remaining_space: &mut Self::LayoutState, - // view: &mut Workspace, - // cx: &mut ViewContext, - // ) -> Self::PaintState { - // let can_resize = settings::get::(cx).active_pane_magnification == 1.; - // let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); - - // let overflowing = *remaining_space < 0.; - // if overflowing { - // cx.scene().push_layer(Some(visible_bounds)); - // } - - // let mut child_origin = bounds.origin(); - - // let mut bounding_boxes = self.bounding_boxes.borrow_mut(); - // bounding_boxes.clear(); - - // let mut children_iter = self.children.iter_mut().enumerate().peekable(); - // while let Some((ix, child)) = children_iter.next() { - // let child_start = child_origin.clone(); - // child.paint(child_origin, visible_bounds, view, cx); - - // bounding_boxes.push(Some(Bounds::new(child_origin, child.size()))); - - // match self.axis { - // Axis::Horizontal => child_origin += vec2f(child.size().x(), 0.0), - // Axis::Vertical => child_origin += vec2f(0.0, child.size().y()), - // } - - // if can_resize && children_iter.peek().is_some() { - // cx.scene().push_stacking_context(None, None); - - // let handle_origin = match self.axis { - // Axis::Horizontal => child_origin - vec2f(HANDLE_HITBOX_SIZE / 2., 0.0), - // Axis::Vertical => child_origin - vec2f(0.0, HANDLE_HITBOX_SIZE / 2.), - // }; - - // let handle_bounds = match self.axis { - // Axis::Horizontal => Bounds::new( - // handle_origin, - // vec2f(HANDLE_HITBOX_SIZE, visible_bounds.height()), - // ), - // Axis::Vertical => Bounds::new( - // handle_origin, - // vec2f(visible_bounds.width(), HANDLE_HITBOX_SIZE), - // ), - // }; - - // let style = match self.axis { - // Axis::Horizontal => CursorStyle::ResizeLeftRight, - // Axis::Vertical => CursorStyle::ResizeUpDown, - // }; - - // cx.scene().push_cursor_region(CursorRegion { - // bounds: handle_bounds, - // style, - // }); - - // enum ResizeHandle {} - // let mut mouse_region = MouseRegion::new::( - // cx.view_id(), - // self.basis + ix, - // handle_bounds, - // ); - // mouse_region = mouse_region - // .on_drag( - // MouseButton::Left, - // Self::handle_resize( - // self.flexes.clone(), - // self.axis, - // ix, - // child_start, - // visible_bounds.clone(), - // ), - // ) - // .on_click(MouseButton::Left, { - // let flexes = self.flexes.clone(); - // move |e, v: &mut Workspace, cx| { - // if e.click_count >= 2 { - // let mut borrow = flexes.borrow_mut(); - // *borrow = vec![1.; borrow.len()]; - // v.schedule_serialize(cx); - // cx.notify(); - // } - // } - // }); - // cx.scene().push_mouse_region(mouse_region); - - // cx.scene().pop_stacking_context(); - // } - // } - - // if overflowing { - // cx.scene().pop_layer(); - // } - // } - - // fn rect_for_text_range( - // &self, - // range_utf16: Range, - // _: Bounds, - // _: Bounds, - // _: &Self::LayoutState, - // _: &Self::PaintState, - // view: &Workspace, - // cx: &ViewContext, - // ) -> Option> { - // self.children - // .iter() - // .find_map(|child| child.rect_for_text_range(range_utf16.clone(), view, cx)) - // } - - // fn debug( - // &self, - // bounds: Bounds, - // _: &Self::LayoutState, - // _: &Self::PaintState, - // view: &Workspace, - // cx: &ViewContext, - // ) -> json::Value { - // serde_json::json!({ - // "type": "PaneAxis", - // "bounds": bounds.to_json(), - // "axis": self.axis.to_json(), - // "flexes": *self.flexes.borrow(), - // "children": self.children.iter().map(|child| child.debug(view, cx)).collect::>() - // }) - // } - // } } diff --git a/crates/workspace2/src/searchable.rs b/crates/workspace2/src/searchable.rs index eadd602c8458d65434be39af241b699205b5e327..59202cbbaf53e5e4f62d77be693e3b13916b555b 100644 --- a/crates/workspace2/src/searchable.rs +++ b/crates/workspace2/src/searchable.rs @@ -193,7 +193,7 @@ impl SearchableItemHandle for View { cx: &mut WindowContext, ) -> Task>> { let matches = self.update(cx, |this, cx| this.find_matches(query, cx)); - cx.spawn(|cx| async { + cx.spawn(|_| async { let matches = matches.await; matches .into_iter() @@ -253,7 +253,7 @@ pub trait WeakSearchableItemHandle: WeakItemHandle { } impl WeakSearchableItemHandle for WeakView { - fn upgrade(&self, cx: &AppContext) -> Option> { + fn upgrade(&self, _cx: &AppContext) -> Option> { Some(Box::new(self.upgrade()?)) } diff --git a/crates/workspace2/src/status_bar.rs b/crates/workspace2/src/status_bar.rs index c0cbd127acaf64df8716a562b167293ec630f5f5..ba571d6e0ad3c70bc64139e90e64f9c59314bfc7 100644 --- a/crates/workspace2/src/status_bar.rs +++ b/crates/workspace2/src/status_bar.rs @@ -51,14 +51,14 @@ impl Render for StatusBar { } impl StatusBar { - fn render_left_tools(&self, cx: &mut ViewContext) -> impl IntoElement { + fn render_left_tools(&self, _: &mut ViewContext) -> impl IntoElement { h_stack() .items_center() .gap_2() .children(self.left_items.iter().map(|item| item.to_any())) } - fn render_right_tools(&self, cx: &mut ViewContext) -> impl IntoElement { + fn render_right_tools(&self, _: &mut ViewContext) -> impl IntoElement { h_stack() .items_center() .gap_2() diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 87083b09292dfca85bd20264bf8148d81f815b6f..8318ba3f0fa064e50081bbd4131d23ac2d3f9d7a 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -1,15 +1,11 @@ -#![allow(unused_variables, dead_code, unused_mut)] -// todo!() this is to make transition easier. - pub mod dock; pub mod item; +mod modal_layer; pub mod notifications; pub mod pane; pub mod pane_group; mod persistence; pub mod searchable; -// todo!() -mod modal_layer; pub mod shared_screen; mod status_bar; mod toolbar; @@ -236,14 +232,14 @@ pub fn init(app_state: Arc, cx: &mut AppContext) { cx.on_action({ let app_state = Arc::downgrade(&app_state); move |_: &Open, cx: &mut AppContext| { - let mut paths = cx.prompt_for_paths(PathPromptOptions { + let paths = cx.prompt_for_paths(PathPromptOptions { files: true, directories: true, multiple: true, }); if let Some(app_state) = app_state.upgrade() { - cx.spawn(move |mut cx| async move { + cx.spawn(move |cx| async move { if let Some(paths) = paths.await.log_err().flatten() { cx.update(|cx| { open_paths(&paths, &app_state, None, cx).detach_and_log_err(cx) @@ -458,7 +454,7 @@ pub struct Workspace { leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>, database_id: WorkspaceId, app_state: Arc, - subscriptions: Vec, + _subscriptions: Vec, _apply_leader_updates: Task>, _observe_current_user: Task>, _schedule_serialize: Option>, @@ -590,12 +586,9 @@ impl Workspace { let left_dock = cx.build_view(|cx| Dock::new(DockPosition::Left, cx)); let bottom_dock = cx.build_view(|cx| Dock::new(DockPosition::Bottom, cx)); let right_dock = cx.build_view(|cx| Dock::new(DockPosition::Right, cx)); - let left_dock_buttons = - cx.build_view(|cx| PanelButtons::new(left_dock.clone(), weak_handle.clone(), cx)); - let bottom_dock_buttons = - cx.build_view(|cx| PanelButtons::new(bottom_dock.clone(), weak_handle.clone(), cx)); - let right_dock_buttons = - cx.build_view(|cx| PanelButtons::new(right_dock.clone(), weak_handle.clone(), cx)); + let left_dock_buttons = cx.build_view(|cx| PanelButtons::new(left_dock.clone(), cx)); + let bottom_dock_buttons = cx.build_view(|cx| PanelButtons::new(bottom_dock.clone(), cx)); + let right_dock_buttons = cx.build_view(|cx| PanelButtons::new(right_dock.clone(), cx)); let status_bar = cx.build_view(|cx| { let mut status_bar = StatusBar::new(¢er_pane.clone(), cx); status_bar.add_left_item(left_dock_buttons, cx); @@ -604,8 +597,7 @@ impl Workspace { status_bar }); - let workspace_handle = cx.view().downgrade(); - let modal_layer = cx.build_view(|cx| ModalLayer::new()); + let modal_layer = cx.build_view(|_| ModalLayer::new()); // todo!() // cx.update_default_global::, _, _>(|drag_and_drop, _| { @@ -703,7 +695,7 @@ impl Workspace { _apply_leader_updates, _schedule_serialize: None, leader_updates_tx, - subscriptions, + _subscriptions: subscriptions, pane_history_timestamp, workspace_actions: Default::default(), // This data will be incorrect, but it will be overwritten by the time it needs to be used. @@ -763,7 +755,7 @@ impl Workspace { }; let window = if let Some(window) = requesting_window { - cx.update_window(window.into(), |old_workspace, cx| { + cx.update_window(window.into(), |_, cx| { cx.replace_root_view(|cx| { Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) }); @@ -1185,8 +1177,7 @@ impl Workspace { } fn save_all(&mut self, action: &SaveAll, cx: &mut ViewContext) { - let save_all = self - .save_all_internal(action.save_intent.unwrap_or(SaveIntent::SaveAll), cx) + self.save_all_internal(action.save_intent.unwrap_or(SaveIntent::SaveAll), cx) .detach_and_log_err(cx); } @@ -1216,7 +1207,7 @@ impl Workspace { cx.spawn(|workspace, mut cx| async move { // Override save mode and display "Save all files" prompt if save_intent == SaveIntent::Close && dirty_items.len() > 1 { - let mut answer = workspace.update(&mut cx, |_, cx| { + let answer = workspace.update(&mut cx, |_, cx| { let prompt = Pane::file_names_for_prompt( &mut dirty_items.iter().map(|(_, handle)| handle), dirty_items.len(), @@ -1261,7 +1252,7 @@ impl Workspace { } pub fn open(&mut self, _: &Open, cx: &mut ViewContext) { - let mut paths = cx.prompt_for_paths(PathPromptOptions { + let paths = cx.prompt_for_paths(PathPromptOptions { files: true, directories: true, multiple: true, @@ -1390,7 +1381,7 @@ impl Workspace { } fn add_folder_to_project(&mut self, _: &AddFolderToProject, cx: &mut ViewContext) { - let mut paths = cx.prompt_for_paths(PathPromptOptions { + let paths = cx.prompt_for_paths(PathPromptOptions { files: false, directories: true, multiple: true, @@ -1670,6 +1661,8 @@ impl Workspace { None } + // todo!("implement zoom") + #[allow(unused)] fn zoom_out(&mut self, cx: &mut ViewContext) { for pane in &self.panes { pane.update(cx, |pane, cx| pane.set_zoomed(false, cx)); @@ -2574,7 +2567,7 @@ impl Workspace { // } // } - fn render_notifications(&self, cx: &ViewContext) -> Option
{ + fn render_notifications(&self, _cx: &ViewContext) -> Option
{ if self.notifications.is_empty() { None } else { @@ -3005,6 +2998,7 @@ impl Workspace { cx.notify(); } + #[allow(unused)] fn schedule_serialize(&mut self, cx: &mut ViewContext) { self._schedule_serialize = Some(cx.spawn(|this, mut cx| async move { cx.background_executor() @@ -3143,12 +3137,7 @@ impl Workspace { cx: &mut ViewContext, ) -> Task>>>> { cx.spawn(|workspace, mut cx| async move { - let (project, old_center_pane) = workspace.update(&mut cx, |workspace, _| { - ( - workspace.project().clone(), - workspace.last_active_center_pane.clone(), - ) - })?; + let project = workspace.update(&mut cx, |workspace, _| workspace.project().clone())?; let mut center_group = None; let mut center_items = None; @@ -3293,7 +3282,7 @@ impl Workspace { .on_action(cx.listener(|workspace, action: &SwapPaneInDirection, cx| { workspace.swap_pane_in_direction(action.0, cx) })) - .on_action(cx.listener(|this, e: &ToggleLeftDock, cx| { + .on_action(cx.listener(|this, _: &ToggleLeftDock, cx| { this.toggle_dock(DockPosition::Left, cx); })) .on_action( @@ -3418,7 +3407,7 @@ impl Workspace { self } - fn add_workspace_actions_listeners(&self, mut div: Div, cx: &mut ViewContext) -> Div { + fn add_workspace_actions_listeners(&self, div: Div, cx: &mut ViewContext) -> Div { let mut div = div .on_action(cx.listener(Self::close_inactive_items_and_panes)) .on_action(cx.listener(Self::close_all_items_and_panes)) @@ -3578,8 +3567,6 @@ impl FocusableView for Workspace { } } -struct WorkspaceBounds(Bounds); - #[derive(Clone, Render)] struct DraggedDock(DockPosition); @@ -3628,7 +3615,7 @@ impl Render for Workspace { .border_b() .border_color(cx.theme().colors().border) .child( - canvas(cx.listener(|workspace, bounds, cx| { + canvas(cx.listener(|workspace, bounds, _| { workspace.bounds = *bounds; })) .absolute() @@ -4056,7 +4043,7 @@ async fn join_channel_internal( active_call: &Model, cx: &mut AsyncAppContext, ) -> Result { - let (should_prompt, open_room) = active_call.read_with(cx, |active_call, cx| { + let (should_prompt, open_room) = active_call.update(cx, |active_call, cx| { let Some(room) = active_call.room().map(|room| room.read(cx)) else { return (false, None); }; @@ -4421,7 +4408,7 @@ pub fn restart(_: &Restart, cx: &mut AppContext) { } cx.spawn(|mut cx| async move { - if let Some(mut prompt) = prompt { + if let Some(prompt) = prompt { let answer = prompt.await?; if answer != 0 { return Ok(()); @@ -4460,6 +4447,8 @@ fn parse_pixel_size_env_var(value: &str) -> Option> { #[cfg(test)] mod tests { + use std::{cell::RefCell, rc::Rc}; + use super::*; use crate::item::{ test::{TestItem, TestProjectItem}, @@ -4470,7 +4459,6 @@ mod tests { use project::{Project, ProjectEntryId}; use serde_json::json; use settings::SettingsStore; - use std::{cell::RefCell, rc::Rc}; #[gpui::test] async fn test_tab_disambiguation(cx: &mut TestAppContext) { @@ -4544,7 +4532,7 @@ mod tests { let project = Project::test(fs, ["root1".as_ref()], cx).await; let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); - let worktree_id = project.read_with(cx, |project, cx| { + let worktree_id = project.update(cx, |project, cx| { project.worktrees().next().unwrap().read(cx).id() }); @@ -4557,7 +4545,7 @@ mod tests { // Add an item to an empty pane workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item1), cx)); - project.read_with(cx, |project, cx| { + project.update(cx, |project, cx| { assert_eq!( project.active_entry(), project @@ -4570,7 +4558,7 @@ mod tests { // Add a second item to a non-empty pane workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item2), cx)); assert_eq!(cx.window_title().as_deref(), Some("two.txt — root1")); - project.read_with(cx, |project, cx| { + project.update(cx, |project, cx| { assert_eq!( project.active_entry(), project @@ -4586,7 +4574,7 @@ mod tests { .await .unwrap(); assert_eq!(cx.window_title().as_deref(), Some("one.txt — root1")); - project.read_with(cx, |project, cx| { + project.update(cx, |project, cx| { assert_eq!( project.active_entry(), project @@ -4970,14 +4958,14 @@ mod tests { item.is_dirty = true; cx.blur(); }); - cx.executor().run_until_parked(); + cx.run_until_parked(); item.update(cx, |item, _| assert_eq!(item.save_count, 5)); // Ensure autosave is prevented for deleted files also when closing the buffer. let _close_items = pane.update(cx, |pane, cx| { pane.close_items(cx, SaveIntent::Close, move |id| id == item_id) }); - cx.executor().run_until_parked(); + cx.run_until_parked(); assert!(cx.has_pending_prompt()); item.update(cx, |item, _| assert_eq!(item.save_count, 5)); } @@ -5036,363 +5024,362 @@ mod tests { }); } - // #[gpui::test] - // async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) { - // init_test(cx); - // let fs = FakeFs::new(cx.executor()); - - // let project = Project::test(fs, [], cx).await; - // let window = cx.add_window(|cx| Workspace::test_new(project, cx)); - // let workspace = window.root(cx); - - // let panel = workspace.update(cx, |workspace, cx| { - // let panel = cx.build_view(|_| TestPanel::new(DockPosition::Right)); - // workspace.add_panel(panel.clone(), cx); - - // workspace - // .right_dock() - // .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); - - // panel - // }); - - // let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); - // pane.update(cx, |pane, cx| { - // let item = cx.build_view(|_| TestItem::new(cx)); - // pane.add_item(Box::new(item), true, true, None, cx); - // }); - - // // Transfer focus from center to panel - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); - - // // Transfer focus from panel to center - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(!panel.has_focus(cx)); - // }); - - // // Close the dock - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(!workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(!panel.has_focus(cx)); - // }); - - // // Open the dock - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); - - // // Focus and zoom panel - // panel.update(cx, |panel, cx| { - // cx.focus_self(); - // panel.set_zoomed(true, cx) - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); - - // // Transfer focus to the center closes the dock - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(!workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(!panel.has_focus(cx)); - // }); - - // // Transferring focus back to the panel keeps it zoomed - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); - - // // Close the dock while it is zoomed - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(!workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(workspace.zoomed.is_none()); - // assert!(!panel.has_focus(cx)); - // }); - - // // Opening the dock, when it's zoomed, retains focus - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(workspace.zoomed.is_some()); - // assert!(panel.has_focus(cx)); - // }); - - // // Unzoom and close the panel, zoom the active pane. - // panel.update(cx, |panel, cx| panel.set_zoomed(false, cx)); - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - // pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx)); + // #[gpui::test] + // async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) { + // init_test(cx); + // let fs = FakeFs::new(cx.executor()); + + // let project = Project::test(fs, [], cx).await; + // let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx)); + + // let panel = workspace.update(cx, |workspace, cx| { + // let panel = cx.build_view(|cx| TestPanel::new(DockPosition::Right, cx)); + // workspace.add_panel(panel.clone(), cx); + + // workspace + // .right_dock() + // .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); + + // panel + // }); + + // let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + // pane.update(cx, |pane, cx| { + // let item = cx.build_view(|cx| TestItem::new(cx)); + // pane.add_item(Box::new(item), true, true, None, cx); + // }); + + // // Transfer focus from center to panel + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_panel_focus::(cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Transfer focus from panel to center + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_panel_focus::(cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + // assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Close the dock + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(!workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + // assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Open the dock + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Focus and zoom panel + // panel.update(cx, |panel, cx| { + // cx.focus_self(); + // panel.set_zoomed(true, cx) + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Transfer focus to the center closes the dock + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_panel_focus::(cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(!workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Transferring focus back to the panel keeps it zoomed + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_panel_focus::(cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Close the dock while it is zoomed + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(!workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(workspace.zoomed.is_none()); + // assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Opening the dock, when it's zoomed, retains focus + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(workspace.zoomed.is_some()); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Unzoom and close the panel, zoom the active pane. + // panel.update(cx, |panel, cx| panel.set_zoomed(false, cx)); + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + // pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx)); + + // // Opening a dock unzooms the pane. + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + // workspace.update(cx, |workspace, cx| { + // let pane = pane.read(cx); + // assert!(!pane.is_zoomed()); + // assert!(!pane.focus_handle(cx).is_focused(cx)); + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(workspace.zoomed.is_none()); + // }); + // } - // // Opening a dock unzooms the pane. - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - // workspace.update(cx, |workspace, cx| { - // let pane = pane.read(cx); - // assert!(!pane.is_zoomed()); - // assert!(!pane.has_focus()); - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(workspace.zoomed.is_none()); + // #[gpui::test] + // async fn test_panels(cx: &mut gpui::TestAppContext) { + // init_test(cx); + // let fs = FakeFs::new(cx.executor()); + + // let project = Project::test(fs, [], cx).await; + // let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx)); + + // let (panel_1, panel_2) = workspace.update(cx, |workspace, cx| { + // // Add panel_1 on the left, panel_2 on the right. + // let panel_1 = cx.build_view(|cx| TestPanel::new(DockPosition::Left, cx)); + // workspace.add_panel(panel_1.clone(), cx); + // workspace + // .left_dock() + // .update(cx, |left_dock, cx| left_dock.set_open(true, cx)); + // let panel_2 = cx.build_view(|cx| TestPanel::new(DockPosition::Right, cx)); + // workspace.add_panel(panel_2.clone(), cx); + // workspace + // .right_dock() + // .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); + + // let left_dock = workspace.left_dock(); + // assert_eq!( + // left_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id() + // ); + // assert_eq!( + // left_dock.read(cx).active_panel_size(cx).unwrap(), + // panel_1.size(cx) + // ); + + // left_dock.update(cx, |left_dock, cx| { + // left_dock.resize_active_panel(Some(1337.), cx) // }); - // } - - // #[gpui::test] - // async fn test_panels(cx: &mut gpui::TestAppContext) { - // init_test(cx); - // let fs = FakeFs::new(cx.executor()); - - // let project = Project::test(fs, [], cx).await; - // let window = cx.add_window(|cx| Workspace::test_new(project, cx)); - // let workspace = window.root(cx); - - // let (panel_1, panel_2) = workspace.update(cx, |workspace, cx| { - // // Add panel_1 on the left, panel_2 on the right. - // let panel_1 = cx.build_view(|_| TestPanel::new(DockPosition::Left)); - // workspace.add_panel(panel_1.clone(), cx); + // assert_eq!( // workspace - // .left_dock() - // .update(cx, |left_dock, cx| left_dock.set_open(true, cx)); - // let panel_2 = cx.build_view(|_| TestPanel::new(DockPosition::Right)); - // workspace.add_panel(panel_2.clone(), cx); + // .right_dock() + // .read(cx) + // .visible_panel() + // .unwrap() + // .panel_id(), + // panel_2.panel_id(), + // ); + + // (panel_1, panel_2) + // }); + + // // Move panel_1 to the right + // panel_1.update(cx, |panel_1, cx| { + // panel_1.set_position(DockPosition::Right, cx) + // }); + + // workspace.update(cx, |workspace, cx| { + // // Since panel_1 was visible on the left, it should now be visible now that it's been moved to the right. + // // Since it was the only panel on the left, the left dock should now be closed. + // assert!(!workspace.left_dock().read(cx).is_open()); + // assert!(workspace.left_dock().read(cx).visible_panel().is_none()); + // let right_dock = workspace.right_dock(); + // assert_eq!( + // right_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id() + // ); + // assert_eq!(right_dock.read(cx).active_panel_size(cx).unwrap(), 1337.); + + // // Now we move panel_2 to the left + // panel_2.set_position(DockPosition::Left, cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // // Since panel_2 was not visible on the right, we don't open the left dock. + // assert!(!workspace.left_dock().read(cx).is_open()); + // // And the right dock is unaffected in it's displaying of panel_1 + // assert!(workspace.right_dock().read(cx).is_open()); + // assert_eq!( // workspace // .right_dock() - // .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); - - // let left_dock = workspace.left_dock(); - // assert_eq!( - // left_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // assert_eq!( - // left_dock.read(cx).active_panel_size(cx).unwrap(), - // panel_1.size(cx) - // ); - - // left_dock.update(cx, |left_dock, cx| { - // left_dock.resize_active_panel(Some(1337.), cx) - // }); - // assert_eq!( - // workspace - // .right_dock() - // .read(cx) - // .visible_panel() - // .unwrap() - // .id(), - // panel_2.id() - // ); - - // (panel_1, panel_2) - // }); - - // // Move panel_1 to the right - // panel_1.update(cx, |panel_1, cx| { - // panel_1.set_position(DockPosition::Right, cx) - // }); - - // workspace.update(cx, |workspace, cx| { - // // Since panel_1 was visible on the left, it should now be visible now that it's been moved to the right. - // // Since it was the only panel on the left, the left dock should now be closed. - // assert!(!workspace.left_dock().read(cx).is_open()); - // assert!(workspace.left_dock().read(cx).visible_panel().is_none()); - // let right_dock = workspace.right_dock(); - // assert_eq!( - // right_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // assert_eq!(right_dock.read(cx).active_panel_size(cx).unwrap(), 1337.); - - // // Now we move panel_2 to the left - // panel_2.set_position(DockPosition::Left, cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // // Since panel_2 was not visible on the right, we don't open the left dock. - // assert!(!workspace.left_dock().read(cx).is_open()); - // // And the right dock is unaffected in it's displaying of panel_1 - // assert!(workspace.right_dock().read(cx).is_open()); - // assert_eq!( - // workspace - // .right_dock() - // .read(cx) - // .visible_panel() - // .unwrap() - // .id(), - // panel_1.id() - // ); - // }); - - // // Move panel_1 back to the left - // panel_1.update(cx, |panel_1, cx| { - // panel_1.set_position(DockPosition::Left, cx) - // }); - - // workspace.update(cx, |workspace, cx| { - // // Since panel_1 was visible on the right, we open the left dock and make panel_1 active. - // let left_dock = workspace.left_dock(); - // assert!(left_dock.read(cx).is_open()); - // assert_eq!( - // left_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // assert_eq!(left_dock.read(cx).active_panel_size(cx).unwrap(), 1337.); - // // And right the dock should be closed as it no longer has any panels. - // assert!(!workspace.right_dock().read(cx).is_open()); - - // // Now we move panel_1 to the bottom - // panel_1.set_position(DockPosition::Bottom, cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // // Since panel_1 was visible on the left, we close the left dock. - // assert!(!workspace.left_dock().read(cx).is_open()); - // // The bottom dock is sized based on the panel's default size, - // // since the panel orientation changed from vertical to horizontal. - // let bottom_dock = workspace.bottom_dock(); - // assert_eq!( - // bottom_dock.read(cx).active_panel_size(cx).unwrap(), - // panel_1.size(cx), - // ); - // // Close bottom dock and move panel_1 back to the left. - // bottom_dock.update(cx, |bottom_dock, cx| bottom_dock.set_open(false, cx)); - // panel_1.set_position(DockPosition::Left, cx); - // }); - - // // Emit activated event on panel 1 - // panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::Activated)); - - // // Now the left dock is open and panel_1 is active and focused. - // workspace.update(cx, |workspace, cx| { - // let left_dock = workspace.left_dock(); - // assert!(left_dock.read(cx).is_open()); - // assert_eq!( - // left_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // assert!(panel_1.is_focused(cx)); - // }); - - // // Emit closed event on panel 2, which is not active - // panel_2.update(cx, |_, cx| cx.emit(TestPanelEvent::Closed)); - - // // Wo don't close the left dock, because panel_2 wasn't the active panel - // workspace.update(cx, |workspace, cx| { - // let left_dock = workspace.left_dock(); - // assert!(left_dock.read(cx).is_open()); - // assert_eq!( - // left_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // }); - - // // Emitting a ZoomIn event shows the panel as zoomed. - // panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::ZoomIn)); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any())); - // assert_eq!(workspace.zoomed_position, Some(DockPosition::Left)); - // }); - - // // Move panel to another dock while it is zoomed - // panel_1.update(cx, |panel, cx| panel.set_position(DockPosition::Right, cx)); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any())); - // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); - // }); - - // // If focus is transferred to another view that's not a panel or another pane, we still show - // // the panel as zoomed. - // let focus_receiver = cx.build_view(|_| EmptyView); - // focus_receiver.update(cx, |_, cx| cx.focus_self()); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any())); - // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); - // }); - - // // If focus is transferred elsewhere in the workspace, the panel is no longer zoomed. - // workspace.update(cx, |_, cx| cx.focus_self()); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, None); - // assert_eq!(workspace.zoomed_position, None); - // }); - - // // If focus is transferred again to another view that's not a panel or a pane, we won't - // // show the panel as zoomed because it wasn't zoomed before. - // focus_receiver.update(cx, |_, cx| cx.focus_self()); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, None); - // assert_eq!(workspace.zoomed_position, None); - // }); - - // // When focus is transferred back to the panel, it is zoomed again. - // panel_1.update(cx, |_, cx| cx.focus_self()); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any())); - // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); - // }); - - // // Emitting a ZoomOut event unzooms the panel. - // panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::ZoomOut)); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, None); - // assert_eq!(workspace.zoomed_position, None); - // }); - - // // Emit closed event on panel 1, which is active - // panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::Closed)); - - // // Now the left dock is closed, because panel_1 was the active panel - // workspace.update(cx, |workspace, cx| { - // let right_dock = workspace.right_dock(); - // assert!(!right_dock.read(cx).is_open()); - // }); - // } + // .read(cx) + // .visible_panel() + // .unwrap() + // .panel_id(), + // panel_1.panel_id(), + // ); + // }); + + // // Move panel_1 back to the left + // panel_1.update(cx, |panel_1, cx| { + // panel_1.set_position(DockPosition::Left, cx) + // }); + + // workspace.update(cx, |workspace, cx| { + // // Since panel_1 was visible on the right, we open the left dock and make panel_1 active. + // let left_dock = workspace.left_dock(); + // assert!(left_dock.read(cx).is_open()); + // assert_eq!( + // left_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id() + // ); + // assert_eq!(left_dock.read(cx).active_panel_size(cx).unwrap(), 1337.); + // // And right the dock should be closed as it no longer has any panels. + // assert!(!workspace.right_dock().read(cx).is_open()); + + // // Now we move panel_1 to the bottom + // panel_1.set_position(DockPosition::Bottom, cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // // Since panel_1 was visible on the left, we close the left dock. + // assert!(!workspace.left_dock().read(cx).is_open()); + // // The bottom dock is sized based on the panel's default size, + // // since the panel orientation changed from vertical to horizontal. + // let bottom_dock = workspace.bottom_dock(); + // assert_eq!( + // bottom_dock.read(cx).active_panel_size(cx).unwrap(), + // panel_1.size(cx), + // ); + // // Close bottom dock and move panel_1 back to the left. + // bottom_dock.update(cx, |bottom_dock, cx| bottom_dock.set_open(false, cx)); + // panel_1.set_position(DockPosition::Left, cx); + // }); + + // // Emit activated event on panel 1 + // panel_1.update(cx, |_, cx| cx.emit(PanelEvent::Activate)); + + // // Now the left dock is open and panel_1 is active and focused. + // workspace.update(cx, |workspace, cx| { + // let left_dock = workspace.left_dock(); + // assert!(left_dock.read(cx).is_open()); + // assert_eq!( + // left_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id(), + // ); + // assert!(panel_1.focus_handle(cx).is_focused(cx)); + // }); + + // // Emit closed event on panel 2, which is not active + // panel_2.update(cx, |_, cx| cx.emit(PanelEvent::Close)); + + // // Wo don't close the left dock, because panel_2 wasn't the active panel + // workspace.update(cx, |workspace, cx| { + // let left_dock = workspace.left_dock(); + // assert!(left_dock.read(cx).is_open()); + // assert_eq!( + // left_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id(), + // ); + // }); + + // // Emitting a ZoomIn event shows the panel as zoomed. + // panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomIn)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade())); + // assert_eq!(workspace.zoomed_position, Some(DockPosition::Left)); + // }); + + // // Move panel to another dock while it is zoomed + // panel_1.update(cx, |panel, cx| panel.set_position(DockPosition::Right, cx)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade())); + + // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); + // }); + + // // If focus is transferred to another view that's not a panel or another pane, we still show + // // the panel as zoomed. + // let other_focus_handle = cx.update(|cx| cx.focus_handle()); + // cx.update(|cx| cx.focus(&other_focus_handle)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade())); + // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); + // }); + + // // If focus is transferred elsewhere in the workspace, the panel is no longer zoomed. + // workspace.update(cx, |_, cx| cx.focus_self()); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, None); + // assert_eq!(workspace.zoomed_position, None); + // }); + + // // If focus is transferred again to another view that's not a panel or a pane, we won't + // // show the panel as zoomed because it wasn't zoomed before. + // cx.update(|cx| cx.focus(&other_focus_handle)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, None); + // assert_eq!(workspace.zoomed_position, None); + // }); + + // // When focus is transferred back to the panel, it is zoomed again. + // panel_1.update(cx, |_, cx| cx.focus_self()); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade())); + // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); + // }); + + // // Emitting a ZoomOut event unzooms the panel. + // panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomOut)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, None); + // assert_eq!(workspace.zoomed_position, None); + // }); + + // // Emit closed event on panel 1, which is active + // panel_1.update(cx, |_, cx| cx.emit(PanelEvent::Close)); + + // // Now the left dock is closed, because panel_1 was the active panel + // workspace.update(cx, |workspace, cx| { + // let right_dock = workspace.right_dock(); + // assert!(!right_dock.read(cx).is_open()); + // }); + // } pub fn init_test(cx: &mut TestAppContext) { cx.update(|cx| { From 4e7005b4f76b32da998e8b781ec2df28d81864d4 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Thu, 14 Dec 2023 17:22:13 -0500 Subject: [PATCH 034/644] Use bitflags to hold error states --- Cargo.lock | 19 ++++++++------- crates/feedback2/Cargo.toml | 6 +++-- crates/feedback2/src/feedback_modal.rs | 33 ++++++++++++++------------ 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68919dffbc943d855143e0f9c0688d19b5b9b694..7b7acd54f2a6bed1f22530b4a80ce7e2c0510634 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,7 +182,7 @@ dependencies = [ "alacritty_config", "alacritty_config_derive", "base64 0.13.1", - "bitflags 2.4.0", + "bitflags 2.4.1", "home", "libc", "log", @@ -1025,9 +1025,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" dependencies = [ "serde", ] @@ -3280,6 +3280,7 @@ name = "feedback2" version = "0.1.0" dependencies = [ "anyhow", + "bitflags 2.4.1", "client2", "db2", "editor2", @@ -4026,7 +4027,7 @@ dependencies = [ "async-task", "backtrace", "bindgen 0.65.1", - "bitflags 2.4.0", + "bitflags 2.4.1", "block", "cbindgen", "cocoa", @@ -6195,7 +6196,7 @@ version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if 1.0.0", "foreign-types", "libc", @@ -7915,7 +7916,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -8031,7 +8032,7 @@ version = "0.38.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "errno 0.3.3", "libc", "linux-raw-sys 0.4.7", @@ -9134,7 +9135,7 @@ dependencies = [ "atoi", "base64 0.21.4", "bigdecimal", - "bitflags 2.4.0", + "bitflags 2.4.1", "byteorder", "bytes 1.5.0", "chrono", @@ -9181,7 +9182,7 @@ dependencies = [ "atoi", "base64 0.21.4", "bigdecimal", - "bitflags 2.4.0", + "bitflags 2.4.1", "byteorder", "chrono", "crc", diff --git a/crates/feedback2/Cargo.toml b/crates/feedback2/Cargo.toml index 0e34ee410b5aa26c1b0417b739c928c464447312..9fe125ec57e53f10209f75072c98ada88fe25947 100644 --- a/crates/feedback2/Cargo.toml +++ b/crates/feedback2/Cargo.toml @@ -18,7 +18,6 @@ gpui = { package = "gpui2", path = "../gpui2" } language = { package = "language2", path = "../language2" } menu = { package = "menu2", path = "../menu2" } project = { package = "project2", path = "../project2" } -regex.workspace = true search = { package = "search2", path = "../search2" } settings = { package = "settings2", path = "../settings2" } theme = { package = "theme2", path = "../theme2" } @@ -26,13 +25,16 @@ ui = { package = "ui2", path = "../ui2" } util = { path = "../util" } workspace = { package = "workspace2", path = "../workspace2"} +bitflags = "2.4.1" +human_bytes = "0.4.1" + anyhow.workspace = true futures.workspace = true -human_bytes = "0.4.1" isahc.workspace = true lazy_static.workspace = true log.workspace = true postage.workspace = true +regex.workspace = true serde.workspace = true serde_derive.workspace = true smallvec.workspace = true diff --git a/crates/feedback2/src/feedback_modal.rs b/crates/feedback2/src/feedback_modal.rs index 3130c4bad6f3a31f0ec89312f6a08c3a990c692a..22904f3a0a2c14857e13bde40c2049e1a0982988 100644 --- a/crates/feedback2/src/feedback_modal.rs +++ b/crates/feedback2/src/feedback_modal.rs @@ -1,6 +1,7 @@ use std::{ops::RangeInclusive, sync::Arc, time::Duration}; use anyhow::{anyhow, bail}; +use bitflags::bitflags; use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL}; use db::kvp::KEY_VALUE_STORE; use editor::{Editor, EditorEvent}; @@ -48,15 +49,17 @@ struct FeedbackRequestBody<'a> { token: &'a str, } -#[derive(Debug, Clone, PartialEq)] -enum InvalidStateIssue { - EmailAddress, - CharacterCount, +bitflags! { + #[derive(Debug, Clone, PartialEq)] + struct InvalidStateFlags: u8 { + const EmailAddress = 0b00000001; + const CharacterCount = 0b00000010; + } } #[derive(Debug, Clone, PartialEq)] enum CannotSubmitReason { - InvalidState { issues: Vec }, + InvalidState { flags: InvalidStateFlags }, AwaitingSubmission, } @@ -322,7 +325,7 @@ impl FeedbackModal { return; } - let mut invalid_state_issues = Vec::new(); + let mut invalid_state_flags = InvalidStateFlags::empty(); let valid_email_address = match self.email_address_editor.read(cx).text_option(cx) { Some(email_address) => Regex::new(EMAIL_REGEX).unwrap().is_match(&email_address), @@ -330,37 +333,37 @@ impl FeedbackModal { }; if !valid_email_address { - invalid_state_issues.push(InvalidStateIssue::EmailAddress); + invalid_state_flags |= InvalidStateFlags::EmailAddress; } if !FEEDBACK_CHAR_LIMIT.contains(&self.character_count) { - invalid_state_issues.push(InvalidStateIssue::CharacterCount); + invalid_state_flags |= InvalidStateFlags::CharacterCount; } - if invalid_state_issues.is_empty() { + if invalid_state_flags.is_empty() { self.submission_state = Some(SubmissionState::CanSubmit); } else { self.submission_state = Some(SubmissionState::CannotSubmit { reason: CannotSubmitReason::InvalidState { - issues: invalid_state_issues, + flags: invalid_state_flags, }, }); } } fn valid_email_address(&self) -> bool { - !self.in_invalid_state(InvalidStateIssue::EmailAddress) + !self.in_invalid_state(InvalidStateFlags::EmailAddress) } fn valid_character_count(&self) -> bool { - !self.in_invalid_state(InvalidStateIssue::CharacterCount) + !self.in_invalid_state(InvalidStateFlags::CharacterCount) } - fn in_invalid_state(&self, a: InvalidStateIssue) -> bool { + fn in_invalid_state(&self, flag: InvalidStateFlags) -> bool { match self.submission_state { Some(SubmissionState::CannotSubmit { - reason: CannotSubmitReason::InvalidState { ref issues }, - }) => issues.contains(&a), + reason: CannotSubmitReason::InvalidState { ref flags }, + }) => flags.contains(flag), _ => false, } } From 6170895932b2f3ec12911dfc4373fbcb8b4cf9de Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 14 Dec 2023 14:27:44 -0800 Subject: [PATCH 035/644] Fix bug in Workspace::activate_pane_in_direction Co-authored-by: Conrad --- crates/workspace2/src/workspace2.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 8318ba3f0fa064e50081bbd4131d23ac2d3f9d7a..6d0b05708387519a39e496d53ac61f9a858d3e04 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -2036,20 +2036,20 @@ impl Workspace { _ => bounding_box.center(), }; - let distance_to_next = 1.; //todo(pane dividers styling) + let distance_to_next = 8.; //todo(pane dividers styling) let target = match direction { SplitDirection::Left => { - Point::new(bounding_box.origin.x - distance_to_next.into(), center.y) + Point::new(bounding_box.left() - distance_to_next.into(), center.y) } SplitDirection::Right => { Point::new(bounding_box.right() + distance_to_next.into(), center.y) } SplitDirection::Up => { - Point::new(center.x, bounding_box.origin.y - distance_to_next.into()) + Point::new(center.x, bounding_box.top() - distance_to_next.into()) } SplitDirection::Down => { - Point::new(center.x, bounding_box.top() + distance_to_next.into()) + Point::new(center.x, bounding_box.bottom() + distance_to_next.into()) } }; self.center.pane_at_pixel_position(target) From 8bac4e199d656fe0179fb300c2a435a63ea727d9 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 14 Dec 2023 17:28:45 -0500 Subject: [PATCH 036/644] Emit `editor_foreground` color from theme converter --- crates/theme2/src/themes/andromeda.rs | 2 ++ crates/theme2/src/themes/ayu.rs | 3 +++ crates/theme2/src/themes/dracula.rs | 1 + crates/theme2/src/themes/gruvbox.rs | 6 +++++ crates/theme2/src/themes/night_owl.rs | 2 ++ crates/theme2/src/themes/noctis.rs | 11 ++++++++ crates/theme2/src/themes/nord.rs | 1 + crates/theme2/src/themes/palenight.rs | 3 +++ crates/theme2/src/themes/rose_pine.rs | 3 +++ crates/theme2/src/themes/solarized.rs | 2 ++ crates/theme2/src/themes/synthwave_84.rs | 1 + crates/theme_importer/src/theme_printer.rs | 1 + crates/theme_importer/src/vscode/converter.rs | 26 ++++++++++++------- 13 files changed, 52 insertions(+), 10 deletions(-) diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index 33284cdbeee1bf548384ebc689861c9db0c69694..32bccf172a61ab7fcdaff19fcc4b9c973fc753bb 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -47,6 +47,7 @@ pub fn andromeda() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x3a3f4c77).into()), scrollbar_track_background: Some(rgba(0x23262eff).into()), scrollbar_track_border: Some(rgba(0x1b1d23ff).into()), + editor_foreground: Some(rgba(0xd5ced9ff).into()), editor_background: Some(rgba(0x23262eff).into()), editor_gutter_background: Some(rgba(0x23262eff).into()), editor_line_number: Some(rgba(0x746f77ff).into()), @@ -261,6 +262,7 @@ pub fn andromeda() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x3a3f4c77).into()), scrollbar_track_background: Some(rgba(0x262a33ff).into()), scrollbar_track_border: Some(rgba(0x1b1d23ff).into()), + editor_foreground: Some(rgba(0xd5ced9ff).into()), editor_background: Some(rgba(0x262a33ff).into()), editor_gutter_background: Some(rgba(0x262a33ff).into()), editor_line_number: Some(rgba(0x746f77ff).into()), diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index 0164e4786f88559bb4234d8acce95e463bdac57c..f7c8f8c12908f072661cd5eb65529e3dd29d71bf 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -46,6 +46,7 @@ pub fn ayu() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x8a919966).into()), scrollbar_track_background: Some(rgba(0xf8f9faff).into()), scrollbar_track_border: Some(rgba(0x6b7d8f1f).into()), + editor_foreground: Some(rgba(0x8a9199ff).into()), editor_background: Some(rgba(0xf8f9faff).into()), editor_gutter_background: Some(rgba(0xf8f9faff).into()), editor_line_number: Some(rgba(0x8a919966).into()), @@ -352,6 +353,7 @@ pub fn ayu() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x707a8c66).into()), scrollbar_track_background: Some(rgba(0x1f2430ff).into()), scrollbar_track_border: Some(rgba(0x171b24ff).into()), + editor_foreground: Some(rgba(0x707a8cff).into()), editor_background: Some(rgba(0x1f2430ff).into()), editor_gutter_background: Some(rgba(0x1f2430ff).into()), editor_line_number: Some(rgba(0x8a919966).into()), @@ -658,6 +660,7 @@ pub fn ayu() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x565b6666).into()), scrollbar_track_background: Some(rgba(0x0b0e14ff).into()), scrollbar_track_border: Some(rgba(0x1e232bff).into()), + editor_foreground: Some(rgba(0x565b66ff).into()), editor_background: Some(rgba(0x0b0e14ff).into()), editor_gutter_background: Some(rgba(0x0b0e14ff).into()), editor_line_number: Some(rgba(0x6c738099).into()), diff --git a/crates/theme2/src/themes/dracula.rs b/crates/theme2/src/themes/dracula.rs index 5933ec46ffe60c0f5ff686b47312c8b283905faa..3fabb67ec2ce1a1a86d5a934731b2593ceb6426b 100644 --- a/crates/theme2/src/themes/dracula.rs +++ b/crates/theme2/src/themes/dracula.rs @@ -43,6 +43,7 @@ pub fn dracula() -> UserThemeFamily { tab_active_background: Some(rgba(0x282a36ff).into()), scrollbar_track_background: Some(rgba(0x282a36ff).into()), scrollbar_track_border: Some(rgba(0x191a21ff).into()), + editor_foreground: Some(rgba(0xf8f8f2ff).into()), editor_background: Some(rgba(0x282a36ff).into()), editor_gutter_background: Some(rgba(0x282a36ff).into()), editor_line_number: Some(rgba(0x6272a4ff).into()), diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index 4573f55ca1725532f1e5f5e03d52da7ef7670b41..2c9666553447d94a460fb122f4993a80dc5318a9 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -46,6 +46,7 @@ pub fn gruvbox() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x50494599).into()), scrollbar_track_background: Some(rgba(0x1d2021ff).into()), scrollbar_track_border: Some(rgba(0x1d202100).into()), + editor_foreground: Some(rgba(0xebdbb2ff).into()), editor_background: Some(rgba(0x1d2021ff).into()), editor_gutter_background: Some(rgba(0x1d2021ff).into()), editor_line_number: Some(rgba(0x665c54ff).into()), @@ -338,6 +339,7 @@ pub fn gruvbox() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x50494599).into()), scrollbar_track_background: Some(rgba(0x282828ff).into()), scrollbar_track_border: Some(rgba(0x28282800).into()), + editor_foreground: Some(rgba(0xebdbb2ff).into()), editor_background: Some(rgba(0x282828ff).into()), editor_gutter_background: Some(rgba(0x282828ff).into()), editor_line_number: Some(rgba(0x665c54ff).into()), @@ -630,6 +632,7 @@ pub fn gruvbox() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x50494599).into()), scrollbar_track_background: Some(rgba(0x32302fff).into()), scrollbar_track_border: Some(rgba(0x32302f00).into()), + editor_foreground: Some(rgba(0xebdbb2ff).into()), editor_background: Some(rgba(0x32302fff).into()), editor_gutter_background: Some(rgba(0x32302fff).into()), editor_line_number: Some(rgba(0x665c54ff).into()), @@ -922,6 +925,7 @@ pub fn gruvbox() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()), scrollbar_track_background: Some(rgba(0xf9f5d7ff).into()), scrollbar_track_border: Some(rgba(0xf9f5d700).into()), + editor_foreground: Some(rgba(0x3c3836ff).into()), editor_background: Some(rgba(0xf9f5d7ff).into()), editor_gutter_background: Some(rgba(0xf9f5d7ff).into()), editor_line_number: Some(rgba(0xbdae93ff).into()), @@ -1214,6 +1218,7 @@ pub fn gruvbox() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()), scrollbar_track_background: Some(rgba(0xfbf1c7ff).into()), scrollbar_track_border: Some(rgba(0xfbf1c700).into()), + editor_foreground: Some(rgba(0x3c3836ff).into()), editor_background: Some(rgba(0xfbf1c7ff).into()), editor_gutter_background: Some(rgba(0xfbf1c7ff).into()), editor_line_number: Some(rgba(0xbdae93ff).into()), @@ -1506,6 +1511,7 @@ pub fn gruvbox() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()), scrollbar_track_background: Some(rgba(0xf2e5bcff).into()), scrollbar_track_border: Some(rgba(0xf2e5bc00).into()), + editor_foreground: Some(rgba(0x3c3836ff).into()), editor_background: Some(rgba(0xf2e5bcff).into()), editor_gutter_background: Some(rgba(0xf2e5bcff).into()), editor_line_number: Some(rgba(0xbdae93ff).into()), diff --git a/crates/theme2/src/themes/night_owl.rs b/crates/theme2/src/themes/night_owl.rs index 71c980e6315314d60d3d761c2bc66524ae732242..778dfabeb8e7c5f1bb6c5afa43c0930205157102 100644 --- a/crates/theme2/src/themes/night_owl.rs +++ b/crates/theme2/src/themes/night_owl.rs @@ -46,6 +46,7 @@ pub fn night_owl() -> UserThemeFamily { scrollbar_thumb_hover_background: Some(rgba(0x084d8180).into()), scrollbar_thumb_border: Some(rgba(0x084d8180).into()), scrollbar_track_background: Some(rgba(0x011627ff).into()), + editor_foreground: Some(rgba(0xd6deebff).into()), editor_background: Some(rgba(0x011627ff).into()), editor_gutter_background: Some(rgba(0x011627ff).into()), editor_line_number: Some(rgba(0x4b6479ff).into()), @@ -305,6 +306,7 @@ pub fn night_owl() -> UserThemeFamily { tab_inactive_background: Some(rgba(0xf0f0f0ff).into()), tab_active_background: Some(rgba(0xf6f6f6ff).into()), scrollbar_track_background: Some(rgba(0xfbfbfbff).into()), + editor_foreground: Some(rgba(0x403f53ff).into()), editor_background: Some(rgba(0xfbfbfbff).into()), editor_gutter_background: Some(rgba(0xfbfbfbff).into()), editor_line_number: Some(rgba(0x90a7b2ff).into()), diff --git a/crates/theme2/src/themes/noctis.rs b/crates/theme2/src/themes/noctis.rs index 51b442a57e46de757b735c5a881be30bd02cdc9c..614553593d5ffa031d385dfbd801af10d9892bfc 100644 --- a/crates/theme2/src/themes/noctis.rs +++ b/crates/theme2/src/themes/noctis.rs @@ -47,6 +47,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x008ee633).into()), scrollbar_track_background: Some(rgba(0x07273bff).into()), scrollbar_track_border: Some(rgba(0x07273bff).into()), + editor_foreground: Some(rgba(0xbecfdaff).into()), editor_background: Some(rgba(0x07273bff).into()), editor_gutter_background: Some(rgba(0x07273bff).into()), editor_line_number: Some(rgba(0x4d6c80ff).into()), @@ -324,6 +325,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0xeb609133).into()), scrollbar_track_background: Some(rgba(0x322a2dff).into()), scrollbar_track_border: Some(rgba(0x322a2dff).into()), + editor_foreground: Some(rgba(0xcbbec2ff).into()), editor_background: Some(rgba(0x322a2dff).into()), editor_gutter_background: Some(rgba(0x322a2dff).into()), editor_line_number: Some(rgba(0x715b63ff).into()), @@ -601,6 +603,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), scrollbar_track_background: Some(rgba(0xf4f6f6ff).into()), scrollbar_track_border: Some(rgba(0xf4f6f6ff).into()), + editor_foreground: Some(rgba(0x005661ff).into()), editor_background: Some(rgba(0xf4f6f6ff).into()), editor_gutter_background: Some(rgba(0xf4f6f6ff).into()), editor_line_number: Some(rgba(0xa0abacff).into()), @@ -878,6 +881,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), scrollbar_track_background: Some(rgba(0xf2f1f8ff).into()), scrollbar_track_border: Some(rgba(0xf2f1f8ff).into()), + editor_foreground: Some(rgba(0x0c006bff).into()), editor_background: Some(rgba(0xf2f1f8ff).into()), editor_gutter_background: Some(rgba(0xf2f1f8ff).into()), editor_line_number: Some(rgba(0x9d9ab1ff).into()), @@ -1155,6 +1159,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), scrollbar_track_background: Some(rgba(0xfef8ecff).into()), scrollbar_track_border: Some(rgba(0xfef8ecff).into()), + editor_foreground: Some(rgba(0x005661ff).into()), editor_background: Some(rgba(0xfef8ecff).into()), editor_gutter_background: Some(rgba(0xfef8ecff).into()), editor_line_number: Some(rgba(0xa0abacff).into()), @@ -1432,6 +1437,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x3f7fa633).into()), scrollbar_track_background: Some(rgba(0x1b2932ff).into()), scrollbar_track_border: Some(rgba(0x1b2932ff).into()), + editor_foreground: Some(rgba(0xc5cdd3ff).into()), editor_background: Some(rgba(0x1b2932ff).into()), editor_gutter_background: Some(rgba(0x1b2932ff).into()), editor_line_number: Some(rgba(0x5d6e79ff).into()), @@ -1709,6 +1715,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), scrollbar_track_background: Some(rgba(0x052529ff).into()), scrollbar_track_border: Some(rgba(0x052529ff).into()), + editor_foreground: Some(rgba(0xb2cacdff).into()), editor_background: Some(rgba(0x052529ff).into()), editor_gutter_background: Some(rgba(0x052529ff).into()), editor_line_number: Some(rgba(0x4e6b6eff).into()), @@ -1986,6 +1993,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), scrollbar_track_background: Some(rgba(0x031417ff).into()), scrollbar_track_border: Some(rgba(0x031417ff).into()), + editor_foreground: Some(rgba(0xb2cacdff).into()), editor_background: Some(rgba(0x031417ff).into()), editor_gutter_background: Some(rgba(0x031417ff).into()), editor_line_number: Some(rgba(0x4e6b6eff).into()), @@ -2263,6 +2271,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), scrollbar_track_background: Some(rgba(0x031417ff).into()), scrollbar_track_border: Some(rgba(0x031417ff).into()), + editor_foreground: Some(rgba(0xb2cacdff).into()), editor_background: Some(rgba(0x031417ff).into()), editor_gutter_background: Some(rgba(0x031417ff).into()), editor_line_number: Some(rgba(0x4e6b6eff).into()), @@ -2540,6 +2549,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x7060eb33).into()), scrollbar_track_background: Some(rgba(0x292640ff).into()), scrollbar_track_border: Some(rgba(0x292640ff).into()), + editor_foreground: Some(rgba(0xc5c2d6ff).into()), editor_background: Some(rgba(0x292640ff).into()), editor_gutter_background: Some(rgba(0x292640ff).into()), editor_line_number: Some(rgba(0x5c5973ff).into()), @@ -2817,6 +2827,7 @@ pub fn noctis() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0xa660eb33).into()), scrollbar_track_background: Some(rgba(0x30243dff).into()), scrollbar_track_border: Some(rgba(0x30243dff).into()), + editor_foreground: Some(rgba(0xccbfd9ff).into()), editor_background: Some(rgba(0x30243dff).into()), editor_gutter_background: Some(rgba(0x30243dff).into()), editor_line_number: Some(rgba(0x665973ff).into()), diff --git a/crates/theme2/src/themes/nord.rs b/crates/theme2/src/themes/nord.rs index 949926c6857d0b0b0d183328c8e837f0007c7afc..f3d03b38892628aa06f21b90eca69c169fca9921 100644 --- a/crates/theme2/src/themes/nord.rs +++ b/crates/theme2/src/themes/nord.rs @@ -46,6 +46,7 @@ pub fn nord() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x434c5e99).into()), scrollbar_track_background: Some(rgba(0x2e3440ff).into()), scrollbar_track_border: Some(rgba(0x3b4252ff).into()), + editor_foreground: Some(rgba(0xd8dee9ff).into()), editor_background: Some(rgba(0x2e3440ff).into()), editor_gutter_background: Some(rgba(0x2e3440ff).into()), editor_line_number: Some(rgba(0x4c566aff).into()), diff --git a/crates/theme2/src/themes/palenight.rs b/crates/theme2/src/themes/palenight.rs index ab47cc104643bc63fba6a85a778474b2fb4925c0..028d326229dfe268a096838f76f2068cd3bf12e5 100644 --- a/crates/theme2/src/themes/palenight.rs +++ b/crates/theme2/src/themes/palenight.rs @@ -46,6 +46,7 @@ pub fn palenight() -> UserThemeFamily { scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()), scrollbar_thumb_border: Some(rgba(0x694ca466).into()), scrollbar_track_background: Some(rgba(0x292d3eff).into()), + editor_foreground: Some(rgba(0xffffffff).into()), editor_background: Some(rgba(0x292d3eff).into()), editor_gutter_background: Some(rgba(0x292d3eff).into()), editor_line_number: Some(rgba(0x4c5374ff).into()), @@ -331,6 +332,7 @@ pub fn palenight() -> UserThemeFamily { scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()), scrollbar_thumb_border: Some(rgba(0x694ca466).into()), scrollbar_track_background: Some(rgba(0x292d3eff).into()), + editor_foreground: Some(rgba(0xffffffff).into()), editor_background: Some(rgba(0x292d3eff).into()), editor_gutter_background: Some(rgba(0x292d3eff).into()), editor_line_number: Some(rgba(0x4c5374ff).into()), @@ -616,6 +618,7 @@ pub fn palenight() -> UserThemeFamily { scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()), scrollbar_thumb_border: Some(rgba(0x694ca466).into()), scrollbar_track_background: Some(rgba(0x292d3eff).into()), + editor_foreground: Some(rgba(0xffffffff).into()), editor_background: Some(rgba(0x292d3eff).into()), editor_gutter_background: Some(rgba(0x292d3eff).into()), editor_line_number: Some(rgba(0x4c5374ff).into()), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index d9091df347dc891d628d601ccea2b8a7c965cf56..a09364405f02e9adb4d74a6b16f82f9dc386db9e 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -47,6 +47,7 @@ pub fn rose_pine() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x6e6a8633).into()), scrollbar_track_background: Some(rgba(0x191724ff).into()), scrollbar_track_border: Some(rgba(0x6e6a8666).into()), + editor_foreground: Some(rgba(0xe0def4ff).into()), editor_background: Some(rgba(0x191724ff).into()), editor_gutter_background: Some(rgba(0x191724ff).into()), editor_line_number: Some(rgba(0x908caaff).into()), @@ -306,6 +307,7 @@ pub fn rose_pine() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x817c9c26).into()), scrollbar_track_background: Some(rgba(0x232136ff).into()), scrollbar_track_border: Some(rgba(0x817c9c4d).into()), + editor_foreground: Some(rgba(0xe0def4ff).into()), editor_background: Some(rgba(0x232136ff).into()), editor_gutter_background: Some(rgba(0x232136ff).into()), editor_line_number: Some(rgba(0x908caaff).into()), @@ -565,6 +567,7 @@ pub fn rose_pine() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x6e6a8614).into()), scrollbar_track_background: Some(rgba(0xfaf4edff).into()), scrollbar_track_border: Some(rgba(0x6e6a8626).into()), + editor_foreground: Some(rgba(0x575279ff).into()), editor_background: Some(rgba(0xfaf4edff).into()), editor_gutter_background: Some(rgba(0xfaf4edff).into()), editor_line_number: Some(rgba(0x797593ff).into()), diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index 25799bea280e0c4f00becefdfcda76b0b4b49ff3..9807a6cd3de000d79bd9b30fc21ffad5e9562906 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -42,6 +42,7 @@ pub fn solarized() -> UserThemeFamily { tab_inactive_background: Some(rgba(0x004052ff).into()), tab_active_background: Some(rgba(0x002b37ff).into()), scrollbar_track_background: Some(rgba(0x002b36ff).into()), + editor_foreground: Some(rgba(0xbbbbbbff).into()), editor_background: Some(rgba(0x002b36ff).into()), editor_gutter_background: Some(rgba(0x002b36ff).into()), editor_line_number: Some(rgba(0x566c74ff).into()), @@ -307,6 +308,7 @@ pub fn solarized() -> UserThemeFamily { tab_inactive_background: Some(rgba(0xd3cbb7ff).into()), tab_active_background: Some(rgba(0xfdf6e3ff).into()), scrollbar_track_background: Some(rgba(0xfdf6e3ff).into()), + editor_foreground: Some(rgba(0x333333ff).into()), editor_background: Some(rgba(0xfdf6e3ff).into()), editor_gutter_background: Some(rgba(0xfdf6e3ff).into()), editor_line_number: Some(rgba(0x9ca8a6ff).into()), diff --git a/crates/theme2/src/themes/synthwave_84.rs b/crates/theme2/src/themes/synthwave_84.rs index 4f62732d7f139e720d357a6fac6192c267f4e776..defc73ae567c788cf221162d549a9254157817c0 100644 --- a/crates/theme2/src/themes/synthwave_84.rs +++ b/crates/theme2/src/themes/synthwave_84.rs @@ -39,6 +39,7 @@ pub fn synthwave_84() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x9d8bca30).into()), scrollbar_track_background: Some(rgba(0x262335ff).into()), scrollbar_track_border: Some(rgba(0x34294fb3).into()), + editor_foreground: Some(rgba(0xffffffff).into()), editor_background: Some(rgba(0x262335ff).into()), editor_gutter_background: Some(rgba(0x262335ff).into()), editor_line_number: Some(rgba(0xffffff73).into()), diff --git a/crates/theme_importer/src/theme_printer.rs b/crates/theme_importer/src/theme_printer.rs index 78c8719105576f9efb7b6bca26dfcda3f07f5873..4726c90c6d1077da8f8f1c947bff49bac9bc9d57 100644 --- a/crates/theme_importer/src/theme_printer.rs +++ b/crates/theme_importer/src/theme_printer.rs @@ -201,6 +201,7 @@ impl<'a> Debug for ThemeColorsRefinementPrinter<'a> { self.0.scrollbar_track_background, ), ("scrollbar_track_border", self.0.scrollbar_track_border), + ("editor_foreground", self.0.editor_foreground), ("editor_background", self.0.editor_background), ("editor_gutter_background", self.0.editor_gutter_background), ( diff --git a/crates/theme_importer/src/vscode/converter.rs b/crates/theme_importer/src/vscode/converter.rs index c9a07a1f7f2a78cb09da7e5c09d21e5fab02cc8a..e4c95d6cf234637a2f509dc2b3a457647d1fc386 100644 --- a/crates/theme_importer/src/vscode/converter.rs +++ b/crates/theme_importer/src/vscode/converter.rs @@ -142,6 +142,16 @@ impl VsCodeThemeConverter { .as_ref() .traverse(|color| try_parse_color(&color))?; + let vscode_token_colors_foreground = self + .theme + .token_colors + .iter() + .find(|token_color| token_color.scope.is_none()) + .and_then(|token_color| token_color.settings.foreground.as_ref()) + .traverse(|color| try_parse_color(&color)) + .ok() + .flatten(); + Ok(ThemeColorsRefinement { border: vscode_panel_border, border_variant: vscode_panel_border, @@ -197,16 +207,7 @@ impl VsCodeThemeConverter { .foreground .as_ref() .traverse(|color| try_parse_color(&color))? - .or_else(|| { - self.theme - .token_colors - .iter() - .find(|token_color| token_color.scope.is_none()) - .and_then(|token_color| token_color.settings.foreground.as_ref()) - .traverse(|color| try_parse_color(&color)) - .ok() - .flatten() - }), + .or(vscode_token_colors_foreground), text_muted: vscode_colors .tab_inactive_foreground .as_ref() @@ -226,6 +227,11 @@ impl VsCodeThemeConverter { .as_ref() .traverse(|color| try_parse_color(&color))? .or(vscode_editor_background), + editor_foreground: vscode_colors + .foreground + .as_ref() + .traverse(|color| try_parse_color(&color))? + .or(vscode_token_colors_foreground), editor_background: vscode_editor_background, editor_gutter_background: vscode_editor_background, editor_line_number: vscode_colors From 292fac37bbe9109e4297d1e288c92c8784b9001d Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 14 Dec 2023 17:30:37 -0500 Subject: [PATCH 037/644] Use `editor.foreground` from VS Code for the editor foreground --- crates/theme2/src/themes/ayu.rs | 6 +++--- crates/theme2/src/themes/palenight.rs | 6 +++--- crates/theme2/src/themes/synthwave_84.rs | 1 - crates/theme_importer/src/vscode/converter.rs | 11 ++++++----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index f7c8f8c12908f072661cd5eb65529e3dd29d71bf..4c5d95123000183ace35e98f4a291762dbd3129e 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -46,7 +46,7 @@ pub fn ayu() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x8a919966).into()), scrollbar_track_background: Some(rgba(0xf8f9faff).into()), scrollbar_track_border: Some(rgba(0x6b7d8f1f).into()), - editor_foreground: Some(rgba(0x8a9199ff).into()), + editor_foreground: Some(rgba(0x5c6166ff).into()), editor_background: Some(rgba(0xf8f9faff).into()), editor_gutter_background: Some(rgba(0xf8f9faff).into()), editor_line_number: Some(rgba(0x8a919966).into()), @@ -353,7 +353,7 @@ pub fn ayu() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x707a8c66).into()), scrollbar_track_background: Some(rgba(0x1f2430ff).into()), scrollbar_track_border: Some(rgba(0x171b24ff).into()), - editor_foreground: Some(rgba(0x707a8cff).into()), + editor_foreground: Some(rgba(0xcccac2ff).into()), editor_background: Some(rgba(0x1f2430ff).into()), editor_gutter_background: Some(rgba(0x1f2430ff).into()), editor_line_number: Some(rgba(0x8a919966).into()), @@ -660,7 +660,7 @@ pub fn ayu() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x565b6666).into()), scrollbar_track_background: Some(rgba(0x0b0e14ff).into()), scrollbar_track_border: Some(rgba(0x1e232bff).into()), - editor_foreground: Some(rgba(0x565b66ff).into()), + editor_foreground: Some(rgba(0xbfbdb6ff).into()), editor_background: Some(rgba(0x0b0e14ff).into()), editor_gutter_background: Some(rgba(0x0b0e14ff).into()), editor_line_number: Some(rgba(0x6c738099).into()), diff --git a/crates/theme2/src/themes/palenight.rs b/crates/theme2/src/themes/palenight.rs index 028d326229dfe268a096838f76f2068cd3bf12e5..501a678577d69a7318b1fd880c81c7790f0b83e5 100644 --- a/crates/theme2/src/themes/palenight.rs +++ b/crates/theme2/src/themes/palenight.rs @@ -46,7 +46,7 @@ pub fn palenight() -> UserThemeFamily { scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()), scrollbar_thumb_border: Some(rgba(0x694ca466).into()), scrollbar_track_background: Some(rgba(0x292d3eff).into()), - editor_foreground: Some(rgba(0xffffffff).into()), + editor_foreground: Some(rgba(0xbfc7d5ff).into()), editor_background: Some(rgba(0x292d3eff).into()), editor_gutter_background: Some(rgba(0x292d3eff).into()), editor_line_number: Some(rgba(0x4c5374ff).into()), @@ -332,7 +332,7 @@ pub fn palenight() -> UserThemeFamily { scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()), scrollbar_thumb_border: Some(rgba(0x694ca466).into()), scrollbar_track_background: Some(rgba(0x292d3eff).into()), - editor_foreground: Some(rgba(0xffffffff).into()), + editor_foreground: Some(rgba(0xbfc7d5ff).into()), editor_background: Some(rgba(0x292d3eff).into()), editor_gutter_background: Some(rgba(0x292d3eff).into()), editor_line_number: Some(rgba(0x4c5374ff).into()), @@ -618,7 +618,7 @@ pub fn palenight() -> UserThemeFamily { scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()), scrollbar_thumb_border: Some(rgba(0x694ca466).into()), scrollbar_track_background: Some(rgba(0x292d3eff).into()), - editor_foreground: Some(rgba(0xffffffff).into()), + editor_foreground: Some(rgba(0xbfc7d5ff).into()), editor_background: Some(rgba(0x292d3eff).into()), editor_gutter_background: Some(rgba(0x292d3eff).into()), editor_line_number: Some(rgba(0x4c5374ff).into()), diff --git a/crates/theme2/src/themes/synthwave_84.rs b/crates/theme2/src/themes/synthwave_84.rs index defc73ae567c788cf221162d549a9254157817c0..4f62732d7f139e720d357a6fac6192c267f4e776 100644 --- a/crates/theme2/src/themes/synthwave_84.rs +++ b/crates/theme2/src/themes/synthwave_84.rs @@ -39,7 +39,6 @@ pub fn synthwave_84() -> UserThemeFamily { scrollbar_thumb_border: Some(rgba(0x9d8bca30).into()), scrollbar_track_background: Some(rgba(0x262335ff).into()), scrollbar_track_border: Some(rgba(0x34294fb3).into()), - editor_foreground: Some(rgba(0xffffffff).into()), editor_background: Some(rgba(0x262335ff).into()), editor_gutter_background: Some(rgba(0x262335ff).into()), editor_line_number: Some(rgba(0xffffff73).into()), diff --git a/crates/theme_importer/src/vscode/converter.rs b/crates/theme_importer/src/vscode/converter.rs index e4c95d6cf234637a2f509dc2b3a457647d1fc386..46d9c3d08608b0f3c060c86ae89cfe464bb8bb07 100644 --- a/crates/theme_importer/src/vscode/converter.rs +++ b/crates/theme_importer/src/vscode/converter.rs @@ -132,6 +132,11 @@ impl VsCodeThemeConverter { .as_ref() .traverse(|color| try_parse_color(&color))?; + let vscode_editor_foreground = vscode_colors + .editor_foreground + .as_ref() + .traverse(|color| try_parse_color(&color))?; + let vscode_editor_background = vscode_colors .editor_background .as_ref() @@ -227,11 +232,7 @@ impl VsCodeThemeConverter { .as_ref() .traverse(|color| try_parse_color(&color))? .or(vscode_editor_background), - editor_foreground: vscode_colors - .foreground - .as_ref() - .traverse(|color| try_parse_color(&color))? - .or(vscode_token_colors_foreground), + editor_foreground: vscode_editor_foreground.or(vscode_token_colors_foreground), editor_background: vscode_editor_background, editor_gutter_background: vscode_editor_background, editor_line_number: vscode_colors From 2b278e69f73589c9bb277ab5c63f5d86453452c7 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 14 Dec 2023 17:34:07 -0500 Subject: [PATCH 038/644] Use `editor_foreground` color in editor --- crates/editor2/src/editor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 89b5fd2efb91ff43f4683b0923f5658888ecc72a..e58aa1000d475caa009b045b89e36145c69b3894 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -9297,7 +9297,7 @@ impl Render for Editor { let settings = ThemeSettings::get_global(cx); let text_style = match self.mode { EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle { - color: cx.theme().colors().text, + color: cx.theme().colors().editor_foreground, font_family: settings.ui_font.family.clone(), font_features: settings.ui_font.features, font_size: rems(0.875).into(), @@ -9310,7 +9310,7 @@ impl Render for Editor { }, EditorMode::Full => TextStyle { - color: cx.theme().colors().text, + color: cx.theme().colors().editor_foreground, font_family: settings.buffer_font.family.clone(), font_features: settings.buffer_font.features, font_size: settings.buffer_font_size(cx).into(), From 3cf003763e3af497351f6294b10259cce081348c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 14 Dec 2023 17:38:22 -0500 Subject: [PATCH 039/644] Use updated story container in Text story --- crates/story/src/story.rs | 118 ++++++++++++++++++++++---- crates/storybook2/src/stories/text.rs | 50 +++++++++-- 2 files changed, 148 insertions(+), 20 deletions(-) diff --git a/crates/story/src/story.rs b/crates/story/src/story.rs index 4985fb1961c3e4957d8ad9b8947929fee996fe52..3419af95b099807609b52b40b9775b17457975a0 100644 --- a/crates/story/src/story.rs +++ b/crates/story/src/story.rs @@ -1,5 +1,6 @@ use gpui::{ - div, hsla, prelude::*, px, rems, AnyElement, Div, ElementId, Hsla, SharedString, WindowContext, + div, hsla, prelude::*, px, rems, AnyElement, Div, ElementId, Hsla, SharedString, Stateful, + WindowContext, }; use itertools::Itertools; use smallvec::SmallVec; @@ -49,47 +50,134 @@ pub fn story_color() -> StoryColor { StoryColor::new() } -pub struct Story {} +#[derive(IntoElement)] +pub struct StoryContainer { + title: SharedString, + relative_path: &'static str, + children: SmallVec<[AnyElement; 2]>, +} -impl Story { - pub fn container() -> Div { - div() - .size_full() - .flex() - .flex_col() - .bg(story_color().background) +impl StoryContainer { + pub fn new(title: impl Into, relative_path: &'static str) -> Self { + Self { + title: title.into(), + relative_path, + children: SmallVec::new(), + } } +} - // TODO: Move all stories to container2, then rename - pub fn container2(relative_path: &'static str) -> Div { +impl ParentElement for StoryContainer { + fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> { + &mut self.children + } +} + +impl RenderOnce for StoryContainer { + type Rendered = Stateful
; + + fn render(self, _cx: &mut WindowContext) -> Self::Rendered { div() .size_full() .flex() .flex_col() + .id("story_container") .bg(story_color().background) .child( div() .flex() + .flex_none() + .w_full() .justify_between() .p_2() + .bg(story_color().background) .border_b() .border_color(story_color().border) - .child(Story::title_for::()) + .child(Story::title(self.title)) .child( div() .text_xs() .text_color(story_color().primary) - .child(Story::open_story_link(relative_path)), + .child(Story::open_story_link(self.relative_path)), ), ) + .child( + div() + .w_full() + .h_px() + .flex_1() + .id("story_body") + .overflow_hidden_x() + .overflow_y_scroll() + .flex() + .flex_col() + .pb_4() + .children(self.children), + ) + } +} + +pub struct Story {} + +impl Story { + pub fn container() -> Div { + div().size_full().overflow_hidden().child( + div() + .id("story_container") + .overflow_y_scroll() + .w_full() + .min_h_full() + .flex() + .flex_col() + .bg(story_color().background), + ) + } + + // TODO: Move all stories to container2, then rename + pub fn container2(relative_path: &'static str) -> Div { + div().size_full().child( + div() + .size_full() + .id("story_container") + .overflow_y_scroll() + .flex() + .flex_col() + .flex_none() + .child( + div() + .flex() + .justify_between() + .p_2() + .border_b() + .border_color(story_color().border) + .child(Story::title_for::()) + .child( + div() + .text_xs() + .text_color(story_color().primary) + .child(Story::open_story_link(relative_path)), + ), + ) + .child( + div() + .w_full() + .min_h_full() + .flex() + .flex_col() + .bg(story_color().background), + ), + ) } pub fn open_story_link(relative_path: &'static str) -> impl Element { let path = PathBuf::from_iter([relative_path]); + div() - .id(SharedString::from(format!("id_{}", relative_path))) + .flex() + .gap_2() .text_xs() .text_color(story_color().primary) + .id(SharedString::from(format!("id_{}", relative_path))) .on_click({ let path = path.clone(); @@ -99,7 +187,7 @@ impl Story { std::process::Command::new("zed").arg(path).spawn().ok(); } }) - .child(Story::link(path.to_string_lossy().to_string())) + .children(vec![div().child(Story::link("Open in Zed →"))]) } pub fn title(title: impl Into) -> impl Element { diff --git a/crates/storybook2/src/stories/text.rs b/crates/storybook2/src/stories/text.rs index b48b9dd4b5ea438564499ec80654e6f052aa4396..7c1d29a2693dd6ba5dd83dfdbbe0030dea261d42 100644 --- a/crates/storybook2/src/stories/text.rs +++ b/crates/storybook2/src/stories/text.rs @@ -1,4 +1,7 @@ -use gpui::{div, red, Div, ParentElement, Render, Styled, View, VisualContext, WindowContext}; +use gpui::{ + div, green, red, Component, Div, HighlightStyle, InteractiveText, IntoElement, ParentElement, + Render, Styled, StyledText, View, VisualContext, WindowContext, +}; use indoc::indoc; use story::*; @@ -11,10 +14,13 @@ impl TextStory { } impl Render for TextStory { - type Element = Div; + type Element = Component; + + fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { + StoryContainer::new("Text Story", "crates/storybook2/src/stories/text.rs") + .children( + vec![ - fn render(&mut self, _cx: &mut gpui::ViewContext) -> Self::Element { - Story::container2::("crates/storybook2/src/stories/text.rs").child( StorySection::new() .child( StoryItem::new("Default", div().bg(gpui::blue()).child("Hello World!")) @@ -71,10 +77,44 @@ impl Render for TextStory { "## }) ) - ) + .child( + StoryItem::new("Interactive Text", + InteractiveText::new( + "interactive", + StyledText::new("Hello world, how is it going?").with_highlights(&cx.text_style(), [ + (6..11, HighlightStyle { + background_color: Some(green()), + ..Default::default() + }), + ]), + ) + .on_click(vec![2..4, 1..3, 7..9], |range_ix, _cx| { + println!("Clicked range {range_ix}"); + }) + ) + .usage(indoc! {r##" + InteractiveText::new( + "interactive", + StyledText::new("Hello world, how is it going?").with_highlights(&cx.text_style(), [ + (6..11, HighlightStyle { + background_color: Some(green()), + ..Default::default() + }), + ]), + ) + .on_click(vec![2..4, 1..3, 7..9], |range_ix, _cx| { + println!("Clicked range {range_ix}"); + }) + "## + }) + ) + ] + ).into_element() } } +// TODO: Check all were updated to new style and remove + // impl Render for TextStory { // type Element = Div; From 936c78be941cbf6948b93c81e6e9ca07def9f4f2 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 14 Dec 2023 17:51:08 -0500 Subject: [PATCH 040/644] WIP IconButton story --- crates/storybook2/src/stories/text.rs | 2 +- .../ui2/src/components/stories/icon_button.rs | 214 +++++++++++++----- 2 files changed, 163 insertions(+), 53 deletions(-) diff --git a/crates/storybook2/src/stories/text.rs b/crates/storybook2/src/stories/text.rs index 7c1d29a2693dd6ba5dd83dfdbbe0030dea261d42..99d722988d086d932c6bd734992720273f02e2e3 100644 --- a/crates/storybook2/src/stories/text.rs +++ b/crates/storybook2/src/stories/text.rs @@ -1,5 +1,5 @@ use gpui::{ - div, green, red, Component, Div, HighlightStyle, InteractiveText, IntoElement, ParentElement, + div, green, red, Component, HighlightStyle, InteractiveText, IntoElement, ParentElement, Render, Styled, StyledText, View, VisualContext, WindowContext, }; use indoc::indoc; diff --git a/crates/ui2/src/components/stories/icon_button.rs b/crates/ui2/src/components/stories/icon_button.rs index 583f453d188b9df5aaaf71b5bb1897814c0a6f51..5391f0ac182c1a2a0d02bdead7350f46b45c1f6c 100644 --- a/crates/ui2/src/components/stories/icon_button.rs +++ b/crates/ui2/src/components/stories/icon_button.rs @@ -1,5 +1,5 @@ -use gpui::{Div, Render}; -use story::Story; +use gpui::{Component, Div, Render}; +use story::{Story, StoryContainer, StoryItem, StorySection}; use crate::{prelude::*, Tooltip}; use crate::{Icon, IconButton}; @@ -7,57 +7,167 @@ use crate::{Icon, IconButton}; pub struct IconButtonStory; impl Render for IconButtonStory { - type Element = Div; + type Element = Component; fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { - Story::container() - .child(Story::title_for::()) - .child(Story::label("Default")) - .child(div().w_8().child(IconButton::new("icon_a", Icon::Hash))) - .child(Story::label("Selected")) - .child( - div() - .w_8() - .child(IconButton::new("icon_a", Icon::Hash).selected(true)), - ) - .child(Story::label("Selected with `selected_icon`")) - .child( - div().w_8().child( - IconButton::new("icon_a", Icon::AudioOn) - .selected(true) - .selected_icon(Icon::AudioOff), - ), - ) - .child(Story::label("Disabled")) - .child( - div() - .w_8() - .child(IconButton::new("icon_a", Icon::Hash).disabled(true)), - ) - .child(Story::label("With `on_click`")) - .child( - div() - .w_8() - .child( - IconButton::new("with_on_click", Icon::Ai).on_click(|_event, _cx| { - println!("Clicked!"); - }), - ), - ) - .child(Story::label("With `tooltip`")) - .child( - div().w_8().child( - IconButton::new("with_tooltip", Icon::MessageBubbles) - .tooltip(|cx| Tooltip::text("Open messages", cx)), - ), - ) - .child(Story::label("Selected with `tooltip`")) - .child( - div().w_8().child( - IconButton::new("selected_with_tooltip", Icon::InlayHint) - .selected(true) - .tooltip(|cx| Tooltip::text("Toggle inlay hints", cx)), - ), - ) + let default_button = StoryItem::new( + "Default", + IconButton::new("default_icon_button", Icon::Hash), + ) + .description("Displays an icon button.") + .usage( + r#" + IconButton::new("default_icon_button", Icon::Hash) + "#, + ); + + let selected_button = StoryItem::new( + "Selected", + IconButton::new("selected_icon_button", Icon::Hash).selected(true), + ) + .description("Displays an icon button that is selected.") + .usage( + r#" + IconButton::new("selected_icon_button", Icon::Hash).selected(true) + "#, + ); + + let selected_with_selected_icon = StoryItem::new( + "Selected with `selected_icon`", + IconButton::new("selected_with_selected_icon_button", Icon::AudioOn) + .selected(true) + .selected_icon(Icon::AudioOff), + ) + .description( + "Displays an icon button that is selected and shows a different icon when selected.", + ) + .usage( + r#" + IconButton::new("selected_with_selected_icon_button", Icon::AudioOn) + .selected(true) + .selected_icon(Icon::AudioOff) + "#, + ); + + let disabled_button = StoryItem::new( + "Disabled", + IconButton::new("disabled_icon_button", Icon::Hash).disabled(true), + ) + .description("Displays an icon button that is disabled.") + .usage( + r#" + IconButton::new("disabled_icon_button", Icon::Hash).disabled(true) + "#, + ); + + let with_on_click_button = StoryItem::new( + "With `on_click`", + IconButton::new("with_on_click_button", Icon::Ai).on_click(|_event, _cx| { + println!("Clicked!"); + }), + ) + .description("Displays an icon button which triggers an event on click.") + .usage( + r#" + IconButton::new("with_on_click_button", Icon::Ai).on_click(|_event, _cx| { + println!("Clicked!"); + }) + "#, + ); + + let with_tooltip_button = StoryItem::new( + "With `tooltip`", + IconButton::new("with_tooltip_button", Icon::MessageBubbles) + .tooltip(|cx| Tooltip::text("Open messages", cx)), + ) + .description("Displays an icon button that has a tooltip when hovered.") + .usage( + r#" + IconButton::new("with_tooltip_button", Icon::MessageBubbles) + .tooltip(|cx| Tooltip::text("Open messages", cx)) + "#, + ); + + let selected_with_tooltip_button = StoryItem::new( + "Selected with `tooltip`", + IconButton::new("selected_with_tooltip_button", Icon::InlayHint) + .selected(true) + .tooltip(|cx| Tooltip::text("Toggle inlay hints", cx)), + ) + .description("Displays a selected icon button with tooltip.") + .usage( + r#" + IconButton::new("selected_with_tooltip_button", Icon::InlayHint) + .selected(true) + .tooltip(|cx| Tooltip::text("Toggle inlay hints", cx)) + "#, + ); + + let buttons = vec![ + default_button, + selected_button, + selected_with_selected_icon, + disabled_button, + with_on_click_button, + with_tooltip_button, + selected_with_tooltip_button, + ]; + + StoryContainer::new( + "Icon Button", + "crates/ui2/src/components/stories/icon_button.rs", + ) + .children(vec![StorySection::new().children(buttons)]) + .into_element() + + // Story::container() + // .child(Story::title_for::()) + // .child(Story::label("Default")) + // .child(div().w_8().child(IconButton::new("icon_a", Icon::Hash))) + // .child(Story::label("Selected")) + // .child( + // div() + // .w_8() + // .child(IconButton::new("icon_a", Icon::Hash).selected(true)), + // ) + // .child(Story::label("Selected with `selected_icon`")) + // .child( + // div().w_8().child( + // IconButton::new("icon_a", Icon::AudioOn) + // .selected(true) + // .selected_icon(Icon::AudioOff), + // ), + // ) + // .child(Story::label("Disabled")) + // .child( + // div() + // .w_8() + // .child(IconButton::new("icon_a", Icon::Hash).disabled(true)), + // ) + // .child(Story::label("With `on_click`")) + // .child( + // div() + // .w_8() + // .child( + // IconButton::new("with_on_click", Icon::Ai).on_click(|_event, _cx| { + // println!("Clicked!"); + // }), + // ), + // ) + // .child(Story::label("With `tooltip`")) + // .child( + // div().w_8().child( + // IconButton::new("with_tooltip", Icon::MessageBubbles) + // .tooltip(|cx| Tooltip::text("Open messages", cx)), + // ), + // ) + // .child(Story::label("Selected with `tooltip`")) + // .child( + // div().w_8().child( + // IconButton::new("selected_with_tooltip", Icon::InlayHint) + // .selected(true) + // .tooltip(|cx| Tooltip::text("Toggle inlay hints", cx)), + // ), + // ) } } From e4f9bddbab32140f23840037a3d8989bc665aecc Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 14 Dec 2023 17:56:42 -0500 Subject: [PATCH 041/644] Remove unused imports --- crates/ui2/src/components/stories/icon_button.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ui2/src/components/stories/icon_button.rs b/crates/ui2/src/components/stories/icon_button.rs index 5391f0ac182c1a2a0d02bdead7350f46b45c1f6c..0d219efbc2fe72ac4e7695e2f86bf305d26c5537 100644 --- a/crates/ui2/src/components/stories/icon_button.rs +++ b/crates/ui2/src/components/stories/icon_button.rs @@ -1,5 +1,5 @@ -use gpui::{Component, Div, Render}; -use story::{Story, StoryContainer, StoryItem, StorySection}; +use gpui::{Component, Render}; +use story::{StoryContainer, StoryItem, StorySection}; use crate::{prelude::*, Tooltip}; use crate::{Icon, IconButton}; From 4c63c74f920d11cff2ecefabd9e09fb001d076d1 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 14 Dec 2023 15:23:24 -0800 Subject: [PATCH 042/644] Fix bug in drag move dispatch co-authored-by: conrad --- crates/gpui2/src/elements/div.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 395afdcc8846b8ee5a256bf59b3fb0ee2639acf3..1019e5f5e6379d9f28e330de153ccb3496c1bc14 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -213,7 +213,7 @@ pub trait InteractiveElement: Sized { listener: impl Fn(&DragMoveEvent, &mut WindowContext) + 'static, ) -> Self where - T: Render, + T: 'static, { self.interactivity().mouse_move_listeners.push(Box::new( move |event, bounds, phase, cx| { @@ -223,7 +223,7 @@ pub trait InteractiveElement: Sized { if cx .active_drag .as_ref() - .is_some_and(|drag| drag.value.type_id() == TypeId::of::()) + .is_some_and(|drag| (*drag.value).type_id() == TypeId::of::()) { (listener)( &DragMoveEvent { From bc3e6649f87ab468e0a564857dbeb23915cf0ef4 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 14 Dec 2023 18:52:14 -0500 Subject: [PATCH 043/644] Fix warning in release mode (#3662) This PR fixes a warning that was present in release mode, which was preventing the nightly builds from running: ``` error: variable does not need to be mutable --> crates/gpui2/src/elements/div.rs:547:9 | 547 | let mut div = Div { | ----^^^ | | | help: remove this `mut` | = note: `-D unused-mut` implied by `-D warnings` ``` Release Notes: - N/A --- crates/gpui2/src/elements/div.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 395afdcc8846b8ee5a256bf59b3fb0ee2639acf3..257ba64b8c325e634fbb6d52799b8ddae8e19e4e 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -544,17 +544,20 @@ pub type ActionListener = Box Div { - let mut div = Div { - interactivity: Interactivity::default(), - children: SmallVec::default(), + #[cfg(debug_assertions)] + let interactivity = { + let mut interactivity = Interactivity::default(); + interactivity.location = Some(*core::panic::Location::caller()); + interactivity }; - #[cfg(debug_assertions)] - { - div.interactivity.location = Some(*core::panic::Location::caller()); - } + #[cfg(not(debug_assertions))] + let interactivity = Interactivity::default(); - div + Div { + interactivity, + children: SmallVec::default(), + } } pub struct Div { From 8b4cf383798fd288f2e0c189b0f3af69b50775e3 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 14 Dec 2023 15:53:06 -0800 Subject: [PATCH 044/644] Fix dock resize handles co-authored-by: conrad --- crates/gpui2/src/elements/canvas.rs | 8 +++--- crates/workspace2/src/dock.rs | 39 ++++++++++++++++++----------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/crates/gpui2/src/elements/canvas.rs b/crates/gpui2/src/elements/canvas.rs index b3afd335d41d4544267a9453e8ffedea5c990b18..6a7d68e831bbc6809a96ccd367ceb85c67bcbf7d 100644 --- a/crates/gpui2/src/elements/canvas.rs +++ b/crates/gpui2/src/elements/canvas.rs @@ -27,7 +27,7 @@ impl IntoElement for Canvas { } impl Element for Canvas { - type State = (); + type State = Style; fn layout( &mut self, @@ -37,11 +37,11 @@ impl Element for Canvas { let mut style = Style::default(); style.refine(&self.style); let layout_id = cx.request_layout(&style, []); - (layout_id, ()) + (layout_id, style) } - fn paint(self, bounds: Bounds, _: &mut (), cx: &mut WindowContext) { - (self.paint_callback)(&bounds, cx) + fn paint(self, bounds: Bounds, style: &mut Style, cx: &mut WindowContext) { + style.paint(bounds, cx, |cx| (self.paint_callback)(&bounds, cx)); } } diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 54480f0b68748870530425f7b6d7910a065f2a0e..f76bb82177084f2e638e31e0e88bad8a3552a182 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -486,12 +486,9 @@ impl Render for Dock { if let Some(entry) = self.visible_entry() { let size = entry.panel.size(cx); - let mut pre_resize_handle = None; - let mut post_resize_handle = None; let position = self.position; - let handler = div() + let mut handle = div() .id("resize-handle") - .bg(cx.theme().colors().border) .on_drag(DraggedDock(position), |dock, cx| { cx.build_view(|_| dock.clone()) }) @@ -506,16 +503,31 @@ impl Render for Dock { match self.position() { DockPosition::Left => { - post_resize_handle = - Some(handler.min_w(HANDLE_SIZE).h_full().cursor_col_resize()) + handle = handle + .absolute() + .right(px(0.)) + .top(px(0.)) + .h_full() + .w(HANDLE_SIZE) + .cursor_col_resize(); } DockPosition::Bottom => { - pre_resize_handle = - Some(handler.w_full().min_h(HANDLE_SIZE).cursor_row_resize()) + handle = handle + .absolute() + .top(px(0.)) + .left(px(0.)) + .w_full() + .h(HANDLE_SIZE) + .cursor_row_resize(); } DockPosition::Right => { - pre_resize_handle = - Some(handler.min_w(HANDLE_SIZE).h_full().cursor_col_resize()) + handle = handle + .absolute() + .top(px(0.)) + .left(px(0.)) + .w_full() + .h(HANDLE_SIZE) + .cursor_col_resize(); } } @@ -531,16 +543,15 @@ impl Render for Dock { DockPosition::Right => this.border_l(), DockPosition::Bottom => this.border_t(), }) - .children(pre_resize_handle) .child( div() .map(|this| match self.position().axis() { - Axis::Horizontal => this.min_w(px(size) - HANDLE_SIZE).h_full(), - Axis::Vertical => this.min_h(px(size) - HANDLE_SIZE).w_full(), + Axis::Horizontal => this.min_w(px(size)).h_full(), + Axis::Vertical => this.min_h(px(size)).w_full(), }) .child(entry.panel.to_any()), ) - .children(post_resize_handle) + .child(handle) } else { div() } From ad8165ae797d48db42689424429bc5f2e195edf7 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 14 Dec 2023 17:20:27 -0700 Subject: [PATCH 045/644] Rename draw2 -> draw_and_update_state --- crates/editor2/src/element.rs | 2 +- crates/gpui2/src/element.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 831b6cd35ae8c80282ba312bc965fb8577e99bd3..0f1b565b9d818504e905ca2a668578ffafc04069 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -933,7 +933,7 @@ impl EditorElement { cx.stop_propagation(); }, )) - .draw2( + .draw_and_update_state( fold_bounds.origin, fold_bounds.size, cx, diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index f4bcb17f3c8180be4bef821092d6ef7ea1b0f88d..b446c2fe86eb4bd4ce12ddc183d55f58262aeaa9 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -23,7 +23,7 @@ pub trait IntoElement: Sized { self.into_element().into_any() } - fn draw2( + fn draw_and_update_state( self, origin: Point, available_space: Size, From d6383ab0c629e09bc5f8177e0db0fcc6e7dcfd06 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 14 Dec 2023 16:20:19 -0800 Subject: [PATCH 046/644] Fix stickiness of main pane drag target Reimplement the pane drag targets using on_drag_move --- crates/gpui2/src/elements/div.rs | 6 +- crates/workspace2/src/pane.rs | 196 ++++++++++++++----------------- 2 files changed, 90 insertions(+), 112 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index aa77480944b77ebfa1a3d95b45f3e188ea289dea..fb730a0700dc870b7b5a74953e595848e1396291 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -33,6 +33,7 @@ pub struct GroupStyle { pub struct DragMoveEvent { pub event: MouseMoveEvent, + pub bounds: Bounds, drag: PhantomData, } @@ -208,7 +209,7 @@ pub trait InteractiveElement: Sized { self } - fn on_drag_move( + fn on_drag_move( mut self, listener: impl Fn(&DragMoveEvent, &mut WindowContext) + 'static, ) -> Self @@ -223,11 +224,12 @@ pub trait InteractiveElement: Sized { if cx .active_drag .as_ref() - .is_some_and(|drag| (*drag.value).type_id() == TypeId::of::()) + .is_some_and(|drag| drag.value.as_ref().type_id() == TypeId::of::()) { (listener)( &DragMoveEvent { event: event.clone(), + bounds: bounds.bounds, drag: PhantomData, }, cx, diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 4c436daada47625f8db784f11978129b3b4082c6..712e447905b4d3062ed686a695ddc01529557213 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -8,9 +8,10 @@ use anyhow::Result; use collections::{HashMap, HashSet, VecDeque}; use gpui::{ actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AppContext, - AsyncWindowContext, DismissEvent, Div, EntityId, EventEmitter, FocusHandle, Focusable, - FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel, Render, - ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext, + AsyncWindowContext, DismissEvent, Div, DragMoveEvent, EntityId, EventEmitter, FocusHandle, + Focusable, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel, + Render, ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView, + WindowContext, }; use parking_lot::Mutex; use project::{Project, ProjectEntryId, ProjectPath}; @@ -28,8 +29,8 @@ use std::{ use theme::ThemeSettings; use ui::{ - h_stack, prelude::*, right_click_menu, ButtonSize, Color, Icon, IconButton, IconSize, - Indicator, Label, Tab, TabBar, TabPosition, Tooltip, + prelude::*, right_click_menu, ButtonSize, Color, Icon, IconButton, IconSize, Indicator, Label, + Tab, TabBar, TabPosition, Tooltip, }; use ui::{v_stack, ContextMenu}; use util::{maybe, truncate_and_remove_front, ResultExt}; @@ -179,6 +180,7 @@ pub struct Pane { // tab_context_menu: ViewHandle, workspace: WeakView, project: Model, + drag_split_direction: Option, // can_drop: Rc, &WindowContext) -> bool>, can_split: bool, // render_tab_bar_buttons: Rc) -> AnyElement>, @@ -361,6 +363,7 @@ impl Pane { new_item_menu: None, split_item_menu: None, tab_bar_scroll_handle: ScrollHandle::new(), + drag_split_direction: None, // tab_bar_context_menu: TabBarContextMenu { // kind: TabBarContextMenuKind::New, // handle: context_menu, @@ -1503,9 +1506,11 @@ impl Pane { .drag_over::(|tab| tab.bg(cx.theme().colors().tab_active_background)) .drag_over::(|tab| tab.bg(gpui::red())) .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { + this.drag_split_direction = None; this.handle_tab_drop(dragged_tab, ix, cx) })) .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { + this.drag_split_direction = None; this.handle_project_entry_drop(entry_id, cx) })) .when_some(item.tab_tooltip_text(cx), |tab, text| { @@ -1655,9 +1660,11 @@ impl Pane { }) .drag_over::(|bar| bar.bg(gpui::red())) .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { + this.drag_split_direction = None; this.handle_tab_drop(dragged_tab, this.items.len(), cx) })) .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { + this.drag_split_direction = None; this.handle_project_entry_drop(entry_id, cx) })), ) @@ -1719,18 +1726,42 @@ impl Pane { self.zoomed } + fn handle_drag_move(&mut self, event: &DragMoveEvent, cx: &mut ViewContext) { + let edge_width = cx.rem_size() * 8; + let cursor = event.event.position; + let direction = if cursor.x < event.bounds.left() + edge_width { + Some(SplitDirection::Left) + } else if cursor.x > event.bounds.right() - edge_width { + Some(SplitDirection::Right) + } else if cursor.y < event.bounds.top() + edge_width { + Some(SplitDirection::Up) + } else if cursor.y > event.bounds.bottom() - edge_width { + Some(SplitDirection::Down) + } else { + None + }; + if direction != self.drag_split_direction { + self.drag_split_direction = direction; + cx.notify(); + } + } + fn handle_tab_drop( &mut self, dragged_tab: &DraggedTab, ix: usize, cx: &mut ViewContext<'_, Pane>, ) { + let mut to_pane = cx.view().clone(); + let split_direction = self.drag_split_direction; let item_id = dragged_tab.item_id; let from_pane = dragged_tab.pane.clone(); - let to_pane = cx.view().clone(); self.workspace .update(cx, |_, cx| { cx.defer(move |workspace, cx| { + if let Some(split_direction) = split_direction { + to_pane = workspace.split_pane(to_pane, split_direction, cx); + } workspace.move_item(from_pane, to_pane, item_id, ix, cx); }); }) @@ -1742,52 +1773,9 @@ impl Pane { project_entry_id: &ProjectEntryId, cx: &mut ViewContext<'_, Pane>, ) { - let to_pane = cx.view().downgrade(); - let project_entry_id = *project_entry_id; - self.workspace - .update(cx, |_, cx| { - cx.defer(move |workspace, cx| { - if let Some(path) = workspace - .project() - .read(cx) - .path_for_entry(project_entry_id, cx) - { - workspace - .open_path(path, Some(to_pane), true, cx) - .detach_and_log_err(cx); - } - }); - }) - .log_err(); - } - - fn handle_split_tab_drop( - &mut self, - dragged_tab: &DraggedTab, - split_direction: SplitDirection, - cx: &mut ViewContext<'_, Pane>, - ) { - let item_id = dragged_tab.item_id; - let from_pane = dragged_tab.pane.clone(); - let to_pane = cx.view().clone(); - self.workspace - .update(cx, |_, cx| { - cx.defer(move |workspace, cx| { - let pane = workspace.split_pane(to_pane, split_direction, cx); - workspace.move_item(from_pane, pane, item_id, 0, cx); - }); - }) - .log_err(); - } - - fn handle_split_project_entry_drop( - &mut self, - project_entry_id: &ProjectEntryId, - split_direction: SplitDirection, - cx: &mut ViewContext<'_, Pane>, - ) { + let mut to_pane = cx.view().clone(); + let split_direction = self.drag_split_direction; let project_entry_id = *project_entry_id; - let current_pane = cx.view().clone(); self.workspace .update(cx, |_, cx| { cx.defer(move |workspace, cx| { @@ -1796,9 +1784,11 @@ impl Pane { .read(cx) .path_for_entry(project_entry_id, cx) { - let pane = workspace.split_pane(current_pane, split_direction, cx); + if let Some(split_direction) = split_direction { + to_pane = workspace.split_pane(to_pane, split_direction, cx); + } workspace - .open_path(path, Some(pane.downgrade()), true, cx) + .open_path(path, Some(to_pane.downgrade()), true, cx) .detach_and_log_err(cx); } }); @@ -1817,6 +1807,9 @@ impl Render for Pane { type Element = Focusable
; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + let mut drag_target_color = cx.theme().colors().text; + drag_target_color.a = 0.5; + v_stack() .key_context("Pane") .track_focus(&self.focus_handle) @@ -1894,71 +1887,54 @@ impl Render for Pane { }), ) .child(self.render_tab_bar(cx)) - .child(self.toolbar.clone()) - .child(if let Some(item) = self.active_item() { - let mut drag_target_color = cx.theme().colors().text; - drag_target_color.a = 0.5; - - div() - .flex() + .child( + // main content + v_stack() .flex_1() .relative() - .child(item.to_any()) + .group("") + .on_drag_move::(cx.listener(Self::handle_drag_move)) + .on_drag_move::(cx.listener(Self::handle_drag_move)) + .child(self.toolbar.clone()) + .map(|div| { + if let Some(item) = self.active_item() { + div.child(item.to_any()) + } else { + div.items_center().size_full().justify_center().child( + Label::new("Open a file or project to get started.") + .color(Color::Muted), + ) + } + }) .child( + // drag target div() + .invisible() .absolute() - .full() - .z_index(1) - .drag_over::(|style| style.bg(drag_target_color)) - .drag_over::(|style| style.bg(gpui::red())) - .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { + .bg(drag_target_color) + .group_drag_over::("", |style| style.visible()) + .group_drag_over::("", |style| style.visible()) + .on_drop(cx.listener(move |this, dragged_tab, cx| { this.handle_tab_drop(dragged_tab, this.active_item_index(), cx) })) - .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { + .on_drop(cx.listener(move |this, entry_id, cx| { this.handle_project_entry_drop(entry_id, cx) - })), - ) - .children( - [ - (SplitDirection::Up, 2), - (SplitDirection::Down, 2), - (SplitDirection::Left, 3), - (SplitDirection::Right, 3), - ] - .into_iter() - .map(|(direction, z_index)| { - let div = div() - .absolute() - .z_index(z_index) - .invisible() - .bg(drag_target_color) - .drag_over::(|style| style.visible()) - .drag_over::(|style| style.visible()) - .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { - this.handle_split_tab_drop(dragged_tab, direction, cx) - })) - .on_drop(cx.listener( - move |this, entry_id: &ProjectEntryId, cx| { - this.handle_split_project_entry_drop( - entry_id, direction, cx, - ) - }, - )); - match direction { - SplitDirection::Up => div.top_0().left_0().right_0().h_32(), - SplitDirection::Down => div.left_0().bottom_0().right_0().h_32(), - SplitDirection::Left => div.top_0().left_0().bottom_0().w_32(), - SplitDirection::Right => div.top_0().bottom_0().right_0().w_32(), - } - }), - ) - } else { - h_stack() - .items_center() - .size_full() - .justify_center() - .child(Label::new("Open a file or project to get started.").color(Color::Muted)) - }) + })) + .map(|div| match self.drag_split_direction { + None => div.full(), + Some(SplitDirection::Up) => div.top_0().left_0().right_0().h_32(), + Some(SplitDirection::Down) => { + div.left_0().bottom_0().right_0().h_32() + } + Some(SplitDirection::Left) => { + div.top_0().left_0().bottom_0().w_32() + } + Some(SplitDirection::Right) => { + div.top_0().bottom_0().right_0().w_32() + } + }), + ), + ) .on_mouse_down( MouseButton::Navigate(NavigationDirection::Back), cx.listener(|pane, _, cx| { From 842f15c65b76d73701a10e4404ee51b4dabb2563 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 14 Dec 2023 16:35:58 -0800 Subject: [PATCH 047/644] Fix centering of empty pane text --- crates/workspace2/src/pane.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 712e447905b4d3062ed686a695ddc01529557213..6b5a131ea0387fb9a0db9444a93122ce75388c6d 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1889,21 +1889,27 @@ impl Render for Pane { .child(self.render_tab_bar(cx)) .child( // main content - v_stack() + div() .flex_1() .relative() .group("") .on_drag_move::(cx.listener(Self::handle_drag_move)) .on_drag_move::(cx.listener(Self::handle_drag_move)) - .child(self.toolbar.clone()) .map(|div| { if let Some(item) = self.active_item() { - div.child(item.to_any()) + div.flex_col() + .child(self.toolbar.clone()) + .child(item.to_any()) } else { - div.items_center().size_full().justify_center().child( - Label::new("Open a file or project to get started.") - .color(Color::Muted), - ) + div.flex() + .flex_row() + .items_center() + .size_full() + .justify_center() + .child( + Label::new("Open a file or project to get started.") + .color(Color::Muted), + ) } }) .child( From 52b9fc303b6393712ec06f5113ce2c1c59e5dad3 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 14 Dec 2023 16:52:03 -0800 Subject: [PATCH 048/644] Fix overlay rendering when dragging onto the center of a pane --- crates/workspace2/src/pane.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 6b5a131ea0387fb9a0db9444a93122ce75388c6d..11588212ef76e3891c57fc5a14778fd8e48a9e37 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1927,7 +1927,7 @@ impl Render for Pane { this.handle_project_entry_drop(entry_id, cx) })) .map(|div| match self.drag_split_direction { - None => div.full(), + None => div.top_0().left_0().right_0().bottom_0(), Some(SplitDirection::Up) => div.top_0().left_0().right_0().h_32(), Some(SplitDirection::Down) => { div.left_0().bottom_0().right_0().h_32() From ead52067412636f9ad09663313a894d3f5635ad4 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 14 Dec 2023 17:00:07 -0800 Subject: [PATCH 049/644] Fix todos in auto-update --- crates/auto_update2/src/auto_update.rs | 19 ++++++------------- .../auto_update2/src/update_notification.rs | 6 ++++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/crates/auto_update2/src/auto_update.rs b/crates/auto_update2/src/auto_update.rs index 31e474242ac7fd9cf918a785b35620ae7764df0e..4bf2bca0633ef1d9199750c38ae2c2d4ed0b2651 100644 --- a/crates/auto_update2/src/auto_update.rs +++ b/crates/auto_update2/src/auto_update.rs @@ -9,12 +9,14 @@ use gpui::{ ViewContext, VisualContext, }; use isahc::AsyncBody; + use serde::Deserialize; use serde_derive::Serialize; use smol::io::AsyncReadExt; use settings::{Settings, SettingsStore}; use smol::{fs::File, process::Command}; + use std::{ffi::OsString, sync::Arc, time::Duration}; use update_notification::UpdateNotification; use util::channel::{AppCommitSha, ReleaseChannel}; @@ -24,16 +26,7 @@ use workspace::Workspace; const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification"; const POLL_INTERVAL: Duration = Duration::from_secs(60 * 60); -//todo!(remove CheckThatAutoUpdaterWorks) -actions!( - auto_update, - [ - Check, - DismissErrorMessage, - ViewReleaseNotes, - CheckThatAutoUpdaterWorks - ] -); +actions!(auto_update, [Check, DismissErrorMessage, ViewReleaseNotes]); #[derive(Serialize)] struct UpdateRequestBody { @@ -90,7 +83,10 @@ pub fn init(http_client: Arc, server_url: String, cx: &mut AppCo cx.observe_new_views(|workspace: &mut Workspace, _cx| { workspace.register_action(|_, action: &Check, cx| check(action, cx)); + workspace.register_action(|_, action, cx| view_release_notes(action, cx)); + // @nate - code to trigger update notification on launch + // todo!("remove this when Nate is done") // workspace.show_notification(0, _cx, |cx| { // cx.build_view(|_| UpdateNotification::new(SemanticVersion::from_str("1.1.1").unwrap())) // }); @@ -119,9 +115,6 @@ pub fn init(http_client: Arc, server_url: String, cx: &mut AppCo updater }); cx.set_global(Some(auto_updater)); - //todo!(action) - // cx.add_global_action(view_release_notes); - // cx.add_action(UpdateNotification::dismiss); } } diff --git a/crates/auto_update2/src/update_notification.rs b/crates/auto_update2/src/update_notification.rs index 4a2efcf8076bb882a67c1f25b6300dd4cd48c1d1..8bb08912b01a13712afe2dbc14e34a9abd49bc24 100644 --- a/crates/auto_update2/src/update_notification.rs +++ b/crates/auto_update2/src/update_notification.rs @@ -2,6 +2,7 @@ use gpui::{ div, DismissEvent, Div, EventEmitter, InteractiveElement, ParentElement, Render, SemanticVersion, StatefulInteractiveElement, Styled, ViewContext, }; +use menu::Cancel; use util::channel::ReleaseChannel; use workspace::ui::{h_stack, v_stack, Icon, IconElement, Label, StyledExt}; @@ -18,6 +19,7 @@ impl Render for UpdateNotification { let app_name = cx.global::().display_name(); v_stack() + .on_action(cx.listener(UpdateNotification::dismiss)) .elevation_3(cx) .p_4() .child( @@ -32,7 +34,7 @@ impl Render for UpdateNotification { .id("cancel") .child(IconElement::new(Icon::Close)) .cursor_pointer() - .on_click(cx.listener(|this, _, cx| this.dismiss(cx))), + .on_click(cx.listener(|this, _, cx| this.dismiss(&menu::Cancel, cx))), ), ) .child( @@ -50,7 +52,7 @@ impl UpdateNotification { Self { version } } - pub fn dismiss(&mut self, cx: &mut ViewContext) { + pub fn dismiss(&mut self, _: &Cancel, cx: &mut ViewContext) { cx.emit(DismissEvent); } } From 6973b1b592cb77954c7324bf1b1216084cf6e8b5 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 14 Dec 2023 17:48:49 -0800 Subject: [PATCH 050/644] Add several red outlines --- crates/collab_ui2/src/collab_panel.rs | 23 +++- .../src/collab_panel/contact_finder.rs | 39 +------ crates/collab_ui2/src/collab_titlebar_item.rs | 106 ++++++++++-------- 3 files changed, 79 insertions(+), 89 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 65a994e6d94326e19245cb68120c1fdb35ea335b..4edf5ef35ba4495d5f3ef4922414d0f79cd46d7c 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2142,7 +2142,7 @@ impl CollabPanel { } fn render_signed_out(&mut self, cx: &mut ViewContext) -> Div { - v_stack().child( + v_stack().border_1().border_color(gpui::red()).child( Button::new("sign_in", "Sign in to collaborate").on_click(cx.listener( |this, _, cx| { let client = this.client.clone(); @@ -2301,9 +2301,14 @@ impl CollabPanel { .into_any_element() }), Section::Contacts => Some( - IconButton::new("add-contact", Icon::Plus) - .on_click(cx.listener(|this, _, cx| this.toggle_contact_finder(cx))) - .tooltip(|cx| Tooltip::text("Search for new contact", cx)) + div() + .border_1() + .border_color(gpui::red()) + .child( + IconButton::new("add-contact", Icon::Plus) + .on_click(cx.listener(|this, _, cx| this.toggle_contact_finder(cx))) + .tooltip(|cx| Tooltip::text("Search for new contact", cx)), + ) .into_any_element(), ), Section::Channels => Some( @@ -2323,7 +2328,7 @@ impl CollabPanel { | Section::Offline => true, }; - h_stack() + let mut row = h_stack() .w_full() .group("section-header") .child( @@ -2350,7 +2355,13 @@ impl CollabPanel { .detach_and_log_err(cx) }, )) - }) + }); + + if section == Section::Offline { + row = div().border_1().border_color(gpui::red()).child(row); + } + + row } fn render_contact( diff --git a/crates/collab_ui2/src/collab_panel/contact_finder.rs b/crates/collab_ui2/src/collab_panel/contact_finder.rs index bd0c5d4b074beef1e8a433c03eec71df4a2d2c7c..3087e6812f2afe93e2ba11a4a9bd836af8ec899a 100644 --- a/crates/collab_ui2/src/collab_panel/contact_finder.rs +++ b/crates/collab_ui2/src/collab_panel/contact_finder.rs @@ -11,14 +11,8 @@ use ui::{prelude::*, Avatar}; use util::{ResultExt as _, TryFutureExt}; use workspace::ModalView; -pub fn init(cx: &mut AppContext) { - //Picker::::init(cx); - //cx.add_action(ContactFinder::dismiss) -} - pub struct ContactFinder { picker: View>, - has_focus: bool, } impl ContactFinder { @@ -31,16 +25,12 @@ impl ContactFinder { }; let picker = cx.build_view(|cx| Picker::new(delegate, cx)); - Self { - picker, - has_focus: false, - } + Self { picker } } pub fn set_query(&mut self, query: String, cx: &mut ViewContext) { self.picker.update(cx, |picker, cx| { - // todo!() - // picker.set_query(query, cx); + picker.set_query(query, cx); }); } } @@ -62,32 +52,9 @@ impl Render for ContactFinder { .w(rems(34.)) } - // fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext) { - // self.has_focus = true; - // if cx.is_self_focused() { - // cx.focus(&self.picker) - // } - // } - - // fn focus_out(&mut self, _: gpui::AnyViewHandle, _: &mut ViewContext) { - // self.has_focus = false; - // } - type Element = Div; } -// impl Modal for ContactFinder { -// fn has_focus(&self) -> bool { -// self.has_focus -// } - -// fn dismiss_on_event(event: &Self::Event) -> bool { -// match event { -// PickerEvent::Dismiss => true, -// } -// } -// } - pub struct ContactFinderDelegate { parent: WeakView, potential_contacts: Arc<[Arc]>, @@ -161,7 +128,6 @@ impl PickerDelegate for ContactFinderDelegate { } fn dismissed(&mut self, cx: &mut ViewContext>) { - //cx.emit(PickerEvent::Dismiss); self.parent .update(cx, |_, cx| cx.emit(DismissEvent)) .log_err(); @@ -191,6 +157,7 @@ impl PickerDelegate for ContactFinderDelegate { .child(Label::new(user.github_login.clone())) .children(icon_path.map(|icon_path| svg().path(icon_path))), ) + // todo!() // Flex::row() // .with_children(user.avatar.clone().map(|avatar| { // Image::from_data(avatar) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 5b3d4c0942f30b33332f3be7913244eec8cd1dd9..2c48a66a1d7be20e155c08df1179eb203cddd614 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -233,56 +233,68 @@ impl Render for CollabTitlebarItem { }), ) }) - .child(h_stack().px_1p5().map(|this| { - if let Some(user) = current_user { - // TODO: Finish implementing user menu popover - // - this.child( - popover_menu("user-menu") - .menu(|cx| { - ContextMenu::build(cx, |menu, _| menu.header("ADADA")) - }) - .trigger( - ButtonLike::new("user-menu") - .child( - h_stack() - .gap_0p5() - .child(Avatar::new(user.avatar_uri.clone())) + .child( + h_stack() + .border_color(gpui::red()) + .border_1() + .px_1p5() + .map(|this| { + if let Some(user) = current_user { + // TODO: Finish implementing user menu popover + // + this.child( + popover_menu("user-menu") + .menu(|cx| { + ContextMenu::build(cx, |menu, _| { + menu.header("ADADA") + }) + }) + .trigger( + ButtonLike::new("user-menu") .child( - IconElement::new(Icon::ChevronDown) - .color(Color::Muted), - ), + h_stack() + .gap_0p5() + .child(Avatar::new( + user.avatar_uri.clone(), + )) + .child( + IconElement::new(Icon::ChevronDown) + .color(Color::Muted), + ), + ) + .style(ButtonStyle::Subtle) + .tooltip(move |cx| { + Tooltip::text("Toggle User Menu", cx) + }), ) - .style(ButtonStyle::Subtle) - .tooltip(move |cx| { - Tooltip::text("Toggle User Menu", cx) - }), + .anchor(gpui::AnchorCorner::TopRight), ) - .anchor(gpui::AnchorCorner::TopRight), - ) - // this.child( - // ButtonLike::new("user-menu") - // .child( - // h_stack().gap_0p5().child(Avatar::data(avatar)).child( - // IconElement::new(Icon::ChevronDown).color(Color::Muted), - // ), - // ) - // .style(ButtonStyle::Subtle) - // .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)), - // ) - } else { - this.child(Button::new("sign_in", "Sign in").on_click(move |_, cx| { - let client = client.clone(); - cx.spawn(move |mut cx| async move { - client - .authenticate_and_connect(true, &cx) - .await - .notify_async_err(&mut cx); - }) - .detach(); - })) - } - })), + // this.child( + // ButtonLike::new("user-menu") + // .child( + // h_stack().gap_0p5().child(Avatar::data(avatar)).child( + // IconElement::new(Icon::ChevronDown).color(Color::Muted), + // ), + // ) + // .style(ButtonStyle::Subtle) + // .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)), + // ) + } else { + this.child(Button::new("sign_in", "Sign in").on_click( + move |_, cx| { + let client = client.clone(); + cx.spawn(move |mut cx| async move { + client + .authenticate_and_connect(true, &cx) + .await + .notify_async_err(&mut cx); + }) + .detach(); + }, + )) + } + }), + ), ) } } From fbcaf96ab5bbdb1b47f301206ad91257dcdd2aed Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 14 Dec 2023 20:58:59 -0500 Subject: [PATCH 051/644] Track focus on TestItem --- crates/project_panel2/src/project_panel.rs | 2 +- crates/workspace2/src/item.rs | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index f7789c1a62af282840bc53acdcf5758a6257dd8c..51d04e046848ac60709834b3d36b2dd942616d6b 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -1671,7 +1671,7 @@ mod tests { path::{Path, PathBuf}, sync::atomic::{self, AtomicUsize}, }; - use workspace::{dock::PanelHandle, AppState}; + use workspace::AppState; #[gpui::test] async fn test_visible_list(cx: &mut gpui::TestAppContext) { diff --git a/crates/workspace2/src/item.rs b/crates/workspace2/src/item.rs index c0242ffa170aedfd00516a0ef031988bee16cdcd..30410550fcabd10cd6104b8e2f1b9e6e4e228350 100644 --- a/crates/workspace2/src/item.rs +++ b/crates/workspace2/src/item.rs @@ -760,8 +760,9 @@ pub mod test { use super::{Item, ItemEvent}; use crate::{ItemId, ItemNavHistory, Pane, Workspace, WorkspaceId}; use gpui::{ - AnyElement, AppContext, Context as _, Div, EntityId, EventEmitter, FocusableView, - IntoElement, Model, Render, SharedString, Task, View, ViewContext, VisualContext, WeakView, + AnyElement, AppContext, Context as _, Div, EntityId, EventEmitter, Focusable, + FocusableView, InteractiveElement, IntoElement, Model, Render, SharedString, Task, View, + ViewContext, VisualContext, WeakView, }; use project::{Project, ProjectEntryId, ProjectPath, WorktreeId}; use std::{any::Any, cell::Cell, path::Path}; @@ -909,10 +910,10 @@ pub mod test { } impl Render for TestItem { - type Element = Div; + type Element = Focusable
; fn render(&mut self, _: &mut ViewContext) -> Self::Element { - gpui::div() + gpui::div().track_focus(&self.focus_handle) } } From ff4da878f9d0026f4cfc78c39b2cfdf8433394fa Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 14 Dec 2023 21:33:11 -0500 Subject: [PATCH 052/644] Render panel in these tests --- crates/project_panel2/src/project_panel.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index 51d04e046848ac60709834b3d36b2dd942616d6b..21989dd3ffb4ca6827955e53bf7a296f11391822 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -1927,7 +1927,12 @@ mod tests { let workspace = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let cx = &mut VisualTestContext::from_window(*workspace, cx); let panel = workspace - .update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)) + .update(cx, |workspace, cx| { + let panel = ProjectPanel::new(workspace, cx); + workspace.add_panel(panel.clone(), cx); + workspace.toggle_dock(panel.read(cx).position(cx), cx); + panel + }) .unwrap(); select_path(&panel, "root1", cx); @@ -2556,7 +2561,12 @@ mod tests { let workspace = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let cx = &mut VisualTestContext::from_window(*workspace, cx); let panel = workspace - .update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)) + .update(cx, |workspace, cx| { + let panel = ProjectPanel::new(workspace, cx); + workspace.add_panel(panel.clone(), cx); + workspace.toggle_dock(panel.read(cx).position(cx), cx); + panel + }) .unwrap(); select_path(&panel, "src/", cx); From d4e09230cc103b8366ba58e3c493b1f34857016b Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 14 Dec 2023 22:29:33 -0500 Subject: [PATCH 053/644] Give result-less project search a focus handle --- crates/search2/src/project_search.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index f1b0c16d5708241cd4421e9c7b88d762383ff532..25a44c4da2a4eb023075b06b1b4b2d030a4049ae 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -273,13 +273,15 @@ pub enum ViewEvent { impl EventEmitter for ProjectSearchView {} impl Render for ProjectSearchView { - type Element = Div; + type Element = AnyElement; + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { if self.has_matches() { div() .flex_1() .size_full() .child(self.results_editor.clone()) + .into_any() } else { let model = self.model.read(cx); let has_no_results = model.no_results.unwrap_or(false); @@ -352,14 +354,20 @@ impl Render for ProjectSearchView { .max_w_96() .child(Label::new(text).size(LabelSize::Small)) }); - v_stack().flex_1().size_full().justify_center().child( - h_stack() - .size_full() - .justify_center() - .child(h_stack().flex_1()) - .child(v_stack().child(major_text).children(minor_text)) - .child(h_stack().flex_1()), - ) + v_stack() + .track_focus(&self.query_editor.focus_handle(cx)) + .flex_1() + .size_full() + .justify_center() + .child( + h_stack() + .size_full() + .justify_center() + .child(h_stack().flex_1()) + .child(v_stack().child(major_text).children(minor_text)) + .child(h_stack().flex_1()), + ) + .into_any() } } } From de523c2d8063610034e94ed803317107154a8977 Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 14 Dec 2023 23:49:44 -0500 Subject: [PATCH 054/644] Give correct focus handle when project search has no matches --- crates/gpui2/src/window.rs | 1 - crates/search2/src/project_search.rs | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index e2f53f7347233241d7363a97ad495dcbcc38fcbe..1c0849785b69b3553bed6fff451c47ecec7c2570 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -489,7 +489,6 @@ impl<'a> WindowContext<'a> { #[cfg(any(test, feature = "test-support"))] { - println!("invalidating focus"); self.window.focus_invalidated = true; } diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index da48625b429b28d39be4a2f52336ac8e7c8357e2..167c6fece282f9d7619780497d8c357f7af2eebf 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -378,7 +378,11 @@ impl Render for ProjectSearchView { impl FocusableView for ProjectSearchView { fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle { - self.results_editor.focus_handle(cx) + if self.has_matches() { + self.results_editor.focus_handle(cx) + } else { + self.query_editor.focus_handle(cx) + } } } From a6403aad1a246a5ca1013cac8c5c37407eada436 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 11:28:48 +0200 Subject: [PATCH 055/644] Remove extra nits, do not panic on clicking the buffer separator --- crates/editor2/src/element.rs | 4 ++-- crates/gpui2/src/platform/mac/metal_renderer.rs | 5 ----- crates/gpui2/src/view.rs | 11 ----------- crates/gpui2/src/window.rs | 2 -- 4 files changed, 2 insertions(+), 20 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 0f1b565b9d818504e905ca2a668578ffafc04069..a6d4bc20b157d4f80a816d5dc78eb7980277cdc2 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -2284,8 +2284,8 @@ impl EditorElement { .cursor_pointer() .hover(|style| style.bg(cx.theme().colors().element_hover)) .on_click(cx.listener(|_editor, _event, _cx| { - // TODO: Implement collapsing path headers - todo!("Clicking path header") + // todo!() Implement collapsing path headers + // todo!("Clicking path header") })) .child( h_stack() diff --git a/crates/gpui2/src/platform/mac/metal_renderer.rs b/crates/gpui2/src/platform/mac/metal_renderer.rs index 3210a53c634e81e5410e732c2971c86a553c808f..68768521ee474cd25c2e98c8d38c7ea669fba1e4 100644 --- a/crates/gpui2/src/platform/mac/metal_renderer.rs +++ b/crates/gpui2/src/platform/mac/metal_renderer.rs @@ -187,8 +187,6 @@ impl MetalRenderer { } pub fn draw(&mut self, scene: &Scene) { - let start = std::time::Instant::now(); - let layer = self.layer.clone(); let viewport_size = layer.drawable_size(); let viewport_size: Size = size( @@ -306,9 +304,6 @@ impl MetalRenderer { command_buffer.commit(); self.sprite_atlas.clear_textures(AtlasTextureKind::Path); - let duration_since_start = start.elapsed(); - println!("renderer draw: {:?}", duration_since_start); - command_buffer.wait_until_completed(); drawable.present(); } diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index fb61190731bddf4859e3fcd5ebbc374976a4b9ca..1b4c2b6346fb56320737ab74a8057da589aba354 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -209,20 +209,9 @@ impl AnyView { cx: &mut WindowContext, ) { cx.with_absolute_element_offset(origin, |cx| { - let start_time = std::time::Instant::now(); let (layout_id, mut rendered_element) = (self.layout)(self, cx); - let duration = start_time.elapsed(); - println!("request layout: {:?}", duration); - - let start_time = std::time::Instant::now(); cx.compute_layout(layout_id, available_space); - let duration = start_time.elapsed(); - println!("compute layout: {:?}", duration); - - let start_time = std::time::Instant::now(); (self.paint)(self, &mut rendered_element, cx); - let duration = start_time.elapsed(); - println!("paint: {:?}", duration); }) } } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 1c0849785b69b3553bed6fff451c47ecec7c2570..74c7204048d781a2dd9d01ae95cef28c85b78ab6 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1255,7 +1255,6 @@ impl<'a> WindowContext<'a> { /// Draw pixels to the display for this window based on the contents of its scene. pub(crate) fn draw(&mut self) -> Scene { - let t0 = std::time::Instant::now(); self.window.dirty = false; self.window.drawing = true; @@ -1347,7 +1346,6 @@ impl<'a> WindowContext<'a> { } self.window.drawing = false; - eprintln!("window draw: {:?}", t0.elapsed()); scene } From 31ff7d40ed67ac55d19f1d4b051d27003765e86f Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 11:34:00 +0200 Subject: [PATCH 056/644] Adjust copy/paste buffer only on the copy error action trigger --- crates/editor2/src/editor.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index e58aa1000d475caa009b045b89e36145c69b3894..664d1d7380634426aa4a8264c4ed66aef008c265 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -9739,12 +9739,8 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend }; highlighted_lines.push(line); } - let message = diagnostic.message; Arc::new(move |cx: &mut BlockContext| { - let message = message.clone(); let copy_id: SharedString = format!("copy-{}", cx.block_id.clone()).to_string().into(); - let write_to_clipboard = cx.write_to_clipboard(ClipboardItem::new(message.clone())); - // TODO: Nate: We should tint the background of the block with the severity color // We need to extend the theme before we can do this v_stack() @@ -9754,7 +9750,6 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend .bg(gpui::red()) .children(highlighted_lines.iter().map(|(line, highlights)| { let group_id = cx.block_id.to_string(); - h_stack() .group(group_id.clone()) .gap_2() @@ -9769,7 +9764,12 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend .size(ButtonSize::Compact) .style(ButtonStyle::Transparent) .visible_on_hover(group_id) - .on_click(cx.listener(move |_, _, cx| write_to_clipboard)) + .on_click(cx.listener({ + let message = diagnostic.message.clone(); + move |_, _, cx| { + cx.write_to_clipboard(ClipboardItem::new(message.clone())) + } + })) .tooltip(|cx| Tooltip::text("Copy diagnostic message", cx)), ), ) From 4bfe46f53a6eaacb02a748e8c33ed6ed24e4929c Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 12:15:20 +0200 Subject: [PATCH 057/644] Restore zed1 behavior for buffer search deploy --- crates/search2/src/buffer_search.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index 45495e502700ee65c3015a9f6fd78bc22fe5053c..5db7aff73670161719188a8cff5051c4a4a46604 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -338,7 +338,9 @@ impl BufferSearchBar { pane.update(cx, |this, cx| { this.toolbar().update(cx, |this, cx| { if let Some(search_bar) = this.item_of_type::() { - search_bar.update(cx, |this, cx| this.toggle(deploy, cx)); + search_bar.update(cx, |this, cx| { + this.deploy(deploy, cx); + }); return; } let view = cx.build_view(|cx| BufferSearchBar::new(cx)); @@ -1483,9 +1485,9 @@ mod tests { search_bar.select_all_matches(&SelectAllMatches, cx); }); assert!( - editor.update(cx, |this, cx| !this.is_focused(cx.window_context())), - "Should not switch focus to editor if SelectAllMatches does not find any matches" - ); + editor.update(cx, |this, cx| !this.is_focused(cx.window_context())), + "Should not switch focus to editor if SelectAllMatches does not find any matches" + ); search_bar.update(cx, |search_bar, cx| { let all_selections = editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)); @@ -1651,6 +1653,7 @@ mod tests { assert_eq!(search_bar.search_options, SearchOptions::NONE); }); } + #[gpui::test] async fn test_replace_simple(cx: &mut TestAppContext) { let (editor, search_bar, cx) = init_test(cx); From 2b3d9deabe66e601e8b984a07188ade678e2689d Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 15 Dec 2023 12:07:25 +0100 Subject: [PATCH 058/644] Dismiss Recent Projects & VCS modals on ESC (#3671) Release Notes: - N/A --- crates/recent_projects2/src/recent_projects.rs | 5 ++++- crates/vcs_menu2/src/lib.rs | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/crates/recent_projects2/src/recent_projects.rs b/crates/recent_projects2/src/recent_projects.rs index dff6aa12ccc30f43766451d244619159c2a7c8bb..3ecf1180af535ea23190bd41ad2c8dd0e329810d 100644 --- a/crates/recent_projects2/src/recent_projects.rs +++ b/crates/recent_projects2/src/recent_projects.rs @@ -76,7 +76,10 @@ impl RecentProjects { let delegate = RecentProjectsDelegate::new(weak_workspace, workspace_locations, true); - RecentProjects::new(delegate, cx) + let modal = RecentProjects::new(delegate, cx); + cx.subscribe(&modal.picker, |_, _, _, cx| cx.emit(DismissEvent)) + .detach(); + modal }); } else { workspace.show_notification(0, cx, |cx| { diff --git a/crates/vcs_menu2/src/lib.rs b/crates/vcs_menu2/src/lib.rs index e867e04dcdb96229eb7513f891d60cc31ce1ec26..ca3b685aa60ad93f63cc2ba203fa52a184ff564b 100644 --- a/crates/vcs_menu2/src/lib.rs +++ b/crates/vcs_menu2/src/lib.rs @@ -65,8 +65,13 @@ impl ModalBranchList { ) -> Result<()> { // Modal branch picker has a longer trailoff than a popover one. let delegate = BranchListDelegate::new(workspace, cx.view().clone(), 70, cx)?; - workspace.toggle_modal(cx, |cx| ModalBranchList { - picker: cx.build_view(|cx| Picker::new(delegate, cx)), + workspace.toggle_modal(cx, |cx| { + let modal = ModalBranchList { + picker: cx.build_view(|cx| Picker::new(delegate, cx)), + }; + cx.subscribe(&modal.picker, |_, _, _, cx| cx.emit(DismissEvent)) + .detach(); + modal }); Ok(()) From ff3f4f3027d7c4d03c8c163bac1158829e1af976 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 15 Dec 2023 12:20:54 +0100 Subject: [PATCH 059/644] search: Reintroduce whole word switch (#3672) It seems to have been lost in the recent styling pass. Release Notes: - N/A --- crates/search2/src/project_search.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index 167c6fece282f9d7619780497d8c357f7af2eebf..7bd60891ced8a78902d856a674c502c8c1546f4a 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -1536,13 +1536,30 @@ impl Render for ProjectSearchBar { cx, ) }) - .selected(self.is_option_enabled(SearchOptions::WHOLE_WORD, cx)) + .selected(self.is_option_enabled(SearchOptions::CASE_SENSITIVE, cx)) .on_click(cx.listener( |this, _, cx| { - this.toggle_search_option(SearchOptions::WHOLE_WORD, cx); + this.toggle_search_option( + SearchOptions::CASE_SENSITIVE, + cx, + ); }, )), ) + .child( + IconButton::new("project-search-whole-word", Icon::WholeWord) + .tooltip(|cx| { + Tooltip::for_action( + "Toggle whole word", + &ToggleWholeWord, + cx, + ) + }) + .selected(self.is_option_enabled(SearchOptions::WHOLE_WORD, cx)) + .on_click(cx.listener(|this, _, cx| { + this.toggle_search_option(SearchOptions::WHOLE_WORD, cx); + })), + ) }), ), ); From e1ca8e81bb83c4a45b0f9b2fc7b5adf089697f9f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 15 Dec 2023 15:13:32 +0100 Subject: [PATCH 060/644] Use an Arena to reuse allocations for listeners --- crates/gpui2/src/arena.rs | 124 +++++++++++++++++++++++++++++++ crates/gpui2/src/gpui2.rs | 1 + crates/gpui2/src/key_dispatch.rs | 10 +-- crates/gpui2/src/window.rs | 105 +++++++++++++++----------- 4 files changed, 191 insertions(+), 49 deletions(-) create mode 100644 crates/gpui2/src/arena.rs diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs new file mode 100644 index 0000000000000000000000000000000000000000..cf6b877ba39258838f278b38088c10e19e4c36ee --- /dev/null +++ b/crates/gpui2/src/arena.rs @@ -0,0 +1,124 @@ +use std::{ + alloc, + ptr::{self, NonNull}, +}; + +pub struct Arena { + start: NonNull, + offset: usize, + elements: Vec, +} + +impl Default for Arena { + fn default() -> Self { + unsafe { + let layout = alloc::Layout::from_size_align(16 * 1024 * 1024, 1).unwrap(); + let ptr = alloc::alloc(layout); + Self { + start: NonNull::new_unchecked(ptr), + offset: 0, + elements: Vec::new(), + } + } + } +} + +struct ArenaElement { + value: NonNull, + drop: unsafe fn(NonNull), +} + +impl Arena { + pub fn clear(&mut self) { + for element in self.elements.drain(..) { + unsafe { + (element.drop)(element.value); + } + } + self.offset = 0; + } + + #[inline(always)] + pub fn alloc(&mut self, value: T) -> ArenaRef { + unsafe fn drop(ptr: NonNull) { + std::ptr::drop_in_place(ptr.cast::().as_ptr()); + } + + unsafe { + let layout = alloc::Layout::for_value(&value).pad_to_align(); + let value_ptr = self.start.as_ptr().add(self.offset).cast::(); + ptr::write(value_ptr, value); + + let value = NonNull::new_unchecked(value_ptr); + self.elements.push(ArenaElement { + value: value.cast(), + drop: drop::, + }); + self.offset += layout.size(); + ArenaRef(value) + } + } +} + +pub struct ArenaRef(NonNull); + +impl Copy for ArenaRef {} + +impl Clone for ArenaRef { + fn clone(&self) -> Self { + Self(self.0) + } +} + +impl ArenaRef { + pub unsafe fn map(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaRef { + let u = f(self.get_mut()); + ArenaRef(NonNull::new_unchecked(u)) + } + + pub unsafe fn get_mut(&mut self) -> &mut T { + self.0.as_mut() + } +} + +#[cfg(test)] +mod tests { + use std::{cell::Cell, rc::Rc}; + + use super::*; + + #[test] + fn test_arena() { + let mut arena = Arena::default(); + let mut a = arena.alloc(1u64); + let mut b = arena.alloc(2u32); + let mut c = arena.alloc(3u16); + let mut d = arena.alloc(4u8); + assert_eq!(unsafe { *a.get_mut() }, 1); + assert_eq!(unsafe { *b.get_mut() }, 2); + assert_eq!(unsafe { *c.get_mut() }, 3); + assert_eq!(unsafe { *d.get_mut() }, 4); + + arena.clear(); + let mut a = arena.alloc(5u64); + let mut b = arena.alloc(6u32); + let mut c = arena.alloc(7u16); + let mut d = arena.alloc(8u8); + assert_eq!(unsafe { *a.get_mut() }, 5); + assert_eq!(unsafe { *b.get_mut() }, 6); + assert_eq!(unsafe { *c.get_mut() }, 7); + assert_eq!(unsafe { *d.get_mut() }, 8); + + // Ensure drop gets called. + let dropped = Rc::new(Cell::new(false)); + struct DropGuard(Rc>); + impl Drop for DropGuard { + fn drop(&mut self) { + self.0.set(true); + } + } + arena.alloc(DropGuard(dropped.clone())); + arena.clear(); + assert!(dropped.get()); + } +} diff --git a/crates/gpui2/src/gpui2.rs b/crates/gpui2/src/gpui2.rs index c711d1f5a2d38daeff8bcd86e90595a48114f601..322ca206081af8c58f17fa2b3cdcaf90ffb7ba4b 100644 --- a/crates/gpui2/src/gpui2.rs +++ b/crates/gpui2/src/gpui2.rs @@ -2,6 +2,7 @@ mod action; mod app; +mod arena; mod assets; mod color; mod element; diff --git a/crates/gpui2/src/key_dispatch.rs b/crates/gpui2/src/key_dispatch.rs index ddb1f1e6ca8b4fd4db5d9c317144ca302519aa87..a9d717ea1acb6866ab75165bcc4c6daedd268899 100644 --- a/crates/gpui2/src/key_dispatch.rs +++ b/crates/gpui2/src/key_dispatch.rs @@ -1,6 +1,6 @@ use crate::{ - Action, ActionRegistry, DispatchPhase, FocusId, KeyBinding, KeyContext, KeyMatch, Keymap, - Keystroke, KeystrokeMatcher, WindowContext, + arena::ArenaRef, Action, ActionRegistry, DispatchPhase, FocusId, KeyBinding, KeyContext, + KeyMatch, Keymap, Keystroke, KeystrokeMatcher, WindowContext, }; use collections::HashMap; use parking_lot::Mutex; @@ -33,12 +33,12 @@ pub(crate) struct DispatchNode { parent: Option, } -type KeyListener = Rc; +type KeyListener = ArenaRef; #[derive(Clone)] pub(crate) struct DispatchActionListener { pub(crate) action_type: TypeId, - pub(crate) listener: Rc, + pub(crate) listener: ArenaRef, } impl DispatchTree { @@ -117,7 +117,7 @@ impl DispatchTree { pub fn on_action( &mut self, action_type: TypeId, - listener: Rc, + listener: ArenaRef, ) { self.active_node() .action_listeners diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 1c0849785b69b3553bed6fff451c47ecec7c2570..202489ef0ef74c193ebd71ad468a859c067a6492 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1,15 +1,17 @@ use crate::{ - key_dispatch::DispatchActionListener, px, size, transparent_black, Action, AnyDrag, AnyView, - AppContext, AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, - CursorStyle, DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, - EntityId, EventEmitter, FileDropEvent, Flatten, FontId, GlobalElementId, GlyphId, Hsla, - ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent, LayoutId, - Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent, - Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, - PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, - RenderSvgParams, ScaledPixels, Scene, SceneBuilder, Shadow, SharedString, Size, Style, - SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, - VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS, + arena::{Arena, ArenaRef}, + key_dispatch::DispatchActionListener, + px, size, transparent_black, Action, AnyDrag, AnyView, AppContext, AsyncWindowContext, + AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle, DevicePixels, DispatchNodeId, + DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter, FileDropEvent, Flatten, + FontId, GlobalElementId, GlyphId, Hsla, ImageData, InputEvent, IsZero, KeyBinding, KeyContext, + KeyDownEvent, KeystrokeEvent, LayoutId, Model, ModelContext, Modifiers, MonochromeSprite, + MouseButton, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, + PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, + RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, Scene, SceneBuilder, + Shadow, SharedString, Size, Style, SubscriberSet, Subscription, Surface, TaffyLayoutEngine, + Task, Underline, UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, + SUBPIXEL_VARIANTS, }; use anyhow::{anyhow, Context as _, Result}; use collections::FxHashMap; @@ -85,7 +87,7 @@ impl DispatchPhase { } type AnyObserver = Box bool + 'static>; -type AnyMouseListener = Box; +type AnyMouseListener = ArenaRef; type AnyWindowFocusListener = Box bool + 'static>; struct FocusEvent { @@ -268,9 +270,9 @@ pub(crate) struct ElementStateBox { type_name: &'static str, } -// #[derive(Default)] pub(crate) struct Frame { focus: Option, + arena: Arena, pub(crate) element_states: FxHashMap, mouse_listeners: FxHashMap>, pub(crate) dispatch_tree: DispatchTree, @@ -285,6 +287,7 @@ impl Frame { fn new(dispatch_tree: DispatchTree) -> Self { Frame { focus: None, + arena: Arena::default(), element_states: FxHashMap::default(), mouse_listeners: FxHashMap::default(), dispatch_tree, @@ -299,6 +302,7 @@ impl Frame { fn clear(&mut self) { self.element_states.clear(); self.mouse_listeners.values_mut().for_each(Vec::clear); + self.arena.clear(); self.dispatch_tree.clear(); self.depth_map.clear(); } @@ -818,25 +822,23 @@ impl<'a> WindowContext<'a> { /// Register a mouse event listener on the window for the next frame. The type of event /// is determined by the first parameter of the given listener. When the next frame is rendered /// the listener will be cleared. - /// - /// This is a fairly low-level method, so prefer using event handlers on elements unless you have - /// a specific need to register a global listener. pub fn on_mouse_event( &mut self, mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { let order = self.window.next_frame.z_index_stack.clone(); + let handler = self.window.next_frame.arena.alloc( + move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { + handler(event.downcast_ref().unwrap(), phase, cx) + }, + ); + let handler = unsafe { handler.map(|handler| handler as _) }; self.window .next_frame .mouse_listeners .entry(TypeId::of::()) .or_default() - .push(( - order, - Box::new(move |event: &dyn Any, phase, cx| { - handler(event.downcast_ref().unwrap(), phase, cx) - }), - )) + .push((order, handler)) } /// Register a key event listener on the window for the next frame. The type of event @@ -847,16 +849,17 @@ impl<'a> WindowContext<'a> { /// a specific need to register a global listener. pub fn on_key_event( &mut self, - handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static, + listener: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { - self.window - .next_frame - .dispatch_tree - .on_key_event(Rc::new(move |event, phase, cx| { + let listener = self.window.next_frame.arena.alloc( + move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { if let Some(event) = event.downcast_ref::() { - handler(event, phase, cx) + listener(event, phase, cx) } - })); + }, + ); + let listener = unsafe { listener.map(|handler| handler as _) }; + self.window.next_frame.dispatch_tree.on_key_event(listener); } /// Register an action listener on the window for the next frame. The type of action @@ -868,12 +871,14 @@ impl<'a> WindowContext<'a> { pub fn on_action( &mut self, action_type: TypeId, - handler: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static, + listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static, ) { - self.window.next_frame.dispatch_tree.on_action( - action_type, - Rc::new(move |action, phase, cx| handler(action, phase, cx)), - ); + let listener = self.window.next_frame.arena.alloc(listener); + let listener = unsafe { listener.map(|handler| handler as _) }; + self.window + .next_frame + .dispatch_tree + .on_action(action_type, listener); } pub fn is_action_available(&self, action: &dyn Action) -> bool { @@ -1274,10 +1279,16 @@ impl<'a> WindowContext<'a> { cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| { for (action_type, action_listeners) in &cx.app.global_action_listeners { for action_listener in action_listeners.iter().cloned() { - cx.window.next_frame.dispatch_tree.on_action( - *action_type, - Rc::new(move |action, phase, cx| action_listener(action, phase, cx)), - ) + let listener = cx.window.next_frame.arena.alloc( + move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { + action_listener(action, phase, cx) + }, + ); + let listener = unsafe { listener.map(|listener| listener as _) }; + cx.window + .next_frame + .dispatch_tree + .on_action(*action_type, listener) } } @@ -1460,6 +1471,7 @@ impl<'a> WindowContext<'a> { // Capture phase, events bubble from back to front. Handlers for this phase are used for // special purposes, such as detecting events outside of a given Bounds. for (_, handler) in &mut handlers { + let handler = unsafe { handler.get_mut() }; handler(event, DispatchPhase::Capture, self); if !self.app.propagate_event { break; @@ -1469,6 +1481,7 @@ impl<'a> WindowContext<'a> { // Bubble phase, where most normal handlers do their work. if self.app.propagate_event { for (_, handler) in handlers.iter_mut().rev() { + let handler = unsafe { handler.get_mut() }; handler(event, DispatchPhase::Bubble, self); if !self.app.propagate_event { break; @@ -1518,7 +1531,8 @@ impl<'a> WindowContext<'a> { context_stack.push(context); } - for key_listener in node.key_listeners.clone() { + for mut key_listener in node.key_listeners.clone() { + let key_listener = unsafe { key_listener.get_mut() }; key_listener(event, DispatchPhase::Capture, self); if !self.propagate_event { return; @@ -1530,7 +1544,8 @@ impl<'a> WindowContext<'a> { for node_id in dispatch_path.iter().rev() { // Handle low level key events let node = self.window.rendered_frame.dispatch_tree.node(*node_id); - for key_listener in node.key_listeners.clone() { + for mut key_listener in node.key_listeners.clone() { + let key_listener = unsafe { key_listener.get_mut() }; key_listener(event, DispatchPhase::Bubble, self); if !self.propagate_event { return; @@ -1582,11 +1597,12 @@ impl<'a> WindowContext<'a> { let node = self.window.rendered_frame.dispatch_tree.node(*node_id); for DispatchActionListener { action_type, - listener, + mut listener, } in node.action_listeners.clone() { let any_action = action.as_any(); if action_type == any_action.type_id() { + let listener = unsafe { listener.get_mut() }; listener(any_action, DispatchPhase::Capture, self); if !self.propagate_event { return; @@ -1599,12 +1615,13 @@ impl<'a> WindowContext<'a> { let node = self.window.rendered_frame.dispatch_tree.node(*node_id); for DispatchActionListener { action_type, - listener, + mut listener, } in node.action_listeners.clone() { let any_action = action.as_any(); if action_type == any_action.type_id() { self.propagate_event = false; // Actions stop propagation by default during the bubble phase + let listener = unsafe { listener.get_mut() }; listener(any_action, DispatchPhase::Bubble, self); if !self.propagate_event { return; @@ -2593,13 +2610,13 @@ impl<'a, V: 'static> ViewContext<'a, V> { pub fn on_action( &mut self, action_type: TypeId, - handler: impl Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext) + 'static, + listener: impl Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext) + 'static, ) { let handle = self.view().clone(); self.window_cx .on_action(action_type, move |action, phase, cx| { handle.update(cx, |view, cx| { - handler(view, action, phase, cx); + listener(view, action, phase, cx); }) }); } From be73dd852d2bf1b709bffd971fa2e92d871727fc Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 15 Dec 2023 16:18:05 +0100 Subject: [PATCH 061/644] Move `Arena` to a thread-local and use it to allocate `AnyElement` --- crates/gpui2/src/arena.rs | 4 ++++ crates/gpui2/src/element.rs | 30 ++++++++++++++------------ crates/gpui2/src/window.rs | 43 +++++++++++++++++++++---------------- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index cf6b877ba39258838f278b38088c10e19e4c36ee..0e01c392b76d644c312a1be07980cf3ac8f9ab38 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -76,6 +76,10 @@ impl ArenaRef { ArenaRef(NonNull::new_unchecked(u)) } + pub unsafe fn get(&self) -> &T { + self.0.as_ref() + } + pub unsafe fn get_mut(&mut self) -> &mut T { self.0.as_mut() } diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index b446c2fe86eb4bd4ce12ddc183d55f58262aeaa9..dcb103b61eac80a3376b6d80110e0c6764604555 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -1,6 +1,6 @@ use crate::{ - AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, Size, ViewContext, - WindowContext, + arena::ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, + Size, ViewContext, WindowContext, FRAME_ARENA, }; use derive_more::{Deref, DerefMut}; pub(crate) use smallvec::SmallVec; @@ -405,7 +405,7 @@ where } } -pub struct AnyElement(Box); +pub struct AnyElement(ArenaRef); impl AnyElement { pub fn new(element: E) -> Self @@ -413,15 +413,18 @@ impl AnyElement { E: 'static + Element, E::State: Any, { - AnyElement(Box::new(Some(DrawableElement::new(element))) as Box) + let element = + FRAME_ARENA.with_borrow_mut(|arena| arena.alloc(Some(DrawableElement::new(element)))); + let element = unsafe { element.map(|element| element as &mut dyn ElementObject) }; + AnyElement(element) } pub fn layout(&mut self, cx: &mut WindowContext) -> LayoutId { - self.0.layout(cx) + unsafe { self.0.get_mut() }.layout(cx) } pub fn paint(&mut self, cx: &mut WindowContext) { - self.0.paint(cx) + unsafe { self.0.get_mut() }.paint(cx) } /// Initializes this element and performs layout within the given available space to determine its size. @@ -430,7 +433,7 @@ impl AnyElement { available_space: Size, cx: &mut WindowContext, ) -> Size { - self.0.measure(available_space, cx) + unsafe { self.0.get_mut() }.measure(available_space, cx) } /// Initializes this element and performs layout in the available space, then paints it at the given origin. @@ -440,16 +443,11 @@ impl AnyElement { available_space: Size, cx: &mut WindowContext, ) { - self.0.draw(origin, available_space, cx) - } - - /// Converts this `AnyElement` into a trait object that can be stored and manipulated. - pub fn into_any(self) -> AnyElement { - AnyElement::new(self) + unsafe { self.0.get_mut() }.draw(origin, available_space, cx) } pub fn inner_id(&self) -> Option { - self.0.element_id() + unsafe { self.0.get() }.element_id() } } @@ -480,6 +478,10 @@ impl IntoElement for AnyElement { fn into_element(self) -> Self::Element { self } + + fn into_any_element(self) -> AnyElement { + self + } } /// The empty element, which renders nothing. diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 202489ef0ef74c193ebd71ad468a859c067a6492..74b67503d52390d7878bc198b03c06fd7e9554ee 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -27,6 +27,7 @@ use smallvec::SmallVec; use std::{ any::{Any, TypeId}, borrow::{Borrow, BorrowMut, Cow}, + cell::RefCell, fmt::Debug, future::Future, hash::{Hash, Hasher}, @@ -97,6 +98,10 @@ struct FocusEvent { slotmap::new_key_type! { pub struct FocusId; } +thread_local! { + pub static FRAME_ARENA: RefCell = RefCell::new(Arena::default()); +} + impl FocusId { /// Obtains whether the element associated with this handle is currently focused. pub fn is_focused(&self, cx: &WindowContext) -> bool { @@ -272,7 +277,6 @@ pub(crate) struct ElementStateBox { pub(crate) struct Frame { focus: Option, - arena: Arena, pub(crate) element_states: FxHashMap, mouse_listeners: FxHashMap>, pub(crate) dispatch_tree: DispatchTree, @@ -287,7 +291,6 @@ impl Frame { fn new(dispatch_tree: DispatchTree) -> Self { Frame { focus: None, - arena: Arena::default(), element_states: FxHashMap::default(), mouse_listeners: FxHashMap::default(), dispatch_tree, @@ -302,7 +305,6 @@ impl Frame { fn clear(&mut self) { self.element_states.clear(); self.mouse_listeners.values_mut().for_each(Vec::clear); - self.arena.clear(); self.dispatch_tree.clear(); self.depth_map.clear(); } @@ -827,11 +829,13 @@ impl<'a> WindowContext<'a> { mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { let order = self.window.next_frame.z_index_stack.clone(); - let handler = self.window.next_frame.arena.alloc( - move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { - handler(event.downcast_ref().unwrap(), phase, cx) - }, - ); + let handler = FRAME_ARENA.with_borrow_mut(|arena| { + arena.alloc( + move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { + handler(event.downcast_ref().unwrap(), phase, cx) + }, + ) + }); let handler = unsafe { handler.map(|handler| handler as _) }; self.window .next_frame @@ -851,13 +855,13 @@ impl<'a> WindowContext<'a> { &mut self, listener: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = self.window.next_frame.arena.alloc( - move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { + let listener = FRAME_ARENA.with_borrow_mut(|arena| { + arena.alloc(move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { if let Some(event) = event.downcast_ref::() { listener(event, phase, cx) } - }, - ); + }) + }); let listener = unsafe { listener.map(|handler| handler as _) }; self.window.next_frame.dispatch_tree.on_key_event(listener); } @@ -873,7 +877,7 @@ impl<'a> WindowContext<'a> { action_type: TypeId, listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = self.window.next_frame.arena.alloc(listener); + let listener = FRAME_ARENA.with_borrow_mut(|arena| arena.alloc(listener)); let listener = unsafe { listener.map(|handler| handler as _) }; self.window .next_frame @@ -1273,17 +1277,20 @@ impl<'a> WindowContext<'a> { self.window.platform_window.clear_input_handler(); self.window.layout_engine.as_mut().unwrap().clear(); self.window.next_frame.clear(); + FRAME_ARENA.with_borrow_mut(|arena| arena.clear()); let root_view = self.window.root_view.take().unwrap(); self.with_z_index(0, |cx| { cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| { for (action_type, action_listeners) in &cx.app.global_action_listeners { for action_listener in action_listeners.iter().cloned() { - let listener = cx.window.next_frame.arena.alloc( - move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { - action_listener(action, phase, cx) - }, - ); + let listener = FRAME_ARENA.with_borrow_mut(|arena| { + arena.alloc( + move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { + action_listener(action, phase, cx) + }, + ) + }); let listener = unsafe { listener.map(|listener| listener as _) }; cx.window .next_frame From 3d9e051b07d20ca5009da8d363dea7307dad1d05 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 10:25:07 -0500 Subject: [PATCH 062/644] Update storybook2.rs --- crates/storybook2/src/bin/storybook2.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/storybook2/src/bin/storybook2.rs b/crates/storybook2/src/bin/storybook2.rs index 43f91db1a471f01d5d48e47161f6163f84dde62b..b77bbcb0666ac9f3ddc4930e72ad2c2fd5c8c6b5 100644 --- a/crates/storybook2/src/bin/storybook2.rs +++ b/crates/storybook2/src/bin/storybook2.rs @@ -11,6 +11,7 @@ use simplelog::SimpleLogger; use theme2::{ThemeRegistry, ThemeSettings}; use ui::prelude::*; +pub use indoc::indoc; use storybook2::assets::Assets; pub use storybook2::story_selector::*; // pub use crate::story_selector::{ComponentStory, StorySelector}; From f459fc5e27c5e905f6be516be134edeca1aa911c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 10:33:27 -0500 Subject: [PATCH 063/644] Fix import --- crates/storybook2/src/storybook2.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/storybook2/src/storybook2.rs b/crates/storybook2/src/storybook2.rs index 13d9a75e2451d607820c9df3c845b285a0f6c40c..523e93cf5267e310d691ee4ca19db1cc67cfbb4b 100644 --- a/crates/storybook2/src/storybook2.rs +++ b/crates/storybook2/src/storybook2.rs @@ -17,10 +17,9 @@ use strum::IntoEnumIterator; use theme2::{ThemeRegistry, ThemeSettings}; use ui::prelude::*; -pub use indoc::indoc; -use storybook2::assets::Assets; use crate::assets::Assets; use crate::story_selector::{ComponentStory, StorySelector}; +pub use indoc::indoc; // gpui::actions! { // storybook, From 50a44dd8ba1d04bc9a69d9292b662e6d1e10d8e7 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 11:07:17 -0500 Subject: [PATCH 064/644] Improve tooltip with keybinding styling --- crates/ui2/src/components/tooltip.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ui2/src/components/tooltip.rs b/crates/ui2/src/components/tooltip.rs index 7c502ac5cb13a4322db626602feedcd34edccdce..0a8eb8d6be5bc6f6e806a5ad153ea038a23f2b44 100644 --- a/crates/ui2/src/components/tooltip.rs +++ b/crates/ui2/src/components/tooltip.rs @@ -78,13 +78,13 @@ impl Render for Tooltip { v_stack() .elevation_2(cx) .font(ui_font) - .text_ui_sm() + .text_ui() .text_color(cx.theme().colors().text) .py_1() .px_2() .child( h_stack() - .gap_2() + .gap_4() .child(self.title.clone()) .when_some(self.key_binding.clone(), |this, key_binding| { this.justify_between().child(key_binding) From 47eaf1abd88863767233df4a843219d65944d2a8 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 11:07:40 -0500 Subject: [PATCH 065/644] Remove red borders, improve left side padding --- crates/collab_ui2/src/collab_titlebar_item.rs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index b127708fa690dfc4976c8df246c9d3afa7b3f1a4..7ce3502c7dbc8f76fc8e04690282e45f64dddb03 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -74,12 +74,16 @@ impl Render for CollabTitlebarItem { // Set a non-scaling min-height here to ensure the titlebar is // always at least the height of the traffic lights. .min_h(px(32.)) - .when( - !matches!(cx.window_bounds(), WindowBounds::Fullscreen), - // Use pixels here instead of a rem-based size because the macOS traffic - // lights are a static size, and don't scale with the rest of the UI. - |s| s.pl(px(68.)), - ) + .pl_2() + .map(|this| { + if matches!(cx.window_bounds(), WindowBounds::Fullscreen) { + this.pl_2() + } else { + // Use pixels here instead of a rem-based size because the macOS traffic + // lights are a static size, and don't scale with the rest of the UI. + this.pl(px(72.)) + } + }) .bg(cx.theme().colors().title_bar_background) .on_click(|event, cx| { if event.up.click_count == 2 { @@ -325,8 +329,6 @@ impl CollabTitlebarItem { let name = util::truncate_and_trailoff(name, MAX_PROJECT_NAME_LENGTH); div() - .border() - .border_color(gpui::red()) .child( Button::new("project_name_trigger", name) .style(ButtonStyle::Subtle) @@ -365,10 +367,9 @@ impl CollabTitlebarItem { Some( div() - .border() - .border_color(gpui::red()) .child( Button::new("project_branch_trigger", branch_name) + .color(Color::Muted) .style(ButtonStyle::Subtle) .tooltip(move |cx| { Tooltip::with_meta( From d099d359488c9ffd890857c44dd986c052ca8d87 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 11:20:56 -0500 Subject: [PATCH 066/644] Reduce intensity of project panel icons --- crates/project_panel2/src/project_panel.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index 2d18d2a6c769396d699ee3059e48f2736a85370a..d8b5c1551f4ef33495e7d84b168a702182479017 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -1389,7 +1389,9 @@ impl ProjectPanel { entry_id: *entry_id, }) }) - .drag_over::(|style| style.bg(cx.theme().colors().ghost_element_hover)) + .drag_over::(|style| { + style.bg(cx.theme().colors().drop_target_background) + }) .on_drop(cx.listener(move |this, dragged_id: &ProjectEntryId, cx| { this.move_entry(*dragged_id, entry_id, kind.is_file(), cx); })) @@ -1399,7 +1401,7 @@ impl ProjectPanel { .indent_step_size(px(settings.indent_size)) .selected(is_selected) .child(if let Some(icon) = &icon { - div().child(IconElement::from_path(icon.to_string())) + div().child(IconElement::from_path(icon.to_string()).color(Color::Muted)) } else { div() }) From 6345e6d4d2857a182d98875c24ea7daf4587b9ac Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 11:25:24 -0500 Subject: [PATCH 067/644] Add some right side padding in titlebar. --- crates/collab_ui2/src/collab_titlebar_item.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 7ce3502c7dbc8f76fc8e04690282e45f64dddb03..706749b28d349a2b9b30d51375c7818ec1031296 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -169,6 +169,7 @@ impl Render for CollabTitlebarItem { .child( h_stack() .gap_1() + .pr_1() .when_some(room, |this, room| { let room = room.read(cx); let is_shared = self.project.read(cx).is_shared(); From 6c10ff8548ccadd6749ab6b5680402942fed4187 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 11:56:03 -0500 Subject: [PATCH 068/644] Render the collab panel using a `gpui::list` --- crates/collab_ui2/src/collab_panel.rs | 287 ++++++++------------------ 1 file changed, 87 insertions(+), 200 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 4edf5ef35ba4495d5f3ef4922414d0f79cd46d7c..3a35c812861c429d5ae24aa45f293296969b433f 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -175,12 +175,12 @@ use editor::Editor; use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt}; use fuzzy::{match_strings, StringMatchCandidate}; use gpui::{ - actions, canvas, div, fill, img, impl_actions, overlay, point, prelude::*, px, rems, + actions, canvas, div, fill, img, impl_actions, list, overlay, point, prelude::*, px, rems, serde_json, size, Action, AnyElement, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div, EventEmitter, FocusHandle, Focusable, FocusableView, Hsla, - InteractiveElement, IntoElement, Length, Model, MouseDownEvent, ParentElement, Pixels, Point, - PromptLevel, Quad, Render, RenderOnce, ScrollHandle, SharedString, Size, Stateful, Styled, - Subscription, Task, View, ViewContext, VisualContext, WeakView, + InteractiveElement, IntoElement, Length, ListState, Model, MouseDownEvent, ParentElement, + Pixels, Point, PromptLevel, Quad, Render, RenderOnce, ScrollHandle, SharedString, Size, + Stateful, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, }; use project::{Fs, Project}; use serde_derive::{Deserialize, Serialize}; @@ -303,6 +303,7 @@ pub struct CollabPanel { channel_clipboard: Option, pending_serialization: Task>, context_menu: Option<(View, Point, Subscription)>, + list_state: ListState, filter_editor: View, channel_name_editor: View, channel_editing_state: Option, @@ -398,7 +399,7 @@ enum ListEntry { impl CollabPanel { pub fn new(workspace: &mut Workspace, cx: &mut ViewContext) -> View { cx.build_view(|cx| { - // let view_id = cx.view_id(); + let view = cx.view().clone(); let filter_editor = cx.build_view(|cx| { let mut editor = Editor::single_line(cx); @@ -445,136 +446,10 @@ impl CollabPanel { }) .detach(); - // let list_state = - // ListState::::new(0, Orientation::Top, 1000., move |this, ix, cx| { - // let theme = theme::current(cx).clone(); - // let is_selected = this.selection == Some(ix); - // let current_project_id = this.project.read(cx).remote_id(); - - // match &this.entries[ix] { - // ListEntry::Header(section) => { - // let is_collapsed = this.collapsed_sections.contains(section); - // this.render_header(*section, &theme, is_selected, is_collapsed, cx) - // } - // ListEntry::CallParticipant { - // user, - // peer_id, - // is_pending, - // } => Self::render_call_participant( - // user, - // *peer_id, - // this.user_store.clone(), - // *is_pending, - // is_selected, - // &theme, - // cx, - // ), - // ListEntry::ParticipantProject { - // project_id, - // worktree_root_names, - // host_user_id, - // is_last, - // } => Self::render_participant_project( - // *project_id, - // worktree_root_names, - // *host_user_id, - // Some(*project_id) == current_project_id, - // *is_last, - // is_selected, - // &theme, - // cx, - // ), - // ListEntry::ParticipantScreen { peer_id, is_last } => { - // Self::render_participant_screen( - // *peer_id, - // *is_last, - // is_selected, - // &theme.collab_panel, - // cx, - // ) - // } - // ListEntry::Channel { - // channel, - // depth, - // has_children, - // } => { - // let channel_row = this.render_channel( - // &*channel, - // *depth, - // &theme, - // is_selected, - // *has_children, - // ix, - // cx, - // ); - - // if is_selected && this.context_menu_on_selected { - // Stack::new() - // .with_child(channel_row) - // .with_child( - // ChildView::new(&this.context_menu, cx) - // .aligned() - // .bottom() - // .right(), - // ) - // .into_any() - // } else { - // return channel_row; - // } - // } - // ListEntry::ChannelNotes { channel_id } => this.render_channel_notes( - // *channel_id, - // &theme.collab_panel, - // is_selected, - // ix, - // cx, - // ), - // ListEntry::ChannelChat { channel_id } => this.render_channel_chat( - // *channel_id, - // &theme.collab_panel, - // is_selected, - // ix, - // cx, - // ), - // ListEntry::ChannelInvite(channel) => Self::render_channel_invite( - // channel.clone(), - // this.channel_store.clone(), - // &theme.collab_panel, - // is_selected, - // cx, - // ), - // ListEntry::IncomingRequest(user) => Self::render_contact_request( - // user.clone(), - // this.user_store.clone(), - // &theme.collab_panel, - // true, - // is_selected, - // cx, - // ), - // ListEntry::OutgoingRequest(user) => Self::render_contact_request( - // user.clone(), - // this.user_store.clone(), - // &theme.collab_panel, - // false, - // is_selected, - // cx, - // ), - // ListEntry::Contact { contact, calling } => Self::render_contact( - // contact, - // *calling, - // &this.project, - // &theme, - // is_selected, - // cx, - // ), - // ListEntry::ChannelEditor { depth } => { - // this.render_channel_editor(&theme, *depth, cx) - // } - // ListEntry::ContactPlaceholder => { - // this.render_contact_placeholder(&theme.collab_panel, is_selected, cx) - // } - // } - // }); + let list_state = + ListState::new(0, gpui::ListAlignment::Top, px(1000.), move |ix, cx| { + view.update(cx, |view, cx| view.render_list_entry(ix, cx)) + }); let mut this = Self { width: None, @@ -583,6 +458,7 @@ impl CollabPanel { fs: workspace.app_state().fs.clone(), pending_serialization: Task::ready(None), context_menu: None, + list_state, channel_name_editor, filter_editor, entries: Vec::default(), @@ -1084,6 +960,8 @@ impl CollabPanel { self.entries.push(ListEntry::ContactPlaceholder); } + self.list_state.reset(self.entries.len()); + if select_same_item { if let Some(prev_selected_entry) = prev_selected_entry { self.selection.take(); @@ -2158,77 +2036,86 @@ impl CollabPanel { ) } + fn render_list_entry( + &mut self, + // entry: &ListEntry, + ix: usize, + cx: &mut ViewContext, + ) -> AnyElement { + let entry = &self.entries[ix]; + + let is_selected = self.selection == Some(ix); + match entry { + ListEntry::Header(section) => { + let is_collapsed = self.collapsed_sections.contains(section); + self.render_header(*section, is_selected, is_collapsed, cx) + .into_any_element() + } + ListEntry::Contact { contact, calling } => self + .render_contact(contact, *calling, is_selected, cx) + .into_any_element(), + ListEntry::ContactPlaceholder => self + .render_contact_placeholder(is_selected, cx) + .into_any_element(), + ListEntry::IncomingRequest(user) => self + .render_contact_request(user, true, is_selected, cx) + .into_any_element(), + ListEntry::OutgoingRequest(user) => self + .render_contact_request(user, false, is_selected, cx) + .into_any_element(), + ListEntry::Channel { + channel, + depth, + has_children, + } => self + .render_channel(channel, *depth, *has_children, is_selected, ix, cx) + .into_any_element(), + ListEntry::ChannelEditor { depth } => { + self.render_channel_editor(*depth, cx).into_any_element() + } + ListEntry::CallParticipant { + user, + peer_id, + is_pending, + } => self + .render_call_participant(user, *peer_id, *is_pending, cx) + .into_any_element(), + ListEntry::ParticipantProject { + project_id, + worktree_root_names, + host_user_id, + is_last, + } => self + .render_participant_project( + *project_id, + &worktree_root_names, + *host_user_id, + *is_last, + cx, + ) + .into_any_element(), + ListEntry::ParticipantScreen { peer_id, is_last } => self + .render_participant_screen(*peer_id, *is_last, cx) + .into_any_element(), + ListEntry::ChannelNotes { channel_id } => self + .render_channel_notes(*channel_id, cx) + .into_any_element(), + ListEntry::ChannelChat { channel_id } => { + self.render_channel_chat(*channel_id, cx).into_any_element() + } + } + } + fn render_signed_in(&mut self, cx: &mut ViewContext) -> Div { v_stack() .size_full() .child( v_stack() .size_full() - .id("scroll") - .overflow_y_scroll() - .track_scroll(&self.scroll_handle) - .children(self.entries.iter().enumerate().map(|(ix, entry)| { - let is_selected = self.selection == Some(ix); - match entry { - ListEntry::Header(section) => { - let is_collapsed = self.collapsed_sections.contains(section); - self.render_header(*section, is_selected, is_collapsed, cx) - .into_any_element() - } - ListEntry::Contact { contact, calling } => self - .render_contact(contact, *calling, is_selected, cx) - .into_any_element(), - ListEntry::ContactPlaceholder => self - .render_contact_placeholder(is_selected, cx) - .into_any_element(), - ListEntry::IncomingRequest(user) => self - .render_contact_request(user, true, is_selected, cx) - .into_any_element(), - ListEntry::OutgoingRequest(user) => self - .render_contact_request(user, false, is_selected, cx) - .into_any_element(), - ListEntry::Channel { - channel, - depth, - has_children, - } => self - .render_channel(channel, *depth, *has_children, is_selected, ix, cx) - .into_any_element(), - ListEntry::ChannelEditor { depth } => { - self.render_channel_editor(*depth, cx).into_any_element() - } - ListEntry::CallParticipant { - user, - peer_id, - is_pending, - } => self - .render_call_participant(user, *peer_id, *is_pending, cx) - .into_any_element(), - ListEntry::ParticipantProject { - project_id, - worktree_root_names, - host_user_id, - is_last, - } => self - .render_participant_project( - *project_id, - &worktree_root_names, - *host_user_id, - *is_last, - cx, - ) - .into_any_element(), - ListEntry::ParticipantScreen { peer_id, is_last } => self - .render_participant_screen(*peer_id, *is_last, cx) - .into_any_element(), - ListEntry::ChannelNotes { channel_id } => self - .render_channel_notes(*channel_id, cx) - .into_any_element(), - ListEntry::ChannelChat { channel_id } => { - self.render_channel_chat(*channel_id, cx).into_any_element() - } - } - })), + // .id("scroll") + // .overflow_y_scroll() + // .track_scroll(&self.scroll_handle) + .child(list(self.list_state.clone()).full().into_any_element()), ) .child( div().p_2().child( From d13c1486dab44094ac29e47a4ff9e1cb74bedc9e Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 12:09:06 -0500 Subject: [PATCH 069/644] Update fold_indicator render --- crates/editor2/src/editor.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 664d1d7380634426aa4a8264c4ed66aef008c265..3dd703bcba26fbc5b5d6e6311c94c5c15608f593 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -4260,11 +4260,7 @@ impl Editor { fold_data .map(|(fold_status, buffer_row, active)| { (active || gutter_hovered || fold_status == FoldStatus::Folded).then(|| { - let icon = match fold_status { - FoldStatus::Folded => ui::Icon::ChevronRight, - FoldStatus::Foldable => ui::Icon::ChevronDown, - }; - IconButton::new(ix as usize, icon) + IconButton::new(ix as usize, ui::Icon::ChevronDown) .on_click(cx.listener(move |editor, e, cx| match fold_status { FoldStatus::Folded => { editor.unfold_at(&UnfoldAt { buffer_row }, cx); @@ -4274,6 +4270,10 @@ impl Editor { } })) .icon_color(ui::Color::Muted) + .icon_size(ui::IconSize::Small) + .selected(fold_status == FoldStatus::Folded) + .selected_icon(ui::Icon::ChevronRight) + .size(ui::ButtonSize::None) }) }) .flatten() From b478a4c4d5676f1d7e07961d29f41e24cf5e7602 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 12:10:40 -0500 Subject: [PATCH 070/644] Perform scroll interactions through the `ListState` --- crates/collab_ui2/src/collab_panel.rs | 53 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 3a35c812861c429d5ae24aa45f293296969b433f..31b1ef0237c9baacb8b40d07c0ad9be72bf0325c 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -178,9 +178,10 @@ use gpui::{ actions, canvas, div, fill, img, impl_actions, list, overlay, point, prelude::*, px, rems, serde_json, size, Action, AnyElement, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div, EventEmitter, FocusHandle, Focusable, FocusableView, Hsla, - InteractiveElement, IntoElement, Length, ListState, Model, MouseDownEvent, ParentElement, - Pixels, Point, PromptLevel, Quad, Render, RenderOnce, ScrollHandle, SharedString, Size, - Stateful, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, + InteractiveElement, IntoElement, Length, ListOffset, ListState, Model, MouseDownEvent, + ParentElement, Pixels, Point, PromptLevel, Quad, Render, RenderOnce, ScrollHandle, + SharedString, Size, Stateful, Styled, Subscription, Task, View, ViewContext, VisualContext, + WeakView, }; use project::{Fs, Project}; use serde_derive::{Deserialize, Serialize}; @@ -314,7 +315,6 @@ pub struct CollabPanel { client: Arc, project: Model, match_candidates: Vec, - scroll_handle: ScrollHandle, subscriptions: Vec, collapsed_sections: Vec
, collapsed_channels: Vec, @@ -469,7 +469,6 @@ impl CollabPanel { project: workspace.project().clone(), subscriptions: Vec::default(), match_candidates: Vec::default(), - scroll_handle: ScrollHandle::new(), collapsed_sections: vec![Section::Offline], collapsed_channels: Vec::default(), workspace: workspace.weak_handle(), @@ -585,6 +584,13 @@ impl CollabPanel { ); } + fn scroll_to_item(&mut self, ix: usize) { + self.list_state.scroll_to(ListOffset { + item_ix: ix, + offset_in_item: px(0.), + }) + } + fn update_entries(&mut self, select_same_item: bool, cx: &mut ViewContext) { let channel_store = self.channel_store.read(cx); let user_store = self.user_store.read(cx); @@ -968,7 +974,7 @@ impl CollabPanel { for (ix, entry) in self.entries.iter().enumerate() { if *entry == prev_selected_entry { self.selection = Some(ix); - self.scroll_handle.scroll_to_item(ix); + self.scroll_to_item(ix); break; } } @@ -979,16 +985,19 @@ impl CollabPanel { None } else { let ix = prev_selection.min(self.entries.len() - 1); - self.scroll_handle.scroll_to_item(ix); + self.scroll_to_item(ix); Some(ix) } }); } if scroll_to_top { - self.scroll_handle.scroll_to_item(0) + self.scroll_to_item(0) } else { - let (old_index, old_offset) = self.scroll_handle.logical_scroll_top(); + let ListOffset { + item_ix: old_index, + offset_in_item: old_offset, + } = self.list_state.logical_scroll_top(); // Attempt to maintain the same scroll position. if let Some(old_top_entry) = old_entries.get(old_index) { let (new_index, new_offset) = self @@ -1014,8 +1023,9 @@ impl CollabPanel { }) .unwrap_or_else(|| (old_index, old_offset)); - self.scroll_handle - .set_logical_scroll_top(new_index, new_offset); + // TODO: How to handle this with `list`? + // self.scroll_handle + // .set_logical_scroll_top(new_index, new_offset); } } @@ -1506,7 +1516,7 @@ impl CollabPanel { } if let Some(ix) = self.selection { - self.scroll_handle.scroll_to_item(ix) + self.scroll_to_item(ix) } cx.notify(); } @@ -1518,7 +1528,7 @@ impl CollabPanel { } if let Some(ix) = self.selection { - self.scroll_handle.scroll_to_item(ix) + self.scroll_to_item(ix) } cx.notify(); } @@ -1841,14 +1851,15 @@ impl CollabPanel { let Some(channel) = self.selected_channel() else { return; }; - let Some(bounds) = self - .selection - .and_then(|ix| self.scroll_handle.bounds_for_item(ix)) - else { - return; - }; - - self.deploy_channel_context_menu(bounds.center(), channel.id, self.selection.unwrap(), cx); + // TODO: How to handle now that we're using `list`? + // let Some(bounds) = self + // .selection + // .and_then(|ix| self.scroll_handle.bounds_for_item(ix)) + // else { + // return; + // }; + // + // self.deploy_channel_context_menu(bounds.center(), channel.id, self.selection.unwrap(), cx); cx.stop_propagation(); } From 83525bf142eebf5af1f69a4a02946475d5796090 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 12:22:33 -0500 Subject: [PATCH 071/644] Revert change to single line editor height --- crates/editor2/src/editor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 3dd703bcba26fbc5b5d6e6311c94c5c15608f593..fc03150fb6055bb7f2dcf6d1c5825cf9c5bcbe2b 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -9303,7 +9303,7 @@ impl Render for Editor { font_size: rems(0.875).into(), font_weight: FontWeight::NORMAL, font_style: FontStyle::Normal, - line_height: relative(1.).into(), + line_height: relative(settings.buffer_line_height.value()), background_color: None, underline: None, white_space: WhiteSpace::Normal, From 4cb0f60779d5deb53ff782ea929e1b0b16d123e4 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 12:29:33 -0500 Subject: [PATCH 072/644] Update size of code action indicator and show when active --- crates/editor2/src/editor.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index fc03150fb6055bb7f2dcf6d1c5825cf9c5bcbe2b..e1e4c7e0adb075289a20dfef91eec6baadef9dd5 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -4228,16 +4228,18 @@ impl Editor { ) -> Option { if self.available_code_actions.is_some() { Some( - IconButton::new("code_actions_indicator", ui::Icon::Bolt).on_click(cx.listener( - |editor, e, cx| { + IconButton::new("code_actions_indicator", ui::Icon::Bolt) + .icon_size(IconSize::Small) + .icon_color(Color::Muted) + .selected(is_active) + .on_click(cx.listener(|editor, e, cx| { editor.toggle_code_actions( &ToggleCodeActions { deployed_from_indicator: true, }, cx, ); - }, - )), + })), ) } else { None From 0a57171066400c64aa282d9350a80220e5cf485e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 15 Dec 2023 18:30:32 +0100 Subject: [PATCH 073/644] Use a safe API for Arena --- crates/gpui2/src/arena.rs | 132 +++++++++++++++++++++++------------- crates/gpui2/src/element.rs | 12 ++-- crates/gpui2/src/window.rs | 70 ++++++++++--------- 3 files changed, 125 insertions(+), 89 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index 0e01c392b76d644c312a1be07980cf3ac8f9ab38..a362c720a2161c3325227891572f43bc3425d114 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -1,40 +1,49 @@ use std::{ alloc, + cell::Cell, + ops::{Deref, DerefMut}, ptr::{self, NonNull}, + rc::Rc, }; +struct ArenaElement { + value: NonNull, + drop: unsafe fn(NonNull), +} + +impl Drop for ArenaElement { + fn drop(&mut self) { + unsafe { + (self.drop)(self.value); + } + } +} + pub struct Arena { start: NonNull, offset: usize, elements: Vec, + valid: Rc>, } -impl Default for Arena { - fn default() -> Self { +impl Arena { + pub fn new(size_in_bytes: usize) -> Self { unsafe { - let layout = alloc::Layout::from_size_align(16 * 1024 * 1024, 1).unwrap(); + let layout = alloc::Layout::from_size_align(size_in_bytes, 1).unwrap(); let ptr = alloc::alloc(layout); Self { start: NonNull::new_unchecked(ptr), offset: 0, elements: Vec::new(), + valid: Rc::new(Cell::new(true)), } } } -} -struct ArenaElement { - value: NonNull, - drop: unsafe fn(NonNull), -} - -impl Arena { pub fn clear(&mut self) { - for element in self.elements.drain(..) { - unsafe { - (element.drop)(element.value); - } - } + self.valid.set(false); + self.valid = Rc::new(Cell::new(true)); + self.elements.clear(); self.offset = 0; } @@ -46,42 +55,71 @@ impl Arena { unsafe { let layout = alloc::Layout::for_value(&value).pad_to_align(); - let value_ptr = self.start.as_ptr().add(self.offset).cast::(); - ptr::write(value_ptr, value); + let ptr = NonNull::new_unchecked(self.start.as_ptr().add(self.offset).cast::()); + ptr::write(ptr.as_ptr(), value); - let value = NonNull::new_unchecked(value_ptr); self.elements.push(ArenaElement { - value: value.cast(), + value: ptr.cast(), drop: drop::, }); self.offset += layout.size(); - ArenaRef(value) + ArenaRef { + ptr, + valid: self.valid.clone(), + } } } } -pub struct ArenaRef(NonNull); +impl Drop for Arena { + fn drop(&mut self) { + self.clear(); + } +} -impl Copy for ArenaRef {} +pub struct ArenaRef { + ptr: NonNull, + valid: Rc>, +} impl Clone for ArenaRef { fn clone(&self) -> Self { - Self(self.0) + Self { + ptr: self.ptr, + valid: self.valid.clone(), + } } } impl ArenaRef { - pub unsafe fn map(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaRef { - let u = f(self.get_mut()); - ArenaRef(NonNull::new_unchecked(u)) + pub fn map(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaRef { + ArenaRef { + ptr: unsafe { NonNull::new_unchecked(f(&mut *self)) }, + valid: self.valid, + } } - pub unsafe fn get(&self) -> &T { - self.0.as_ref() + fn validate(&self) { + assert!( + self.valid.get(), + "attempted to dereference an ArenaRef after its Arena was cleared" + ); } +} + +impl Deref for ArenaRef { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.validate(); + unsafe { self.ptr.as_ref() } + } +} - pub unsafe fn get_mut(&mut self) -> &mut T { - self.0.as_mut() +impl DerefMut for ArenaRef { + fn deref_mut(&mut self) -> &mut Self::Target { + self.validate(); + unsafe { self.ptr.as_mut() } } } @@ -93,25 +131,25 @@ mod tests { #[test] fn test_arena() { - let mut arena = Arena::default(); - let mut a = arena.alloc(1u64); - let mut b = arena.alloc(2u32); - let mut c = arena.alloc(3u16); - let mut d = arena.alloc(4u8); - assert_eq!(unsafe { *a.get_mut() }, 1); - assert_eq!(unsafe { *b.get_mut() }, 2); - assert_eq!(unsafe { *c.get_mut() }, 3); - assert_eq!(unsafe { *d.get_mut() }, 4); + let mut arena = Arena::new(1024); + let a = arena.alloc(1u64); + let b = arena.alloc(2u32); + let c = arena.alloc(3u16); + let d = arena.alloc(4u8); + assert_eq!(*a, 1); + assert_eq!(*b, 2); + assert_eq!(*c, 3); + assert_eq!(*d, 4); arena.clear(); - let mut a = arena.alloc(5u64); - let mut b = arena.alloc(6u32); - let mut c = arena.alloc(7u16); - let mut d = arena.alloc(8u8); - assert_eq!(unsafe { *a.get_mut() }, 5); - assert_eq!(unsafe { *b.get_mut() }, 6); - assert_eq!(unsafe { *c.get_mut() }, 7); - assert_eq!(unsafe { *d.get_mut() }, 8); + let a = arena.alloc(5u64); + let b = arena.alloc(6u32); + let c = arena.alloc(7u16); + let d = arena.alloc(8u8); + assert_eq!(*a, 5); + assert_eq!(*b, 6); + assert_eq!(*c, 7); + assert_eq!(*d, 8); // Ensure drop gets called. let dropped = Rc::new(Cell::new(false)); diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index dcb103b61eac80a3376b6d80110e0c6764604555..d54d1c245da61fb9c2d03044a305a67587baea46 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -415,16 +415,16 @@ impl AnyElement { { let element = FRAME_ARENA.with_borrow_mut(|arena| arena.alloc(Some(DrawableElement::new(element)))); - let element = unsafe { element.map(|element| element as &mut dyn ElementObject) }; + let element = element.map(|element| element as &mut dyn ElementObject); AnyElement(element) } pub fn layout(&mut self, cx: &mut WindowContext) -> LayoutId { - unsafe { self.0.get_mut() }.layout(cx) + self.0.layout(cx) } pub fn paint(&mut self, cx: &mut WindowContext) { - unsafe { self.0.get_mut() }.paint(cx) + self.0.paint(cx) } /// Initializes this element and performs layout within the given available space to determine its size. @@ -433,7 +433,7 @@ impl AnyElement { available_space: Size, cx: &mut WindowContext, ) -> Size { - unsafe { self.0.get_mut() }.measure(available_space, cx) + self.0.measure(available_space, cx) } /// Initializes this element and performs layout in the available space, then paints it at the given origin. @@ -443,11 +443,11 @@ impl AnyElement { available_space: Size, cx: &mut WindowContext, ) { - unsafe { self.0.get_mut() }.draw(origin, available_space, cx) + self.0.draw(origin, available_space, cx) } pub fn inner_id(&self) -> Option { - unsafe { self.0.get() }.element_id() + self.0.element_id() } } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 74b67503d52390d7878bc198b03c06fd7e9554ee..76fa36c68b1889baf073524e54c7025d9055180b 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -99,7 +99,7 @@ struct FocusEvent { slotmap::new_key_type! { pub struct FocusId; } thread_local! { - pub static FRAME_ARENA: RefCell = RefCell::new(Arena::default()); + pub static FRAME_ARENA: RefCell = RefCell::new(Arena::new(16 * 1024 * 1024)); } impl FocusId { @@ -829,14 +829,15 @@ impl<'a> WindowContext<'a> { mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { let order = self.window.next_frame.z_index_stack.clone(); - let handler = FRAME_ARENA.with_borrow_mut(|arena| { - arena.alloc( - move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { - handler(event.downcast_ref().unwrap(), phase, cx) - }, - ) - }); - let handler = unsafe { handler.map(|handler| handler as _) }; + let handler = FRAME_ARENA + .with_borrow_mut(|arena| { + arena.alloc( + move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { + handler(event.downcast_ref().unwrap(), phase, cx) + }, + ) + }) + .map(|handler| handler as _); self.window .next_frame .mouse_listeners @@ -855,14 +856,15 @@ impl<'a> WindowContext<'a> { &mut self, listener: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = FRAME_ARENA.with_borrow_mut(|arena| { - arena.alloc(move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { - if let Some(event) = event.downcast_ref::() { - listener(event, phase, cx) - } + let listener = FRAME_ARENA + .with_borrow_mut(|arena| { + arena.alloc(move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { + if let Some(event) = event.downcast_ref::() { + listener(event, phase, cx) + } + }) }) - }); - let listener = unsafe { listener.map(|handler| handler as _) }; + .map(|handler| handler as _); self.window.next_frame.dispatch_tree.on_key_event(listener); } @@ -877,8 +879,9 @@ impl<'a> WindowContext<'a> { action_type: TypeId, listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = FRAME_ARENA.with_borrow_mut(|arena| arena.alloc(listener)); - let listener = unsafe { listener.map(|handler| handler as _) }; + let listener = FRAME_ARENA + .with_borrow_mut(|arena| arena.alloc(listener)) + .map(|handler| handler as _); self.window .next_frame .dispatch_tree @@ -1284,14 +1287,15 @@ impl<'a> WindowContext<'a> { cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| { for (action_type, action_listeners) in &cx.app.global_action_listeners { for action_listener in action_listeners.iter().cloned() { - let listener = FRAME_ARENA.with_borrow_mut(|arena| { - arena.alloc( - move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { - action_listener(action, phase, cx) - }, - ) - }); - let listener = unsafe { listener.map(|listener| listener as _) }; + let listener = FRAME_ARENA + .with_borrow_mut(|arena| { + arena.alloc( + move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { + action_listener(action, phase, cx) + }, + ) + }) + .map(|listener| listener as _); cx.window .next_frame .dispatch_tree @@ -1478,7 +1482,6 @@ impl<'a> WindowContext<'a> { // Capture phase, events bubble from back to front. Handlers for this phase are used for // special purposes, such as detecting events outside of a given Bounds. for (_, handler) in &mut handlers { - let handler = unsafe { handler.get_mut() }; handler(event, DispatchPhase::Capture, self); if !self.app.propagate_event { break; @@ -1488,7 +1491,6 @@ impl<'a> WindowContext<'a> { // Bubble phase, where most normal handlers do their work. if self.app.propagate_event { for (_, handler) in handlers.iter_mut().rev() { - let handler = unsafe { handler.get_mut() }; handler(event, DispatchPhase::Bubble, self); if !self.app.propagate_event { break; @@ -1538,8 +1540,7 @@ impl<'a> WindowContext<'a> { context_stack.push(context); } - for mut key_listener in node.key_listeners.clone() { - let key_listener = unsafe { key_listener.get_mut() }; + for key_listener in node.key_listeners.clone() { key_listener(event, DispatchPhase::Capture, self); if !self.propagate_event { return; @@ -1551,8 +1552,7 @@ impl<'a> WindowContext<'a> { for node_id in dispatch_path.iter().rev() { // Handle low level key events let node = self.window.rendered_frame.dispatch_tree.node(*node_id); - for mut key_listener in node.key_listeners.clone() { - let key_listener = unsafe { key_listener.get_mut() }; + for key_listener in node.key_listeners.clone() { key_listener(event, DispatchPhase::Bubble, self); if !self.propagate_event { return; @@ -1604,12 +1604,11 @@ impl<'a> WindowContext<'a> { let node = self.window.rendered_frame.dispatch_tree.node(*node_id); for DispatchActionListener { action_type, - mut listener, + listener, } in node.action_listeners.clone() { let any_action = action.as_any(); if action_type == any_action.type_id() { - let listener = unsafe { listener.get_mut() }; listener(any_action, DispatchPhase::Capture, self); if !self.propagate_event { return; @@ -1622,13 +1621,12 @@ impl<'a> WindowContext<'a> { let node = self.window.rendered_frame.dispatch_tree.node(*node_id); for DispatchActionListener { action_type, - mut listener, + listener, } in node.action_listeners.clone() { let any_action = action.as_any(); if action_type == any_action.type_id() { self.propagate_event = false; // Actions stop propagation by default during the bubble phase - let listener = unsafe { listener.get_mut() }; listener(any_action, DispatchPhase::Bubble, self); if !self.propagate_event { return; From a2852e36ce8df6d1bc86a8cc2a59b31af60b2e22 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Fri, 15 Dec 2023 10:07:10 -0800 Subject: [PATCH 074/644] Fix pane resizing --- crates/workspace2/src/pane_group.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index 966e2c6341a5c9fa7808424a07ea0571d99a5bf6..d35c138d5c8217b32786a2b95cb7c5e9c9009030 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -693,7 +693,8 @@ mod element { use gpui::{ px, relative, Along, AnyElement, Axis, Bounds, CursorStyle, Element, IntoElement, - MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Style, WindowContext, + MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, Size, Style, + WindowContext, }; use parking_lot::Mutex; use smallvec::SmallVec; @@ -736,7 +737,8 @@ mod element { e: &MouseMoveEvent, ix: usize, axis: Axis, - axis_bounds: Bounds, + child_start: Point, + container_size: Size, cx: &mut WindowContext, ) { let min_size = match axis { @@ -747,7 +749,7 @@ mod element { debug_assert!(flex_values_in_bounds(flexes.as_slice())); let size = move |ix, flexes: &[f32]| { - axis_bounds.size.along(axis) * (flexes[ix] / flexes.len() as f32) + container_size.along(axis) * (flexes[ix] / flexes.len() as f32) }; // Don't allow resizing to less than the minimum size, if elements are already too small @@ -756,10 +758,10 @@ mod element { } let mut proposed_current_pixel_change = - (e.position - axis_bounds.origin).along(axis) - size(ix, flexes.as_slice()); + (e.position - child_start).along(axis) - size(ix, flexes.as_slice()); let flex_changes = |pixel_dx, target_ix, next: isize, flexes: &[f32]| { - let flex_change = pixel_dx / axis_bounds.size.along(axis); + let flex_change = pixel_dx / container_size.along(axis); let current_target_flex = flexes[target_ix] + flex_change; let next_target_flex = flexes[(target_ix as isize + next) as usize] - flex_change; (current_target_flex, next_target_flex) @@ -854,7 +856,15 @@ mod element { cx.on_mouse_event(move |e: &MouseMoveEvent, phase, cx| { let dragged_handle = dragged_handle.borrow(); if phase.bubble() && *dragged_handle == Some(ix) { - Self::compute_resize(&flexes, e, ix, axis, axis_bounds, cx) + Self::compute_resize( + &flexes, + e, + ix, + axis, + pane_bounds.origin, + axis_bounds.size, + cx, + ) } }); }); From 47fc03ab98536b3ba2cbd75cf169ff516a5eb07f Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 13:24:30 -0500 Subject: [PATCH 075/644] Fix positioning of the inline context menu Added a new `bounds_for_item` for `ListState`. Co-authored-by: Max --- crates/collab_ui2/src/collab_panel.rs | 55 ++++++++++----------------- crates/gpui2/src/elements/list.rs | 46 ++++++++++++++++++---- 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 31b1ef0237c9baacb8b40d07c0ad9be72bf0325c..6f21649dd6a07f4d47ecb69e7f7183d4c4b789b3 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -165,7 +165,7 @@ struct ChannelMoveClipboard { const COLLABORATION_PANEL_KEY: &'static str = "CollaborationPanel"; -use std::{iter::once, mem, sync::Arc}; +use std::{mem, sync::Arc}; use call::ActiveCall; use channel::{Channel, ChannelEvent, ChannelId, ChannelStore}; @@ -175,12 +175,11 @@ use editor::Editor; use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt}; use fuzzy::{match_strings, StringMatchCandidate}; use gpui::{ - actions, canvas, div, fill, img, impl_actions, list, overlay, point, prelude::*, px, rems, - serde_json, size, Action, AnyElement, AppContext, AsyncWindowContext, Bounds, ClipboardItem, - DismissEvent, Div, EventEmitter, FocusHandle, Focusable, FocusableView, Hsla, - InteractiveElement, IntoElement, Length, ListOffset, ListState, Model, MouseDownEvent, - ParentElement, Pixels, Point, PromptLevel, Quad, Render, RenderOnce, ScrollHandle, - SharedString, Size, Stateful, Styled, Subscription, Task, View, ViewContext, VisualContext, + actions, canvas, div, fill, impl_actions, list, overlay, point, prelude::*, px, serde_json, + AnyElement, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div, + EventEmitter, FocusHandle, Focusable, FocusableView, InteractiveElement, IntoElement, + ListOffset, ListState, Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, + Render, RenderOnce, SharedString, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, }; use project::{Fs, Project}; @@ -189,7 +188,7 @@ use settings::{Settings, SettingsStore}; use ui::prelude::*; use ui::{ h_stack, v_stack, Avatar, Button, Color, ContextMenu, Icon, IconButton, IconElement, IconSize, - Label, List, ListHeader, ListItem, Tooltip, + Label, ListHeader, ListItem, Tooltip, }; use util::{maybe, ResultExt, TryFutureExt}; use workspace::{ @@ -1023,9 +1022,10 @@ impl CollabPanel { }) .unwrap_or_else(|| (old_index, old_offset)); - // TODO: How to handle this with `list`? - // self.scroll_handle - // .set_logical_scroll_top(new_index, new_offset); + self.list_state.scroll_to(ListOffset { + item_ix: new_index, + offset_in_item: new_offset, + }); } } @@ -1851,15 +1851,14 @@ impl CollabPanel { let Some(channel) = self.selected_channel() else { return; }; - // TODO: How to handle now that we're using `list`? - // let Some(bounds) = self - // .selection - // .and_then(|ix| self.scroll_handle.bounds_for_item(ix)) - // else { - // return; - // }; - // - // self.deploy_channel_context_menu(bounds.center(), channel.id, self.selection.unwrap(), cx); + let Some(bounds) = self + .selection + .and_then(|ix| self.list_state.bounds_for_item(ix)) + else { + return; + }; + + self.deploy_channel_context_menu(bounds.center(), channel.id, self.selection.unwrap(), cx); cx.stop_propagation(); } @@ -2047,12 +2046,7 @@ impl CollabPanel { ) } - fn render_list_entry( - &mut self, - // entry: &ListEntry, - ix: usize, - cx: &mut ViewContext, - ) -> AnyElement { + fn render_list_entry(&mut self, ix: usize, cx: &mut ViewContext) -> AnyElement { let entry = &self.entries[ix]; let is_selected = self.selection == Some(ix); @@ -2120,14 +2114,7 @@ impl CollabPanel { fn render_signed_in(&mut self, cx: &mut ViewContext) -> Div { v_stack() .size_full() - .child( - v_stack() - .size_full() - // .id("scroll") - // .overflow_y_scroll() - // .track_scroll(&self.scroll_handle) - .child(list(self.list_state.clone()).full().into_any_element()), - ) + .child(list(self.list_state.clone()).full()) .child( div().p_2().child( div() diff --git a/crates/gpui2/src/elements/list.rs b/crates/gpui2/src/elements/list.rs index 6818c5c7a2e62baab27aad701dfa27cfa80dbce4..108703370cf4ab12cb7cc2e7bbb6464fab7892f3 100644 --- a/crates/gpui2/src/elements/list.rs +++ b/crates/gpui2/src/elements/list.rs @@ -1,6 +1,7 @@ use crate::{ - px, AnyElement, AvailableSpace, BorrowAppContext, DispatchPhase, Element, IntoElement, Pixels, - Point, ScrollWheelEvent, Size, Style, StyleRefinement, Styled, WindowContext, + point, px, AnyElement, AvailableSpace, BorrowAppContext, Bounds, DispatchPhase, Element, + IntoElement, Pixels, Point, ScrollWheelEvent, Size, Style, StyleRefinement, Styled, + WindowContext, }; use collections::VecDeque; use refineable::Refineable as _; @@ -23,7 +24,7 @@ pub struct List { pub struct ListState(Rc>); struct StateInner { - last_layout_width: Option, + last_layout_bounds: Option>, render_item: Box AnyElement>, items: SumTree, logical_scroll_top: Option, @@ -83,7 +84,7 @@ impl ListState { let mut items = SumTree::new(); items.extend((0..element_count).map(|_| ListItem::Unrendered), &()); Self(Rc::new(RefCell::new(StateInner { - last_layout_width: None, + last_layout_bounds: None, render_item: Box::new(render_item), items, logical_scroll_top: None, @@ -152,6 +153,35 @@ impl ListState { } state.logical_scroll_top = Some(scroll_top); } + + /// Get the bounds for the given item in window coordinates. + pub fn bounds_for_item(&self, ix: usize) -> Option> { + let state = &*self.0.borrow(); + let bounds = state.last_layout_bounds.unwrap_or_default(); + let scroll_top = state.logical_scroll_top.unwrap_or_default(); + + if ix < scroll_top.item_ix { + return None; + } + + let mut cursor = state.items.cursor::<(Count, Height)>(); + cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &()); + + let scroll_top = cursor.start().1 .0 + scroll_top.offset_in_item; + + cursor.seek_forward(&Count(ix), Bias::Right, &()); + if let Some(&ListItem::Rendered { height }) = cursor.item() { + let &(Count(count), Height(top)) = cursor.start(); + if count == ix { + let top = bounds.top() + top - scroll_top; + return Some(Bounds::from_corners( + point(bounds.left(), top), + point(bounds.right(), top + height), + )); + } + } + None + } } impl StateInner { @@ -234,7 +264,7 @@ impl std::fmt::Debug for ListItem { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Default)] pub struct ListOffset { pub item_ix: usize, pub offset_in_item: Pixels, @@ -265,7 +295,9 @@ impl Element for List { let state = &mut *self.state.0.borrow_mut(); // If the width of the list has changed, invalidate all cached item heights - if state.last_layout_width != Some(bounds.size.width) { + if state.last_layout_bounds.map_or(true, |last_bounds| { + last_bounds.size.width != bounds.size.width + }) { state.items = SumTree::from_iter( (0..state.items.summary().count).map(|_| ListItem::Unrendered), &(), @@ -392,7 +424,7 @@ impl Element for List { } state.items = new_items; - state.last_layout_width = Some(bounds.size.width); + state.last_layout_bounds = Some(bounds); let list_state = self.state.clone(); let height = bounds.size.height; From b4135dd2f1aa7f1da9daa3245f29d6b963ef0d6b Mon Sep 17 00:00:00 2001 From: Mikayla Date: Fri, 15 Dec 2023 10:26:41 -0800 Subject: [PATCH 076/644] Fix editor mouse event dispatch --- crates/editor2/src/editor.rs | 2 +- crates/editor2/src/element.rs | 106 ++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 51 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 664d1d7380634426aa4a8264c4ed66aef008c265..c6d83ef24e498cc85b0280a5d0f1fbc9eed0ed93 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -9758,7 +9758,7 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend .px_1p5() .child(HighlightedLabel::new(line.clone(), highlights.clone())) .child( - div().border().border_color(gpui::red()).child( + div().z_index(1).child( IconButton::new(copy_id.clone(), Icon::Copy) .icon_color(Color::Muted) .size(ButtonSize::Compact) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index a6d4bc20b157d4f80a816d5dc78eb7980277cdc2..a04af377b432967ccf01046e824c027ace7549ec 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -2447,13 +2447,13 @@ impl EditorElement { let interactive_bounds = interactive_bounds.clone(); move |event: &ScrollWheelEvent, phase, cx| { - if phase != DispatchPhase::Bubble { - return; + if phase == DispatchPhase::Bubble + && interactive_bounds.visibly_contains(&event.position, cx) + { + editor.update(cx, |editor, cx| { + Self::scroll(editor, event, &position_map, &interactive_bounds, cx) + }); } - - editor.update(cx, |editor, cx| { - Self::scroll(editor, event, &position_map, &interactive_bounds, cx) - }); } }); @@ -2461,29 +2461,30 @@ impl EditorElement { let position_map = layout.position_map.clone(); let editor = self.editor.clone(); let stacking_order = cx.stacking_order().clone(); + let interactive_bounds = interactive_bounds.clone(); move |event: &MouseDownEvent, phase, cx| { - if phase != DispatchPhase::Bubble { - return; + if phase == DispatchPhase::Bubble + && interactive_bounds.visibly_contains(&event.position, cx) + { + match event.button { + MouseButton::Left => editor.update(cx, |editor, cx| { + Self::mouse_left_down( + editor, + event, + &position_map, + text_bounds, + gutter_bounds, + &stacking_order, + cx, + ); + }), + MouseButton::Right => editor.update(cx, |editor, cx| { + Self::mouse_right_down(editor, event, &position_map, text_bounds, cx); + }), + _ => {} + }; } - - match event.button { - MouseButton::Left => editor.update(cx, |editor, cx| { - Self::mouse_left_down( - editor, - event, - &position_map, - text_bounds, - gutter_bounds, - &stacking_order, - cx, - ); - }), - MouseButton::Right => editor.update(cx, |editor, cx| { - Self::mouse_right_down(editor, event, &position_map, text_bounds, cx); - }), - _ => {} - }; } }); @@ -2491,18 +2492,23 @@ impl EditorElement { let position_map = layout.position_map.clone(); let editor = self.editor.clone(); let stacking_order = cx.stacking_order().clone(); + let interactive_bounds = interactive_bounds.clone(); move |event: &MouseUpEvent, phase, cx| { - editor.update(cx, |editor, cx| { - Self::mouse_up( - editor, - event, - &position_map, - text_bounds, - &stacking_order, - cx, - ) - }); + if phase == DispatchPhase::Bubble + && interactive_bounds.visibly_contains(&event.position, cx) + { + editor.update(cx, |editor, cx| { + Self::mouse_up( + editor, + event, + &position_map, + text_bounds, + &stacking_order, + cx, + ) + }); + } } }); cx.on_mouse_event({ @@ -2511,21 +2517,21 @@ impl EditorElement { let stacking_order = cx.stacking_order().clone(); move |event: &MouseMoveEvent, phase, cx| { - if phase != DispatchPhase::Bubble { - return; + if phase == DispatchPhase::Bubble + && interactive_bounds.visibly_contains(&event.position, cx) + { + editor.update(cx, |editor, cx| { + Self::mouse_moved( + editor, + event, + &position_map, + text_bounds, + gutter_bounds, + &stacking_order, + cx, + ) + }); } - - editor.update(cx, |editor, cx| { - Self::mouse_moved( - editor, - event, - &position_map, - text_bounds, - gutter_bounds, - &stacking_order, - cx, - ) - }); } }); } From a40f04b71fd72e3818d3b9f23c4e31c30c4d47b6 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 13:50:51 -0500 Subject: [PATCH 077/644] Only scroll enough to reveal the next channel if it isn't visible Co-authored-by: Max --- crates/collab_ui2/src/collab_panel.rs | 5 +--- crates/gpui2/src/elements/list.rs | 33 +++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 6f21649dd6a07f4d47ecb69e7f7183d4c4b789b3..1ca6101c54a19cfd51f4e05c34a0dcb0bbb4fc3d 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -584,10 +584,7 @@ impl CollabPanel { } fn scroll_to_item(&mut self, ix: usize) { - self.list_state.scroll_to(ListOffset { - item_ix: ix, - offset_in_item: px(0.), - }) + self.list_state.scroll_to_reveal_item(ix) } fn update_entries(&mut self, select_same_item: bool, cx: &mut ViewContext) { diff --git a/crates/gpui2/src/elements/list.rs b/crates/gpui2/src/elements/list.rs index 108703370cf4ab12cb7cc2e7bbb6464fab7892f3..415a3b7368bb6a88049ec5377bb1aafc21b3596e 100644 --- a/crates/gpui2/src/elements/list.rs +++ b/crates/gpui2/src/elements/list.rs @@ -154,11 +154,40 @@ impl ListState { state.logical_scroll_top = Some(scroll_top); } + pub fn scroll_to_reveal_item(&self, ix: usize) { + let state = &mut *self.0.borrow_mut(); + let mut scroll_top = state.logical_scroll_top(); + let height = state + .last_layout_bounds + .map_or(px(0.), |bounds| bounds.size.height); + + if ix <= scroll_top.item_ix { + scroll_top.item_ix = ix; + scroll_top.offset_in_item = px(0.); + } else { + let mut cursor = state.items.cursor::(); + cursor.seek(&Count(ix + 1), Bias::Right, &()); + let bottom = cursor.start().height; + let goal_top = px(0.).max(bottom - height); + + cursor.seek(&Height(goal_top), Bias::Left, &()); + let start_ix = cursor.start().count; + let start_item_top = cursor.start().height; + + if start_ix >= scroll_top.item_ix { + scroll_top.item_ix = start_ix; + scroll_top.offset_in_item = goal_top - start_item_top; + } + } + + state.logical_scroll_top = Some(scroll_top); + } + /// Get the bounds for the given item in window coordinates. pub fn bounds_for_item(&self, ix: usize) -> Option> { let state = &*self.0.borrow(); let bounds = state.last_layout_bounds.unwrap_or_default(); - let scroll_top = state.logical_scroll_top.unwrap_or_default(); + let scroll_top = state.logical_scroll_top(); if ix < scroll_top.item_ix { return None; @@ -264,7 +293,7 @@ impl std::fmt::Debug for ListItem { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Clone, Copy)] pub struct ListOffset { pub item_ix: usize, pub offset_in_item: Pixels, From d0dbf8e1e269ae46ae456cf2485b70011134b8b7 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 15 Dec 2023 11:59:06 -0700 Subject: [PATCH 078/644] Fix bug where vim commands were copied on each update_matches In zed1, the array of commands was recalculated on every update_matches, In zed2 it's cached before we change the focus. --- crates/command_palette2/src/command_palette.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/command_palette2/src/command_palette.rs b/crates/command_palette2/src/command_palette.rs index 393fb16f8148b5f61d3591a1af5e7189fc033aeb..04efe1df53ae200273dc6d35e9231b55304571c2 100644 --- a/crates/command_palette2/src/command_palette.rs +++ b/crates/command_palette2/src/command_palette.rs @@ -101,6 +101,7 @@ pub struct CommandInterceptResult { pub struct CommandPaletteDelegate { command_palette: WeakView, + all_commands: Vec, commands: Vec, matches: Vec, selected_ix: usize, @@ -135,6 +136,7 @@ impl CommandPaletteDelegate { ) -> Self { Self { command_palette, + all_commands: commands.clone(), matches: vec![], commands, selected_ix: 0, @@ -167,7 +169,7 @@ impl PickerDelegate for CommandPaletteDelegate { query: String, cx: &mut ViewContext>, ) -> gpui::Task<()> { - let mut commands = self.commands.clone(); + let mut commands = self.all_commands.clone(); cx.spawn(move |picker, mut cx| async move { cx.read_global::(|hit_counts, _| { From 541712790295a6950afbf610a44d755b4c9ae143 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 14:01:24 -0500 Subject: [PATCH 079/644] Fix channel drag and drop Also add the ability to unnest a channel by dragging it to the "Channels" header. This is currently not working due to a collab server issue. Co-authored-by: Max --- crates/collab_ui2/src/collab_panel.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 1ca6101c54a19cfd51f4e05c34a0dcb0bbb4fc3d..c2da29ba9f0ceffe488be53c3d1cb17938ccfd23 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2225,14 +2225,14 @@ impl CollabPanel { .selected(is_selected), ) .when(section == Section::Channels, |el| { - el.drag_over::(|style| { + el.drag_over::(|style| { style.bg(cx.theme().colors().ghost_element_hover) }) .on_drop(cx.listener( - move |this, view: &View, cx| { + move |this, dragged_channel: &Channel, cx| { this.channel_store .update(cx, |channel_store, cx| { - channel_store.move_channel(view.read(cx).channel.id, None, cx) + channel_store.move_channel(dragged_channel.id, None, cx) }) .detach_and_log_err(cx) }, @@ -2451,15 +2451,15 @@ impl CollabPanel { width, }) }) - .drag_over::(|style| { + .drag_over::(|style| { style.bg(cx.theme().colors().ghost_element_hover) }) .on_drop( - cx.listener(move |this, view: &View, cx| { + cx.listener(move |this, dragged_channel: &Channel, cx| { this.channel_store .update(cx, |channel_store, cx| { channel_store.move_channel( - view.read(cx).channel.id, + dragged_channel.id, Some(channel_id), cx, ) From 5c060ceb1c2e3ae85503f89c57da34ac8e4446ad Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 14:03:49 -0500 Subject: [PATCH 080/644] Format code --- crates/collab_ui2/src/collab_panel.rs | 34 +++++++++------------------ 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index c2da29ba9f0ceffe488be53c3d1cb17938ccfd23..ec723df25d740c5d020eecb378a35978dd179baf 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2225,18 +2225,14 @@ impl CollabPanel { .selected(is_selected), ) .when(section == Section::Channels, |el| { - el.drag_over::(|style| { - style.bg(cx.theme().colors().ghost_element_hover) - }) - .on_drop(cx.listener( - move |this, dragged_channel: &Channel, cx| { + el.drag_over::(|style| style.bg(cx.theme().colors().ghost_element_hover)) + .on_drop(cx.listener(move |this, dragged_channel: &Channel, cx| { this.channel_store .update(cx, |channel_store, cx| { channel_store.move_channel(dragged_channel.id, None, cx) }) .detach_and_log_err(cx) - }, - )) + })) }); if section == Section::Offline { @@ -2451,22 +2447,14 @@ impl CollabPanel { width, }) }) - .drag_over::(|style| { - style.bg(cx.theme().colors().ghost_element_hover) - }) - .on_drop( - cx.listener(move |this, dragged_channel: &Channel, cx| { - this.channel_store - .update(cx, |channel_store, cx| { - channel_store.move_channel( - dragged_channel.id, - Some(channel_id), - cx, - ) - }) - .detach_and_log_err(cx) - }), - ) + .drag_over::(|style| style.bg(cx.theme().colors().ghost_element_hover)) + .on_drop(cx.listener(move |this, dragged_channel: &Channel, cx| { + this.channel_store + .update(cx, |channel_store, cx| { + channel_store.move_channel(dragged_channel.id, Some(channel_id), cx) + }) + .detach_and_log_err(cx) + })) .child( ListItem::new(channel_id as usize) // Offset the indent depth by one to give us room to show the disclosure. From 793381f4552378b5d8d65e8f73d8243acd372322 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 14 Dec 2023 17:41:29 -0800 Subject: [PATCH 081/644] Render zoomed item in the workspace --- crates/workspace2/src/workspace2.rs | 49 ++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index a789809537d1bf5fdc530cf293d5f8b9d542c8b2..f2482d034c1de03950aba7d62639241f806c0eae 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -3556,6 +3556,8 @@ impl Render for Workspace { ) }; + let theme = cx.theme().clone(); + let colors = theme.colors(); cx.set_rem_size(ui_font_size); self.actions(div(), cx) @@ -3568,10 +3570,10 @@ impl Render for Workspace { .gap_0() .justify_start() .items_start() - .text_color(cx.theme().colors().text) - .bg(cx.theme().colors().background) + .text_color(colors.text) + .bg(colors.background) .border() - .border_color(cx.theme().colors().border) + .border_color(colors.border) .children(self.titlebar_item.clone()) .child( div() @@ -3584,7 +3586,7 @@ impl Render for Workspace { .overflow_hidden() .border_t() .border_b() - .border_color(cx.theme().colors().border) + .border_color(colors.border) .child( canvas(cx.listener(|workspace, bounds, _| { workspace.bounds = *bounds; @@ -3623,13 +3625,17 @@ impl Render for Workspace { .flex_row() .h_full() // Left Dock - .child( - div() - .flex() - .flex_none() - .overflow_hidden() - .child(self.left_dock.clone()), - ) + .children(if self.zoomed_position == Some(DockPosition::Left) { + None + } else { + Some( + div() + .flex() + .flex_none() + .overflow_hidden() + .child(self.left_dock.clone()), + ) + }) // Panes .child( div() @@ -3657,7 +3663,26 @@ impl Render for Workspace { .child(self.right_dock.clone()), ), ) - .children(self.render_notifications(cx)), + .children(self.render_notifications(cx)) + .children(self.zoomed.as_ref().and_then(|view| { + let zoomed_view = view.upgrade()?; + let div = div() + .z_index(1) + .absolute() + .overflow_hidden() + .border_color(colors.border) + .bg(colors.background) + .child(zoomed_view) + .inset_0() + .shadow_lg(); + + Some(match self.zoomed_position { + Some(DockPosition::Left) => div.right_2().border_r(), + Some(DockPosition::Right) => div.left_2().border_l(), + Some(DockPosition::Bottom) => div.top_2().border_t(), + None => div.top_2().bottom_2().left_2().right_2().border(), + }) + })), ) .child(self.status_bar.clone()) } From b1a61ca21e9fd4b2b615f9c61012d54b9895832b Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 14:44:29 -0500 Subject: [PATCH 082/644] Fix toolbar width (#3681) This PR fixes an issue with the toolbar width introduced in #3666. The lack of a flex container was making the toolbar contents not take up the full width, and thus not positions items correctly along its main axis. Release Notes: - N/A --- crates/workspace2/src/pane.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 11588212ef76e3891c57fc5a14778fd8e48a9e37..65e7f2a1063add17b8321f6594746871af418bdc 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1897,19 +1897,14 @@ impl Render for Pane { .on_drag_move::(cx.listener(Self::handle_drag_move)) .map(|div| { if let Some(item) = self.active_item() { - div.flex_col() + div.v_flex() .child(self.toolbar.clone()) .child(item.to_any()) } else { - div.flex() - .flex_row() - .items_center() - .size_full() - .justify_center() - .child( - Label::new("Open a file or project to get started.") - .color(Color::Muted), - ) + div.h_flex().size_full().justify_center().child( + Label::new("Open a file or project to get started.") + .color(Color::Muted), + ) } }) .child( From a4c123bb1103d1953b6bbdee6ef001845069bee0 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 15 Dec 2023 11:47:01 -0800 Subject: [PATCH 083/644] Fix logic for activating panel when re-docking it --- crates/workspace2/src/dock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index f76bb82177084f2e638e31e0e88bad8a3552a182..e44471a871ac416546657880964720f3ee638d3c 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -317,7 +317,7 @@ impl Dock { new_dock.add_panel(panel.clone(), workspace.clone(), cx); if was_visible { new_dock.set_open(true, cx); - new_dock.activate_panel(this.panels_len() - 1, cx); + new_dock.activate_panel(new_dock.panels_len() - 1, cx); } }); } From 9a8225c8553e7d6208fd1a962fc182f5f3eb3c89 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 15 Dec 2023 11:48:25 -0800 Subject: [PATCH 084/644] When a dock is zoomed, don't render it in its normal place --- crates/workspace2/src/workspace2.rs | 165 ++++------------------------ 1 file changed, 19 insertions(+), 146 deletions(-) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index f2482d034c1de03950aba7d62639241f806c0eae..866762e7d5e3cabf301decb43f32fb8e9a1c7645 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -3625,17 +3625,15 @@ impl Render for Workspace { .flex_row() .h_full() // Left Dock - .children(if self.zoomed_position == Some(DockPosition::Left) { - None - } else { - Some( + .children(self.zoomed_position.ne(&Some(DockPosition::Left)).then( + || { div() .flex() .flex_none() .overflow_hidden() - .child(self.left_dock.clone()), - ) - }) + .child(self.left_dock.clone()) + }, + )) // Panes .child( div() @@ -3652,16 +3650,22 @@ impl Render for Workspace { &self.app_state, cx, )) - .child(self.bottom_dock.clone()), + .children( + self.zoomed_position + .ne(&Some(DockPosition::Bottom)) + .then(|| self.bottom_dock.clone()), + ), ) // Right Dock - .child( - div() - .flex() - .flex_none() - .overflow_hidden() - .child(self.right_dock.clone()), - ), + .children(self.zoomed_position.ne(&Some(DockPosition::Right)).then( + || { + div() + .flex() + .flex_none() + .overflow_hidden() + .child(self.right_dock.clone()) + }, + )), ) .children(self.render_notifications(cx)) .children(self.zoomed.as_ref().and_then(|view| { @@ -3688,137 +3692,6 @@ impl Render for Workspace { } } -// impl View for Workspace { - -// fn render(&mut self, cx: &mut ViewContext) -> AnyElement { -// let theme = theme::current(cx).clone(); -// Stack::new() -// .with_child( -// Flex::column() -// .with_child(self.render_titlebar(&theme, cx)) -// .with_child( -// Stack::new() -// .with_child({ -// let project = self.project.clone(); -// Flex::row() -// .with_children(self.render_dock(DockPosition::Left, cx)) -// .with_child( -// Flex::column() -// .with_child( -// FlexItem::new( -// self.center.render( -// &project, -// &theme, -// &self.follower_states, -// self.active_call(), -// self.active_pane(), -// self.zoomed -// .as_ref() -// .and_then(|zoomed| zoomed.upgrade(cx)) -// .as_ref(), -// &self.app_state, -// cx, -// ), -// ) -// .flex(1., true), -// ) -// .with_children( -// self.render_dock(DockPosition::Bottom, cx), -// ) -// .flex(1., true), -// ) -// .with_children(self.render_dock(DockPosition::Right, cx)) -// }) -// .with_child(Overlay::new( -// Stack::new() -// .with_children(self.zoomed.as_ref().and_then(|zoomed| { -// enum ZoomBackground {} -// let zoomed = zoomed.upgrade(cx)?; - -// let mut foreground_style = -// theme.workspace.zoomed_pane_foreground; -// if let Some(zoomed_dock_position) = self.zoomed_position { -// foreground_style = -// theme.workspace.zoomed_panel_foreground; -// let margin = foreground_style.margin.top; -// let border = foreground_style.border.top; - -// // Only include a margin and border on the opposite side. -// foreground_style.margin.top = 0.; -// foreground_style.margin.left = 0.; -// foreground_style.margin.bottom = 0.; -// foreground_style.margin.right = 0.; -// foreground_style.border.top = false; -// foreground_style.border.left = false; -// foreground_style.border.bottom = false; -// foreground_style.border.right = false; -// match zoomed_dock_position { -// DockPosition::Left => { -// foreground_style.margin.right = margin; -// foreground_style.border.right = border; -// } -// DockPosition::Right => { -// foreground_style.margin.left = margin; -// foreground_style.border.left = border; -// } -// DockPosition::Bottom => { -// foreground_style.margin.top = margin; -// foreground_style.border.top = border; -// } -// } -// } - -// Some( -// ChildView::new(&zoomed, cx) -// .contained() -// .with_style(foreground_style) -// .aligned() -// .contained() -// .with_style(theme.workspace.zoomed_background) -// .mouse::(0) -// .capture_all() -// .on_down( -// MouseButton::Left, -// |_, this: &mut Self, cx| { -// this.zoom_out(cx); -// }, -// ), -// ) -// })) -// .with_children(self.modal.as_ref().map(|modal| { -// // Prevent clicks within the modal from falling -// // through to the rest of the workspace. -// enum ModalBackground {} -// MouseEventHandler::new::( -// 0, -// cx, -// |_, cx| ChildView::new(modal.view.as_any(), cx), -// ) -// .on_click(MouseButton::Left, |_, _, _| {}) -// .contained() -// .with_style(theme.workspace.modal) -// .aligned() -// .top() -// })) -// .with_children(self.render_notifications(&theme.workspace, cx)), -// )) -// .provide_resize_bounds::() -// .flex(1.0, true), -// ) -// .with_child(ChildView::new(&self.status_bar, cx)) -// .contained() -// .with_background_color(theme.workspace.background), -// ) -// .with_children(DragAndDrop::render(cx)) -// .with_children(self.render_disconnected_overlay(cx)) -// .into_any_named("workspace") -// } - -// fn modifiers_changed(&mut self, e: &ModifiersChangedEvent, cx: &mut ViewContext) -> bool { -// DragAndDrop::::update_modifiers(e.modifiers, cx) -// } -// } - impl WorkspaceStore { pub fn new(client: Arc, cx: &mut ModelContext) -> Self { Self { From a35fdf45fc9de57b7696c4deacbc62c49b26a516 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 15 Dec 2023 12:54:12 -0700 Subject: [PATCH 085/644] Don't scroll beyond end of uniform list --- crates/gpui2/src/elements/uniform_list.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 9fedbad41c580b767d5c4425be1aa7a5c5f3b9b9..27499b93a69dabd081226fa275892ec71662ae81 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -191,7 +191,7 @@ impl Element for UniformList { content_size, &mut element_state.interactive, cx, - |style, scroll_offset, cx| { + |style, mut scroll_offset, cx| { let border = style.border_widths.to_pixels(cx.rem_size()); let padding = style.padding.to_pixels(bounds.size.into(), cx.rem_size()); @@ -204,6 +204,13 @@ impl Element for UniformList { cx.with_z_index(style.z_index.unwrap_or(0), |cx| { style.paint(bounds, cx, |cx| { if self.item_count > 0 { + let min_scroll_offset = + padded_bounds.size.height - (item_height * self.item_count); + if scroll_offset.y < min_scroll_offset { + shared_scroll_offset.borrow_mut().y = min_scroll_offset; + scroll_offset.y = min_scroll_offset; + } + if let Some(scroll_handle) = self.scroll_handle.clone() { scroll_handle.0.borrow_mut().replace(ScrollHandleState { item_height, From 4c3ec0a8e553dbe7afd5779e805a75283ced0597 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 15 Dec 2023 12:00:58 -0800 Subject: [PATCH 086/644] Enable pane tests --- crates/workspace2/src/pane.rs | 1187 +++++++++++++++------------------ 1 file changed, 535 insertions(+), 652 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 11588212ef76e3891c57fc5a14778fd8e48a9e37..e5b4125447668fb1246821f2b4d5d78c8a6d438f 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -177,7 +177,7 @@ pub struct Pane { toolbar: View, new_item_menu: Option>, split_item_menu: Option>, - // tab_context_menu: ViewHandle, + // tab_context_menu: View, workspace: WeakView, project: Model, drag_split_direction: Option, @@ -256,11 +256,11 @@ struct DraggedTab { // struct TabBarContextMenu { // kind: TabBarContextMenuKind, -// handle: ViewHandle, +// handle: View, // } // impl TabBarContextMenu { -// fn handle_if_kind(&self, kind: TabBarContextMenuKind) -> Option> { +// fn handle_if_kind(&self, kind: TabBarContextMenuKind) -> Option> { // if self.kind == kind { // return Some(self.handle.clone()); // } @@ -329,7 +329,7 @@ impl Pane { ) -> Self { // todo!("context menu") // let pane_view_id = cx.view_id(); - // let context_menu = cx.add_view(|cx| ContextMenu::new(pane_view_id, cx)); + // let context_menu = cx.build_view(|cx| ContextMenu::new(pane_view_id, cx)); // context_menu.update(cx, |menu, _| { // menu.set_position_mode(OverlayPositionMode::Local) // }); @@ -368,7 +368,7 @@ impl Pane { // kind: TabBarContextMenuKind::New, // handle: context_menu, // }, - // tab_context_menu: cx.add_view(|cx| ContextMenu::new(pane_view_id, cx)), + // tab_context_menu: cx.build_view(|_| ContextMenu::new(pane_view_id, cx)), workspace, project, // can_drop: Rc::new(|_, _| true), @@ -1968,52 +1968,6 @@ impl Render for Pane { }), ) } - - // fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext) { - // if !self.has_focus { - // self.has_focus = true; - // cx.emit(Event::Focus); - // cx.notify(); - // } - - // self.toolbar.update(cx, |toolbar, cx| { - // toolbar.focus_changed(true, cx); - // }); - - // if let Some(active_item) = self.active_item() { - // if cx.is_self_focused() { - // // Pane was focused directly. We need to either focus a view inside the active item, - // // or focus the active item itself - // if let Some(weak_last_focused_view) = - // self.last_focused_view_by_item.get(&active_item.id()) - // { - // if let Some(last_focused_view) = weak_last_focused_view.upgrade(cx) { - // cx.focus(&last_focused_view); - // return; - // } else { - // self.last_focused_view_by_item.remove(&active_item.id()); - // } - // } - - // cx.focus(active_item.as_any()); - // } else if focused != self.tab_bar_context_menu.handle { - // self.last_focused_view_by_item - // .insert(active_item.id(), focused.downgrade()); - // } - // } - // } - - // fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - // self.has_focus = false; - // self.toolbar.update(cx, |toolbar, cx| { - // toolbar.focus_changed(false, cx); - // }); - // cx.notify(); - // } - - // fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) { - // Self::reset_to_default_keymap_context(keymap); - // } } impl ItemNavHistory { @@ -2171,98 +2125,6 @@ impl NavHistoryState { } } -// pub struct PaneBackdrop { -// child_view: usize, -// child: AnyElement, -// } - -// impl PaneBackdrop { -// pub fn new(pane_item_view: usize, child: AnyElement) -> Self { -// PaneBackdrop { -// child, -// child_view: pane_item_view, -// } -// } -// } - -// impl Element for PaneBackdrop { -// type LayoutState = (); - -// type PaintState = (); - -// fn layout( -// &mut self, -// constraint: gpui::SizeConstraint, -// view: &mut V, -// cx: &mut ViewContext, -// ) -> (Vector2F, Self::LayoutState) { -// let size = self.child.layout(constraint, view, cx); -// (size, ()) -// } - -// fn paint( -// &mut self, -// bounds: RectF, -// visible_bounds: RectF, -// _: &mut Self::LayoutState, -// view: &mut V, -// cx: &mut ViewContext, -// ) -> Self::PaintState { -// let background = theme::current(cx).editor.background; - -// let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); - -// cx.scene().push_quad(gpui::Quad { -// bounds: RectF::new(bounds.origin(), bounds.size()), -// background: Some(background), -// ..Default::default() -// }); - -// let child_view_id = self.child_view; -// cx.scene().push_mouse_region( -// MouseRegion::new::(child_view_id, 0, visible_bounds).on_down( -// gpui::platform::MouseButton::Left, -// move |_, _: &mut V, cx| { -// let window = cx.window(); -// cx.app_context().focus(window, Some(child_view_id)) -// }, -// ), -// ); - -// cx.scene().push_layer(Some(bounds)); -// self.child.paint(bounds.origin(), visible_bounds, view, cx); -// cx.scene().pop_layer(); -// } - -// fn rect_for_text_range( -// &self, -// range_utf16: std::ops::Range, -// _bounds: RectF, -// _visible_bounds: RectF, -// _layout: &Self::LayoutState, -// _paint: &Self::PaintState, -// view: &V, -// cx: &gpui::ViewContext, -// ) -> Option { -// self.child.rect_for_text_range(range_utf16, view, cx) -// } - -// fn debug( -// &self, -// _bounds: RectF, -// _layout: &Self::LayoutState, -// _paint: &Self::PaintState, -// view: &V, -// cx: &gpui::ViewContext, -// ) -> serde_json::Value { -// gpui::json::json!({ -// "type": "Pane Back Drop", -// "view": self.child_view, -// "child": self.child.debug(view, cx), -// }) -// } -// } - fn dirty_message_for(buffer_path: Option) -> String { let path = buffer_path .as_ref() @@ -2272,528 +2134,549 @@ fn dirty_message_for(buffer_path: Option) -> String { format!("{path} contains unsaved edits. Do you want to save it?") } -// todo!("uncomment tests") -// #[cfg(test)] -// mod tests { -// use super::*; -// use crate::item::test::{TestItem, TestProjectItem}; -// use gpui::TestAppContext; -// use project::FakeFs; -// use settings::SettingsStore; - -// #[gpui::test] -// async fn test_remove_active_empty(cx: &mut TestAppContext) { -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// pane.update(cx, |pane, cx| { -// assert!(pane -// .close_active_item(&CloseActiveItem { save_intent: None }, cx) -// .is_none()) -// }); -// } +#[cfg(test)] +mod tests { + use super::*; + use crate::item::test::{TestItem, TestProjectItem}; + use gpui::{TestAppContext, VisualTestContext}; + use project::FakeFs; + use settings::SettingsStore; + use theme::LoadThemes; + + #[gpui::test] + async fn test_remove_active_empty(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + + pane.update(cx, |pane, cx| { + assert!(pane + .close_active_item(&CloseActiveItem { save_intent: None }, cx) + .is_none()) + }); + } -// #[gpui::test] -// async fn test_add_item_with_new_item(cx: &mut TestAppContext) { -// cx.foreground().forbid_parking(); -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// // 1. Add with a destination index -// // a. Add before the active item -// set_labeled_items(&pane, ["A", "B*", "C"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item( -// Box::new(cx.add_view(|_| TestItem::new().with_label("D"))), -// false, -// false, -// Some(0), -// cx, -// ); -// }); -// assert_item_labels(&pane, ["D*", "A", "B", "C"], cx); - -// // b. Add after the active item -// set_labeled_items(&pane, ["A", "B*", "C"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item( -// Box::new(cx.add_view(|_| TestItem::new().with_label("D"))), -// false, -// false, -// Some(2), -// cx, -// ); -// }); -// assert_item_labels(&pane, ["A", "B", "D*", "C"], cx); - -// // c. Add at the end of the item list (including off the length) -// set_labeled_items(&pane, ["A", "B*", "C"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item( -// Box::new(cx.add_view(|_| TestItem::new().with_label("D"))), -// false, -// false, -// Some(5), -// cx, -// ); -// }); -// assert_item_labels(&pane, ["A", "B", "C", "D*"], cx); - -// // 2. Add without a destination index -// // a. Add with active item at the start of the item list -// set_labeled_items(&pane, ["A*", "B", "C"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item( -// Box::new(cx.add_view(|_| TestItem::new().with_label("D"))), -// false, -// false, -// None, -// cx, -// ); -// }); -// set_labeled_items(&pane, ["A", "D*", "B", "C"], cx); - -// // b. Add with active item at the end of the item list -// set_labeled_items(&pane, ["A", "B", "C*"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item( -// Box::new(cx.add_view(|_| TestItem::new().with_label("D"))), -// false, -// false, -// None, -// cx, -// ); -// }); -// assert_item_labels(&pane, ["A", "B", "C", "D*"], cx); -// } + #[gpui::test] + async fn test_add_item_with_new_item(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + + // 1. Add with a destination index + // a. Add before the active item + set_labeled_items(&pane, ["A", "B*", "C"], cx); + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| TestItem::new(cx).with_label("D"))), + false, + false, + Some(0), + cx, + ); + }); + assert_item_labels(&pane, ["D*", "A", "B", "C"], cx); + + // b. Add after the active item + set_labeled_items(&pane, ["A", "B*", "C"], cx); + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| TestItem::new(cx).with_label("D"))), + false, + false, + Some(2), + cx, + ); + }); + assert_item_labels(&pane, ["A", "B", "D*", "C"], cx); + + // c. Add at the end of the item list (including off the length) + set_labeled_items(&pane, ["A", "B*", "C"], cx); + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| TestItem::new(cx).with_label("D"))), + false, + false, + Some(5), + cx, + ); + }); + assert_item_labels(&pane, ["A", "B", "C", "D*"], cx); + + // 2. Add without a destination index + // a. Add with active item at the start of the item list + set_labeled_items(&pane, ["A*", "B", "C"], cx); + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| TestItem::new(cx).with_label("D"))), + false, + false, + None, + cx, + ); + }); + set_labeled_items(&pane, ["A", "D*", "B", "C"], cx); + + // b. Add with active item at the end of the item list + set_labeled_items(&pane, ["A", "B", "C*"], cx); + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| TestItem::new(cx).with_label("D"))), + false, + false, + None, + cx, + ); + }); + assert_item_labels(&pane, ["A", "B", "C", "D*"], cx); + } -// #[gpui::test] -// async fn test_add_item_with_existing_item(cx: &mut TestAppContext) { -// cx.foreground().forbid_parking(); -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// // 1. Add with a destination index -// // 1a. Add before the active item -// let [_, _, _, d] = set_labeled_items(&pane, ["A", "B*", "C", "D"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item(d, false, false, Some(0), cx); -// }); -// assert_item_labels(&pane, ["D*", "A", "B", "C"], cx); - -// // 1b. Add after the active item -// let [_, _, _, d] = set_labeled_items(&pane, ["A", "B*", "C", "D"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item(d, false, false, Some(2), cx); -// }); -// assert_item_labels(&pane, ["A", "B", "D*", "C"], cx); - -// // 1c. Add at the end of the item list (including off the length) -// let [a, _, _, _] = set_labeled_items(&pane, ["A", "B*", "C", "D"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item(a, false, false, Some(5), cx); -// }); -// assert_item_labels(&pane, ["B", "C", "D", "A*"], cx); - -// // 1d. Add same item to active index -// let [_, b, _] = set_labeled_items(&pane, ["A", "B*", "C"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item(b, false, false, Some(1), cx); -// }); -// assert_item_labels(&pane, ["A", "B*", "C"], cx); - -// // 1e. Add item to index after same item in last position -// let [_, _, c] = set_labeled_items(&pane, ["A", "B*", "C"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item(c, false, false, Some(2), cx); -// }); -// assert_item_labels(&pane, ["A", "B", "C*"], cx); - -// // 2. Add without a destination index -// // 2a. Add with active item at the start of the item list -// let [_, _, _, d] = set_labeled_items(&pane, ["A*", "B", "C", "D"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item(d, false, false, None, cx); -// }); -// assert_item_labels(&pane, ["A", "D*", "B", "C"], cx); - -// // 2b. Add with active item at the end of the item list -// let [a, _, _, _] = set_labeled_items(&pane, ["A", "B", "C", "D*"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item(a, false, false, None, cx); -// }); -// assert_item_labels(&pane, ["B", "C", "D", "A*"], cx); - -// // 2c. Add active item to active item at end of list -// let [_, _, c] = set_labeled_items(&pane, ["A", "B", "C*"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item(c, false, false, None, cx); -// }); -// assert_item_labels(&pane, ["A", "B", "C*"], cx); - -// // 2d. Add active item to active item at start of list -// let [a, _, _] = set_labeled_items(&pane, ["A*", "B", "C"], cx); -// pane.update(cx, |pane, cx| { -// pane.add_item(a, false, false, None, cx); -// }); -// assert_item_labels(&pane, ["A*", "B", "C"], cx); -// } + #[gpui::test] + async fn test_add_item_with_existing_item(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); -// #[gpui::test] -// async fn test_add_item_with_same_project_entries(cx: &mut TestAppContext) { -// cx.foreground().forbid_parking(); -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// // singleton view -// pane.update(cx, |pane, cx| { -// let item = TestItem::new() -// .with_singleton(true) -// .with_label("buffer 1") -// .with_project_items(&[TestProjectItem::new(1, "one.txt", cx)]); - -// pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx); -// }); -// assert_item_labels(&pane, ["buffer 1*"], cx); - -// // new singleton view with the same project entry -// pane.update(cx, |pane, cx| { -// let item = TestItem::new() -// .with_singleton(true) -// .with_label("buffer 1") -// .with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]); - -// pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx); -// }); -// assert_item_labels(&pane, ["buffer 1*"], cx); - -// // new singleton view with different project entry -// pane.update(cx, |pane, cx| { -// let item = TestItem::new() -// .with_singleton(true) -// .with_label("buffer 2") -// .with_project_items(&[TestProjectItem::new(2, "2.txt", cx)]); -// pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx); -// }); -// assert_item_labels(&pane, ["buffer 1", "buffer 2*"], cx); - -// // new multibuffer view with the same project entry -// pane.update(cx, |pane, cx| { -// let item = TestItem::new() -// .with_singleton(false) -// .with_label("multibuffer 1") -// .with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]); - -// pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx); -// }); -// assert_item_labels(&pane, ["buffer 1", "buffer 2", "multibuffer 1*"], cx); - -// // another multibuffer view with the same project entry -// pane.update(cx, |pane, cx| { -// let item = TestItem::new() -// .with_singleton(false) -// .with_label("multibuffer 1b") -// .with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]); - -// pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx); -// }); -// assert_item_labels( -// &pane, -// ["buffer 1", "buffer 2", "multibuffer 1", "multibuffer 1b*"], -// cx, -// ); -// } + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); -// #[gpui::test] -// async fn test_remove_item_ordering(cx: &mut TestAppContext) { -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// add_labeled_item(&pane, "A", false, cx); -// add_labeled_item(&pane, "B", false, cx); -// add_labeled_item(&pane, "C", false, cx); -// add_labeled_item(&pane, "D", false, cx); -// assert_item_labels(&pane, ["A", "B", "C", "D*"], cx); - -// pane.update(cx, |pane, cx| pane.activate_item(1, false, false, cx)); -// add_labeled_item(&pane, "1", false, cx); -// assert_item_labels(&pane, ["A", "B", "1*", "C", "D"], cx); - -// pane.update(cx, |pane, cx| { -// pane.close_active_item(&CloseActiveItem { save_intent: None }, cx) -// }) -// .unwrap() -// .await -// .unwrap(); -// assert_item_labels(&pane, ["A", "B*", "C", "D"], cx); - -// pane.update(cx, |pane, cx| pane.activate_item(3, false, false, cx)); -// assert_item_labels(&pane, ["A", "B", "C", "D*"], cx); - -// pane.update(cx, |pane, cx| { -// pane.close_active_item(&CloseActiveItem { save_intent: None }, cx) -// }) -// .unwrap() -// .await -// .unwrap(); -// assert_item_labels(&pane, ["A", "B*", "C"], cx); - -// pane.update(cx, |pane, cx| { -// pane.close_active_item(&CloseActiveItem { save_intent: None }, cx) -// }) -// .unwrap() -// .await -// .unwrap(); -// assert_item_labels(&pane, ["A", "C*"], cx); - -// pane.update(cx, |pane, cx| { -// pane.close_active_item(&CloseActiveItem { save_intent: None }, cx) -// }) -// .unwrap() -// .await -// .unwrap(); -// assert_item_labels(&pane, ["A*"], cx); -// } + // 1. Add with a destination index + // 1a. Add before the active item + let [_, _, _, d] = set_labeled_items(&pane, ["A", "B*", "C", "D"], cx); + pane.update(cx, |pane, cx| { + pane.add_item(d, false, false, Some(0), cx); + }); + assert_item_labels(&pane, ["D*", "A", "B", "C"], cx); -// #[gpui::test] -// async fn test_close_inactive_items(cx: &mut TestAppContext) { -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx); - -// pane.update(cx, |pane, cx| { -// pane.close_inactive_items(&CloseInactiveItems, cx) -// }) -// .unwrap() -// .await -// .unwrap(); -// assert_item_labels(&pane, ["C*"], cx); -// } + // 1b. Add after the active item + let [_, _, _, d] = set_labeled_items(&pane, ["A", "B*", "C", "D"], cx); + pane.update(cx, |pane, cx| { + pane.add_item(d, false, false, Some(2), cx); + }); + assert_item_labels(&pane, ["A", "B", "D*", "C"], cx); -// #[gpui::test] -// async fn test_close_clean_items(cx: &mut TestAppContext) { -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// add_labeled_item(&pane, "A", true, cx); -// add_labeled_item(&pane, "B", false, cx); -// add_labeled_item(&pane, "C", true, cx); -// add_labeled_item(&pane, "D", false, cx); -// add_labeled_item(&pane, "E", false, cx); -// assert_item_labels(&pane, ["A^", "B", "C^", "D", "E*"], cx); - -// pane.update(cx, |pane, cx| pane.close_clean_items(&CloseCleanItems, cx)) -// .unwrap() -// .await -// .unwrap(); -// assert_item_labels(&pane, ["A^", "C*^"], cx); -// } + // 1c. Add at the end of the item list (including off the length) + let [a, _, _, _] = set_labeled_items(&pane, ["A", "B*", "C", "D"], cx); + pane.update(cx, |pane, cx| { + pane.add_item(a, false, false, Some(5), cx); + }); + assert_item_labels(&pane, ["B", "C", "D", "A*"], cx); -// #[gpui::test] -// async fn test_close_items_to_the_left(cx: &mut TestAppContext) { -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx); - -// pane.update(cx, |pane, cx| { -// pane.close_items_to_the_left(&CloseItemsToTheLeft, cx) -// }) -// .unwrap() -// .await -// .unwrap(); -// assert_item_labels(&pane, ["C*", "D", "E"], cx); -// } + // 1d. Add same item to active index + let [_, b, _] = set_labeled_items(&pane, ["A", "B*", "C"], cx); + pane.update(cx, |pane, cx| { + pane.add_item(b, false, false, Some(1), cx); + }); + assert_item_labels(&pane, ["A", "B*", "C"], cx); -// #[gpui::test] -// async fn test_close_items_to_the_right(cx: &mut TestAppContext) { -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx); - -// pane.update(cx, |pane, cx| { -// pane.close_items_to_the_right(&CloseItemsToTheRight, cx) -// }) -// .unwrap() -// .await -// .unwrap(); -// assert_item_labels(&pane, ["A", "B", "C*"], cx); -// } + // 1e. Add item to index after same item in last position + let [_, _, c] = set_labeled_items(&pane, ["A", "B*", "C"], cx); + pane.update(cx, |pane, cx| { + pane.add_item(c, false, false, Some(2), cx); + }); + assert_item_labels(&pane, ["A", "B", "C*"], cx); -// #[gpui::test] -// async fn test_close_all_items(cx: &mut TestAppContext) { -// init_test(cx); -// let fs = FakeFs::new(cx.background()); - -// let project = Project::test(fs, None, cx).await; -// let window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); -// let workspace = window.root(cx); -// let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone()); - -// add_labeled_item(&pane, "A", false, cx); -// add_labeled_item(&pane, "B", false, cx); -// add_labeled_item(&pane, "C", false, cx); -// assert_item_labels(&pane, ["A", "B", "C*"], cx); - -// pane.update(cx, |pane, cx| { -// pane.close_all_items(&CloseAllItems { save_intent: None }, cx) -// }) -// .unwrap() -// .await -// .unwrap(); -// assert_item_labels(&pane, [], cx); - -// add_labeled_item(&pane, "A", true, cx); -// add_labeled_item(&pane, "B", true, cx); -// add_labeled_item(&pane, "C", true, cx); -// assert_item_labels(&pane, ["A^", "B^", "C*^"], cx); - -// let save = pane -// .update(cx, |pane, cx| { -// pane.close_all_items(&CloseAllItems { save_intent: None }, cx) -// }) -// .unwrap(); - -// cx.foreground().run_until_parked(); -// window.simulate_prompt_answer(2, cx); -// save.await.unwrap(); -// assert_item_labels(&pane, [], cx); -// } + // 2. Add without a destination index + // 2a. Add with active item at the start of the item list + let [_, _, _, d] = set_labeled_items(&pane, ["A*", "B", "C", "D"], cx); + pane.update(cx, |pane, cx| { + pane.add_item(d, false, false, None, cx); + }); + assert_item_labels(&pane, ["A", "D*", "B", "C"], cx); -// fn init_test(cx: &mut TestAppContext) { -// cx.update(|cx| { -// cx.set_global(SettingsStore::test(cx)); -// theme::init((), cx); -// crate::init_settings(cx); -// Project::init_settings(cx); -// }); -// } + // 2b. Add with active item at the end of the item list + let [a, _, _, _] = set_labeled_items(&pane, ["A", "B", "C", "D*"], cx); + pane.update(cx, |pane, cx| { + pane.add_item(a, false, false, None, cx); + }); + assert_item_labels(&pane, ["B", "C", "D", "A*"], cx); -// fn add_labeled_item( -// pane: &ViewHandle, -// label: &str, -// is_dirty: bool, -// cx: &mut TestAppContext, -// ) -> Box> { -// pane.update(cx, |pane, cx| { -// let labeled_item = -// Box::new(cx.add_view(|_| TestItem::new().with_label(label).with_dirty(is_dirty))); -// pane.add_item(labeled_item.clone(), false, false, None, cx); -// labeled_item -// }) -// } + // 2c. Add active item to active item at end of list + let [_, _, c] = set_labeled_items(&pane, ["A", "B", "C*"], cx); + pane.update(cx, |pane, cx| { + pane.add_item(c, false, false, None, cx); + }); + assert_item_labels(&pane, ["A", "B", "C*"], cx); -// fn set_labeled_items( -// pane: &ViewHandle, -// labels: [&str; COUNT], -// cx: &mut TestAppContext, -// ) -> [Box>; COUNT] { -// pane.update(cx, |pane, cx| { -// pane.items.clear(); -// let mut active_item_index = 0; - -// let mut index = 0; -// let items = labels.map(|mut label| { -// if label.ends_with("*") { -// label = label.trim_end_matches("*"); -// active_item_index = index; -// } - -// let labeled_item = Box::new(cx.add_view(|_| TestItem::new().with_label(label))); -// pane.add_item(labeled_item.clone(), false, false, None, cx); -// index += 1; -// labeled_item -// }); - -// pane.activate_item(active_item_index, false, false, cx); - -// items -// }) -// } + // 2d. Add active item to active item at start of list + let [a, _, _] = set_labeled_items(&pane, ["A*", "B", "C"], cx); + pane.update(cx, |pane, cx| { + pane.add_item(a, false, false, None, cx); + }); + assert_item_labels(&pane, ["A*", "B", "C"], cx); + } + + #[gpui::test] + async fn test_add_item_with_same_project_entries(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + + // singleton view + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| { + TestItem::new(cx) + .with_singleton(true) + .with_label("buffer 1") + .with_project_items(&[TestProjectItem::new(1, "one.txt", cx)]) + })), + false, + false, + None, + cx, + ); + }); + assert_item_labels(&pane, ["buffer 1*"], cx); + + // new singleton view with the same project entry + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| { + TestItem::new(cx) + .with_singleton(true) + .with_label("buffer 1") + .with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]) + })), + false, + false, + None, + cx, + ); + }); + assert_item_labels(&pane, ["buffer 1*"], cx); + + // new singleton view with different project entry + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| { + TestItem::new(cx) + .with_singleton(true) + .with_label("buffer 2") + .with_project_items(&[TestProjectItem::new(2, "2.txt", cx)]) + })), + false, + false, + None, + cx, + ); + }); + assert_item_labels(&pane, ["buffer 1", "buffer 2*"], cx); + + // new multibuffer view with the same project entry + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| { + TestItem::new(cx) + .with_singleton(false) + .with_label("multibuffer 1") + .with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]) + })), + false, + false, + None, + cx, + ); + }); + assert_item_labels(&pane, ["buffer 1", "buffer 2", "multibuffer 1*"], cx); + + // another multibuffer view with the same project entry + pane.update(cx, |pane, cx| { + pane.add_item( + Box::new(cx.build_view(|cx| { + TestItem::new(cx) + .with_singleton(false) + .with_label("multibuffer 1b") + .with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]) + })), + false, + false, + None, + cx, + ); + }); + assert_item_labels( + &pane, + ["buffer 1", "buffer 2", "multibuffer 1", "multibuffer 1b*"], + cx, + ); + } -// // Assert the item label, with the active item label suffixed with a '*' -// fn assert_item_labels( -// pane: &ViewHandle, -// expected_states: [&str; COUNT], -// cx: &mut TestAppContext, -// ) { -// pane.read_with(cx, |pane, cx| { -// let actual_states = pane -// .items -// .iter() -// .enumerate() -// .map(|(ix, item)| { -// let mut state = item -// .as_any() -// .downcast_ref::() -// .unwrap() -// .read(cx) -// .label -// .clone(); -// if ix == pane.active_item_index { -// state.push('*'); -// } -// if item.is_dirty(cx) { -// state.push('^'); -// } -// state -// }) -// .collect::>(); - -// assert_eq!( -// actual_states, expected_states, -// "pane items do not match expectation" -// ); -// }) -// } -// } + #[gpui::test] + async fn test_remove_item_ordering(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + + add_labeled_item(&pane, "A", false, cx); + add_labeled_item(&pane, "B", false, cx); + add_labeled_item(&pane, "C", false, cx); + add_labeled_item(&pane, "D", false, cx); + assert_item_labels(&pane, ["A", "B", "C", "D*"], cx); + + pane.update(cx, |pane, cx| pane.activate_item(1, false, false, cx)); + add_labeled_item(&pane, "1", false, cx); + assert_item_labels(&pane, ["A", "B", "1*", "C", "D"], cx); + + pane.update(cx, |pane, cx| { + pane.close_active_item(&CloseActiveItem { save_intent: None }, cx) + }) + .unwrap() + .await + .unwrap(); + assert_item_labels(&pane, ["A", "B*", "C", "D"], cx); + + pane.update(cx, |pane, cx| pane.activate_item(3, false, false, cx)); + assert_item_labels(&pane, ["A", "B", "C", "D*"], cx); + + pane.update(cx, |pane, cx| { + pane.close_active_item(&CloseActiveItem { save_intent: None }, cx) + }) + .unwrap() + .await + .unwrap(); + assert_item_labels(&pane, ["A", "B*", "C"], cx); + + pane.update(cx, |pane, cx| { + pane.close_active_item(&CloseActiveItem { save_intent: None }, cx) + }) + .unwrap() + .await + .unwrap(); + assert_item_labels(&pane, ["A", "C*"], cx); + + pane.update(cx, |pane, cx| { + pane.close_active_item(&CloseActiveItem { save_intent: None }, cx) + }) + .unwrap() + .await + .unwrap(); + assert_item_labels(&pane, ["A*"], cx); + } + + #[gpui::test] + async fn test_close_inactive_items(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + + set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx); + + pane.update(cx, |pane, cx| { + pane.close_inactive_items(&CloseInactiveItems, cx) + }) + .unwrap() + .await + .unwrap(); + assert_item_labels(&pane, ["C*"], cx); + } + + #[gpui::test] + async fn test_close_clean_items(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + + add_labeled_item(&pane, "A", true, cx); + add_labeled_item(&pane, "B", false, cx); + add_labeled_item(&pane, "C", true, cx); + add_labeled_item(&pane, "D", false, cx); + add_labeled_item(&pane, "E", false, cx); + assert_item_labels(&pane, ["A^", "B", "C^", "D", "E*"], cx); + + pane.update(cx, |pane, cx| pane.close_clean_items(&CloseCleanItems, cx)) + .unwrap() + .await + .unwrap(); + assert_item_labels(&pane, ["A^", "C*^"], cx); + } + + #[gpui::test] + async fn test_close_items_to_the_left(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + + set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx); + + pane.update(cx, |pane, cx| { + pane.close_items_to_the_left(&CloseItemsToTheLeft, cx) + }) + .unwrap() + .await + .unwrap(); + assert_item_labels(&pane, ["C*", "D", "E"], cx); + } + + #[gpui::test] + async fn test_close_items_to_the_right(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + + set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx); + + pane.update(cx, |pane, cx| { + pane.close_items_to_the_right(&CloseItemsToTheRight, cx) + }) + .unwrap() + .await + .unwrap(); + assert_item_labels(&pane, ["A", "B", "C*"], cx); + } + + #[gpui::test] + async fn test_close_all_items(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + + let project = Project::test(fs, None, cx).await; + let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); + let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + + add_labeled_item(&pane, "A", false, cx); + add_labeled_item(&pane, "B", false, cx); + add_labeled_item(&pane, "C", false, cx); + assert_item_labels(&pane, ["A", "B", "C*"], cx); + + pane.update(cx, |pane, cx| { + pane.close_all_items(&CloseAllItems { save_intent: None }, cx) + }) + .unwrap() + .await + .unwrap(); + assert_item_labels(&pane, [], cx); + + add_labeled_item(&pane, "A", true, cx); + add_labeled_item(&pane, "B", true, cx); + add_labeled_item(&pane, "C", true, cx); + assert_item_labels(&pane, ["A^", "B^", "C*^"], cx); + + let save = pane + .update(cx, |pane, cx| { + pane.close_all_items(&CloseAllItems { save_intent: None }, cx) + }) + .unwrap(); + + cx.executor().run_until_parked(); + cx.simulate_prompt_answer(2); + save.await.unwrap(); + assert_item_labels(&pane, [], cx); + } + + fn init_test(cx: &mut TestAppContext) { + cx.update(|cx| { + let settings_store = SettingsStore::test(cx); + cx.set_global(settings_store); + theme::init(LoadThemes::JustBase, cx); + crate::init_settings(cx); + Project::init_settings(cx); + }); + } + + fn add_labeled_item( + pane: &View, + label: &str, + is_dirty: bool, + cx: &mut VisualTestContext, + ) -> Box> { + pane.update(cx, |pane, cx| { + let labeled_item = Box::new( + cx.build_view(|cx| TestItem::new(cx).with_label(label).with_dirty(is_dirty)), + ); + pane.add_item(labeled_item.clone(), false, false, None, cx); + labeled_item + }) + } + + fn set_labeled_items( + pane: &View, + labels: [&str; COUNT], + cx: &mut VisualTestContext, + ) -> [Box>; COUNT] { + pane.update(cx, |pane, cx| { + pane.items.clear(); + let mut active_item_index = 0; + + let mut index = 0; + let items = labels.map(|mut label| { + if label.ends_with("*") { + label = label.trim_end_matches("*"); + active_item_index = index; + } + + let labeled_item = + Box::new(cx.build_view(|cx| TestItem::new(cx).with_label(label))); + pane.add_item(labeled_item.clone(), false, false, None, cx); + index += 1; + labeled_item + }); + + pane.activate_item(active_item_index, false, false, cx); + + items + }) + } + + // Assert the item label, with the active item label suffixed with a '*' + fn assert_item_labels( + pane: &View, + expected_states: [&str; COUNT], + cx: &mut VisualTestContext, + ) { + pane.update(cx, |pane, cx| { + let actual_states = pane + .items + .iter() + .enumerate() + .map(|(ix, item)| { + let mut state = item + .to_any() + .downcast::() + .unwrap() + .read(cx) + .label + .clone(); + if ix == pane.active_item_index { + state.push('*'); + } + if item.is_dirty(cx) { + state.push('^'); + } + state + }) + .collect::>(); + + assert_eq!( + actual_states, expected_states, + "pane items do not match expectation" + ); + }) + } +} impl Render for DraggedTab { type Element = ::Rendered; From 2fe9a1df218009e078e8a885b512346adde3c9aa Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 15 Dec 2023 13:18:51 -0700 Subject: [PATCH 087/644] Restore position of uniform_list padding It should be inside the scrollable area. --- crates/gpui2/src/elements/uniform_list.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 27499b93a69dabd081226fa275892ec71662ae81..866bd4a1d0f695a7cb3c412249c9135d5ba95a95 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -196,16 +196,16 @@ impl Element for UniformList { let padding = style.padding.to_pixels(bounds.size.into(), cx.rem_size()); let padded_bounds = Bounds::from_corners( - bounds.origin + point(border.left + padding.left, border.top + padding.top), - bounds.lower_right() - - point(border.right + padding.right, border.bottom + padding.bottom), + bounds.origin + point(border.left + padding.left, border.top), + bounds.lower_right() - point(border.right + padding.right, border.bottom), ); cx.with_z_index(style.z_index.unwrap_or(0), |cx| { style.paint(bounds, cx, |cx| { if self.item_count > 0 { - let min_scroll_offset = - padded_bounds.size.height - (item_height * self.item_count); + let content_height = + item_height * self.item_count + padding.top + padding.bottom; + let min_scroll_offset = padded_bounds.size.height - content_height; if scroll_offset.y < min_scroll_offset { shared_scroll_offset.borrow_mut().y = min_scroll_offset; scroll_offset.y = min_scroll_offset; @@ -220,7 +220,7 @@ impl Element for UniformList { } let first_visible_element_ix = - (-scroll_offset.y / item_height).floor() as usize; + (-(scroll_offset.y + padding.top) / item_height).floor() as usize; let last_visible_element_ix = ((-scroll_offset.y + padded_bounds.size.height) / item_height) .ceil() as usize; @@ -233,7 +233,10 @@ impl Element for UniformList { cx.with_content_mask(Some(content_mask), |cx| { for (item, ix) in items.iter_mut().zip(visible_range) { let item_origin = padded_bounds.origin - + point(px(0.), item_height * ix + scroll_offset.y); + + point( + px(0.), + item_height * ix + scroll_offset.y + padding.top, + ); let available_space = size( AvailableSpace::Definite(padded_bounds.size.width), AvailableSpace::Definite(item_height), From e71f2b49e8a97dd269a045cdf66d9aae5eef2f5e Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 15 Dec 2023 15:41:53 -0500 Subject: [PATCH 088/644] Style fold control --- crates/editor2/src/element.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index a6d4bc20b157d4f80a816d5dc78eb7980277cdc2..20012ae41d29ce83ba607252e83014b4b2f121da 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -939,11 +939,11 @@ impl EditorElement { cx, |fold_element_state, cx| { if fold_element_state.is_active() { - gpui::blue() + cx.theme().colors().ghost_element_active } else if fold_bounds.contains(&cx.mouse_position()) { - gpui::black() + cx.theme().colors().ghost_element_hover } else { - gpui::red() + cx.theme().colors().ghost_element_background } }, ) From e3e988c150e1ad656d91bdc87039f4da6312c67f Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 15 Dec 2023 13:26:36 -0800 Subject: [PATCH 089/644] Always render panes via pane_group::Member::render Remove distinct code path for rendering panes in a PaneAxis, as this dropped the logic for rendering the leader border and info box. --- crates/workspace2/src/pane_group.rs | 160 +++------------------------- 1 file changed, 14 insertions(+), 146 deletions(-) diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index d35c138d5c8217b32786a2b95cb7c5e9c9009030..4f29f08ef2666f752113a6c347e54c91011f31d9 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -270,6 +270,7 @@ impl Member { project, basis + 1, follower_states, + active_call, active_pane, zoomed, app_state, @@ -277,133 +278,6 @@ impl Member { ) .into_any(), } - - // enum FollowIntoExternalProject {} - - // match self { - // Member::Pane(pane) => { - // let pane_element = if Some(&**pane) == zoomed { - // Empty::new().into_any() - // } else { - // ChildView::new(pane, cx).into_any() - // }; - - // let leader = follower_states.get(pane).and_then(|state| { - // let room = active_call?.read(cx).room()?.read(cx); - // room.remote_participant_for_peer_id(state.leader_id) - // }); - - // let mut leader_border = Border::default(); - // let mut leader_status_box = None; - // if let Some(leader) = &leader { - // let leader_color = theme - // .editor - // .selection_style_for_room_participant(leader.participant_index.0) - // .cursor; - // leader_border = Border::all(theme.workspace.leader_border_width, leader_color); - // leader_border - // .color - // .fade_out(1. - theme.workspace.leader_border_opacity); - // leader_border.overlay = true; - - // leader_status_box = match leader.location { - // ParticipantLocation::SharedProject { - // project_id: leader_project_id, - // } => { - // if Some(leader_project_id) == project.read(cx).remote_id() { - // None - // } else { - // let leader_user = leader.user.clone(); - // let leader_user_id = leader.user.id; - // Some( - // MouseEventHandler::new::( - // pane.id(), - // cx, - // |_, _| { - // Label::new( - // format!( - // "Follow {} to their active project", - // leader_user.github_login, - // ), - // theme - // .workspace - // .external_location_message - // .text - // .clone(), - // ) - // .contained() - // .with_style( - // theme.workspace.external_location_message.container, - // ) - // }, - // ) - // .with_cursor_style(CursorStyle::PointingHand) - // .on_click(MouseButton::Left, move |_, this, cx| { - // crate::join_remote_project( - // leader_project_id, - // leader_user_id, - // this.app_state().clone(), - // cx, - // ) - // .detach_and_log_err(cx); - // }) - // .aligned() - // .bottom() - // .right() - // .into_any(), - // ) - // } - // } - // ParticipantLocation::UnsharedProject => Some( - // Label::new( - // format!( - // "{} is viewing an unshared Zed project", - // leader.user.github_login - // ), - // theme.workspace.external_location_message.text.clone(), - // ) - // .contained() - // .with_style(theme.workspace.external_location_message.container) - // .aligned() - // .bottom() - // .right() - // .into_any(), - // ), - // ParticipantLocation::External => Some( - // Label::new( - // format!( - // "{} is viewing a window outside of Zed", - // leader.user.github_login - // ), - // theme.workspace.external_location_message.text.clone(), - // ) - // .contained() - // .with_style(theme.workspace.external_location_message.container) - // .aligned() - // .bottom() - // .right() - // .into_any(), - // ), - // }; - // } - - // Stack::new() - // .with_child(pane_element.contained().with_border(leader_border)) - // .with_children(leader_status_box) - // .into_any() - // } - // Member::Axis(axis) => axis.render( - // project, - // basis + 1, - // theme, - // follower_states, - // active_call, - // active_pane, - // zoomed, - // app_state, - // cx, - // ), - // } } fn collect_panes<'a>(&'a self, panes: &mut Vec<&'a View>) { @@ -586,6 +460,7 @@ impl PaneAxis { project: &Model, basis: usize, follower_states: &HashMap, FollowerState>, + active_call: Option<&Model>, active_pane: &View, zoomed: Option<&AnyWeakView>, app_state: &Arc, @@ -604,25 +479,18 @@ impl PaneAxis { if member.contains(active_pane) { active_pane_ix = Some(ix); } - - match member { - Member::Axis(axis) => axis - .render( - project, - (basis + ix) * 10, - follower_states, - active_pane, - zoomed, - app_state, - cx, - ) - .into_any_element(), - Member::Pane(pane) => div() - .size_full() - .border() - .child(pane.clone()) - .into_any_element(), - } + member + .render( + project, + (basis + ix) * 10, + follower_states, + active_call, + active_pane, + zoomed, + app_state, + cx, + ) + .into_any_element() })) .with_active_pane(active_pane_ix) .into_any_element() From a5e037befa7067501089928947d51e49c07f9ffe Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 15 Dec 2023 13:26:48 -0800 Subject: [PATCH 090/644] Avoid duplicate render of a pane when it is zoomed --- crates/workspace2/src/pane_group.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index 4f29f08ef2666f752113a6c347e54c91011f31d9..b52cec2b1885516494824c21ae27ee5d91e959b4 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -172,6 +172,10 @@ impl Member { ) -> impl IntoElement { match self { Member::Pane(pane) => { + if zoomed == Some(&pane.downgrade().into()) { + return div().into_any(); + } + let leader = follower_states.get(pane).and_then(|state| { let room = active_call?.read(cx).room()?.read(cx); room.remote_participant_for_peer_id(state.leader_id) From 0ea59d6466e064decc45767b0eb0792ad8f1fcd3 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 16:27:58 -0500 Subject: [PATCH 091/644] Format `zed-local` script --- script/zed-local | 97 ++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 53 deletions(-) diff --git a/script/zed-local b/script/zed-local index 20f0d22ea1a710261f5bc747470062a751047509..6fef809985d2cf840c1e24e09b8b7b13e70195ae 100755 --- a/script/zed-local +++ b/script/zed-local @@ -1,95 +1,86 @@ #!/usr/bin/env node -const {spawn, execFileSync} = require('child_process') +const { spawn, execFileSync } = require("child_process"); -const RESOLUTION_REGEX = /(\d+) x (\d+)/ -const DIGIT_FLAG_REGEX = /^--?(\d+)$/ -const ZED_2_MODE = "--zed2" +const RESOLUTION_REGEX = /(\d+) x (\d+)/; +const DIGIT_FLAG_REGEX = /^--?(\d+)$/; +const ZED_2_MODE = "--zed2"; -const args = process.argv.slice(2) +const args = process.argv.slice(2); // Parse the number of Zed instances to spawn. -let instanceCount = 1 -const digitMatch = args[0]?.match(DIGIT_FLAG_REGEX) +let instanceCount = 1; +const digitMatch = args[0]?.match(DIGIT_FLAG_REGEX); if (digitMatch) { - instanceCount = parseInt(digitMatch[1]) - args.shift() + instanceCount = parseInt(digitMatch[1]); + args.shift(); } -const isZed2 = args.some(arg => arg === ZED_2_MODE); +const isZed2 = args.some((arg) => arg === ZED_2_MODE); if (instanceCount > 4) { - throw new Error('Cannot spawn more than 4 instances') + throw new Error("Cannot spawn more than 4 instances"); } // Parse the resolution of the main screen const displayInfo = JSON.parse( - execFileSync( - 'system_profiler', - ['SPDisplaysDataType', '-json'], - {encoding: 'utf8'} - ) -) -const mainDisplayResolution = displayInfo - ?.SPDisplaysDataType[0] - ?.spdisplays_ndrvs - ?.find(entry => entry.spdisplays_main === "spdisplays_yes") - ?._spdisplays_resolution - ?.match(RESOLUTION_REGEX) + execFileSync("system_profiler", ["SPDisplaysDataType", "-json"], { + encoding: "utf8", + }), +); +const mainDisplayResolution = + displayInfo?.SPDisplaysDataType[0]?.spdisplays_ndrvs + ?.find((entry) => entry.spdisplays_main === "spdisplays_yes") + ?._spdisplays_resolution?.match(RESOLUTION_REGEX); if (!mainDisplayResolution) { - throw new Error('Could not parse screen resolution') + throw new Error("Could not parse screen resolution"); } -const screenWidth = parseInt(mainDisplayResolution[1]) -const screenHeight = parseInt(mainDisplayResolution[2]) +const screenWidth = parseInt(mainDisplayResolution[1]); +const screenHeight = parseInt(mainDisplayResolution[2]); // Determine the window size for each instance -let instanceWidth = screenWidth -let instanceHeight = screenHeight +let instanceWidth = screenWidth; +let instanceHeight = screenHeight; if (instanceCount > 1) { - instanceWidth = Math.floor(screenWidth / 2) + instanceWidth = Math.floor(screenWidth / 2); if (instanceCount > 2) { - instanceHeight = Math.floor(screenHeight / 2) + instanceHeight = Math.floor(screenHeight / 2); } } -let users = [ - 'nathansobo', - 'as-cii', - 'maxbrunsfeld', - 'iamnbutler' -] +let users = ["nathansobo", "as-cii", "maxbrunsfeld", "iamnbutler"]; -const RUST_LOG = process.env.RUST_LOG || 'info' +const RUST_LOG = process.env.RUST_LOG || "info"; // If a user is specified, make sure it's first in the list -const user = process.env.ZED_IMPERSONATE +const user = process.env.ZED_IMPERSONATE; if (user) { - users = [user].concat(users.filter(u => u !== user)) + users = [user].concat(users.filter((u) => u !== user)); } const positions = [ - '0,0', + "0,0", `${instanceWidth},0`, `0,${instanceHeight}`, - `${instanceWidth},${instanceHeight}` -] + `${instanceWidth},${instanceHeight}`, +]; -const buildArgs = isZed2 ? ["build", "-p", "zed2"] : ["build"] -const zedBinary = isZed2 ? "target/debug/Zed2" : "target/debug/Zed" -execFileSync('cargo', buildArgs, { stdio: 'inherit' }) +const buildArgs = isZed2 ? ["build", "-p", "zed2"] : ["build"]; +const zedBinary = isZed2 ? "target/debug/Zed2" : "target/debug/Zed"; +execFileSync("cargo", buildArgs, { stdio: "inherit" }); setTimeout(() => { for (let i = 0; i < instanceCount; i++) { spawn(zedBinary, i == 0 ? args : [], { - stdio: 'inherit', + stdio: "inherit", env: { ZED_IMPERSONATE: users[i], ZED_WINDOW_POSITION: positions[i], - ZED_STATELESS: '1', - ZED_ALWAYS_ACTIVE: '1', - ZED_SERVER_URL: 'http://localhost:8080', - ZED_ADMIN_API_TOKEN: 'secret', + ZED_STATELESS: "1", + ZED_ALWAYS_ACTIVE: "1", + ZED_SERVER_URL: "http://localhost:8080", + ZED_ADMIN_API_TOKEN: "secret", ZED_WINDOW_SIZE: `${instanceWidth},${instanceHeight}`, PATH: process.env.PATH, RUST_LOG, - } - }) + }, + }); } -}, 0.1) +}, 0.1); From 170e3324170797dd38898a2f98cb70c7d9f2ad81 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 16:28:23 -0500 Subject: [PATCH 092/644] Add support for `--release` flag to `zed-local` script --- script/zed-local | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/script/zed-local b/script/zed-local index 6fef809985d2cf840c1e24e09b8b7b13e70195ae..bb0f1bd5da3af5daf56db31a2842d14301e05135 100755 --- a/script/zed-local +++ b/script/zed-local @@ -5,6 +5,7 @@ const { spawn, execFileSync } = require("child_process"); const RESOLUTION_REGEX = /(\d+) x (\d+)/; const DIGIT_FLAG_REGEX = /^--?(\d+)$/; const ZED_2_MODE = "--zed2"; +const RELEASE_MODE = "--release"; const args = process.argv.slice(2); @@ -16,6 +17,7 @@ if (digitMatch) { args.shift(); } const isZed2 = args.some((arg) => arg === ZED_2_MODE); +const isReleaseMode = args.some((arg) => arg === RELEASE_MODE); if (instanceCount > 4) { throw new Error("Cannot spawn more than 4 instances"); } @@ -63,8 +65,25 @@ const positions = [ `${instanceWidth},${instanceHeight}`, ]; -const buildArgs = isZed2 ? ["build", "-p", "zed2"] : ["build"]; -const zedBinary = isZed2 ? "target/debug/Zed2" : "target/debug/Zed"; +const buildArgs = (() => { + const buildArgs = ["build"]; + if (isReleaseMode) { + buildArgs.push("--release"); + } + + if (isZed2) { + buildArgs.push("-p", "zed2"); + } + + return buildArgs; +})(); +const zedBinary = (() => { + const target = isReleaseMode ? "release" : "debug"; + const binary = isZed2 ? "Zed2" : "Zed"; + + return `target/${target}/${binary}`; +})(); + execFileSync("cargo", buildArgs, { stdio: "inherit" }); setTimeout(() => { for (let i = 0; i < instanceCount; i++) { From 149a718d65c6df6a71acdc0a45e8fe5c6907b933 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 15 Dec 2023 13:38:49 -0800 Subject: [PATCH 093/644] Don't scroll List on scroll wheel events outside of its bounds --- crates/gpui2/src/elements/list.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/gpui2/src/elements/list.rs b/crates/gpui2/src/elements/list.rs index 415a3b7368bb6a88049ec5377bb1aafc21b3596e..73bd319afc843cbc3911a03709a991bc6ed22af1 100644 --- a/crates/gpui2/src/elements/list.rs +++ b/crates/gpui2/src/elements/list.rs @@ -458,7 +458,10 @@ impl Element for List { let list_state = self.state.clone(); let height = bounds.size.height; cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { - if phase == DispatchPhase::Bubble { + if phase == DispatchPhase::Bubble + && bounds.contains(&event.position) + && cx.was_top_layer(&event.position, cx.stacking_order()) + { list_state.0.borrow_mut().scroll( &scroll_top, height, From 5447c6d5eeadb6e97ec6e344101ff9ff6b52c10e Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 17:03:59 -0500 Subject: [PATCH 094/644] Fix channel filter input (#3686) This PR fixes the channel filter in the collab panel not showing up. Release Notes: - N/A --- crates/collab_ui2/src/collab_panel.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index ec723df25d740c5d020eecb378a35978dd179baf..5f01d4987838961e9c7e086ec1f115e527bbee33 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2113,8 +2113,8 @@ impl CollabPanel { .size_full() .child(list(self.list_state.clone()).full()) .child( - div().p_2().child( - div() + v_stack().p_2().child( + v_stack() .border_primary(cx) .border_t() .child(self.filter_editor.clone()), From 54eb4521442d0edaf82cfa1104fb8947620ac0a5 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Dec 2023 17:53:10 -0500 Subject: [PATCH 095/644] Only apply scroll correction in `uniform_list` when already scrolled (#3687) This PR fixes an issue where the scroll correction added to the uniform list in a35fdf45fc9de57b7696c4deacbc62c49b26a516 was being applied even if the list wasn't scrolled at all. This manifested in the project panel starting with an incorrect scroll offset that would disappear once scrolled. It seems like we should only need to apply this scroll correction when the list is already scrolled. Release Notes: - N/A --- crates/gpui2/src/elements/uniform_list.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 866bd4a1d0f695a7cb3c412249c9135d5ba95a95..26b1df4cda7c1d125df2f976bf09f9e6e3db6fef 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -206,7 +206,9 @@ impl Element for UniformList { let content_height = item_height * self.item_count + padding.top + padding.bottom; let min_scroll_offset = padded_bounds.size.height - content_height; - if scroll_offset.y < min_scroll_offset { + let is_scrolled = scroll_offset.y != px(0.); + + if is_scrolled && scroll_offset.y < min_scroll_offset { shared_scroll_offset.borrow_mut().y = min_scroll_offset; scroll_offset.y = min_scroll_offset; } From a4cdf365be1c696679ad4be35e648367515a7bc8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 15 Dec 2023 16:15:31 -0800 Subject: [PATCH 096/644] Fix accidental drop of following task. Add back FollowNextCollaborator --- .../collab2/src/tests/channel_buffer_tests.rs | 4 +- crates/workspace2/src/workspace2.rs | 124 +++++++----------- 2 files changed, 53 insertions(+), 75 deletions(-) diff --git a/crates/collab2/src/tests/channel_buffer_tests.rs b/crates/collab2/src/tests/channel_buffer_tests.rs index b0af360fd52ee78300060e669ba38620d07ec4e7..19411ed892b98c613f15d52e19e1365af0738610 100644 --- a/crates/collab2/src/tests/channel_buffer_tests.rs +++ b/crates/collab2/src/tests/channel_buffer_tests.rs @@ -685,7 +685,9 @@ async fn test_following_to_channel_notes_without_a_shared_project( // Client B follows client A. workspace_b .update(cx_b, |workspace, cx| { - workspace.follow(client_a.peer_id().unwrap(), cx).unwrap() + workspace + .start_following(client_a.peer_id().unwrap(), cx) + .unwrap() }) .await .unwrap(); diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 866762e7d5e3cabf301decb43f32fb8e9a1c7645..8cb8c3dc9afd8ac057dd88f350e92b45a45d731c 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -2292,7 +2292,7 @@ impl Workspace { cx.notify(); } - fn start_following( + pub fn start_following( &mut self, leader_id: PeerId, cx: &mut ViewContext, @@ -2347,57 +2347,55 @@ impl Workspace { })) } - // pub fn follow_next_collaborator( - // &mut self, - // _: &FollowNextCollaborator, - // cx: &mut ViewContext, - // ) { - // let collaborators = self.project.read(cx).collaborators(); - // let next_leader_id = if let Some(leader_id) = self.leader_for_pane(&self.active_pane) { - // let mut collaborators = collaborators.keys().copied(); - // for peer_id in collaborators.by_ref() { - // if peer_id == leader_id { - // break; - // } - // } - // collaborators.next() - // } else if let Some(last_leader_id) = - // self.last_leaders_by_pane.get(&self.active_pane.downgrade()) - // { - // if collaborators.contains_key(last_leader_id) { - // Some(*last_leader_id) - // } else { - // None - // } - // } else { - // None - // }; - - // let pane = self.active_pane.clone(); - // let Some(leader_id) = next_leader_id.or_else(|| collaborators.keys().copied().next()) - // else { - // return; - // }; - // if Some(leader_id) == self.unfollow(&pane, cx) { - // return; - // } - // if let Some(task) = self.follow(leader_id, cx) { - // task.detach(); - // } - // } - - pub fn follow( + pub fn follow_next_collaborator( &mut self, - leader_id: PeerId, + _: &FollowNextCollaborator, cx: &mut ViewContext, - ) -> Option>> { - let room = ActiveCall::global(cx).read(cx).room()?.read(cx); - let project = self.project.read(cx); + ) { + let collaborators = self.project.read(cx).collaborators(); + let next_leader_id = if let Some(leader_id) = self.leader_for_pane(&self.active_pane) { + let mut collaborators = collaborators.keys().copied(); + for peer_id in collaborators.by_ref() { + if peer_id == leader_id { + break; + } + } + collaborators.next() + } else if let Some(last_leader_id) = + self.last_leaders_by_pane.get(&self.active_pane.downgrade()) + { + if collaborators.contains_key(last_leader_id) { + Some(*last_leader_id) + } else { + None + } + } else { + None + }; + let pane = self.active_pane.clone(); + let Some(leader_id) = next_leader_id.or_else(|| collaborators.keys().copied().next()) + else { + return; + }; + if Some(leader_id) == self.unfollow(&pane, cx) { + return; + } + self.start_following(leader_id, cx) + .map(|task| task.detach_and_log_err(cx)); + } + + pub fn follow(&mut self, leader_id: PeerId, cx: &mut ViewContext) { + let Some(room) = ActiveCall::global(cx).read(cx).room() else { + return; + }; + let room = room.read(cx); let Some(remote_participant) = room.remote_participant_for_peer_id(leader_id) else { - return None; + return; }; + let project = self.project.read(cx); + let other_project_id = match remote_participant.location { call::ParticipantLocation::External => None, call::ParticipantLocation::UnsharedProject => None, @@ -2413,38 +2411,23 @@ impl Workspace { // if they are active in another project, follow there. if let Some(project_id) = other_project_id { let app_state = self.app_state.clone(); - return Some(crate::join_remote_project( - project_id, - remote_participant.user.id, - app_state, - cx, - )); + crate::join_remote_project(project_id, remote_participant.user.id, app_state, cx) + .detach_and_log_err(cx); } // if you're already following, find the right pane and focus it. for (pane, state) in &self.follower_states { if leader_id == state.leader_id { cx.focus_view(pane); - return None; + return; } } // Otherwise, follow. self.start_following(leader_id, cx) + .map(|task| task.detach_and_log_err(cx)); } - // // if you're already following, find the right pane and focus it. - // for (pane, state) in &self.follower_states { - // if leader_id == state.leader_id { - // cx.focus(pane); - // return None; - // } - // } - - // // Otherwise, follow. - // self.start_following(leader_id, cx) - // } - pub fn unfollow(&mut self, pane: &View, cx: &mut ViewContext) -> Option { let state = self.follower_states.remove(pane)?; let leader_id = state.leader_id; @@ -2855,12 +2838,6 @@ impl Workspace { if leader_in_this_project || !item.is_project_item(cx) { items_to_activate.push((pane.clone(), item.boxed_clone())); } - } else { - log::warn!( - "unknown view id {:?} for leader {:?}", - active_view_id, - leader_id - ); } continue; } @@ -3255,6 +3232,7 @@ impl Workspace { .on_action(cx.listener(Self::close_all_items_and_panes)) .on_action(cx.listener(Self::save_all)) .on_action(cx.listener(Self::add_folder_to_project)) + .on_action(cx.listener(Self::follow_next_collaborator)) .on_action(cx.listener(|workspace, _: &Unfollow, cx| { let pane = workspace.active_pane().clone(); workspace.unfollow(&pane, cx); @@ -4240,9 +4218,7 @@ pub fn join_remote_project( }); if let Some(follow_peer_id) = follow_peer_id { - workspace - .follow(follow_peer_id, cx) - .map(|follow| follow.detach_and_log_err(cx)); + workspace.follow(follow_peer_id, cx); } } })?; From b5ae2f060b420371076a75bc7c94d899e7fb767e Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 15 Dec 2023 16:26:56 -0800 Subject: [PATCH 097/644] Remove div around all avatars in titlebar facepile --- crates/collab_ui2/src/collab_titlebar_item.rs | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 706749b28d349a2b9b30d51375c7818ec1031296..023b77ab8f340a8f46e306aa0578c4037090cdd0 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -401,33 +401,30 @@ impl CollabTitlebarItem { ) -> Option { let followers = project_id.map_or(&[] as &[_], |id| room.followers_for(peer_id, id)); - let pile = FacePile::default().child( - div() - .child( - Avatar::new(user.avatar_uri.clone()) - .grayscale(!is_present) - .border_color(if is_speaking { - gpui::blue() - } else if is_muted { - gpui::red() - } else { - Hsla::default() - }), - ) - .children(followers.iter().filter_map(|follower_peer_id| { - let follower = room - .remote_participants() - .values() - .find_map(|p| (p.peer_id == *follower_peer_id).then_some(&p.user)) - .or_else(|| { - (self.client.peer_id() == Some(*follower_peer_id)) - .then_some(current_user) - })? - .clone(); - - Some(div().child(Avatar::new(follower.avatar_uri.clone()))) - })), - ); + let pile = FacePile::default() + .child( + Avatar::new(user.avatar_uri.clone()) + .grayscale(!is_present) + .border_color(if is_speaking { + gpui::blue() + } else if is_muted { + gpui::red() + } else { + Hsla::default() + }), + ) + .children(followers.iter().filter_map(|follower_peer_id| { + let follower = room + .remote_participants() + .values() + .find_map(|p| (p.peer_id == *follower_peer_id).then_some(&p.user)) + .or_else(|| { + (self.client.peer_id() == Some(*follower_peer_id)).then_some(current_user) + })? + .clone(); + + Some(Avatar::new(follower.avatar_uri.clone())) + })); Some(pile) } From 5a4e2e6b90900fe685ce69ff230da5163f370a76 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 18 Dec 2023 10:41:20 +0100 Subject: [PATCH 098/644] Use a closure to allocate structs onto the `Arena` This is a trick borrowed from Bumpalo that helps LLVM understand it should instantiate the object directly on the heap, as opposed to doing so on the stack and then moving it. --- crates/gpui2/src/arena.rs | 36 ++++++++++++++++-------- crates/gpui2/src/element.rs | 9 +++--- crates/gpui2/src/gpui2.rs | 1 + crates/gpui2/src/window.rs | 56 +++++++++++++++++-------------------- 4 files changed, 55 insertions(+), 47 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index a362c720a2161c3325227891572f43bc3425d114..c99f09d29f46e33117698cfc8ffbacaa239c9e9e 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -12,6 +12,7 @@ struct ArenaElement { } impl Drop for ArenaElement { + #[inline(always)] fn drop(&mut self) { unsafe { (self.drop)(self.value); @@ -48,15 +49,23 @@ impl Arena { } #[inline(always)] - pub fn alloc(&mut self, value: T) -> ArenaRef { + pub fn alloc(&mut self, f: impl FnOnce() -> T) -> ArenaRef { + #[inline(always)] + unsafe fn inner_writer(ptr: *mut T, f: F) + where + F: FnOnce() -> T, + { + ptr::write(ptr, f()); + } + unsafe fn drop(ptr: NonNull) { std::ptr::drop_in_place(ptr.cast::().as_ptr()); } unsafe { - let layout = alloc::Layout::for_value(&value).pad_to_align(); + let layout = alloc::Layout::new::().pad_to_align(); let ptr = NonNull::new_unchecked(self.start.as_ptr().add(self.offset).cast::()); - ptr::write(ptr.as_ptr(), value); + inner_writer(ptr.as_ptr(), f); self.elements.push(ArenaElement { value: ptr.cast(), @@ -92,6 +101,7 @@ impl Clone for ArenaRef { } impl ArenaRef { + #[inline(always)] pub fn map(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaRef { ArenaRef { ptr: unsafe { NonNull::new_unchecked(f(&mut *self)) }, @@ -110,6 +120,7 @@ impl ArenaRef { impl Deref for ArenaRef { type Target = T; + #[inline(always)] fn deref(&self) -> &Self::Target { self.validate(); unsafe { self.ptr.as_ref() } @@ -117,6 +128,7 @@ impl Deref for ArenaRef { } impl DerefMut for ArenaRef { + #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { self.validate(); unsafe { self.ptr.as_mut() } @@ -132,20 +144,20 @@ mod tests { #[test] fn test_arena() { let mut arena = Arena::new(1024); - let a = arena.alloc(1u64); - let b = arena.alloc(2u32); - let c = arena.alloc(3u16); - let d = arena.alloc(4u8); + let a = arena.alloc(|| 1u64); + let b = arena.alloc(|| 2u32); + let c = arena.alloc(|| 3u16); + let d = arena.alloc(|| 4u8); assert_eq!(*a, 1); assert_eq!(*b, 2); assert_eq!(*c, 3); assert_eq!(*d, 4); arena.clear(); - let a = arena.alloc(5u64); - let b = arena.alloc(6u32); - let c = arena.alloc(7u16); - let d = arena.alloc(8u8); + let a = arena.alloc(|| 5u64); + let b = arena.alloc(|| 6u32); + let c = arena.alloc(|| 7u16); + let d = arena.alloc(|| 8u8); assert_eq!(*a, 5); assert_eq!(*b, 6); assert_eq!(*c, 7); @@ -159,7 +171,7 @@ mod tests { self.0.set(true); } } - arena.alloc(DropGuard(dropped.clone())); + arena.alloc(|| DropGuard(dropped.clone())); arena.clear(); assert!(dropped.get()); } diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index d54d1c245da61fb9c2d03044a305a67587baea46..6f739d8e33ac93972401508039a8d9e9db3e5c52 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -1,6 +1,6 @@ use crate::{ - arena::ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, - Size, ViewContext, WindowContext, FRAME_ARENA, + frame_alloc, ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, + Point, Size, ViewContext, WindowContext, }; use derive_more::{Deref, DerefMut}; pub(crate) use smallvec::SmallVec; @@ -413,9 +413,8 @@ impl AnyElement { E: 'static + Element, E::State: Any, { - let element = - FRAME_ARENA.with_borrow_mut(|arena| arena.alloc(Some(DrawableElement::new(element)))); - let element = element.map(|element| element as &mut dyn ElementObject); + let element = frame_alloc(|| Some(DrawableElement::new(element))) + .map(|element| element as &mut dyn ElementObject); AnyElement(element) } diff --git a/crates/gpui2/src/gpui2.rs b/crates/gpui2/src/gpui2.rs index 322ca206081af8c58f17fa2b3cdcaf90ffb7ba4b..6af274ef5d8998cbca7e5b1880188d44cff7dbbc 100644 --- a/crates/gpui2/src/gpui2.rs +++ b/crates/gpui2/src/gpui2.rs @@ -39,6 +39,7 @@ mod private { pub use action::*; pub use anyhow::Result; pub use app::*; +pub(crate) use arena::*; pub use assets::*; pub use color::*; pub use ctor::ctor; diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 56c5466b6380e73891625a53d67ec01f154dc47a..337f61272f12e351aeb98e832692f117f2ea2310 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -102,6 +102,11 @@ thread_local! { pub static FRAME_ARENA: RefCell = RefCell::new(Arena::new(16 * 1024 * 1024)); } +#[inline(always)] +pub(crate) fn frame_alloc(f: impl FnOnce() -> T) -> ArenaRef { + FRAME_ARENA.with_borrow_mut(|arena| arena.alloc(f)) +} + impl FocusId { /// Obtains whether the element associated with this handle is currently focused. pub fn is_focused(&self, cx: &WindowContext) -> bool { @@ -829,15 +834,12 @@ impl<'a> WindowContext<'a> { mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { let order = self.window.next_frame.z_index_stack.clone(); - let handler = FRAME_ARENA - .with_borrow_mut(|arena| { - arena.alloc( - move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { - handler(event.downcast_ref().unwrap(), phase, cx) - }, - ) - }) - .map(|handler| handler as _); + let handler = frame_alloc(|| { + move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { + handler(event.downcast_ref().unwrap(), phase, cx) + } + }) + .map(|handler| handler as _); self.window .next_frame .mouse_listeners @@ -856,15 +858,14 @@ impl<'a> WindowContext<'a> { &mut self, listener: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = FRAME_ARENA - .with_borrow_mut(|arena| { - arena.alloc(move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { - if let Some(event) = event.downcast_ref::() { - listener(event, phase, cx) - } - }) - }) - .map(|handler| handler as _); + let listener = frame_alloc(|| { + move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { + if let Some(event) = event.downcast_ref::() { + listener(event, phase, cx) + } + } + }) + .map(|handler| handler as _); self.window.next_frame.dispatch_tree.on_key_event(listener); } @@ -879,9 +880,7 @@ impl<'a> WindowContext<'a> { action_type: TypeId, listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = FRAME_ARENA - .with_borrow_mut(|arena| arena.alloc(listener)) - .map(|handler| handler as _); + let listener = frame_alloc(|| listener).map(|handler| handler as _); self.window .next_frame .dispatch_tree @@ -1286,15 +1285,12 @@ impl<'a> WindowContext<'a> { cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| { for (action_type, action_listeners) in &cx.app.global_action_listeners { for action_listener in action_listeners.iter().cloned() { - let listener = FRAME_ARENA - .with_borrow_mut(|arena| { - arena.alloc( - move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { - action_listener(action, phase, cx) - }, - ) - }) - .map(|listener| listener as _); + let listener = frame_alloc(|| { + move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { + action_listener(action, phase, cx) + } + }) + .map(|listener| listener as _); cx.window .next_frame .dispatch_tree From 7e21e0f0eb43ed57e8b2371f7c05b2e6a8c93e34 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 18 Dec 2023 13:05:25 +0200 Subject: [PATCH 099/644] Do not panic on non-worktree file indexing --- crates/project/src/worktree.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index c721d127add1344ee22df0a4224413c60c3fc9b2..8b9fdd2c651e56dc8e5f5794aac0f683c9a8c5e1 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -963,12 +963,19 @@ impl LocalWorktree { let mut index_task = None; let snapshot = this.read_with(&cx, |this, _| this.as_local().unwrap().snapshot()); if let Some(repo) = snapshot.repository_for_path(&path) { - let repo_path = repo.work_directory.relativize(&snapshot, &path).unwrap(); - if let Some(repo) = snapshot.git_repositories.get(&*repo.work_directory) { - let repo = repo.repo_ptr.clone(); - index_task = Some( - cx.background() - .spawn(async move { repo.lock().load_index_text(&repo_path) }), + if let Some(repo_path) = repo.work_directory.relativize(&snapshot, &path) { + if let Some(repo) = snapshot.git_repositories.get(&*repo.work_directory) { + let repo = repo.repo_ptr.clone(); + index_task = Some( + cx.background() + .spawn(async move { repo.lock().load_index_text(&repo_path) }), + ); + } + } else { + log::warn!( + "Skipping loading index text from path {:?} is not in repository {:?}", + path, + repo.work_directory, ); } } From b4042feccd22a9343ccd0c57f5f24edf45c99110 Mon Sep 17 00:00:00 2001 From: Julia Date: Mon, 18 Dec 2023 10:44:34 -0500 Subject: [PATCH 100/644] Unbork project search focus --- crates/search2/src/project_search.rs | 131 ++++++++++++++++++--------- crates/workspace2/src/workspace2.rs | 89 +++++++----------- 2 files changed, 117 insertions(+), 103 deletions(-) diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index 7bd60891ced8a78902d856a674c502c8c1546f4a..284875c7f5e2868b2455b89c378abc476a7bde5b 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -13,9 +13,9 @@ use editor::{ use editor::{EditorElement, EditorStyle}; use gpui::{ actions, div, AnyElement, AnyView, AppContext, Context as _, Div, Element, EntityId, - EventEmitter, FocusableView, FontStyle, FontWeight, InteractiveElement, IntoElement, - KeyContext, Model, ModelContext, ParentElement, PromptLevel, Render, SharedString, Styled, - Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakModel, WeakView, + EventEmitter, FocusHandle, FocusableView, FontStyle, FontWeight, InteractiveElement, + IntoElement, KeyContext, Model, ModelContext, ParentElement, PromptLevel, Render, SharedString, + Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext, }; use menu::Confirm; @@ -91,6 +91,7 @@ enum InputPanel { } pub struct ProjectSearchView { + focus_handle: FocusHandle, model: Model, query_editor: View, replacement_editor: View, @@ -107,6 +108,7 @@ pub struct ProjectSearchView { filters_enabled: bool, replace_enabled: bool, current_mode: SearchMode, + _subscriptions: Vec, } struct SemanticState { @@ -284,6 +286,7 @@ impl Render for ProjectSearchView { div() .flex_1() .size_full() + .track_focus(&self.focus_handle) .child(self.results_editor.clone()) .into_any() } else { @@ -359,10 +362,10 @@ impl Render for ProjectSearchView { .child(Label::new(text).size(LabelSize::Small)) }); v_stack() - .track_focus(&self.query_editor.focus_handle(cx)) .flex_1() .size_full() .justify_center() + .track_focus(&self.focus_handle) .child( h_stack() .size_full() @@ -377,12 +380,8 @@ impl Render for ProjectSearchView { } impl FocusableView for ProjectSearchView { - fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle { - if self.has_matches() { - self.results_editor.focus_handle(cx) - } else { - self.query_editor.focus_handle(cx) - } + fn focus_handle(&self, _: &AppContext) -> gpui::FocusHandle { + self.focus_handle.clone() } } @@ -783,6 +782,7 @@ impl ProjectSearchView { let excerpts; let mut replacement_text = None; let mut query_text = String::new(); + let mut subscriptions = Vec::new(); // Read in settings if available let (mut options, current_mode, filters_enabled) = if let Some(settings) = settings { @@ -805,8 +805,7 @@ impl ProjectSearchView { options = SearchOptions::from_query(active_query); } } - cx.observe(&model, |this, _, cx| this.model_changed(cx)) - .detach(); + subscriptions.push(cx.observe(&model, |this, _, cx| this.model_changed(cx))); let query_editor = cx.build_view(|cx| { let mut editor = Editor::single_line(cx); @@ -815,10 +814,11 @@ impl ProjectSearchView { editor }); // Subscribe to query_editor in order to reraise editor events for workspace item activation purposes - cx.subscribe(&query_editor, |_, _, event: &EditorEvent, cx| { - cx.emit(ViewEvent::EditorEvent(event.clone())) - }) - .detach(); + subscriptions.push( + cx.subscribe(&query_editor, |_, _, event: &EditorEvent, cx| { + cx.emit(ViewEvent::EditorEvent(event.clone())) + }), + ); let replacement_editor = cx.build_view(|cx| { let mut editor = Editor::single_line(cx); editor.set_placeholder_text("Replace in project..", cx); @@ -832,17 +832,17 @@ impl ProjectSearchView { editor.set_searchable(false); editor }); - cx.observe(&results_editor, |_, _, cx| cx.emit(ViewEvent::UpdateTab)) - .detach(); + subscriptions.push(cx.observe(&results_editor, |_, _, cx| cx.emit(ViewEvent::UpdateTab))); - cx.subscribe(&results_editor, |this, _, event: &EditorEvent, cx| { - if matches!(event, editor::EditorEvent::SelectionsChanged { .. }) { - this.update_match_index(cx); - } - // Reraise editor events for workspace item activation purposes - cx.emit(ViewEvent::EditorEvent(event.clone())); - }) - .detach(); + subscriptions.push( + cx.subscribe(&results_editor, |this, _, event: &EditorEvent, cx| { + if matches!(event, editor::EditorEvent::SelectionsChanged { .. }) { + this.update_match_index(cx); + } + // Reraise editor events for workspace item activation purposes + cx.emit(ViewEvent::EditorEvent(event.clone())); + }), + ); let included_files_editor = cx.build_view(|cx| { let mut editor = Editor::single_line(cx); @@ -851,10 +851,11 @@ impl ProjectSearchView { editor }); // Subscribe to include_files_editor in order to reraise editor events for workspace item activation purposes - cx.subscribe(&included_files_editor, |_, _, event: &EditorEvent, cx| { - cx.emit(ViewEvent::EditorEvent(event.clone())) - }) - .detach(); + subscriptions.push( + cx.subscribe(&included_files_editor, |_, _, event: &EditorEvent, cx| { + cx.emit(ViewEvent::EditorEvent(event.clone())) + }), + ); let excluded_files_editor = cx.build_view(|cx| { let mut editor = Editor::single_line(cx); @@ -863,13 +864,26 @@ impl ProjectSearchView { editor }); // Subscribe to excluded_files_editor in order to reraise editor events for workspace item activation purposes - cx.subscribe(&excluded_files_editor, |_, _, event: &EditorEvent, cx| { - cx.emit(ViewEvent::EditorEvent(event.clone())) - }) - .detach(); + subscriptions.push( + cx.subscribe(&excluded_files_editor, |_, _, event: &EditorEvent, cx| { + cx.emit(ViewEvent::EditorEvent(event.clone())) + }), + ); + + let focus_handle = cx.focus_handle(); + subscriptions.push(cx.on_focus_in(&focus_handle, |this, cx| { + if this.focus_handle.is_focused(cx) { + if this.has_matches() { + this.results_editor.focus_handle(cx).focus(cx); + } else { + this.query_editor.focus_handle(cx).focus(cx); + } + } + })); // Check if Worktrees have all been previously indexed let mut this = ProjectSearchView { + focus_handle, replacement_editor, search_id: model.read(cx).search_id, model, @@ -886,6 +900,7 @@ impl ProjectSearchView { filters_enabled, current_mode, replace_enabled: false, + _subscriptions: subscriptions, }; this.model_changed(cx); this @@ -1186,6 +1201,7 @@ impl ProjectSearchBar { subscription: Default::default(), } } + fn cycle_mode(&self, _: &CycleMode, cx: &mut ViewContext) { if let Some(view) = self.active_project_search.as_ref() { view.update(cx, |this, cx| { @@ -1197,6 +1213,7 @@ impl ProjectSearchBar { }); } } + fn confirm(&mut self, _: &Confirm, cx: &mut ViewContext) { if let Some(search_view) = self.active_project_search.as_ref() { search_view.update(cx, |search_view, cx| { @@ -1307,6 +1324,7 @@ impl ProjectSearchBar { false } } + fn toggle_replace(&mut self, _: &ToggleReplace, cx: &mut ViewContext) { if let Some(search) = &self.active_project_search { search.update(cx, |this, cx| { @@ -1400,6 +1418,7 @@ impl ProjectSearchBar { }); } } + fn new_placeholder_text(&self, cx: &mut ViewContext) -> Option { let previous_query_keystrokes = cx .bindings_for_action(&PreviousHistoryQuery {}) @@ -2305,6 +2324,7 @@ pub mod tests { let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.clone(); + let search_bar = window.build_view(cx, |_| ProjectSearchBar::new()); let active_item = cx.read(|cx| { workspace @@ -2320,8 +2340,14 @@ pub mod tests { "Expected no search panel to be active" ); - workspace - .update(cx, |workspace, cx| { + window + .update(cx, move |workspace, cx| { + assert_eq!(workspace.panes().len(), 1); + workspace.panes()[0].update(cx, move |pane, cx| { + pane.toolbar() + .update(cx, |toolbar, cx| toolbar.add_item(search_bar, cx)) + }); + ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx) }) .unwrap(); @@ -2600,6 +2626,7 @@ pub mod tests { }); let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx).unwrap(); + let search_bar = window.build_view(cx, |_| ProjectSearchBar::new()); let active_item = cx.read(|cx| { workspace @@ -2614,6 +2641,16 @@ pub mod tests { "Expected no search panel to be active" ); + window + .update(cx, move |workspace, cx| { + assert_eq!(workspace.panes().len(), 1); + workspace.panes()[0].update(cx, move |pane, cx| { + pane.toolbar() + .update(cx, |toolbar, cx| toolbar.add_item(search_bar, cx)) + }); + }) + .unwrap(); + let one_file_entry = cx.update(|cx| { workspace .read(cx) @@ -2734,9 +2771,20 @@ pub mod tests { let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let window = cx.add_window(|cx| Workspace::test_new(project, cx)); let workspace = window.root(cx).unwrap(); + let search_bar = window.build_view(cx, |_| ProjectSearchBar::new()); + window - .update(cx, |workspace, cx| { - ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx) + .update(cx, { + let search_bar = search_bar.clone(); + move |workspace, cx| { + assert_eq!(workspace.panes().len(), 1); + workspace.panes()[0].update(cx, move |pane, cx| { + pane.toolbar() + .update(cx, |toolbar, cx| toolbar.add_item(search_bar, cx)) + }); + + ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx) + } }) .unwrap(); @@ -2750,13 +2798,6 @@ pub mod tests { .expect("Search view expected to appear after new search event trigger") }); - let search_bar = window.build_view(cx, |cx| { - let mut search_bar = ProjectSearchBar::new(); - search_bar.set_active_pane_item(Some(&search_view), cx); - // search_bar.show(cx); - search_bar - }); - // Add 3 search items into the history + another unsubmitted one. window .update(cx, |_, cx| { diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 866762e7d5e3cabf301decb43f32fb8e9a1c7645..061a6aed3fb8aa948078437903cc2f9106d5a8f0 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -3556,8 +3556,6 @@ impl Render for Workspace { ) }; - let theme = cx.theme().clone(); - let colors = theme.colors(); cx.set_rem_size(ui_font_size); self.actions(div(), cx) @@ -3570,10 +3568,10 @@ impl Render for Workspace { .gap_0() .justify_start() .items_start() - .text_color(colors.text) - .bg(colors.background) + .text_color(cx.theme().colors().text) + .bg(cx.theme().colors().background) .border() - .border_color(colors.border) + .border_color(cx.theme().colors().border) .children(self.titlebar_item.clone()) .child( div() @@ -3586,7 +3584,7 @@ impl Render for Workspace { .overflow_hidden() .border_t() .border_b() - .border_color(colors.border) + .border_color(cx.theme().colors().border) .child( canvas(cx.listener(|workspace, bounds, _| { workspace.bounds = *bounds; @@ -3625,15 +3623,13 @@ impl Render for Workspace { .flex_row() .h_full() // Left Dock - .children(self.zoomed_position.ne(&Some(DockPosition::Left)).then( - || { - div() - .flex() - .flex_none() - .overflow_hidden() - .child(self.left_dock.clone()) - }, - )) + .child( + div() + .flex() + .flex_none() + .overflow_hidden() + .child(self.left_dock.clone()), + ) // Panes .child( div() @@ -3641,52 +3637,29 @@ impl Render for Workspace { .flex_col() .flex_1() .overflow_hidden() - .child(self.center.render( - &self.project, - &self.follower_states, - self.active_call(), - &self.active_pane, - self.zoomed.as_ref(), - &self.app_state, - cx, - )) - .children( - self.zoomed_position - .ne(&Some(DockPosition::Bottom)) - .then(|| self.bottom_dock.clone()), - ), + .child({ + self.center.render( + &self.project, + &self.follower_states, + self.active_call(), + &self.active_pane, + self.zoomed.as_ref(), + &self.app_state, + cx, + ) + }) + .child(self.bottom_dock.clone()), ) // Right Dock - .children(self.zoomed_position.ne(&Some(DockPosition::Right)).then( - || { - div() - .flex() - .flex_none() - .overflow_hidden() - .child(self.right_dock.clone()) - }, - )), + .child( + div() + .flex() + .flex_none() + .overflow_hidden() + .child(self.right_dock.clone()), + ), ) - .children(self.render_notifications(cx)) - .children(self.zoomed.as_ref().and_then(|view| { - let zoomed_view = view.upgrade()?; - let div = div() - .z_index(1) - .absolute() - .overflow_hidden() - .border_color(colors.border) - .bg(colors.background) - .child(zoomed_view) - .inset_0() - .shadow_lg(); - - Some(match self.zoomed_position { - Some(DockPosition::Left) => div.right_2().border_r(), - Some(DockPosition::Right) => div.left_2().border_l(), - Some(DockPosition::Bottom) => div.top_2().border_t(), - None => div.top_2().bottom_2().left_2().right_2().border(), - }) - })), + .children(self.render_notifications(cx)), ) .child(self.status_bar.clone()) } From 02bcc7bbeb484bb9715a1936cfd380e22edd63c6 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Mon, 18 Dec 2023 11:09:54 -0500 Subject: [PATCH 101/644] Add release channel to zed2 collab server --- crates/collab2/src/api.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/collab2/src/api.rs b/crates/collab2/src/api.rs index a84fcf328ba4e92214074b55fc0d849e5b69db61..8d286388cfe936f3e3883f41759f7b8a62466afb 100644 --- a/crates/collab2/src/api.rs +++ b/crates/collab2/src/api.rs @@ -116,12 +116,13 @@ struct CreateUserResponse { #[derive(Debug, Deserialize)] struct Panic { version: String, + release_channel: String, text: String, } #[instrument(skip(panic))] async fn trace_panic(panic: Json) -> Result<()> { - tracing::error!(version = %panic.version, text = %panic.text, "panic report"); + tracing::error!(version = %panic.version, release_channel = %panic.release_channel, text = %panic.text, "panic report"); Ok(()) } From 7cd6825eee83af355699096436e40b3531d98a30 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Mon, 18 Dec 2023 11:12:23 -0500 Subject: [PATCH 102/644] Add backtrace hash to collab server panic api --- crates/collab/src/api.rs | 3 ++- crates/collab2/src/api.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/collab/src/api.rs b/crates/collab/src/api.rs index 8d286388cfe936f3e3883f41759f7b8a62466afb..a28aeac9ab23dd293fbfbd9a7c851709855408d4 100644 --- a/crates/collab/src/api.rs +++ b/crates/collab/src/api.rs @@ -117,12 +117,13 @@ struct CreateUserResponse { struct Panic { version: String, release_channel: String, + backtrace_hash: String, text: String, } #[instrument(skip(panic))] async fn trace_panic(panic: Json) -> Result<()> { - tracing::error!(version = %panic.version, release_channel = %panic.release_channel, text = %panic.text, "panic report"); + tracing::error!(version = %panic.version, release_channel = %panic.release_channel, backtrace_hash = %panic.backtrace_hash, text = %panic.text, "panic report"); Ok(()) } diff --git a/crates/collab2/src/api.rs b/crates/collab2/src/api.rs index 8d286388cfe936f3e3883f41759f7b8a62466afb..a28aeac9ab23dd293fbfbd9a7c851709855408d4 100644 --- a/crates/collab2/src/api.rs +++ b/crates/collab2/src/api.rs @@ -117,12 +117,13 @@ struct CreateUserResponse { struct Panic { version: String, release_channel: String, + backtrace_hash: String, text: String, } #[instrument(skip(panic))] async fn trace_panic(panic: Json) -> Result<()> { - tracing::error!(version = %panic.version, release_channel = %panic.release_channel, text = %panic.text, "panic report"); + tracing::error!(version = %panic.version, release_channel = %panic.release_channel, backtrace_hash = %panic.backtrace_hash, text = %panic.text, "panic report"); Ok(()) } From b46f5be490f35132bd38cce235bd731f6cef2562 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 11:16:00 -0500 Subject: [PATCH 103/644] Style One Dark wrap guides --- crates/theme2/src/one_themes.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/theme2/src/one_themes.rs b/crates/theme2/src/one_themes.rs index 23b3ff508906dfbb012e210d328145b31f854149..72411dc40c374582025725ce827d8654a8987871 100644 --- a/crates/theme2/src/one_themes.rs +++ b/crates/theme2/src/one_themes.rs @@ -86,8 +86,8 @@ pub(crate) fn one_dark() -> Theme { editor_line_number: hsla(222.0 / 360., 11.5 / 100., 34.1 / 100., 1.0), editor_active_line_number: hsla(216.0 / 360., 5.9 / 100., 49.6 / 100., 1.0), editor_invisible: hsla(222.0 / 360., 11.5 / 100., 34.1 / 100., 1.0), - editor_wrap_guide: gpui::black(), - editor_active_wrap_guide: gpui::red(), + editor_wrap_guide: hsla(228. / 360., 8. / 100., 25. / 100., 1.), + editor_active_wrap_guide: hsla(228. / 360., 8. / 100., 25. / 100., 1.), editor_document_highlight_read_background: hsla( 207.8 / 360., 81. / 100., From da7628cc1e644b2c376943e6330a616a0d0120ef Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 11:16:22 -0500 Subject: [PATCH 104/644] Style wrap guides for imported themes --- crates/theme2/src/themes/andromeda.rs | 4 ++++ crates/theme2/src/themes/ayu.rs | 6 +++++ crates/theme2/src/themes/dracula.rs | 2 ++ crates/theme2/src/themes/gruvbox.rs | 12 ++++++++++ crates/theme2/src/themes/night_owl.rs | 4 ++++ crates/theme2/src/themes/noctis.rs | 22 +++++++++++++++++++ crates/theme2/src/themes/nord.rs | 2 ++ crates/theme2/src/themes/palenight.rs | 6 +++++ crates/theme2/src/themes/rose_pine.rs | 6 +++++ crates/theme2/src/themes/solarized.rs | 4 ++++ crates/theme_importer/src/vscode/converter.rs | 2 ++ script/import-themes | 3 +++ 12 files changed, 73 insertions(+) create mode 100755 script/import-themes diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index 32bccf172a61ab7fcdaff19fcc4b9c973fc753bb..513b6f02123552f35ee2606bfd74332265f9d736 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -52,6 +52,8 @@ pub fn andromeda() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x23262eff).into()), editor_line_number: Some(rgba(0x746f77ff).into()), editor_active_line_number: Some(rgba(0xd5ced9ff).into()), + editor_wrap_guide: Some(rgba(0x1b1d23ff).into()), + editor_active_wrap_guide: Some(rgba(0x1b1d23ff).into()), terminal_ansi_bright_red: Some(rgba(0xee5d43ff).into()), terminal_ansi_bright_green: Some(rgba(0x96e072ff).into()), terminal_ansi_bright_yellow: Some(rgba(0xffe66dff).into()), @@ -267,6 +269,8 @@ pub fn andromeda() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x262a33ff).into()), editor_line_number: Some(rgba(0x746f77ff).into()), editor_active_line_number: Some(rgba(0xd5ced9ff).into()), + editor_wrap_guide: Some(rgba(0x1b1d23ff).into()), + editor_active_wrap_guide: Some(rgba(0x1b1d23ff).into()), terminal_ansi_bright_red: Some(rgba(0xee5d43ff).into()), terminal_ansi_bright_green: Some(rgba(0x96e072ff).into()), terminal_ansi_bright_yellow: Some(rgba(0xffe66dff).into()), diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index 4c5d95123000183ace35e98f4a291762dbd3129e..79aed9e1b5fbf69751454b7c8ef09e9ae40b1b94 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -51,6 +51,8 @@ pub fn ayu() -> UserThemeFamily { editor_gutter_background: Some(rgba(0xf8f9faff).into()), editor_line_number: Some(rgba(0x8a919966).into()), editor_active_line_number: Some(rgba(0x5c6166ff).into()), + editor_wrap_guide: Some(rgba(0x6b7d8f1f).into()), + editor_active_wrap_guide: Some(rgba(0x6b7d8f1f).into()), terminal_background: Some(rgba(0xf8f9faff).into()), terminal_ansi_bright_black: Some(rgba(0x686868ff).into()), terminal_ansi_bright_red: Some(rgba(0xf07171ff).into()), @@ -358,6 +360,8 @@ pub fn ayu() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x1f2430ff).into()), editor_line_number: Some(rgba(0x8a919966).into()), editor_active_line_number: Some(rgba(0xcccac2ff).into()), + editor_wrap_guide: Some(rgba(0x171b24ff).into()), + editor_active_wrap_guide: Some(rgba(0x171b24ff).into()), terminal_background: Some(rgba(0x1f2430ff).into()), terminal_ansi_bright_black: Some(rgba(0x686868ff).into()), terminal_ansi_bright_red: Some(rgba(0xf28779ff).into()), @@ -665,6 +669,8 @@ pub fn ayu() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x0b0e14ff).into()), editor_line_number: Some(rgba(0x6c738099).into()), editor_active_line_number: Some(rgba(0xbfbdb6ff).into()), + editor_wrap_guide: Some(rgba(0x1e232bff).into()), + editor_active_wrap_guide: Some(rgba(0x1e232bff).into()), terminal_background: Some(rgba(0x0b0e14ff).into()), terminal_ansi_bright_black: Some(rgba(0x686868ff).into()), terminal_ansi_bright_red: Some(rgba(0xf07178ff).into()), diff --git a/crates/theme2/src/themes/dracula.rs b/crates/theme2/src/themes/dracula.rs index 3fabb67ec2ce1a1a86d5a934731b2593ceb6426b..9d9da27eed7a9bfa9a767d43d01d26888cd6eb25 100644 --- a/crates/theme2/src/themes/dracula.rs +++ b/crates/theme2/src/themes/dracula.rs @@ -48,6 +48,8 @@ pub fn dracula() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x282a36ff).into()), editor_line_number: Some(rgba(0x6272a4ff).into()), editor_active_line_number: Some(rgba(0xf8f8f2ff).into()), + editor_wrap_guide: Some(rgba(0xbd93f9ff).into()), + editor_active_wrap_guide: Some(rgba(0xbd93f9ff).into()), terminal_background: Some(rgba(0x282a36ff).into()), terminal_ansi_bright_black: Some(rgba(0x6272a4ff).into()), terminal_ansi_bright_red: Some(rgba(0xff6e6eff).into()), diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index 2c9666553447d94a460fb122f4993a80dc5318a9..35f5b31aa2328156d15468251c36cba2462d00e1 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -51,6 +51,8 @@ pub fn gruvbox() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x1d2021ff).into()), editor_line_number: Some(rgba(0x665c54ff).into()), editor_active_line_number: Some(rgba(0xebdbb2ff).into()), + editor_wrap_guide: Some(rgba(0x3c3836ff).into()), + editor_active_wrap_guide: Some(rgba(0x3c3836ff).into()), terminal_background: Some(rgba(0x1d2021ff).into()), terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), terminal_ansi_bright_red: Some(rgba(0xfb4934ff).into()), @@ -344,6 +346,8 @@ pub fn gruvbox() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x282828ff).into()), editor_line_number: Some(rgba(0x665c54ff).into()), editor_active_line_number: Some(rgba(0xebdbb2ff).into()), + editor_wrap_guide: Some(rgba(0x3c3836ff).into()), + editor_active_wrap_guide: Some(rgba(0x3c3836ff).into()), terminal_background: Some(rgba(0x282828ff).into()), terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), terminal_ansi_bright_red: Some(rgba(0xfb4934ff).into()), @@ -637,6 +641,8 @@ pub fn gruvbox() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x32302fff).into()), editor_line_number: Some(rgba(0x665c54ff).into()), editor_active_line_number: Some(rgba(0xebdbb2ff).into()), + editor_wrap_guide: Some(rgba(0x3c3836ff).into()), + editor_active_wrap_guide: Some(rgba(0x3c3836ff).into()), terminal_background: Some(rgba(0x32302fff).into()), terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), terminal_ansi_bright_red: Some(rgba(0xfb4934ff).into()), @@ -930,6 +936,8 @@ pub fn gruvbox() -> UserThemeFamily { editor_gutter_background: Some(rgba(0xf9f5d7ff).into()), editor_line_number: Some(rgba(0xbdae93ff).into()), editor_active_line_number: Some(rgba(0x3c3836ff).into()), + editor_wrap_guide: Some(rgba(0xebdbb2ff).into()), + editor_active_wrap_guide: Some(rgba(0xebdbb2ff).into()), terminal_background: Some(rgba(0xf9f5d7ff).into()), terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), terminal_ansi_bright_red: Some(rgba(0x9d0006ff).into()), @@ -1223,6 +1231,8 @@ pub fn gruvbox() -> UserThemeFamily { editor_gutter_background: Some(rgba(0xfbf1c7ff).into()), editor_line_number: Some(rgba(0xbdae93ff).into()), editor_active_line_number: Some(rgba(0x3c3836ff).into()), + editor_wrap_guide: Some(rgba(0xebdbb2ff).into()), + editor_active_wrap_guide: Some(rgba(0xebdbb2ff).into()), terminal_background: Some(rgba(0xfbf1c7ff).into()), terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), terminal_ansi_bright_red: Some(rgba(0x9d0006ff).into()), @@ -1516,6 +1526,8 @@ pub fn gruvbox() -> UserThemeFamily { editor_gutter_background: Some(rgba(0xf2e5bcff).into()), editor_line_number: Some(rgba(0xbdae93ff).into()), editor_active_line_number: Some(rgba(0x3c3836ff).into()), + editor_wrap_guide: Some(rgba(0xebdbb2ff).into()), + editor_active_wrap_guide: Some(rgba(0xebdbb2ff).into()), terminal_background: Some(rgba(0xf2e5bcff).into()), terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), terminal_ansi_bright_red: Some(rgba(0x9d0006ff).into()), diff --git a/crates/theme2/src/themes/night_owl.rs b/crates/theme2/src/themes/night_owl.rs index 778dfabeb8e7c5f1bb6c5afa43c0930205157102..437f79d4c7b594672d0cefd2dd8f433d3bc187e1 100644 --- a/crates/theme2/src/themes/night_owl.rs +++ b/crates/theme2/src/themes/night_owl.rs @@ -51,6 +51,8 @@ pub fn night_owl() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x011627ff).into()), editor_line_number: Some(rgba(0x4b6479ff).into()), editor_active_line_number: Some(rgba(0xd6deebff).into()), + editor_wrap_guide: Some(rgba(0x5f7e97ff).into()), + editor_active_wrap_guide: Some(rgba(0x5f7e97ff).into()), terminal_ansi_bright_black: Some(rgba(0x575656ff).into()), terminal_ansi_bright_red: Some(rgba(0xef5350ff).into()), terminal_ansi_bright_green: Some(rgba(0x22da6eff).into()), @@ -311,6 +313,8 @@ pub fn night_owl() -> UserThemeFamily { editor_gutter_background: Some(rgba(0xfbfbfbff).into()), editor_line_number: Some(rgba(0x90a7b2ff).into()), editor_active_line_number: Some(rgba(0x403f53ff).into()), + editor_wrap_guide: Some(rgba(0xd9d9d9ff).into()), + editor_active_wrap_guide: Some(rgba(0xd9d9d9ff).into()), terminal_background: Some(rgba(0xf6f6f6ff).into()), terminal_ansi_bright_black: Some(rgba(0x403f53ff).into()), terminal_ansi_bright_red: Some(rgba(0xde3d3bff).into()), diff --git a/crates/theme2/src/themes/noctis.rs b/crates/theme2/src/themes/noctis.rs index 614553593d5ffa031d385dfbd801af10d9892bfc..273b52a34ac294955ca8afb4d4a9c610367374d5 100644 --- a/crates/theme2/src/themes/noctis.rs +++ b/crates/theme2/src/themes/noctis.rs @@ -52,6 +52,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x07273bff).into()), editor_line_number: Some(rgba(0x4d6c80ff).into()), editor_active_line_number: Some(rgba(0xbecfdaff).into()), + editor_wrap_guide: Some(rgba(0x1679b6ff).into()), + editor_active_wrap_guide: Some(rgba(0x1679b6ff).into()), terminal_background: Some(rgba(0x051b29ff).into()), terminal_ansi_bright_black: Some(rgba(0x475e6cff).into()), terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), @@ -330,6 +332,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x322a2dff).into()), editor_line_number: Some(rgba(0x715b63ff).into()), editor_active_line_number: Some(rgba(0xcbbec2ff).into()), + editor_wrap_guide: Some(rgba(0x997582ff).into()), + editor_active_wrap_guide: Some(rgba(0x997582ff).into()), terminal_background: Some(rgba(0x272022ff).into()), terminal_ansi_bright_black: Some(rgba(0x69545bff).into()), terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), @@ -608,6 +612,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0xf4f6f6ff).into()), editor_line_number: Some(rgba(0xa0abacff).into()), editor_active_line_number: Some(rgba(0x005661ff).into()), + editor_wrap_guide: Some(rgba(0x00c6e0ff).into()), + editor_active_wrap_guide: Some(rgba(0x00c6e0ff).into()), terminal_background: Some(rgba(0xe1eeefff).into()), terminal_ansi_bright_black: Some(rgba(0x004d57ff).into()), terminal_ansi_bright_red: Some(rgba(0xff4000ff).into()), @@ -886,6 +892,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0xf2f1f8ff).into()), editor_line_number: Some(rgba(0x9d9ab1ff).into()), editor_active_line_number: Some(rgba(0x0c006bff).into()), + editor_wrap_guide: Some(rgba(0xaea4f4ff).into()), + editor_active_wrap_guide: Some(rgba(0xaea4f4ff).into()), terminal_background: Some(rgba(0xe9e7f3ff).into()), terminal_ansi_bright_black: Some(rgba(0x0f0080ff).into()), terminal_ansi_bright_red: Some(rgba(0xff4000ff).into()), @@ -1164,6 +1172,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0xfef8ecff).into()), editor_line_number: Some(rgba(0xa0abacff).into()), editor_active_line_number: Some(rgba(0x005661ff).into()), + editor_wrap_guide: Some(rgba(0x00c6e0ff).into()), + editor_active_wrap_guide: Some(rgba(0x00c6e0ff).into()), terminal_background: Some(rgba(0xf6eddaff).into()), terminal_ansi_bright_black: Some(rgba(0x004d57ff).into()), terminal_ansi_bright_red: Some(rgba(0xff4000ff).into()), @@ -1442,6 +1452,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x1b2932ff).into()), editor_line_number: Some(rgba(0x5d6e79ff).into()), editor_active_line_number: Some(rgba(0xc5cdd3ff).into()), + editor_wrap_guide: Some(rgba(0x496d83ff).into()), + editor_active_wrap_guide: Some(rgba(0x496d83ff).into()), terminal_background: Some(rgba(0x0e1920ff).into()), terminal_ansi_bright_black: Some(rgba(0x425866ff).into()), terminal_ansi_bright_red: Some(rgba(0xca8468ff).into()), @@ -1720,6 +1732,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x052529ff).into()), editor_line_number: Some(rgba(0x4e6b6eff).into()), editor_active_line_number: Some(rgba(0xb2cacdff).into()), + editor_wrap_guide: Some(rgba(0x0e6671ff).into()), + editor_active_wrap_guide: Some(rgba(0x0e6671ff).into()), terminal_background: Some(rgba(0x03191bff).into()), terminal_ansi_bright_black: Some(rgba(0x47686cff).into()), terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), @@ -1998,6 +2012,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x031417ff).into()), editor_line_number: Some(rgba(0x4e6b6eff).into()), editor_active_line_number: Some(rgba(0xb2cacdff).into()), + editor_wrap_guide: Some(rgba(0x0e6671ff).into()), + editor_active_wrap_guide: Some(rgba(0x0e6671ff).into()), terminal_background: Some(rgba(0x020c0eff).into()), terminal_ansi_bright_black: Some(rgba(0x47686cff).into()), terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), @@ -2276,6 +2292,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x031417ff).into()), editor_line_number: Some(rgba(0x4e6b6eff).into()), editor_active_line_number: Some(rgba(0xb2cacdff).into()), + editor_wrap_guide: Some(rgba(0x0e6671ff).into()), + editor_active_wrap_guide: Some(rgba(0x0e6671ff).into()), terminal_background: Some(rgba(0x020c0eff).into()), terminal_ansi_bright_black: Some(rgba(0x47686cff).into()), terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), @@ -2554,6 +2572,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x292640ff).into()), editor_line_number: Some(rgba(0x5c5973ff).into()), editor_active_line_number: Some(rgba(0xc5c2d6ff).into()), + editor_wrap_guide: Some(rgba(0x6e67a8ff).into()), + editor_active_wrap_guide: Some(rgba(0x6e67a8ff).into()), terminal_background: Some(rgba(0x1f1d30ff).into()), terminal_ansi_bright_black: Some(rgba(0x504e65ff).into()), terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), @@ -2832,6 +2852,8 @@ pub fn noctis() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x30243dff).into()), editor_line_number: Some(rgba(0x665973ff).into()), editor_active_line_number: Some(rgba(0xccbfd9ff).into()), + editor_wrap_guide: Some(rgba(0x8767a8ff).into()), + editor_active_wrap_guide: Some(rgba(0x8767a8ff).into()), terminal_background: Some(rgba(0x291d35ff).into()), terminal_ansi_bright_black: Some(rgba(0x594e65ff).into()), terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), diff --git a/crates/theme2/src/themes/nord.rs b/crates/theme2/src/themes/nord.rs index f3d03b38892628aa06f21b90eca69c169fca9921..83fafa7a8740ced232d082018c21bdbbeafb4b08 100644 --- a/crates/theme2/src/themes/nord.rs +++ b/crates/theme2/src/themes/nord.rs @@ -51,6 +51,8 @@ pub fn nord() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x2e3440ff).into()), editor_line_number: Some(rgba(0x4c566aff).into()), editor_active_line_number: Some(rgba(0xd8dee9ff).into()), + editor_wrap_guide: Some(rgba(0x3b4252ff).into()), + editor_active_wrap_guide: Some(rgba(0x3b4252ff).into()), terminal_background: Some(rgba(0x2e3440ff).into()), terminal_ansi_bright_black: Some(rgba(0x4c566aff).into()), terminal_ansi_bright_red: Some(rgba(0xbf616aff).into()), diff --git a/crates/theme2/src/themes/palenight.rs b/crates/theme2/src/themes/palenight.rs index 501a678577d69a7318b1fd880c81c7790f0b83e5..2fceb8055ec253bbe6e9b71794ce0f0debf449c4 100644 --- a/crates/theme2/src/themes/palenight.rs +++ b/crates/theme2/src/themes/palenight.rs @@ -51,6 +51,8 @@ pub fn palenight() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x292d3eff).into()), editor_line_number: Some(rgba(0x4c5374ff).into()), editor_active_line_number: Some(rgba(0xbfc7d5ff).into()), + editor_wrap_guide: Some(rgba(0x282b3cff).into()), + editor_active_wrap_guide: Some(rgba(0x282b3cff).into()), terminal_ansi_bright_black: Some(rgba(0x676e95ff).into()), terminal_ansi_bright_red: Some(rgba(0xff5572ff).into()), terminal_ansi_bright_green: Some(rgba(0xc3e88dff).into()), @@ -337,6 +339,8 @@ pub fn palenight() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x292d3eff).into()), editor_line_number: Some(rgba(0x4c5374ff).into()), editor_active_line_number: Some(rgba(0xbfc7d5ff).into()), + editor_wrap_guide: Some(rgba(0x282b3cff).into()), + editor_active_wrap_guide: Some(rgba(0x282b3cff).into()), terminal_ansi_bright_black: Some(rgba(0x676e95ff).into()), terminal_ansi_bright_red: Some(rgba(0xff5572ff).into()), terminal_ansi_bright_green: Some(rgba(0xc3e88dff).into()), @@ -623,6 +627,8 @@ pub fn palenight() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x292d3eff).into()), editor_line_number: Some(rgba(0x4c5374ff).into()), editor_active_line_number: Some(rgba(0xbfc7d5ff).into()), + editor_wrap_guide: Some(rgba(0x2c2f40ff).into()), + editor_active_wrap_guide: Some(rgba(0x2c2f40ff).into()), terminal_ansi_bright_black: Some(rgba(0x676e95ff).into()), terminal_ansi_bright_red: Some(rgba(0xff5572ff).into()), terminal_ansi_bright_green: Some(rgba(0xc3e88dff).into()), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index a09364405f02e9adb4d74a6b16f82f9dc386db9e..51e3a2451c8bf2f69218cc0fb7f823d99acce154 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -52,6 +52,8 @@ pub fn rose_pine() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x191724ff).into()), editor_line_number: Some(rgba(0x908caaff).into()), editor_active_line_number: Some(rgba(0xe0def4ff).into()), + editor_wrap_guide: Some(rgba(0x00000000).into()), + editor_active_wrap_guide: Some(rgba(0x00000000).into()), terminal_ansi_bright_black: Some(rgba(0x908caaff).into()), terminal_ansi_bright_red: Some(rgba(0xeb6f92ff).into()), terminal_ansi_bright_green: Some(rgba(0x31748fff).into()), @@ -312,6 +314,8 @@ pub fn rose_pine() -> UserThemeFamily { editor_gutter_background: Some(rgba(0x232136ff).into()), editor_line_number: Some(rgba(0x908caaff).into()), editor_active_line_number: Some(rgba(0xe0def4ff).into()), + editor_wrap_guide: Some(rgba(0x00000000).into()), + editor_active_wrap_guide: Some(rgba(0x00000000).into()), terminal_ansi_bright_black: Some(rgba(0x908caaff).into()), terminal_ansi_bright_red: Some(rgba(0xeb6f92ff).into()), terminal_ansi_bright_green: Some(rgba(0x3e8fb0ff).into()), @@ -572,6 +576,8 @@ pub fn rose_pine() -> UserThemeFamily { editor_gutter_background: Some(rgba(0xfaf4edff).into()), editor_line_number: Some(rgba(0x797593ff).into()), editor_active_line_number: Some(rgba(0x575279ff).into()), + editor_wrap_guide: Some(rgba(0x00000000).into()), + editor_active_wrap_guide: Some(rgba(0x00000000).into()), terminal_ansi_bright_black: Some(rgba(0x797593ff).into()), terminal_ansi_bright_red: Some(rgba(0xb4637aff).into()), terminal_ansi_bright_green: Some(rgba(0x286983ff).into()), diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index 9807a6cd3de000d79bd9b30fc21ffad5e9562906..8a5bf96c1652a57b32c8efd881bcf428d0b9d2aa 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -46,6 +46,8 @@ pub fn solarized() -> UserThemeFamily { editor_background: Some(rgba(0x002b36ff).into()), editor_gutter_background: Some(rgba(0x002b36ff).into()), editor_line_number: Some(rgba(0x566c74ff).into()), + editor_wrap_guide: Some(rgba(0x003847ff).into()), + editor_active_wrap_guide: Some(rgba(0x003847ff).into()), terminal_ansi_bright_black: Some(rgba(0x586e75ff).into()), terminal_ansi_bright_red: Some(rgba(0xcb4b16ff).into()), terminal_ansi_bright_green: Some(rgba(0x859900ff).into()), @@ -312,6 +314,8 @@ pub fn solarized() -> UserThemeFamily { editor_background: Some(rgba(0xfdf6e3ff).into()), editor_gutter_background: Some(rgba(0xfdf6e3ff).into()), editor_line_number: Some(rgba(0x9ca8a6ff).into()), + editor_wrap_guide: Some(rgba(0xddd6c1ff).into()), + editor_active_wrap_guide: Some(rgba(0xddd6c1ff).into()), terminal_ansi_bright_black: Some(rgba(0x657b83ff).into()), terminal_ansi_bright_red: Some(rgba(0xcb4b16ff).into()), terminal_ansi_bright_green: Some(rgba(0x859900ff).into()), diff --git a/crates/theme_importer/src/vscode/converter.rs b/crates/theme_importer/src/vscode/converter.rs index 46d9c3d08608b0f3c060c86ae89cfe464bb8bb07..f5a606b329dfe65b2ba94468b80c9b11a1e0d621 100644 --- a/crates/theme_importer/src/vscode/converter.rs +++ b/crates/theme_importer/src/vscode/converter.rs @@ -243,6 +243,8 @@ impl VsCodeThemeConverter { .editor_foreground .as_ref() .traverse(|color| try_parse_color(&color))?, + editor_wrap_guide: vscode_panel_border, + editor_active_wrap_guide: vscode_panel_border, scrollbar_track_background: vscode_editor_background, scrollbar_track_border: vscode_colors .editor_overview_ruler_border diff --git a/script/import-themes b/script/import-themes new file mode 100755 index 0000000000000000000000000000000000000000..ce9ce9ef12f7ee815e17055a08501a4c5eb7f1d4 --- /dev/null +++ b/script/import-themes @@ -0,0 +1,3 @@ +#!/bin/bash + +cargo run -p theme_importer From 4707248714ac29b9c5adee694d67f11c163a8a3c Mon Sep 17 00:00:00 2001 From: Julia <30666851+ForLoveOfCats@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:32:06 -0500 Subject: [PATCH 105/644] Revert accidental merge of old version of workspace2 render function (#3694) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Something happened with my local diff and https://github.com/zed-industries/zed/pull/3691 somehow contained an old version of workspace2's render function. Perhaps I rebased at some point and borked it? Not sure 🤷‍♀️ Release Notes: - N/A --- crates/workspace2/src/workspace2.rs | 89 +++++++++++++++++++---------- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 617b5c51bff97c21b3d858c48beaaf85586115f6..8cb8c3dc9afd8ac057dd88f350e92b45a45d731c 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -3534,6 +3534,8 @@ impl Render for Workspace { ) }; + let theme = cx.theme().clone(); + let colors = theme.colors(); cx.set_rem_size(ui_font_size); self.actions(div(), cx) @@ -3546,10 +3548,10 @@ impl Render for Workspace { .gap_0() .justify_start() .items_start() - .text_color(cx.theme().colors().text) - .bg(cx.theme().colors().background) + .text_color(colors.text) + .bg(colors.background) .border() - .border_color(cx.theme().colors().border) + .border_color(colors.border) .children(self.titlebar_item.clone()) .child( div() @@ -3562,7 +3564,7 @@ impl Render for Workspace { .overflow_hidden() .border_t() .border_b() - .border_color(cx.theme().colors().border) + .border_color(colors.border) .child( canvas(cx.listener(|workspace, bounds, _| { workspace.bounds = *bounds; @@ -3601,13 +3603,15 @@ impl Render for Workspace { .flex_row() .h_full() // Left Dock - .child( - div() - .flex() - .flex_none() - .overflow_hidden() - .child(self.left_dock.clone()), - ) + .children(self.zoomed_position.ne(&Some(DockPosition::Left)).then( + || { + div() + .flex() + .flex_none() + .overflow_hidden() + .child(self.left_dock.clone()) + }, + )) // Panes .child( div() @@ -3615,29 +3619,52 @@ impl Render for Workspace { .flex_col() .flex_1() .overflow_hidden() - .child({ - self.center.render( - &self.project, - &self.follower_states, - self.active_call(), - &self.active_pane, - self.zoomed.as_ref(), - &self.app_state, - cx, - ) - }) - .child(self.bottom_dock.clone()), + .child(self.center.render( + &self.project, + &self.follower_states, + self.active_call(), + &self.active_pane, + self.zoomed.as_ref(), + &self.app_state, + cx, + )) + .children( + self.zoomed_position + .ne(&Some(DockPosition::Bottom)) + .then(|| self.bottom_dock.clone()), + ), ) // Right Dock - .child( - div() - .flex() - .flex_none() - .overflow_hidden() - .child(self.right_dock.clone()), - ), + .children(self.zoomed_position.ne(&Some(DockPosition::Right)).then( + || { + div() + .flex() + .flex_none() + .overflow_hidden() + .child(self.right_dock.clone()) + }, + )), ) - .children(self.render_notifications(cx)), + .children(self.render_notifications(cx)) + .children(self.zoomed.as_ref().and_then(|view| { + let zoomed_view = view.upgrade()?; + let div = div() + .z_index(1) + .absolute() + .overflow_hidden() + .border_color(colors.border) + .bg(colors.background) + .child(zoomed_view) + .inset_0() + .shadow_lg(); + + Some(match self.zoomed_position { + Some(DockPosition::Left) => div.right_2().border_r(), + Some(DockPosition::Right) => div.left_2().border_l(), + Some(DockPosition::Bottom) => div.top_2().border_t(), + None => div.top_2().bottom_2().left_2().right_2().border(), + }) + })), ) .child(self.status_bar.clone()) } From 196df1c37889f3b220a41da4e5fd6f8024183b35 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 11:33:37 -0500 Subject: [PATCH 106/644] Start on collab panel empty state --- crates/collab_ui2/src/collab_panel.rs | 41 ++++++++++++++++++--------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 5f01d4987838961e9c7e086ec1f115e527bbee33..a845e117d5f1ffa2e3b21f60fec4d3817aca2aa3 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2027,20 +2027,33 @@ impl CollabPanel { } fn render_signed_out(&mut self, cx: &mut ViewContext) -> Div { - v_stack().border_1().border_color(gpui::red()).child( - Button::new("sign_in", "Sign in to collaborate").on_click(cx.listener( - |this, _, cx| { - let client = this.client.clone(); - cx.spawn(|_, mut cx| async move { - client - .authenticate_and_connect(true, &cx) - .await - .notify_async_err(&mut cx); - }) - .detach() - }, - )), - ) + v_stack() + .justify_center() + .items_center() + .child(v_stack().gap_1().p_4() + .child( + Label::new("Work with your team with realtive collaborative editing, voice, shared notes and more.") + ) + .child( + Label::new("Sign in to enable collaboration.") + ) + .child( + Button::new("sign_in", "Sign in") + .style(ButtonStyle::Filled) + .full_width() + .on_click(cx.listener( + |this, _, cx| { + let client = this.client.clone(); + cx.spawn(|_, mut cx| async move { + client + .authenticate_and_connect(true, &cx) + .await + .notify_async_err(&mut cx); + }) + .detach() + }, + )), + )) } fn render_list_entry(&mut self, ix: usize, cx: &mut ViewContext) -> AnyElement { From 5900b815e1565325a7c79f1621e6e24a2fc0ac9f Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 18 Dec 2023 12:53:08 -0500 Subject: [PATCH 107/644] Remove unimplemented toggling for project search entries (#3695) This PR removes the unimplemented toggling of search results in the project search. This is new functionality that didn't exist in Zed1, and it's likely that we won't be adding it before launch, so removing it for now. Release Notes: - N/A --- crates/editor2/src/element.rs | 41 ++++++++++------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 3af62811211b4e8daabf2abe8b596f7448bde8b3..328f2f08ba1912212cbd54c3d1ca085a70194c7e 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -2283,36 +2283,19 @@ impl EditorElement { .justify_between() .cursor_pointer() .hover(|style| style.bg(cx.theme().colors().element_hover)) - .on_click(cx.listener(|_editor, _event, _cx| { - // todo!() Implement collapsing path headers - // todo!("Clicking path header") - })) .child( - h_stack() - .gap_3() - // TODO: Add open/close state and toggle action - .child( - div().border().border_color(gpui::red()).child( - ButtonLike::new("path-header-disclosure-control") - .style(ButtonStyle::Subtle) - .child(IconElement::new(match is_open { - true => Icon::ChevronDown, - false => Icon::ChevronRight, - })), - ), - ) - .child( - h_stack() - .gap_2() - .child(Label::new( - filename - .map(SharedString::from) - .unwrap_or_else(|| "untitled".into()), - )) - .when_some(parent_path, |then, path| { - then.child(Label::new(path).color(Color::Muted)) - }), - ), + h_stack().gap_3().child( + h_stack() + .gap_2() + .child(Label::new( + filename + .map(SharedString::from) + .unwrap_or_else(|| "untitled".into()), + )) + .when_some(parent_path, |then, path| { + then.child(Label::new(path).color(Color::Muted)) + }), + ), ) .children(jump_handler.map(|jump_handler| { IconButton::new(block_id, Icon::ArrowUpRight) From d72cd3795aba48be2f4a0c37821eef12dc4a34d7 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 12:56:50 -0500 Subject: [PATCH 108/644] Fix implementation of full_width and icon_position in button --- crates/ui2/src/components/button/button.rs | 33 +++++++++++-------- .../ui2/src/components/button/button_like.rs | 2 +- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/crates/ui2/src/components/button/button.rs b/crates/ui2/src/components/button/button.rs index fc7ca2c12872142e5e41a8a2a96e6c8fe764697a..014a2f536278e6064769a5605eb43dafd01a4ee0 100644 --- a/crates/ui2/src/components/button/button.rs +++ b/crates/ui2/src/components/button/button.rs @@ -151,26 +151,31 @@ impl RenderOnce for Button { self.base.child( h_stack() .gap_1() - .map(|this| { - if self.icon_position == Some(IconPosition::End) { - this.flex_row_reverse() - } else { - this - } + .when(self.icon_position.is_some(), |this| { + this.children(self.icon.map(|icon| { + ButtonIcon::new(icon) + .disabled(is_disabled) + .selected(is_selected) + .selected_icon(self.selected_icon) + .size(self.icon_size) + .color(self.icon_color) + })) }) .child( Label::new(label) .color(label_color) .line_height_style(LineHeightStyle::UILabel), ) - .children(self.icon.map(|icon| { - ButtonIcon::new(icon) - .disabled(is_disabled) - .selected(is_selected) - .selected_icon(self.selected_icon) - .size(self.icon_size) - .color(self.icon_color) - })), + .when(!self.icon_position.is_some(), |this| { + this.children(self.icon.map(|icon| { + ButtonIcon::new(icon) + .disabled(is_disabled) + .selected(is_selected) + .selected_icon(self.selected_icon) + .size(self.icon_size) + .color(self.icon_color) + })) + }), ) } } diff --git a/crates/ui2/src/components/button/button_like.rs b/crates/ui2/src/components/button/button_like.rs index 8255490476b8a58f4a39d03de10412151f320db6..54f2a0e9eaa0a7a87a93927088bc3a6e7975c06b 100644 --- a/crates/ui2/src/components/button/button_like.rs +++ b/crates/ui2/src/components/button/button_like.rs @@ -355,7 +355,7 @@ impl RenderOnce for ButtonLike { .group("") .flex_none() .h(self.size.height()) - .when_some(self.width, |this, width| this.w(width)) + .when_some(self.width, |this, width| this.w(width).justify_center()) .rounded_md() .gap_1() .map(|this| match self.size { From eeaa1e5cf9a6ea0369bf237705439b392f9ad382 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 12:56:57 -0500 Subject: [PATCH 109/644] Add github icon --- assets/icons/github.svg | 1 + crates/ui2/src/components/icon.rs | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 assets/icons/github.svg diff --git a/assets/icons/github.svg b/assets/icons/github.svg new file mode 100644 index 0000000000000000000000000000000000000000..28148b9894b21f0f5995f3ffcfc464b161f3169a --- /dev/null +++ b/assets/icons/github.svg @@ -0,0 +1 @@ + diff --git a/crates/ui2/src/components/icon.rs b/crates/ui2/src/components/icon.rs index 6876630100e95d3ec23252e80787642263783d56..6216acac483489f283366177fe5b6416495122c9 100644 --- a/crates/ui2/src/components/icon.rs +++ b/crates/ui2/src/components/icon.rs @@ -67,6 +67,7 @@ pub enum Icon { Folder, FolderOpen, FolderX, + Github, Hash, InlayHint, Link, @@ -147,6 +148,7 @@ impl Icon { Icon::Folder => "icons/file_icons/folder.svg", Icon::FolderOpen => "icons/file_icons/folder_open.svg", Icon::FolderX => "icons/stop_sharing.svg", + Icon::Github => "icons/github.svg", Icon::Hash => "icons/hash.svg", Icon::InlayHint => "icons/inlay_hint.svg", Icon::Link => "icons/link.svg", From cef9aa359079f74dd8ae44accf3e6a162a76b162 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 18 Dec 2023 18:58:40 +0100 Subject: [PATCH 110/644] Use a different frame arena for each window Co-Authored-By: Max Brunsfeld Co-Authored-By: Nathan Sobo --- crates/gpui2/src/window.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 337f61272f12e351aeb98e832692f117f2ea2310..e00c707de34f5a098cc4539aa3a75568969b21d9 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -99,12 +99,12 @@ struct FocusEvent { slotmap::new_key_type! { pub struct FocusId; } thread_local! { - pub static FRAME_ARENA: RefCell = RefCell::new(Arena::new(16 * 1024 * 1024)); + pub static FRAME_ARENA: RefCell> = RefCell::new(None); } #[inline(always)] pub(crate) fn frame_alloc(f: impl FnOnce() -> T) -> ArenaRef { - FRAME_ARENA.with_borrow_mut(|arena| arena.alloc(f)) + FRAME_ARENA.with_borrow_mut(|arena| arena.as_mut().unwrap().alloc(f)) } impl FocusId { @@ -254,6 +254,7 @@ pub struct Window { pub(crate) element_id_stack: GlobalElementId, pub(crate) rendered_frame: Frame, pub(crate) next_frame: Frame, + frame_arena: Option, pub(crate) focus_handles: Arc>>, focus_listeners: SubscriberSet<(), AnyWindowFocusListener>, blur_listeners: SubscriberSet<(), AnyObserver>, @@ -397,6 +398,7 @@ impl Window { element_id_stack: GlobalElementId::default(), rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), + frame_arena: Some(Arena::new(16 * 1024 * 1024)), focus_handles: Arc::new(RwLock::new(SlotMap::with_key())), focus_listeners: SubscriberSet::new(), blur_listeners: SubscriberSet::new(), @@ -1278,7 +1280,9 @@ impl<'a> WindowContext<'a> { self.window.platform_window.clear_input_handler(); self.window.layout_engine.as_mut().unwrap().clear(); self.window.next_frame.clear(); - FRAME_ARENA.with_borrow_mut(|arena| arena.clear()); + let mut frame_arena = self.window.frame_arena.take().unwrap(); + frame_arena.clear(); + FRAME_ARENA.replace(Some(frame_arena)); let root_view = self.window.root_view.take().unwrap(); self.with_z_index(0, |cx| { @@ -1364,6 +1368,7 @@ impl<'a> WindowContext<'a> { } self.window.drawing = false; + self.window.frame_arena = Some(FRAME_ARENA.take().unwrap()); scene } From 89b231afebe71e270025ba4556d66d08aa58e1b8 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 13:09:46 -0500 Subject: [PATCH 111/644] Update collab panel signed out state --- crates/collab_ui2/src/collab_panel.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index a845e117d5f1ffa2e3b21f60fec4d3817aca2aa3..18d9916bb3881cf316863510c278c6754711d7f7 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2028,17 +2028,20 @@ impl CollabPanel { fn render_signed_out(&mut self, cx: &mut ViewContext) -> Div { v_stack() - .justify_center() + // .flex_1() + // .justify_center() .items_center() - .child(v_stack().gap_1().p_4() + .child(v_stack().gap_6().p_4() .child( - Label::new("Work with your team with realtive collaborative editing, voice, shared notes and more.") - ) - .child( - Label::new("Sign in to enable collaboration.") + Label::new("Work with your team in realtime with collaborative editing, voice, shared notes and more.") ) + .child(v_stack().gap_2() + .child( Button::new("sign_in", "Sign in") + .icon_color(Color::Muted) + .icon(Icon::Github) + .icon_position(IconPosition::Start) .style(ButtonStyle::Filled) .full_width() .on_click(cx.listener( @@ -2052,6 +2055,12 @@ impl CollabPanel { }) .detach() }, + ))) + .child( + div().flex().w_full().items_center().child( + Label::new("Sign in to enable collaboration.") + .color(Color::Muted) + .size(LabelSize::Small) )), )) } From 9d014b0f9a886e308b3ad80aa1f7318a541c5a89 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 13:11:51 -0500 Subject: [PATCH 112/644] Remove comment --- crates/collab_ui2/src/collab_panel.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 18d9916bb3881cf316863510c278c6754711d7f7..5fc0c77d0c151a130ce9900a724dfaaa17e99cb7 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2028,8 +2028,6 @@ impl CollabPanel { fn render_signed_out(&mut self, cx: &mut ViewContext) -> Div { v_stack() - // .flex_1() - // .justify_center() .items_center() .child(v_stack().gap_6().p_4() .child( From 0aa690f915067ada7de8ab9902cf3f1b8acc681d Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 18 Dec 2023 13:27:47 -0500 Subject: [PATCH 113/644] Always show channel toggle when collapsed (#3698) This PR makes the channel toggle disclosure always visible when a channel tree is collapsed, as opposed to just being visible on hover. This makes it possible to visually identify collapsed channel trees without having to hover over each entry. Release Notes: - N/A --- crates/ui2/src/components/list/list_item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ui2/src/components/list/list_item.rs b/crates/ui2/src/components/list/list_item.rs index 481d96d242e81d78e656be158f555a4077a1ee89..a8ca45d1d7ae9ea123d7959392a9e9763a6e9080 100644 --- a/crates/ui2/src/components/list/list_item.rs +++ b/crates/ui2/src/components/list/list_item.rs @@ -192,7 +192,7 @@ impl RenderOnce for ListItem { .flex() .absolute() .left(rems(-1.)) - .visible_on_hover("") + .when(is_open, |this| this.visible_on_hover("")) .child(Disclosure::new(is_open).on_toggle(self.on_toggle)) })) .child( From 98f5a3d544a661a05184c6286c992ed61cf273c3 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 18 Dec 2023 13:35:05 -0500 Subject: [PATCH 114/644] Center text on welcome screen (#3699) This PR centers the text "Code at the speed of thought" on the welcome screen. Release Notes: - N/A --- crates/welcome2/src/welcome.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/welcome2/src/welcome.rs b/crates/welcome2/src/welcome.rs index c553a04fc7bcad5c7be3ca980a84581dacfa0d69..91620595ce557dbf0e1a5227ec75f2366a999066 100644 --- a/crates/welcome2/src/welcome.rs +++ b/crates/welcome2/src/welcome.rs @@ -74,7 +74,11 @@ impl Render for WelcomePage { .h(px(96.)) .mx_auto(), ) - .child(Label::new("Code at the speed of thought")) + .child( + h_stack() + .justify_center() + .child(Label::new("Code at the speed of thought")), + ) .child( v_stack() .gap_2() From 37efe82c5e5f98978b386df85b3be61ccc83b078 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 18 Dec 2023 19:35:17 +0100 Subject: [PATCH 115/644] Use a different frame arena for all elements Co-Authored-By: Nathan Sobo Co-Authored-By: Max Brunsfeld --- crates/gpui2/src/arena.rs | 4 +++ crates/gpui2/src/element.rs | 7 ++-- crates/gpui2/src/window.rs | 70 ++++++++++++++++++++----------------- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index c99f09d29f46e33117698cfc8ffbacaa239c9e9e..24434153fb344b442d7c2652f3da25b4811d48a2 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -78,6 +78,10 @@ impl Arena { } } } + + pub fn size(&self) -> usize { + self.offset + } } impl Drop for Arena { diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index 6f739d8e33ac93972401508039a8d9e9db3e5c52..d0ed50a3d54780130a0894b77c35493b0278e344 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -1,6 +1,6 @@ use crate::{ - frame_alloc, ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, - Point, Size, ViewContext, WindowContext, + ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, Size, + ViewContext, WindowContext, ELEMENT_ARENA, }; use derive_more::{Deref, DerefMut}; pub(crate) use smallvec::SmallVec; @@ -413,7 +413,8 @@ impl AnyElement { E: 'static + Element, E::State: Any, { - let element = frame_alloc(|| Some(DrawableElement::new(element))) + let element = ELEMENT_ARENA + .with_borrow_mut(|arena| arena.alloc(|| Some(DrawableElement::new(element)))) .map(|element| element as &mut dyn ElementObject); AnyElement(element) } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index e00c707de34f5a098cc4539aa3a75568969b21d9..0cef1644605a977417efffb43dca42263884d172 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -99,12 +99,7 @@ struct FocusEvent { slotmap::new_key_type! { pub struct FocusId; } thread_local! { - pub static FRAME_ARENA: RefCell> = RefCell::new(None); -} - -#[inline(always)] -pub(crate) fn frame_alloc(f: impl FnOnce() -> T) -> ArenaRef { - FRAME_ARENA.with_borrow_mut(|arena| arena.as_mut().unwrap().alloc(f)) + pub(crate) static ELEMENT_ARENA: RefCell = RefCell::new(Arena::new(4 * 1024 * 1024)); } impl FocusId { @@ -254,7 +249,7 @@ pub struct Window { pub(crate) element_id_stack: GlobalElementId, pub(crate) rendered_frame: Frame, pub(crate) next_frame: Frame, - frame_arena: Option, + frame_arena: Arena, pub(crate) focus_handles: Arc>>, focus_listeners: SubscriberSet<(), AnyWindowFocusListener>, blur_listeners: SubscriberSet<(), AnyObserver>, @@ -398,7 +393,7 @@ impl Window { element_id_stack: GlobalElementId::default(), rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), - frame_arena: Some(Arena::new(16 * 1024 * 1024)), + frame_arena: Arena::new(1 * 1024 * 1024), focus_handles: Arc::new(RwLock::new(SlotMap::with_key())), focus_listeners: SubscriberSet::new(), blur_listeners: SubscriberSet::new(), @@ -836,12 +831,15 @@ impl<'a> WindowContext<'a> { mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { let order = self.window.next_frame.z_index_stack.clone(); - let handler = frame_alloc(|| { - move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { - handler(event.downcast_ref().unwrap(), phase, cx) - } - }) - .map(|handler| handler as _); + let handler = self + .window + .frame_arena + .alloc(|| { + move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { + handler(event.downcast_ref().unwrap(), phase, cx) + } + }) + .map(|handler| handler as _); self.window .next_frame .mouse_listeners @@ -860,14 +858,17 @@ impl<'a> WindowContext<'a> { &mut self, listener: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = frame_alloc(|| { - move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { - if let Some(event) = event.downcast_ref::() { - listener(event, phase, cx) + let listener = self + .window + .frame_arena + .alloc(|| { + move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { + if let Some(event) = event.downcast_ref::() { + listener(event, phase, cx) + } } - } - }) - .map(|handler| handler as _); + }) + .map(|handler| handler as _); self.window.next_frame.dispatch_tree.on_key_event(listener); } @@ -882,7 +883,11 @@ impl<'a> WindowContext<'a> { action_type: TypeId, listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = frame_alloc(|| listener).map(|handler| handler as _); + let listener = self + .window + .frame_arena + .alloc(|| listener) + .map(|handler| handler as _); self.window .next_frame .dispatch_tree @@ -1280,21 +1285,22 @@ impl<'a> WindowContext<'a> { self.window.platform_window.clear_input_handler(); self.window.layout_engine.as_mut().unwrap().clear(); self.window.next_frame.clear(); - let mut frame_arena = self.window.frame_arena.take().unwrap(); - frame_arena.clear(); - FRAME_ARENA.replace(Some(frame_arena)); + self.window.frame_arena.clear(); let root_view = self.window.root_view.take().unwrap(); self.with_z_index(0, |cx| { cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| { for (action_type, action_listeners) in &cx.app.global_action_listeners { for action_listener in action_listeners.iter().cloned() { - let listener = frame_alloc(|| { - move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { - action_listener(action, phase, cx) - } - }) - .map(|listener| listener as _); + let listener = cx + .window + .frame_arena + .alloc(|| { + move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { + action_listener(action, phase, cx) + } + }) + .map(|listener| listener as _); cx.window .next_frame .dispatch_tree @@ -1368,7 +1374,7 @@ impl<'a> WindowContext<'a> { } self.window.drawing = false; - self.window.frame_arena = Some(FRAME_ARENA.take().unwrap()); + ELEMENT_ARENA.with_borrow_mut(|element_arena| element_arena.clear()); scene } From 0000e6831094c38bf3455acc0617922ced877516 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 18 Dec 2023 10:41:02 -0800 Subject: [PATCH 116/644] Remove unused Arena::sized method --- crates/gpui2/src/arena.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index 24434153fb344b442d7c2652f3da25b4811d48a2..c99f09d29f46e33117698cfc8ffbacaa239c9e9e 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -78,10 +78,6 @@ impl Arena { } } } - - pub fn size(&self) -> usize { - self.offset - } } impl Drop for Arena { From c9893ce2fd87f349cbb5f92d2ba8eb86889494f8 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 13:51:04 -0500 Subject: [PATCH 117/644] Use flex_1 div instead of justify_center in toolbar --- crates/workspace2/src/toolbar.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index a6c8f9d0bff03ec3edd42779b49bdf4382a15a25..c9bcc9346e86ab5f68ab0efcb851a58d2587f2c7 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -108,7 +108,6 @@ impl Render for Toolbar { .bg(cx.theme().colors().toolbar_background) .child( h_stack() - .justify_between() .when(self.left_items().count() > 0, |this| { this.child( h_stack() @@ -117,6 +116,11 @@ impl Render for Toolbar { .children(self.left_items().map(|item| item.to_any())), ) }) + // Render an empty div that takes up the space between + // the left and right sides. This won't cause items to + // be centered like justify_center() will if left or + // right is missing. + .child(div().flex_1()) .when(self.right_items().count() > 0, |this| { this.child( h_stack() From 4fdf6a867ad085308ed89524ee4649e4b9b6d1a8 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 18 Dec 2023 13:54:11 -0500 Subject: [PATCH 118/644] Wire up offline contact list (#3700) This PR wires up the offline contact list. Also enables toggling both the online and offline contact lists. Release Notes: - N/A --- crates/collab_ui2/src/collab_panel.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 5fc0c77d0c151a130ce9900a724dfaaa17e99cb7..ab823100948705bef58654f7e9990136ee77e730 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2230,15 +2230,17 @@ impl CollabPanel { | Section::Offline => true, }; - let mut row = h_stack() + h_stack() .w_full() .group("section-header") .child( ListHeader::new(text) - .toggle(if can_collapse { - Some(!is_collapsed) - } else { - None + .when(can_collapse, |header| { + header.toggle(Some(!is_collapsed)).on_toggle(cx.listener( + move |this, event, cx| { + this.toggle_section_expanded(section, cx); + }, + )) }) .inset(true) .end_slot::(button) @@ -2253,13 +2255,7 @@ impl CollabPanel { }) .detach_and_log_err(cx) })) - }); - - if section == Section::Offline { - row = div().border_1().border_color(gpui::red()).child(row); - } - - row + }) } fn render_contact( From 2ae39b70c8dcef9d8a0459a07887b678a3e2e9f7 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 13:55:30 -0500 Subject: [PATCH 119/644] Add left side padding --- crates/workspace2/src/toolbar.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index c9bcc9346e86ab5f68ab0efcb851a58d2587f2c7..ef8595ae0941478e3a7dc0ccf2177212d1712284 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -111,6 +111,7 @@ impl Render for Toolbar { .when(self.left_items().count() > 0, |this| { this.child( h_stack() + .p_1() .flex_1() .justify_start() .children(self.left_items().map(|item| item.to_any())), From 9cd8e99a9a39e346d3a31dd491039496a1fb6f51 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 14:10:12 -0500 Subject: [PATCH 120/644] Update toolbar.rs --- crates/workspace2/src/toolbar.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index ef8595ae0941478e3a7dc0ccf2177212d1712284..df19ca44516384483e8044623e1723ea2338cf8b 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -117,11 +117,6 @@ impl Render for Toolbar { .children(self.left_items().map(|item| item.to_any())), ) }) - // Render an empty div that takes up the space between - // the left and right sides. This won't cause items to - // be centered like justify_center() will if left or - // right is missing. - .child(div().flex_1()) .when(self.right_items().count() > 0, |this| { this.child( h_stack() From 9785481abadbe740f6e731c5bb26ac77eab5e0b1 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 18 Dec 2023 15:21:04 -0500 Subject: [PATCH 121/644] Make `Disclosure` accept an ID (#3701) This PR makes the `Disclosure` component accept an ID rather than using a static ID for all disclosures. Release Notes: - N/A --- crates/ui2/src/components/disclosure.rs | 6 +- crates/ui2/src/components/list/list_header.rs | 87 ++++++++++--------- crates/ui2/src/components/list/list_item.rs | 2 +- .../ui2/src/components/stories/disclosure.rs | 4 +- 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/crates/ui2/src/components/disclosure.rs b/crates/ui2/src/components/disclosure.rs index 7d0f911d9689372971585f6d76148ffa35ed1b59..729023986d2f1bda905c17850d2e209bc982071b 100644 --- a/crates/ui2/src/components/disclosure.rs +++ b/crates/ui2/src/components/disclosure.rs @@ -4,13 +4,15 @@ use crate::{prelude::*, Color, Icon, IconButton, IconSize}; #[derive(IntoElement)] pub struct Disclosure { + id: ElementId, is_open: bool, on_toggle: Option>, } impl Disclosure { - pub fn new(is_open: bool) -> Self { + pub fn new(id: impl Into, is_open: bool) -> Self { Self { + id: id.into(), is_open, on_toggle: None, } @@ -30,7 +32,7 @@ impl RenderOnce for Disclosure { fn render(self, _cx: &mut WindowContext) -> Self::Rendered { IconButton::new( - "toggle", + self.id, match self.is_open { true => Icon::ChevronDown, false => Icon::ChevronRight, diff --git a/crates/ui2/src/components/list/list_header.rs b/crates/ui2/src/components/list/list_header.rs index d082574a92fbdc36cc09d132c192b5f018920042..0c07867c6d08941258488349b67498b25e832d1b 100644 --- a/crates/ui2/src/components/list/list_header.rs +++ b/crates/ui2/src/components/list/list_header.rs @@ -1,5 +1,6 @@ +use gpui::{AnyElement, ClickEvent, Div, Stateful}; + use crate::{h_stack, prelude::*, Disclosure, Label}; -use gpui::{AnyElement, ClickEvent, Div}; #[derive(IntoElement)] pub struct ListHeader { @@ -75,48 +76,52 @@ impl Selectable for ListHeader { } impl RenderOnce for ListHeader { - type Rendered = Div; + type Rendered = Stateful
; fn render(self, cx: &mut WindowContext) -> Self::Rendered { - h_stack().w_full().relative().group("list_header").child( - div() - .h_7() - .when(self.inset, |this| this.px_2()) - .when(self.selected, |this| { - this.bg(cx.theme().colors().ghost_element_selected) - }) - .flex() - .flex_1() - .items_center() - .justify_between() - .w_full() - .gap_1() - .child( - h_stack() - .gap_1() - .children( - self.toggle - .map(|is_open| Disclosure::new(is_open).on_toggle(self.on_toggle)), - ) - .child( - div() - .flex() - .gap_1() - .items_center() - .children(self.start_slot) - .child(Label::new(self.label.clone()).color(Color::Muted)), - ), - ) - .child(h_stack().children(self.end_slot)) - .when_some(self.end_hover_slot, |this, end_hover_slot| { - this.child( - div() - .absolute() - .right_0() - .visible_on_hover("list_header") - .child(end_hover_slot), + h_stack() + .id(self.label.clone()) + .w_full() + .relative() + .group("list_header") + .child( + div() + .h_7() + .when(self.inset, |this| this.px_2()) + .when(self.selected, |this| { + this.bg(cx.theme().colors().ghost_element_selected) + }) + .flex() + .flex_1() + .items_center() + .justify_between() + .w_full() + .gap_1() + .child( + h_stack() + .gap_1() + .children(self.toggle.map(|is_open| { + Disclosure::new("toggle", is_open).on_toggle(self.on_toggle) + })) + .child( + div() + .flex() + .gap_1() + .items_center() + .children(self.start_slot) + .child(Label::new(self.label.clone()).color(Color::Muted)), + ), ) - }), - ) + .child(h_stack().children(self.end_slot)) + .when_some(self.end_hover_slot, |this, end_hover_slot| { + this.child( + div() + .absolute() + .right_0() + .visible_on_hover("list_header") + .child(end_hover_slot), + ) + }), + ) } } diff --git a/crates/ui2/src/components/list/list_item.rs b/crates/ui2/src/components/list/list_item.rs index a8ca45d1d7ae9ea123d7959392a9e9763a6e9080..bdb5c2b854f2cfb7a04cbd70334d81a4daab98c4 100644 --- a/crates/ui2/src/components/list/list_item.rs +++ b/crates/ui2/src/components/list/list_item.rs @@ -193,7 +193,7 @@ impl RenderOnce for ListItem { .absolute() .left(rems(-1.)) .when(is_open, |this| this.visible_on_hover("")) - .child(Disclosure::new(is_open).on_toggle(self.on_toggle)) + .child(Disclosure::new("toggle", is_open).on_toggle(self.on_toggle)) })) .child( h_stack() diff --git a/crates/ui2/src/components/stories/disclosure.rs b/crates/ui2/src/components/stories/disclosure.rs index 7a2c4194562b0696c0c303a70172b3bac96eedb4..cf2491b387c2e4bfba228a4fa4166ca5af9041c1 100644 --- a/crates/ui2/src/components/stories/disclosure.rs +++ b/crates/ui2/src/components/stories/disclosure.rs @@ -13,8 +13,8 @@ impl Render for DisclosureStory { Story::container() .child(Story::title_for::()) .child(Story::label("Toggled")) - .child(Disclosure::new(true)) + .child(Disclosure::new("toggled", true)) .child(Story::label("Not Toggled")) - .child(Disclosure::new(false)) + .child(Disclosure::new("not_toggled", false)) } } From a286ec46504093365f52abf5ad9f9c3838683d24 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 18 Dec 2023 16:10:13 -0500 Subject: [PATCH 122/644] Update toolbar.rs --- crates/workspace2/src/toolbar.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index df19ca44516384483e8044623e1723ea2338cf8b..1c60b8967f4b3553905b706b2038e077954be2b3 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -108,6 +108,7 @@ impl Render for Toolbar { .bg(cx.theme().colors().toolbar_background) .child( h_stack() + .justify_between() .when(self.left_items().count() > 0, |this| { this.child( h_stack() From 64ceb61aa32727f31f54bcc1ef61966394fc69f6 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 18 Dec 2023 16:32:51 -0500 Subject: [PATCH 123/644] Add pane dividers (#3703) This PR adds dividers between panes in a split. Release Notes: - N/A --- crates/workspace2/src/pane_group.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index b52cec2b1885516494824c21ae27ee5d91e959b4..7416b72331b094ceeba92c0f32971c93d6dca33a 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -570,9 +570,12 @@ mod element { }; use parking_lot::Mutex; use smallvec::SmallVec; + use ui::prelude::*; use super::{HANDLE_HITBOX_SIZE, HORIZONTAL_MIN_SIZE, VERTICAL_MIN_SIZE}; + const DIVIDER_SIZE: f32 = 1.0; + pub fn pane_axis( axis: Axis, basis: usize, @@ -699,12 +702,18 @@ mod element { cx: &mut WindowContext, ) { let handle_bounds = Bounds { - origin: pane_bounds.origin.apply_along(axis, |o| { - o + pane_bounds.size.along(axis) - Pixels(HANDLE_HITBOX_SIZE / 2.) + origin: pane_bounds.origin.apply_along(axis, |origin| { + origin + pane_bounds.size.along(axis) - px(HANDLE_HITBOX_SIZE / 2.) }), size: pane_bounds .size - .apply_along(axis, |_| Pixels(HANDLE_HITBOX_SIZE)), + .apply_along(axis, |_| px(HANDLE_HITBOX_SIZE)), + }; + let divider_bounds = Bounds { + origin: pane_bounds + .origin + .apply_along(axis, |origin| origin + pane_bounds.size.along(axis)), + size: pane_bounds.size.apply_along(axis, |_| px(DIVIDER_SIZE)), }; cx.with_z_index(3, |cx| { @@ -716,6 +725,7 @@ mod element { } cx.add_opaque_layer(handle_bounds); + cx.paint_quad(gpui::fill(divider_bounds, cx.theme().colors().border)); cx.on_mouse_event({ let dragged_handle = dragged_handle.clone(); @@ -790,7 +800,7 @@ mod element { for (ix, child) in self.children.iter_mut().enumerate() { //todo!(active_pane_magnification) - // If usign active pane magnification, need to switch to using + // If using active pane magnification, need to switch to using // 1 for all non-active panes, and then the magnification for the // active pane. let child_size = bounds From 734bbfa66f268220c849455568f467427884eed7 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 18 Dec 2023 16:56:44 -0500 Subject: [PATCH 124/644] Use status colors for contact availability indicators (#3704) This PR updates the availability indicators in the contact list to use the status colors from the theme. Release Notes: - N/A --- crates/ui2/src/components/avatar.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/ui2/src/components/avatar.rs b/crates/ui2/src/components/avatar.rs index 33c8d716251b638eccd2431ef5742fca9d99ca4e..0ab6ce2d85bf39c75f34d8c89849df02752d05ba 100644 --- a/crates/ui2/src/components/avatar.rs +++ b/crates/ui2/src/components/avatar.rs @@ -47,7 +47,11 @@ impl RenderOnce for Avatar { div() .absolute() .z_index(1) - .bg(if is_free { gpui::green() } else { gpui::red() }) + .bg(if is_free { + cx.theme().status().created + } else { + cx.theme().status().deleted + }) .size(indicator_size) .rounded(indicator_size) .bottom_0() From 912f7e6c1a149d62b5f36f50304ff63ed0201840 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 18 Dec 2023 17:18:49 -0500 Subject: [PATCH 125/644] Add ability to warn on missing theme values (#3705) This PR adds the ability to warn in the `theme_importer` when a theme is missing values. Providing the `--warn-on-missing` flag to the `theme_importer` will print a warning for missing theme value when printing the theme. ```sh cargo run -p theme_importer -- --warn-on-missing ``` Release Notes: - N/A --- Cargo.lock | 1 + crates/theme_importer/Cargo.toml | 1 + crates/theme_importer/src/main.rs | 31 +++++++++++++++++----- crates/theme_importer/src/theme_printer.rs | 2 ++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a4801524eae5937fd476fd2cd6dac129cae228e..cb0d54022f2d4233285fd66735a21625064cb38f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9813,6 +9813,7 @@ name = "theme_importer" version = "0.1.0" dependencies = [ "anyhow", + "clap 4.4.4", "convert_case 0.6.0", "gpui2", "indexmap 1.9.3", diff --git a/crates/theme_importer/Cargo.toml b/crates/theme_importer/Cargo.toml index 82ab18d48d2803a2c4ea844ca42c22590bd377ff..4b8641faa47eefce6438fdca04a5a3cda80232bd 100644 --- a/crates/theme_importer/Cargo.toml +++ b/crates/theme_importer/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies] anyhow.workspace = true +clap = { version = "4.4", features = ["derive"] } convert_case = "0.6.0" gpui = { package = "gpui2", path = "../gpui2" } indexmap = { version = "1.6.2", features = ["serde"] } diff --git a/crates/theme_importer/src/main.rs b/crates/theme_importer/src/main.rs index 0005d932d4ac621b417982a261047a04950e4827..a02b1ca1149529d66298c8fc637389d1c2cebeb3 100644 --- a/crates/theme_importer/src/main.rs +++ b/crates/theme_importer/src/main.rs @@ -10,6 +10,7 @@ use std::process::Command; use std::str::FromStr; use anyhow::{anyhow, Context, Result}; +use clap::Parser; use convert_case::{Case, Casing}; use gpui::serde_json; use indexmap::IndexMap; @@ -61,16 +62,34 @@ pub struct ThemeMetadata { pub appearance: ThemeAppearanceJson, } +#[derive(Parser)] +#[command(author, version, about, long_about = None)] +struct Args { + /// Whether to warn when values are missing from the theme. + #[arg(long)] + warn_on_missing: bool, +} + fn main() -> Result<()> { const SOURCE_PATH: &str = "assets/themes/src/vscode"; const OUT_PATH: &str = "crates/theme2/src/themes"; - let log_config = simplelog::ConfigBuilder::new() - .set_level_color(log::Level::Trace, simplelog::Color::Cyan) - .set_level_color(log::Level::Info, simplelog::Color::Blue) - .set_level_color(log::Level::Warn, simplelog::Color::Yellow) - .set_level_color(log::Level::Error, simplelog::Color::Red) - .build(); + let args = Args::parse(); + + let log_config = { + let mut config = simplelog::ConfigBuilder::new(); + config + .set_level_color(log::Level::Trace, simplelog::Color::Cyan) + .set_level_color(log::Level::Info, simplelog::Color::Blue) + .set_level_color(log::Level::Warn, simplelog::Color::Yellow) + .set_level_color(log::Level::Error, simplelog::Color::Red); + + if !args.warn_on_missing { + config.add_filter_ignore_str("theme_printer"); + } + + config.build() + }; TermLogger::init(LevelFilter::Trace, log_config, TerminalMode::Mixed) .expect("could not initialize logger"); diff --git a/crates/theme_importer/src/theme_printer.rs b/crates/theme_importer/src/theme_printer.rs index 4726c90c6d1077da8f8f1c947bff49bac9bc9d57..13123d854f99a7c32763f695182d6ac73c0a8d14 100644 --- a/crates/theme_importer/src/theme_printer.rs +++ b/crates/theme_importer/src/theme_printer.rs @@ -282,6 +282,8 @@ impl<'a> Debug for ThemeColorsRefinementPrinter<'a> { HslaPrinter(color).fmt(f)?; f.write_str(")")?; f.write_str(",")?; + } else { + log::warn!(target: "theme_printer", "No value for '{}' in theme", color_name); } } From 91f1be213bd182c28cf4555a52b955ca82136c49 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 18 Dec 2023 18:13:09 -0500 Subject: [PATCH 126/644] Style project share notification (#3706) This PR styles the project share notification, so we're not staring a red rectangle. Screenshot 2023-12-18 at 6 06 14 PM Release Notes: - N/A --- .../project_shared_notification.rs | 111 ++++++++++-------- 1 file changed, 63 insertions(+), 48 deletions(-) diff --git a/crates/collab_ui2/src/notifications/project_shared_notification.rs b/crates/collab_ui2/src/notifications/project_shared_notification.rs index e130f09b1664aba64d276d5d8c70d8f1f18d380a..2dc0dee6f47e8a9dfc4dcf9fef957cc75147a3d2 100644 --- a/crates/collab_ui2/src/notifications/project_shared_notification.rs +++ b/crates/collab_ui2/src/notifications/project_shared_notification.rs @@ -3,11 +3,12 @@ use call::{room, ActiveCall}; use client::User; use collections::HashMap; use gpui::{ - px, AppContext, Div, Element, ParentElement, Render, RenderOnce, Size, Styled, ViewContext, - VisualContext, + img, px, AppContext, Div, ParentElement, Render, Size, Styled, ViewContext, VisualContext, }; +use settings::Settings; use std::sync::{Arc, Weak}; -use ui::{h_stack, v_stack, Avatar, Button, Clickable, Label}; +use theme::ThemeSettings; +use ui::{h_stack, prelude::*, v_stack, Button, Label}; use workspace::AppState; pub fn init(app_state: &Arc, cx: &mut AppContext) { @@ -21,8 +22,8 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { worktree_root_names, } => { let window_size = Size { - width: px(380.), - height: px(64.), + width: px(400.), + height: px(96.), }; for screen in cx.displays() { @@ -116,56 +117,70 @@ impl ProjectSharedNotification { }); } } - - fn render_owner(&self) -> impl Element { - h_stack() - .child(Avatar::new(self.owner.avatar_uri.clone())) - .child( - v_stack() - .child(Label::new(self.owner.github_login.clone())) - .child(Label::new(format!( - "is sharing a project in Zed{}", - if self.worktree_root_names.is_empty() { - "" - } else { - ":" - } - ))) - .children(if self.worktree_root_names.is_empty() { - None - } else { - Some(Label::new(self.worktree_root_names.join(", "))) - }), - ) - } - - fn render_buttons(&self, cx: &mut ViewContext) -> impl Element { - let this = cx.view().clone(); - v_stack() - .child(Button::new("open", "Open").render(cx).on_click({ - let this = this.clone(); - move |_, cx| { - this.update(cx, |this, cx| this.join(cx)); - } - })) - .child( - Button::new("dismiss", "Dismiss") - .render(cx) - .on_click(move |_, cx| { - this.update(cx, |this, cx| this.dismiss(cx)); - }), - ) - } } impl Render for ProjectSharedNotification { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + // TODO: Is there a better place for us to initialize the font? + let (ui_font, ui_font_size) = { + let theme_settings = ThemeSettings::get_global(cx); + ( + theme_settings.ui_font.family.clone(), + theme_settings.ui_font_size.clone(), + ) + }; + + cx.set_rem_size(ui_font_size); + h_stack() + .font(ui_font) + .text_ui() + .justify_between() .size_full() - .bg(gpui::red()) - .child(self.render_owner()) - .child(self.render_buttons(cx)) + .elevation_3(cx) + .p_2() + .gap_2() + .child( + h_stack() + .gap_2() + .child( + img(self.owner.avatar_uri.clone()) + .w_16() + .h_16() + .rounded_full(), + ) + .child( + v_stack() + .child(Label::new(self.owner.github_login.clone())) + .child(Label::new(format!( + "is sharing a project in Zed{}", + if self.worktree_root_names.is_empty() { + "" + } else { + ":" + } + ))) + .children(if self.worktree_root_names.is_empty() { + None + } else { + Some(Label::new(self.worktree_root_names.join(", "))) + }), + ), + ) + .child( + v_stack() + .child(Button::new("open", "Open").on_click(cx.listener( + move |this, _event, cx| { + this.join(cx); + }, + ))) + .child(Button::new("dismiss", "Dismiss").on_click(cx.listener( + move |this, _event, cx| { + this.dismiss(cx); + }, + ))), + ) } } From e6f3731efd6983818dd188bf5d817eac16500e81 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 18 Dec 2023 13:51:23 -0800 Subject: [PATCH 127/644] Fix position of right dock handle Co-authored-by: Nathan Sobo --- crates/workspace2/src/dock.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index e44471a871ac416546657880964720f3ee638d3c..3997b8f9b011f26869ec6717591994bbb52978ae 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -490,6 +490,7 @@ impl Render for Dock { let mut handle = div() .id("resize-handle") .on_drag(DraggedDock(position), |dock, cx| { + cx.stop_propagation(); cx.build_view(|_| dock.clone()) }) .on_click(cx.listener(|v, e: &ClickEvent, cx| { @@ -525,8 +526,8 @@ impl Render for Dock { .absolute() .top(px(0.)) .left(px(0.)) - .w_full() - .h(HANDLE_SIZE) + .h_full() + .w(HANDLE_SIZE) .cursor_col_resize(); } } From ee8e1454fcb2edb90fa1ceb10b1f9dd508756327 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 18 Dec 2023 13:51:23 -0800 Subject: [PATCH 128/644] Fix drag and drop logic in div's mouse handling * Attach mouse up and mouse move listeners immediately, not just when there is already a drag in progress, because when starting a drag, these other events may fire before the next frame. * Remove bounds checks for handling mouse move and mouse events, since a dragged object may be moved outside of its original container. Co-authored-by: Nathan Sobo --- crates/gpui2/src/elements/div.rs | 153 ++++++++++++++++--------------- 1 file changed, 81 insertions(+), 72 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 1f56f44900477780085b556f46adc508f4ff119a..f6dd2fa09e5a7b7281ac24115561efe4cc1d4b1b 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -151,9 +151,7 @@ impl Interactivity { { self.mouse_move_listeners .push(Box::new(move |event, bounds, phase, cx| { - if phase == DispatchPhase::Capture - && bounds.drag_target_contains(&event.position, cx) - { + if phase == DispatchPhase::Capture { if cx .active_drag .as_ref() @@ -1131,19 +1129,19 @@ impl Interactivity { }); } - if cx.active_drag.is_some() { - let drop_listeners = mem::take(&mut self.drop_listeners); - let interactive_bounds = interactive_bounds.clone(); - if !drop_listeners.is_empty() { - cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && interactive_bounds.drag_target_contains(&event.position, cx) - { - if let Some(drag_state_type) = cx - .active_drag - .as_ref() - .map(|drag| drag.value.as_ref().type_id()) + let mut drag_listener = mem::take(&mut self.drag_listener); + let drop_listeners = mem::take(&mut self.drop_listeners); + let click_listeners = mem::take(&mut self.click_listeners); + + if !drop_listeners.is_empty() { + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + move |event: &MouseUpEvent, phase, cx| { + if let Some(drag) = &cx.active_drag { + if phase == DispatchPhase::Bubble + && interactive_bounds.drag_target_contains(&event.position, cx) { + let drag_state_type = drag.value.as_ref().type_id(); for (drop_state_type, listener) in &drop_listeners { if *drop_state_type == drag_state_type { let drag = cx @@ -1156,86 +1154,97 @@ impl Interactivity { cx.stop_propagation(); } } - } else { - cx.active_drag = None; } } - }); - } + } + }); } - let click_listeners = mem::take(&mut self.click_listeners); - let mut drag_listener = mem::take(&mut self.drag_listener); - if !click_listeners.is_empty() || drag_listener.is_some() { let pending_mouse_down = element_state .pending_mouse_down .get_or_insert_with(Default::default) .clone(); - let mouse_down = pending_mouse_down.borrow().clone(); - if let Some(mouse_down) = mouse_down { - if drag_listener.is_some() { - let active_state = element_state - .clicked_state - .get_or_insert_with(Default::default) - .clone(); - let interactive_bounds = interactive_bounds.clone(); - - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + + let active_state = element_state + .clicked_state + .get_or_insert_with(Default::default) + .clone(); + + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + let pending_mouse_down = pending_mouse_down.clone(); + move |event: &MouseDownEvent, phase, cx| { + if phase == DispatchPhase::Bubble + && event.button == MouseButton::Left + && interactive_bounds.visibly_contains(&event.position, cx) + { + *pending_mouse_down.borrow_mut() = Some(event.clone()); + cx.notify(); + } + } + }); + + cx.on_mouse_event({ + let pending_mouse_down = pending_mouse_down.clone(); + move |event: &MouseMoveEvent, phase, cx| { + let mut pending_mouse_down = pending_mouse_down.borrow_mut(); + if let Some(mouse_down) = pending_mouse_down.clone() { if cx.active_drag.is_some() { if phase == DispatchPhase::Capture { cx.notify(); } } else if phase == DispatchPhase::Bubble - && interactive_bounds.visibly_contains(&event.position, cx) && (event.position - mouse_down.position).magnitude() > DRAG_THRESHOLD { - let (drag_value, drag_listener) = drag_listener - .take() - .expect("The notify below should invalidate this callback"); - - *active_state.borrow_mut() = ElementClickedState::default(); - let cursor_offset = event.position - bounds.origin; - let drag = (drag_listener)(drag_value.as_ref(), cx); - cx.active_drag = Some(AnyDrag { - view: drag, - value: drag_value, - cursor_offset, - }); - cx.notify(); - cx.stop_propagation(); + if let Some((drag_value, drag_listener)) = drag_listener.take() { + *active_state.borrow_mut() = ElementClickedState::default(); + let cursor_offset = event.position - bounds.origin; + let drag = (drag_listener)(drag_value.as_ref(), cx); + cx.active_drag = Some(AnyDrag { + view: drag, + value: drag_value, + cursor_offset, + }); + pending_mouse_down.take(); + cx.notify(); + cx.stop_propagation(); + } } - }); + } } + }); + cx.on_mouse_event({ let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && interactive_bounds.visibly_contains(&event.position, cx) - { - let mouse_click = ClickEvent { - down: mouse_down.clone(), - up: event.clone(), - }; - for listener in &click_listeners { - listener(&mouse_click, cx); + let mut captured_mouse_down = None; + move |event: &MouseUpEvent, phase, cx| match phase { + // Clear the pending mouse down during the capture phase, + // so that it happens even if another event handler stops + // propagation. + DispatchPhase::Capture => { + let mut pending_mouse_down = pending_mouse_down.borrow_mut(); + if pending_mouse_down.is_some() { + captured_mouse_down = pending_mouse_down.take(); + cx.notify(); } } - *pending_mouse_down.borrow_mut() = None; - cx.notify(); - }); - } else { - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && event.button == MouseButton::Left - && interactive_bounds.visibly_contains(&event.position, cx) - { - *pending_mouse_down.borrow_mut() = Some(event.clone()); - cx.notify(); + // Fire click handlers during the bubble phase. + DispatchPhase::Bubble => { + if let Some(mouse_down) = captured_mouse_down.take() { + if interactive_bounds.visibly_contains(&event.position, cx) { + let mouse_click = ClickEvent { + down: mouse_down, + up: event.clone(), + }; + for listener in &click_listeners { + listener(&mouse_click, cx); + } + } + } } - }); - } + } + }); } if let Some(hover_listener) = self.hover_listener.take() { From b88370d5ade5d6954c6db989ec89942c91151b9c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 18 Dec 2023 18:02:19 -0800 Subject: [PATCH 129/644] Respect a div's own z-index when adding its event listeners --- crates/gpui2/src/elements/div.rs | 953 +++++++++++----------- crates/gpui2/src/elements/uniform_list.rs | 96 ++- 2 files changed, 524 insertions(+), 525 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index f6dd2fa09e5a7b7281ac24115561efe4cc1d4b1b..02b9d08b40e19ed24a30501a9f141a7e100cbb86 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -778,20 +778,16 @@ impl Element for Div { &mut element_state.interactive_state, cx, |style, scroll_offset, cx| { - let z_index = style.z_index.unwrap_or(0); - - cx.with_z_index(z_index, |cx| { - style.paint(bounds, cx, |cx| { - cx.with_text_style(style.text_style().cloned(), |cx| { - cx.with_content_mask(style.overflow_mask(bounds), |cx| { - cx.with_element_offset(scroll_offset, |cx| { - for child in &mut self.children { - child.paint(cx); - } - }) + style.paint(bounds, cx, |cx| { + cx.with_text_style(style.text_style().cloned(), |cx| { + cx.with_content_mask(style.overflow_mask(bounds), |cx| { + cx.with_element_offset(scroll_offset, |cx| { + for child in &mut self.children { + child.paint(cx); + } }) }) - }); + }) }) }, ); @@ -918,542 +914,547 @@ impl Interactivity { return; } - #[cfg(debug_assertions)] - if self.element_id.is_some() - && (style.debug || style.debug_below || cx.has_global::()) - && bounds.contains(&cx.mouse_position()) - { - const FONT_SIZE: crate::Pixels = crate::Pixels(10.); - let element_id = format!("{:?}", self.element_id.as_ref().unwrap()); - let str_len = element_id.len(); - - let render_debug_text = |cx: &mut WindowContext| { - if let Some(text) = cx - .text_system() - .shape_text( - &element_id, - FONT_SIZE, - &[cx.text_style().to_run(str_len)], - None, - ) - .ok() - .map(|mut text| text.pop()) - .flatten() - { - text.paint(bounds.origin, FONT_SIZE, cx).ok(); - - let text_bounds = crate::Bounds { - origin: bounds.origin, - size: text.size(FONT_SIZE), - }; - if self.location.is_some() - && text_bounds.contains(&cx.mouse_position()) - && cx.modifiers().command + let z_index = style.z_index.unwrap_or(0); + cx.with_z_index(z_index, |cx| { + #[cfg(debug_assertions)] + if self.element_id.is_some() + && (style.debug || style.debug_below || cx.has_global::()) + && bounds.contains(&cx.mouse_position()) + { + const FONT_SIZE: crate::Pixels = crate::Pixels(10.); + let element_id = format!("{:?}", self.element_id.as_ref().unwrap()); + let str_len = element_id.len(); + + let render_debug_text = |cx: &mut WindowContext| { + if let Some(text) = cx + .text_system() + .shape_text( + &element_id, + FONT_SIZE, + &[cx.text_style().to_run(str_len)], + None, + ) + .ok() + .map(|mut text| text.pop()) + .flatten() { - let command_held = cx.modifiers().command; - cx.on_key_event({ - let text_bounds = text_bounds.clone(); - move |e: &crate::ModifiersChangedEvent, _phase, cx| { - if e.modifiers.command != command_held - && text_bounds.contains(&cx.mouse_position()) - { - cx.notify(); + text.paint(bounds.origin, FONT_SIZE, cx).ok(); + + let text_bounds = crate::Bounds { + origin: bounds.origin, + size: text.size(FONT_SIZE), + }; + if self.location.is_some() + && text_bounds.contains(&cx.mouse_position()) + && cx.modifiers().command + { + let command_held = cx.modifiers().command; + cx.on_key_event({ + let text_bounds = text_bounds.clone(); + move |e: &crate::ModifiersChangedEvent, _phase, cx| { + if e.modifiers.command != command_held + && text_bounds.contains(&cx.mouse_position()) + { + cx.notify(); + } } - } - }); + }); - let hovered = bounds.contains(&cx.mouse_position()); - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - if phase == DispatchPhase::Capture { - if bounds.contains(&event.position) != hovered { - cx.notify(); + let hovered = bounds.contains(&cx.mouse_position()); + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + if phase == DispatchPhase::Capture { + if bounds.contains(&event.position) != hovered { + cx.notify(); + } } - } - }); - - cx.on_mouse_event({ - let location = self.location.clone().unwrap(); - let text_bounds = text_bounds.clone(); - move |e: &crate::MouseDownEvent, phase, cx| { - if text_bounds.contains(&e.position) && phase.capture() { - cx.stop_propagation(); - let Ok(dir) = std::env::current_dir() else { - return; - }; - - eprintln!( - "This element is created at:\n{}:{}:{}", - location.file(), - location.line(), - location.column() - ); - - std::process::Command::new("zed") - .arg(format!( - "{}/{}:{}:{}", - dir.to_string_lossy(), + }); + + cx.on_mouse_event({ + let location = self.location.clone().unwrap(); + let text_bounds = text_bounds.clone(); + move |e: &crate::MouseDownEvent, phase, cx| { + if text_bounds.contains(&e.position) && phase.capture() { + cx.stop_propagation(); + let Ok(dir) = std::env::current_dir() else { + return; + }; + + eprintln!( + "This element is created at:\n{}:{}:{}", location.file(), location.line(), location.column() - )) - .spawn() - .ok(); + ); + + std::process::Command::new("zed") + .arg(format!( + "{}/{}:{}:{}", + dir.to_string_lossy(), + location.file(), + location.line(), + location.column() + )) + .spawn() + .ok(); + } } - } - }); - cx.paint_quad(crate::outline( - crate::Bounds { - origin: bounds.origin - + crate::point(crate::px(0.), FONT_SIZE - px(2.)), - size: crate::Size { - width: text_bounds.size.width, - height: crate::px(1.), + }); + cx.paint_quad(crate::outline( + crate::Bounds { + origin: bounds.origin + + crate::point(crate::px(0.), FONT_SIZE - px(2.)), + size: crate::Size { + width: text_bounds.size.width, + height: crate::px(1.), + }, }, - }, - crate::red(), - )) + crate::red(), + )) + } } - } - }; - - cx.with_z_index(1, |cx| { - cx.with_text_style( - Some(crate::TextStyleRefinement { - color: Some(crate::red()), - line_height: Some(FONT_SIZE.into()), - background_color: Some(crate::white()), - ..Default::default() - }), - render_debug_text, - ) - }); - } + }; + + cx.with_z_index(1, |cx| { + cx.with_text_style( + Some(crate::TextStyleRefinement { + color: Some(crate::red()), + line_height: Some(FONT_SIZE.into()), + background_color: Some(crate::white()), + ..Default::default() + }), + render_debug_text, + ) + }); + } - if style - .background - .as_ref() - .is_some_and(|fill| fill.color().is_some_and(|color| !color.is_transparent())) - { - cx.with_z_index(style.z_index.unwrap_or(0), |cx| cx.add_opaque_layer(bounds)) - } + if style + .background + .as_ref() + .is_some_and(|fill| fill.color().is_some_and(|color| !color.is_transparent())) + { + cx.add_opaque_layer(bounds) + } - let interactive_bounds = InteractiveBounds { - bounds: bounds.intersect(&cx.content_mask().bounds), - stacking_order: cx.stacking_order().clone(), - }; + let interactive_bounds = InteractiveBounds { + bounds: bounds.intersect(&cx.content_mask().bounds), + stacking_order: cx.stacking_order().clone(), + }; - if let Some(mouse_cursor) = style.mouse_cursor { - let mouse_position = &cx.mouse_position(); - let hovered = interactive_bounds.visibly_contains(mouse_position, cx); - if hovered { - cx.set_cursor_style(mouse_cursor); + if let Some(mouse_cursor) = style.mouse_cursor { + let mouse_position = &cx.mouse_position(); + let hovered = interactive_bounds.visibly_contains(mouse_position, cx); + if hovered { + cx.set_cursor_style(mouse_cursor); + } } - } - // If this element can be focused, register a mouse down listener - // that will automatically transfer focus when hitting the element. - // This behavior can be suppressed by using `cx.prevent_default()`. - if let Some(focus_handle) = element_state.focus_handle.clone() { - cx.on_mouse_event({ - let interactive_bounds = interactive_bounds.clone(); - move |event: &MouseDownEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && !cx.default_prevented() - && interactive_bounds.visibly_contains(&event.position, cx) - { - cx.focus(&focus_handle); - // If there is a parent that is also focusable, prevent it - // from trasferring focus because we already did so. - cx.prevent_default(); + // If this element can be focused, register a mouse down listener + // that will automatically transfer focus when hitting the element. + // This behavior can be suppressed by using `cx.prevent_default()`. + if let Some(focus_handle) = element_state.focus_handle.clone() { + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + move |event: &MouseDownEvent, phase, cx| { + if phase == DispatchPhase::Bubble + && !cx.default_prevented() + && interactive_bounds.visibly_contains(&event.position, cx) + { + cx.focus(&focus_handle); + // If there is a parent that is also focusable, prevent it + // from trasferring focus because we already did so. + cx.prevent_default(); + } } - } - }); - } + }); + } - for listener in self.mouse_down_listeners.drain(..) { - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| { - listener(event, &interactive_bounds, phase, cx); - }) - } + for listener in self.mouse_down_listeners.drain(..) { + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| { + listener(event, &interactive_bounds, phase, cx); + }) + } - for listener in self.mouse_up_listeners.drain(..) { - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { - listener(event, &interactive_bounds, phase, cx); - }) - } + for listener in self.mouse_up_listeners.drain(..) { + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { + listener(event, &interactive_bounds, phase, cx); + }) + } - for listener in self.mouse_move_listeners.drain(..) { - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - listener(event, &interactive_bounds, phase, cx); - }) - } + for listener in self.mouse_move_listeners.drain(..) { + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + listener(event, &interactive_bounds, phase, cx); + }) + } - for listener in self.scroll_wheel_listeners.drain(..) { - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { - listener(event, &interactive_bounds, phase, cx); - }) - } + for listener in self.scroll_wheel_listeners.drain(..) { + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { + listener(event, &interactive_bounds, phase, cx); + }) + } - let hover_group_bounds = self - .group_hover_style - .as_ref() - .and_then(|group_hover| GroupBounds::get(&group_hover.group, cx)); + let hover_group_bounds = self + .group_hover_style + .as_ref() + .and_then(|group_hover| GroupBounds::get(&group_hover.group, cx)); - if let Some(group_bounds) = hover_group_bounds { - let hovered = group_bounds.contains(&cx.mouse_position()); - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - if phase == DispatchPhase::Capture { - if group_bounds.contains(&event.position) != hovered { - cx.notify(); + if let Some(group_bounds) = hover_group_bounds { + let hovered = group_bounds.contains(&cx.mouse_position()); + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + if phase == DispatchPhase::Capture { + if group_bounds.contains(&event.position) != hovered { + cx.notify(); + } } - } - }); - } + }); + } - if self.hover_style.is_some() - || self.base_style.mouse_cursor.is_some() - || cx.active_drag.is_some() && !self.drag_over_styles.is_empty() - { - let bounds = bounds.intersect(&cx.content_mask().bounds); - let hovered = bounds.contains(&cx.mouse_position()); - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - if phase == DispatchPhase::Capture { - if bounds.contains(&event.position) != hovered { - cx.notify(); + if self.hover_style.is_some() + || self.base_style.mouse_cursor.is_some() + || cx.active_drag.is_some() && !self.drag_over_styles.is_empty() + { + let bounds = bounds.intersect(&cx.content_mask().bounds); + let hovered = bounds.contains(&cx.mouse_position()); + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + if phase == DispatchPhase::Capture { + if bounds.contains(&event.position) != hovered { + cx.notify(); + } } - } - }); - } + }); + } - let mut drag_listener = mem::take(&mut self.drag_listener); - let drop_listeners = mem::take(&mut self.drop_listeners); - let click_listeners = mem::take(&mut self.click_listeners); + let mut drag_listener = mem::take(&mut self.drag_listener); + let drop_listeners = mem::take(&mut self.drop_listeners); + let click_listeners = mem::take(&mut self.click_listeners); + + if !drop_listeners.is_empty() { + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + move |event: &MouseUpEvent, phase, cx| { + if let Some(drag) = &cx.active_drag { + if phase == DispatchPhase::Bubble + && interactive_bounds.drag_target_contains(&event.position, cx) + { + let drag_state_type = drag.value.as_ref().type_id(); + for (drop_state_type, listener) in &drop_listeners { + if *drop_state_type == drag_state_type { + let drag = cx + .active_drag + .take() + .expect("checked for type drag state type above"); + + listener(drag.value.as_ref(), cx); + cx.notify(); + cx.stop_propagation(); + } + } + } + } + } + }); + } - if !drop_listeners.is_empty() { - cx.on_mouse_event({ - let interactive_bounds = interactive_bounds.clone(); - move |event: &MouseUpEvent, phase, cx| { - if let Some(drag) = &cx.active_drag { + if !click_listeners.is_empty() || drag_listener.is_some() { + let pending_mouse_down = element_state + .pending_mouse_down + .get_or_insert_with(Default::default) + .clone(); + + let active_state = element_state + .clicked_state + .get_or_insert_with(Default::default) + .clone(); + + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + let pending_mouse_down = pending_mouse_down.clone(); + move |event: &MouseDownEvent, phase, cx| { if phase == DispatchPhase::Bubble - && interactive_bounds.drag_target_contains(&event.position, cx) + && event.button == MouseButton::Left + && interactive_bounds.visibly_contains(&event.position, cx) { - let drag_state_type = drag.value.as_ref().type_id(); - for (drop_state_type, listener) in &drop_listeners { - if *drop_state_type == drag_state_type { - let drag = cx - .active_drag - .take() - .expect("checked for type drag state type above"); - - listener(drag.value.as_ref(), cx); + *pending_mouse_down.borrow_mut() = Some(event.clone()); + cx.notify(); + } + } + }); + + cx.on_mouse_event({ + let pending_mouse_down = pending_mouse_down.clone(); + move |event: &MouseMoveEvent, phase, cx| { + let mut pending_mouse_down = pending_mouse_down.borrow_mut(); + + if let Some(mouse_down) = pending_mouse_down.clone() { + if cx.active_drag.is_some() { + if phase == DispatchPhase::Capture { + cx.notify(); + } + } else if phase == DispatchPhase::Bubble + && (event.position - mouse_down.position).magnitude() + > DRAG_THRESHOLD + { + if let Some((drag_value, drag_listener)) = drag_listener.take() { + *active_state.borrow_mut() = ElementClickedState::default(); + let cursor_offset = event.position - bounds.origin; + let drag = (drag_listener)(drag_value.as_ref(), cx); + cx.active_drag = Some(AnyDrag { + view: drag, + value: drag_value, + cursor_offset, + }); + pending_mouse_down.take(); cx.notify(); cx.stop_propagation(); } } } } - } - }); - } - - if !click_listeners.is_empty() || drag_listener.is_some() { - let pending_mouse_down = element_state - .pending_mouse_down - .get_or_insert_with(Default::default) - .clone(); - - let active_state = element_state - .clicked_state - .get_or_insert_with(Default::default) - .clone(); - - cx.on_mouse_event({ - let interactive_bounds = interactive_bounds.clone(); - let pending_mouse_down = pending_mouse_down.clone(); - move |event: &MouseDownEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && event.button == MouseButton::Left - && interactive_bounds.visibly_contains(&event.position, cx) - { - *pending_mouse_down.borrow_mut() = Some(event.clone()); - cx.notify(); - } - } - }); - - cx.on_mouse_event({ - let pending_mouse_down = pending_mouse_down.clone(); - move |event: &MouseMoveEvent, phase, cx| { - let mut pending_mouse_down = pending_mouse_down.borrow_mut(); - if let Some(mouse_down) = pending_mouse_down.clone() { - if cx.active_drag.is_some() { - if phase == DispatchPhase::Capture { + }); + + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + let mut captured_mouse_down = None; + move |event: &MouseUpEvent, phase, cx| match phase { + // Clear the pending mouse down during the capture phase, + // so that it happens even if another event handler stops + // propagation. + DispatchPhase::Capture => { + let mut pending_mouse_down = pending_mouse_down.borrow_mut(); + if pending_mouse_down.is_some() { + captured_mouse_down = pending_mouse_down.take(); cx.notify(); } - } else if phase == DispatchPhase::Bubble - && (event.position - mouse_down.position).magnitude() > DRAG_THRESHOLD - { - if let Some((drag_value, drag_listener)) = drag_listener.take() { - *active_state.borrow_mut() = ElementClickedState::default(); - let cursor_offset = event.position - bounds.origin; - let drag = (drag_listener)(drag_value.as_ref(), cx); - cx.active_drag = Some(AnyDrag { - view: drag, - value: drag_value, - cursor_offset, - }); - pending_mouse_down.take(); - cx.notify(); - cx.stop_propagation(); + } + // Fire click handlers during the bubble phase. + DispatchPhase::Bubble => { + if let Some(mouse_down) = captured_mouse_down.take() { + if interactive_bounds.visibly_contains(&event.position, cx) { + let mouse_click = ClickEvent { + down: mouse_down, + up: event.clone(), + }; + for listener in &click_listeners { + listener(&mouse_click, cx); + } + } } } } - } - }); + }); + } - cx.on_mouse_event({ + if let Some(hover_listener) = self.hover_listener.take() { + let was_hovered = element_state + .hover_state + .get_or_insert_with(Default::default) + .clone(); + let has_mouse_down = element_state + .pending_mouse_down + .get_or_insert_with(Default::default) + .clone(); let interactive_bounds = interactive_bounds.clone(); - let mut captured_mouse_down = None; - move |event: &MouseUpEvent, phase, cx| match phase { - // Clear the pending mouse down during the capture phase, - // so that it happens even if another event handler stops - // propagation. - DispatchPhase::Capture => { - let mut pending_mouse_down = pending_mouse_down.borrow_mut(); - if pending_mouse_down.is_some() { - captured_mouse_down = pending_mouse_down.take(); - cx.notify(); - } + + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + if phase != DispatchPhase::Bubble { + return; } - // Fire click handlers during the bubble phase. - DispatchPhase::Bubble => { - if let Some(mouse_down) = captured_mouse_down.take() { - if interactive_bounds.visibly_contains(&event.position, cx) { - let mouse_click = ClickEvent { - down: mouse_down, - up: event.clone(), - }; - for listener in &click_listeners { - listener(&mouse_click, cx); - } - } - } + let is_hovered = interactive_bounds.visibly_contains(&event.position, cx) + && has_mouse_down.borrow().is_none(); + let mut was_hovered = was_hovered.borrow_mut(); + + if is_hovered != was_hovered.clone() { + *was_hovered = is_hovered; + drop(was_hovered); + + hover_listener(&is_hovered, cx); } - } - }); - } + }); + } - if let Some(hover_listener) = self.hover_listener.take() { - let was_hovered = element_state - .hover_state - .get_or_insert_with(Default::default) - .clone(); - let has_mouse_down = element_state - .pending_mouse_down - .get_or_insert_with(Default::default) - .clone(); - let interactive_bounds = interactive_bounds.clone(); + if let Some(tooltip_builder) = self.tooltip_builder.take() { + let active_tooltip = element_state + .active_tooltip + .get_or_insert_with(Default::default) + .clone(); + let pending_mouse_down = element_state + .pending_mouse_down + .get_or_insert_with(Default::default) + .clone(); + let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - if phase != DispatchPhase::Bubble { - return; - } - let is_hovered = interactive_bounds.visibly_contains(&event.position, cx) - && has_mouse_down.borrow().is_none(); - let mut was_hovered = was_hovered.borrow_mut(); + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + let is_hovered = interactive_bounds.visibly_contains(&event.position, cx) + && pending_mouse_down.borrow().is_none(); + if !is_hovered { + active_tooltip.borrow_mut().take(); + return; + } - if is_hovered != was_hovered.clone() { - *was_hovered = is_hovered; - drop(was_hovered); + if phase != DispatchPhase::Bubble { + return; + } - hover_listener(&is_hovered, cx); + if active_tooltip.borrow().is_none() { + let task = cx.spawn({ + let active_tooltip = active_tooltip.clone(); + let tooltip_builder = tooltip_builder.clone(); + + move |mut cx| async move { + cx.background_executor().timer(TOOLTIP_DELAY).await; + cx.update(|_, cx| { + active_tooltip.borrow_mut().replace(ActiveTooltip { + tooltip: Some(AnyTooltip { + view: tooltip_builder(cx), + cursor_offset: cx.mouse_position(), + }), + _task: None, + }); + cx.notify(); + }) + .ok(); + } + }); + active_tooltip.borrow_mut().replace(ActiveTooltip { + tooltip: None, + _task: Some(task), + }); + } + }); + + let active_tooltip = element_state + .active_tooltip + .get_or_insert_with(Default::default) + .clone(); + cx.on_mouse_event(move |_: &MouseDownEvent, _, _| { + active_tooltip.borrow_mut().take(); + }); + + if let Some(active_tooltip) = element_state + .active_tooltip + .get_or_insert_with(Default::default) + .borrow() + .as_ref() + { + if active_tooltip.tooltip.is_some() { + cx.active_tooltip = active_tooltip.tooltip.clone() + } } - }); - } + } - if let Some(tooltip_builder) = self.tooltip_builder.take() { - let active_tooltip = element_state - .active_tooltip - .get_or_insert_with(Default::default) - .clone(); - let pending_mouse_down = element_state - .pending_mouse_down + let active_state = element_state + .clicked_state .get_or_insert_with(Default::default) .clone(); - let interactive_bounds = interactive_bounds.clone(); + if active_state.borrow().is_clicked() { + cx.on_mouse_event(move |_: &MouseUpEvent, phase, cx| { + if phase == DispatchPhase::Capture { + *active_state.borrow_mut() = ElementClickedState::default(); + cx.notify(); + } + }); + } else { + let active_group_bounds = self + .group_active_style + .as_ref() + .and_then(|group_active| GroupBounds::get(&group_active.group, cx)); + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |down: &MouseDownEvent, phase, cx| { + if phase == DispatchPhase::Bubble && !cx.default_prevented() { + let group = active_group_bounds + .map_or(false, |bounds| bounds.contains(&down.position)); + let element = interactive_bounds.visibly_contains(&down.position, cx); + if group || element { + *active_state.borrow_mut() = ElementClickedState { group, element }; + cx.notify(); + } + } + }); + } - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - let is_hovered = interactive_bounds.visibly_contains(&event.position, cx) - && pending_mouse_down.borrow().is_none(); - if !is_hovered { - active_tooltip.borrow_mut().take(); - return; + let overflow = style.overflow; + if overflow.x == Overflow::Scroll || overflow.y == Overflow::Scroll { + if let Some(scroll_handle) = &self.scroll_handle { + scroll_handle.0.borrow_mut().overflow = overflow; } - if phase != DispatchPhase::Bubble { - return; - } + let scroll_offset = element_state + .scroll_offset + .get_or_insert_with(Rc::default) + .clone(); + let line_height = cx.line_height(); + let scroll_max = (content_size - bounds.size).max(&Size::default()); + let interactive_bounds = interactive_bounds.clone(); - if active_tooltip.borrow().is_none() { - let task = cx.spawn({ - let active_tooltip = active_tooltip.clone(); - let tooltip_builder = tooltip_builder.clone(); - - move |mut cx| async move { - cx.background_executor().timer(TOOLTIP_DELAY).await; - cx.update(|_, cx| { - active_tooltip.borrow_mut().replace(ActiveTooltip { - tooltip: Some(AnyTooltip { - view: tooltip_builder(cx), - cursor_offset: cx.mouse_position(), - }), - _task: None, - }); - cx.notify(); - }) - .ok(); - } - }); - active_tooltip.borrow_mut().replace(ActiveTooltip { - tooltip: None, - _task: Some(task), - }); - } - }); + cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { + if phase == DispatchPhase::Bubble + && interactive_bounds.visibly_contains(&event.position, cx) + { + let mut scroll_offset = scroll_offset.borrow_mut(); + let old_scroll_offset = *scroll_offset; + let delta = event.delta.pixel_delta(line_height); - let active_tooltip = element_state - .active_tooltip - .get_or_insert_with(Default::default) - .clone(); - cx.on_mouse_event(move |_: &MouseDownEvent, _, _| { - active_tooltip.borrow_mut().take(); - }); + if overflow.x == Overflow::Scroll { + scroll_offset.x = + (scroll_offset.x + delta.x).clamp(-scroll_max.width, px(0.)); + } - if let Some(active_tooltip) = element_state - .active_tooltip - .get_or_insert_with(Default::default) - .borrow() - .as_ref() - { - if active_tooltip.tooltip.is_some() { - cx.active_tooltip = active_tooltip.tooltip.clone() - } - } - } + if overflow.y == Overflow::Scroll { + scroll_offset.y = + (scroll_offset.y + delta.y).clamp(-scroll_max.height, px(0.)); + } - let active_state = element_state - .clicked_state - .get_or_insert_with(Default::default) - .clone(); - if active_state.borrow().is_clicked() { - cx.on_mouse_event(move |_: &MouseUpEvent, phase, cx| { - if phase == DispatchPhase::Capture { - *active_state.borrow_mut() = ElementClickedState::default(); - cx.notify(); - } - }); - } else { - let active_group_bounds = self - .group_active_style - .as_ref() - .and_then(|group_active| GroupBounds::get(&group_active.group, cx)); - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |down: &MouseDownEvent, phase, cx| { - if phase == DispatchPhase::Bubble && !cx.default_prevented() { - let group = - active_group_bounds.map_or(false, |bounds| bounds.contains(&down.position)); - let element = interactive_bounds.visibly_contains(&down.position, cx); - if group || element { - *active_state.borrow_mut() = ElementClickedState { group, element }; - cx.notify(); + if *scroll_offset != old_scroll_offset { + cx.notify(); + cx.stop_propagation(); + } } - } - }); - } + }); + } - let overflow = style.overflow; - if overflow.x == Overflow::Scroll || overflow.y == Overflow::Scroll { - if let Some(scroll_handle) = &self.scroll_handle { - scroll_handle.0.borrow_mut().overflow = overflow; + if let Some(group) = self.group.clone() { + GroupBounds::push(group, bounds, cx); } let scroll_offset = element_state .scroll_offset - .get_or_insert_with(Rc::default) - .clone(); - let line_height = cx.line_height(); - let scroll_max = (content_size - bounds.size).max(&Size::default()); - let interactive_bounds = interactive_bounds.clone(); - - cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && interactive_bounds.visibly_contains(&event.position, cx) - { - let mut scroll_offset = scroll_offset.borrow_mut(); - let old_scroll_offset = *scroll_offset; - let delta = event.delta.pixel_delta(line_height); - - if overflow.x == Overflow::Scroll { - scroll_offset.x = - (scroll_offset.x + delta.x).clamp(-scroll_max.width, px(0.)); + .as_ref() + .map(|scroll_offset| *scroll_offset.borrow()); + + let key_down_listeners = mem::take(&mut self.key_down_listeners); + let key_up_listeners = mem::take(&mut self.key_up_listeners); + let action_listeners = mem::take(&mut self.action_listeners); + cx.with_key_dispatch( + self.key_context.clone(), + element_state.focus_handle.clone(), + |_, cx| { + for listener in key_down_listeners { + cx.on_key_event(move |event: &KeyDownEvent, phase, cx| { + listener(event, phase, cx); + }) } - if overflow.y == Overflow::Scroll { - scroll_offset.y = - (scroll_offset.y + delta.y).clamp(-scroll_max.height, px(0.)); + for listener in key_up_listeners { + cx.on_key_event(move |event: &KeyUpEvent, phase, cx| { + listener(event, phase, cx); + }) } - if *scroll_offset != old_scroll_offset { - cx.notify(); - cx.stop_propagation(); + for (action_type, listener) in action_listeners { + cx.on_action(action_type, listener) } - } - }); - } - - if let Some(group) = self.group.clone() { - GroupBounds::push(group, bounds, cx); - } - - let scroll_offset = element_state - .scroll_offset - .as_ref() - .map(|scroll_offset| *scroll_offset.borrow()); - - let key_down_listeners = mem::take(&mut self.key_down_listeners); - let key_up_listeners = mem::take(&mut self.key_up_listeners); - let action_listeners = mem::take(&mut self.action_listeners); - cx.with_key_dispatch( - self.key_context.clone(), - element_state.focus_handle.clone(), - |_, cx| { - for listener in key_down_listeners { - cx.on_key_event(move |event: &KeyDownEvent, phase, cx| { - listener(event, phase, cx); - }) - } - for listener in key_up_listeners { - cx.on_key_event(move |event: &KeyUpEvent, phase, cx| { - listener(event, phase, cx); - }) - } + f(style, scroll_offset.unwrap_or_default(), cx) + }, + ); - for (action_type, listener) in action_listeners { - cx.on_action(action_type, listener) - } - - f(style, scroll_offset.unwrap_or_default(), cx) - }, - ); - - if let Some(group) = self.group.as_ref() { - GroupBounds::pop(group, cx); - } + if let Some(group) = self.group.as_ref() { + GroupBounds::pop(group, cx); + } + }); } pub fn compute_style( diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 26b1df4cda7c1d125df2f976bf09f9e6e3db6fef..7fba7ef47777553ae6e5e36ab8e20f5e01869360 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -200,58 +200,56 @@ impl Element for UniformList { bounds.lower_right() - point(border.right + padding.right, border.bottom), ); - cx.with_z_index(style.z_index.unwrap_or(0), |cx| { - style.paint(bounds, cx, |cx| { - if self.item_count > 0 { - let content_height = - item_height * self.item_count + padding.top + padding.bottom; - let min_scroll_offset = padded_bounds.size.height - content_height; - let is_scrolled = scroll_offset.y != px(0.); - - if is_scrolled && scroll_offset.y < min_scroll_offset { - shared_scroll_offset.borrow_mut().y = min_scroll_offset; - scroll_offset.y = min_scroll_offset; - } - - if let Some(scroll_handle) = self.scroll_handle.clone() { - scroll_handle.0.borrow_mut().replace(ScrollHandleState { - item_height, - list_height: padded_bounds.size.height, - scroll_offset: shared_scroll_offset, - }); - } - - let first_visible_element_ix = - (-(scroll_offset.y + padding.top) / item_height).floor() as usize; - let last_visible_element_ix = - ((-scroll_offset.y + padded_bounds.size.height) / item_height) - .ceil() as usize; - let visible_range = first_visible_element_ix - ..cmp::min(last_visible_element_ix, self.item_count); - - let mut items = (self.render_items)(visible_range.clone(), cx); - cx.with_z_index(1, |cx| { - let content_mask = ContentMask { bounds }; - cx.with_content_mask(Some(content_mask), |cx| { - for (item, ix) in items.iter_mut().zip(visible_range) { - let item_origin = padded_bounds.origin - + point( - px(0.), - item_height * ix + scroll_offset.y + padding.top, - ); - let available_space = size( - AvailableSpace::Definite(padded_bounds.size.width), - AvailableSpace::Definite(item_height), - ); - item.draw(item_origin, available_space, cx); - } - }); + style.paint(bounds, cx, |cx| { + if self.item_count > 0 { + let content_height = + item_height * self.item_count + padding.top + padding.bottom; + let min_scroll_offset = padded_bounds.size.height - content_height; + let is_scrolled = scroll_offset.y != px(0.); + + if is_scrolled && scroll_offset.y < min_scroll_offset { + shared_scroll_offset.borrow_mut().y = min_scroll_offset; + scroll_offset.y = min_scroll_offset; + } + + if let Some(scroll_handle) = self.scroll_handle.clone() { + scroll_handle.0.borrow_mut().replace(ScrollHandleState { + item_height, + list_height: padded_bounds.size.height, + scroll_offset: shared_scroll_offset, }); } - }); - }) + + let first_visible_element_ix = + (-(scroll_offset.y + padding.top) / item_height).floor() as usize; + let last_visible_element_ix = + ((-scroll_offset.y + padded_bounds.size.height) / item_height).ceil() + as usize; + let visible_range = first_visible_element_ix + ..cmp::min(last_visible_element_ix, self.item_count); + + let mut items = (self.render_items)(visible_range.clone(), cx); + cx.with_z_index(1, |cx| { + let content_mask = ContentMask { bounds }; + cx.with_content_mask(Some(content_mask), |cx| { + for (item, ix) in items.iter_mut().zip(visible_range) { + let item_origin = padded_bounds.origin + + point( + px(0.), + item_height * ix + scroll_offset.y + padding.top, + ); + let available_space = size( + AvailableSpace::Definite(padded_bounds.size.width), + AvailableSpace::Definite(item_height), + ); + item.draw(item_origin, available_space, cx); + } + }); + }); + } + }); }, - ); + ) } } From 2979eb9da96c2b5940e94af863dd8fa966518aeb Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 18 Dec 2023 18:32:03 -0800 Subject: [PATCH 130/644] Allow transparent divs to be considered "top layers" This changes the meaning of `was_top_layer` so that it is checking that nothing opaque is on top of the given layer. The layer in question need not be opaque. --- crates/gpui2/src/window.rs | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 0cef1644605a977417efffb43dca42263884d172..ccfdb6a273835cf9c1f0c49adf349dfde65d6d35 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -942,16 +942,20 @@ impl<'a> WindowContext<'a> { } } - /// Returns true if the top-most opaque layer painted over this point was part of the - /// same layer as the given stacking order. + /// Returns true if there is no opaque layer containing the given point + /// on top of the given level. Layers whose level is an extension of the + /// level are not considered to be on top of the level. pub fn was_top_layer(&self, point: &Point, level: &StackingOrder) -> bool { - for (stack, bounds) in self.window.rendered_frame.depth_map.iter() { - if bounds.contains(point) { - return level.starts_with(stack) || stack.starts_with(level); + for (opaque_level, bounds) in self.window.rendered_frame.depth_map.iter() { + if level >= opaque_level { + break; } - } - false + if bounds.contains(point) && !opaque_level.starts_with(level) { + return false; + } + } + true } pub fn was_top_layer_under_active_drag( @@ -959,16 +963,19 @@ impl<'a> WindowContext<'a> { point: &Point, level: &StackingOrder, ) -> bool { - for (stack, bounds) in self.window.rendered_frame.depth_map.iter() { - if stack.starts_with(&[ACTIVE_DRAG_Z_INDEX]) { + for (opaque_level, bounds) in self.window.rendered_frame.depth_map.iter() { + if level >= opaque_level { + break; + } + if opaque_level.starts_with(&[ACTIVE_DRAG_Z_INDEX]) { continue; } - if bounds.contains(point) { - return level.starts_with(stack) || stack.starts_with(level); + + if bounds.contains(point) && !opaque_level.starts_with(level) { + return false; } } - - false + true } /// Called during painting to get the current stacking order. From 4b74f30d0a24afde4e6f118504f5778137cccdae Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 19 Dec 2023 06:44:26 +0200 Subject: [PATCH 131/644] Properly restore termina current dir when deserializing the project --- crates/terminal_view2/src/terminal_view.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/terminal_view2/src/terminal_view.rs b/crates/terminal_view2/src/terminal_view.rs index 1ac5ba8ab5a301e0f0330f7d82ae0bd54addd5fe..f82a43959bc1a4dbd04c0e6b2962b6ebb46071ff 100644 --- a/crates/terminal_view2/src/terminal_view.rs +++ b/crates/terminal_view2/src/terminal_view.rs @@ -752,8 +752,7 @@ impl Item for TerminalView { ) -> Task>> { let window = cx.window_handle(); cx.spawn(|pane, mut cx| async move { - let cwd = None; - TERMINAL_DB + let cwd = TERMINAL_DB .get_working_directory(item_id, workspace_id) .log_err() .flatten() From ba0d7e35bb74cf09833828542fbe0e0094287812 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 19 Dec 2023 10:26:06 +0100 Subject: [PATCH 132/644] Set window edited --- crates/gpui2/src/window.rs | 4 ++++ crates/workspace2/src/workspace2.rs | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 0cef1644605a977417efffb43dca42263884d172..ca91a806ad570e84419e166a2b05b3e553e67c45 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -773,6 +773,10 @@ impl<'a> WindowContext<'a> { self.window.platform_window.set_title(title); } + pub fn set_window_edited(&mut self, edited: bool) { + self.window.platform_window.set_edited(edited); + } + pub fn display(&self) -> Option> { self.platform .displays() diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 8cb8c3dc9afd8ac057dd88f350e92b45a45d731c..4f911d1073d4ac6273deed1707fb0758d0969de4 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -2520,8 +2520,7 @@ impl Workspace { .any(|item| item.has_conflict(cx) || item.is_dirty(cx)); if is_edited != self.window_edited { self.window_edited = is_edited; - // todo!() - // cx.set_window_edited(self.window_edited) + cx.set_window_edited(self.window_edited) } } From ae32706cfed3b5e51f4f7a4990b8e8fc0b22399b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 19 Dec 2023 11:04:32 +0100 Subject: [PATCH 133/644] Fix tests --- crates/gpui2/src/app/test_context.rs | 7 +------ crates/gpui2/src/platform/test/window.rs | 12 +++++++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/crates/gpui2/src/app/test_context.rs b/crates/gpui2/src/app/test_context.rs index 9f0c7e6aca01a934277f2f11f22bee90c4d68d36..c77ec29bdf288f1300210b4c2b82cedbf0aef3bc 100644 --- a/crates/gpui2/src/app/test_context.rs +++ b/crates/gpui2/src/app/test_context.rs @@ -567,12 +567,7 @@ impl<'a> VisualTestContext<'a> { pub fn window_title(&mut self) -> Option { self.cx .update_window(self.window, |_, cx| { - cx.window - .platform_window - .as_test() - .unwrap() - .window_title - .clone() + cx.window.platform_window.as_test().unwrap().title.clone() }) .unwrap() } diff --git a/crates/gpui2/src/platform/test/window.rs b/crates/gpui2/src/platform/test/window.rs index 0f981d44783ed2434361d639234ebed2c1ceb85f..9df513d1f7ea46b0dffb452d27dbd82f5aba2176 100644 --- a/crates/gpui2/src/platform/test/window.rs +++ b/crates/gpui2/src/platform/test/window.rs @@ -21,7 +21,8 @@ pub(crate) struct TestWindowHandlers { pub struct TestWindow { pub(crate) bounds: WindowBounds, display: Rc, - pub(crate) window_title: Option, + pub(crate) title: Option, + pub(crate) edited: bool, pub(crate) input_handler: Option>>>, pub(crate) handlers: Arc>, platform: Weak, @@ -41,7 +42,8 @@ impl TestWindow { input_handler: None, sprite_atlas: Arc::new(TestAtlas::new()), handlers: Default::default(), - window_title: Default::default(), + title: Default::default(), + edited: false, } } } @@ -109,11 +111,11 @@ impl PlatformWindow for TestWindow { } fn set_title(&mut self, title: &str) { - self.window_title = Some(title.to_owned()); + self.title = Some(title.to_owned()); } - fn set_edited(&mut self, _edited: bool) { - unimplemented!() + fn set_edited(&mut self, edited: bool) { + self.edited = edited; } fn show_character_palette(&self) { From 02e53025f30efbd56b7b03f53d1aaf4237742ba1 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 19 Dec 2023 14:26:30 +0100 Subject: [PATCH 134/644] Track caller on h_stack and v_stack --- crates/gpui2/src/elements/div.rs | 2 +- crates/ui2/src/components/stack.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 1f56f44900477780085b556f46adc508f4ff119a..631ffc43c679cdb4fc7147cf29607a4e53aa9935 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1065,7 +1065,7 @@ impl Interactivity { { cx.focus(&focus_handle); // If there is a parent that is also focusable, prevent it - // from trasferring focus because we already did so. + // from transferring focus because we already did so. cx.prevent_default(); } } diff --git a/crates/ui2/src/components/stack.rs b/crates/ui2/src/components/stack.rs index 6ae88cb1a296913666df46ba6a86998ae57a991c..a6321b93d7c9e15afa1d3053fa61fb467acdbeb0 100644 --- a/crates/ui2/src/components/stack.rs +++ b/crates/ui2/src/components/stack.rs @@ -5,6 +5,7 @@ use crate::StyledExt; /// Horizontally stacks elements. /// /// Sets `flex()`, `flex_row()`, `items_center()` +#[track_caller] pub fn h_stack() -> Div { div().h_flex() } @@ -12,6 +13,7 @@ pub fn h_stack() -> Div { /// Vertically stacks elements. /// /// Sets `flex()`, `flex_col()` +#[track_caller] pub fn v_stack() -> Div { div().v_flex() } From afbc61a344856ed43c7397533c706db5727e7cfa Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 19 Dec 2023 14:26:44 +0100 Subject: [PATCH 135/644] Prevent default when mousing down on a button that responds to clicks This ensures that ancestors that track focus don't accidentally steal it on mouse down, which was preventing the editor from deploying the code actions menu. --- crates/ui2/src/components/button/button_like.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/ui2/src/components/button/button_like.rs b/crates/ui2/src/components/button/button_like.rs index 54f2a0e9eaa0a7a87a93927088bc3a6e7975c06b..bd4e9cd523d7d4f407f07e9cb501dc53e6f2aad7 100644 --- a/crates/ui2/src/components/button/button_like.rs +++ b/crates/ui2/src/components/button/button_like.rs @@ -1,4 +1,4 @@ -use gpui::{relative, DefiniteLength}; +use gpui::{relative, DefiniteLength, MouseButton}; use gpui::{rems, transparent_black, AnyElement, AnyView, ClickEvent, Div, Hsla, Rems, Stateful}; use smallvec::SmallVec; @@ -372,10 +372,11 @@ impl RenderOnce for ButtonLike { .when_some( self.on_click.filter(|_| !self.disabled), |this, on_click| { - this.on_click(move |event, cx| { - cx.stop_propagation(); - (on_click)(event, cx) - }) + this.on_mouse_down(MouseButton::Left, |_, cx| cx.prevent_default()) + .on_click(move |event, cx| { + cx.stop_propagation(); + (on_click)(event, cx) + }) }, ) .when_some(self.tooltip, |this, tooltip| { From b30fd3f5743863b8fc566ecb479f97c8f57ab30f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 19 Dec 2023 15:29:05 +0100 Subject: [PATCH 136/644] Fix janky editor scrollbar dragging We can receive multiple events before computing the next frame, and in that case we want to compute a drag delta between the position for the previous mouse event and the current one. --- crates/editor2/src/element.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 328f2f08ba1912212cbd54c3d1ca085a70194c7e..cf34863ba6dc364dea8370427e514ec490579292 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -1351,7 +1351,7 @@ impl EditorElement { )); } - let mouse_position = cx.mouse_position(); + let mut mouse_position = cx.mouse_position(); if track_bounds.contains(&mouse_position) { cx.set_cursor_style(CursorStyle::Arrow); } @@ -1377,6 +1377,8 @@ impl EditorElement { } editor.set_scroll_position(position, cx); } + + mouse_position = event.position; cx.stop_propagation(); } else { editor.scroll_manager.set_is_dragging_scrollbar(false, cx); @@ -1392,6 +1394,10 @@ impl EditorElement { cx.on_mouse_event({ let editor = self.editor.clone(); move |event: &MouseUpEvent, phase, cx| { + if phase == DispatchPhase::Capture { + return; + } + editor.update(cx, |editor, cx| { editor.scroll_manager.set_is_dragging_scrollbar(false, cx); cx.stop_propagation(); @@ -1402,6 +1408,10 @@ impl EditorElement { cx.on_mouse_event({ let editor = self.editor.clone(); move |event: &MouseDownEvent, phase, cx| { + if phase == DispatchPhase::Capture { + return; + } + editor.update(cx, |editor, cx| { if track_bounds.contains(&event.position) { editor.scroll_manager.set_is_dragging_scrollbar(true, cx); From 49502af4d3a645187b8c2c844c88864ccd7474dc Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 09:56:29 -0500 Subject: [PATCH 137/644] Update conversation item rendering --- crates/assistant2/src/assistant_panel.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 79ebb6602d77776ee30f905cacba3ce6434e9512..4c1abbe4b8bd6f858878a2a2858e8c78954e2f98 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -1020,10 +1020,18 @@ impl AssistantPanel { this.open_conversation(path.clone(), cx) .detach_and_log_err(cx) })) - .child(Label::new( - conversation.mtime.format("%F %I:%M%p").to_string(), - )) - .child(Label::new(conversation.title.clone())) + .child( + div() + .flex() + .flex_1() + .gap_2() + .child( + Label::new(conversation.mtime.format("%F %I:%M%p").to_string()) + .color(Color::Muted) + .size(LabelSize::Small), + ) + .child(Label::new(conversation.title.clone()).size(LabelSize::Small)), + ) } fn open_conversation(&mut self, path: PathBuf, cx: &mut ViewContext) -> Task> { From 2c402f9b5deab38e331248fe8d8d87dab5ab2926 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 10:03:26 -0500 Subject: [PATCH 138/644] Ensure conversation items fill the container --- crates/assistant2/src/assistant_panel.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 4c1abbe4b8bd6f858878a2a2858e8c78954e2f98..ec2fa4fba05832cd678a1bf3b4ebaac2c1aa2649 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -1020,10 +1020,11 @@ impl AssistantPanel { this.open_conversation(path.clone(), cx) .detach_and_log_err(cx) })) + .full_width() .child( div() .flex() - .flex_1() + .w_full() .gap_2() .child( Label::new(conversation.mtime.format("%F %I:%M%p").to_string()) From 42a02e4fb6c0b76457b1bcff2117b2ec2a6fd12c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 10:03:59 -0500 Subject: [PATCH 139/644] Remove red border --- crates/assistant2/src/assistant_panel.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index ec2fa4fba05832cd678a1bf3b4ebaac2c1aa2649..0cac69661a2035a333c2a5e46dca5be034d0ac3d 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -1174,8 +1174,6 @@ impl Render for AssistantPanel { .into_any_element() }), ) - .border() - .border_color(gpui::red()) } } } From dd84993d76b9ba0e9ab8a760ae8eba0fd61bec2d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 19 Dec 2023 16:06:00 +0100 Subject: [PATCH 140/644] Maintain scroll position in CollabPanel after updating entries Co-Authored-By: Julia --- crates/collab_ui2/src/collab_panel.rs | 49 ++++++++++++++------------- crates/gpui2/src/elements/list.rs | 2 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index ab823100948705bef58654f7e9990136ee77e730..2179d82cf32b068ed2a748587ab1d455aaa573d7 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -962,15 +962,12 @@ impl CollabPanel { self.entries.push(ListEntry::ContactPlaceholder); } - self.list_state.reset(self.entries.len()); - if select_same_item { if let Some(prev_selected_entry) = prev_selected_entry { self.selection.take(); for (ix, entry) in self.entries.iter().enumerate() { if *entry == prev_selected_entry { self.selection = Some(ix); - self.scroll_to_item(ix); break; } } @@ -980,49 +977,53 @@ impl CollabPanel { if self.entries.is_empty() { None } else { - let ix = prev_selection.min(self.entries.len() - 1); - self.scroll_to_item(ix); - Some(ix) + Some(prev_selection.min(self.entries.len() - 1)) } }); } + let old_scroll_top = self.list_state.logical_scroll_top(); + self.list_state.reset(self.entries.len()); + if scroll_to_top { - self.scroll_to_item(0) + self.list_state.scroll_to(ListOffset::default()); } else { - let ListOffset { - item_ix: old_index, - offset_in_item: old_offset, - } = self.list_state.logical_scroll_top(); // Attempt to maintain the same scroll position. - if let Some(old_top_entry) = old_entries.get(old_index) { - let (new_index, new_offset) = self + if let Some(old_top_entry) = old_entries.get(old_scroll_top.item_ix) { + let new_scroll_top = self .entries .iter() .position(|entry| entry == old_top_entry) - .map(|item_ix| (item_ix, old_offset)) + .map(|item_ix| ListOffset { + item_ix, + offset_in_item: old_scroll_top.offset_in_item, + }) .or_else(|| { - let entry_after_old_top = old_entries.get(old_index + 1)?; + let entry_after_old_top = old_entries.get(old_scroll_top.item_ix + 1)?; let item_ix = self .entries .iter() .position(|entry| entry == entry_after_old_top)?; - Some((item_ix, px(0.))) + Some(ListOffset { + item_ix, + offset_in_item: Pixels::ZERO, + }) }) .or_else(|| { - let entry_before_old_top = old_entries.get(old_index.saturating_sub(1))?; + let entry_before_old_top = + old_entries.get(old_scroll_top.item_ix.saturating_sub(1))?; let item_ix = self .entries .iter() .position(|entry| entry == entry_before_old_top)?; - Some((item_ix, px(0.))) - }) - .unwrap_or_else(|| (old_index, old_offset)); + Some(ListOffset { + item_ix, + offset_in_item: Pixels::ZERO, + }) + }); - self.list_state.scroll_to(ListOffset { - item_ix: new_index, - offset_in_item: new_offset, - }); + self.list_state + .scroll_to(new_scroll_top.unwrap_or(old_scroll_top)); } } diff --git a/crates/gpui2/src/elements/list.rs b/crates/gpui2/src/elements/list.rs index 73bd319afc843cbc3911a03709a991bc6ed22af1..a0467aaaa3c92acd1b045a69bae3fb9658eb0f01 100644 --- a/crates/gpui2/src/elements/list.rs +++ b/crates/gpui2/src/elements/list.rs @@ -293,7 +293,7 @@ impl std::fmt::Debug for ListItem { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Default)] pub struct ListOffset { pub item_ix: usize, pub offset_in_item: Pixels, From 57efaa92cf6bb43330e1be225a151ecd1eab41ae Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 10:30:46 -0500 Subject: [PATCH 141/644] Style assistant header, update icons --- assets/icons/maximize.svg | 5 +- assets/icons/menu.svg | 4 +- assets/icons/minimize.svg | 5 +- assets/icons/quote.svg | 9 +--- assets/icons/snip.svg | 1 + assets/icons/split_message.svg | 1 - crates/assistant2/src/assistant_panel.rs | 58 ++++++++++++++++++------ crates/ui2/src/components/icon.rs | 6 ++- 8 files changed, 54 insertions(+), 35 deletions(-) create mode 100644 assets/icons/snip.svg delete mode 100644 assets/icons/split_message.svg diff --git a/assets/icons/maximize.svg b/assets/icons/maximize.svg index f37f6a2087f968728170539b379206cca7551b0e..b3504b5701e3081f82c4fc0ee2ec89642fb439c4 100644 --- a/assets/icons/maximize.svg +++ b/assets/icons/maximize.svg @@ -1,4 +1 @@ - - - - + diff --git a/assets/icons/menu.svg b/assets/icons/menu.svg index 060caeecbfd58603530f253248a0c369ba329b4e..6598697ff83fbb54e760711e569c26f5fac6776f 100644 --- a/assets/icons/menu.svg +++ b/assets/icons/menu.svg @@ -1,3 +1 @@ - - - + diff --git a/assets/icons/minimize.svg b/assets/icons/minimize.svg index ec78f152e13eda0c887a18b99b585d0c65acc8a8..0451233cc9b5455396d7655f8a9b1bc4791d0fc7 100644 --- a/assets/icons/minimize.svg +++ b/assets/icons/minimize.svg @@ -1,4 +1 @@ - - - - + diff --git a/assets/icons/quote.svg b/assets/icons/quote.svg index 50205479c300e789b302cb1dcd687aaf7f9353f8..b970db14300b1837691d346498e8af989442e721 100644 --- a/assets/icons/quote.svg +++ b/assets/icons/quote.svg @@ -1,8 +1 @@ - - - + diff --git a/assets/icons/snip.svg b/assets/icons/snip.svg new file mode 100644 index 0000000000000000000000000000000000000000..03ae4ce0399fae65f847224aa26695530dbd1a66 --- /dev/null +++ b/assets/icons/snip.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/split_message.svg b/assets/icons/split_message.svg deleted file mode 100644 index 54d9e81224cbf55eca2a4f354f7fcfc8f98b6854..0000000000000000000000000000000000000000 --- a/assets/icons/split_message.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 0cac69661a2035a333c2a5e46dca5be034d0ac3d..17a020fb9c9ed9a3a667a9126d358a06095c564e 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -54,7 +54,8 @@ use std::{ }; use theme::ThemeSettings; use ui::{ - h_stack, prelude::*, v_stack, Button, ButtonLike, Icon, IconButton, IconElement, Label, Tooltip, + h_stack, prelude::*, v_stack, Button, ButtonLike, Icon, IconButton, IconElement, Label, TabBar, + Tooltip, }; use util::{paths::CONVERSATIONS_DIR, post_inc, ResultExt, TryFutureExt}; use uuid::Uuid; @@ -939,7 +940,7 @@ impl AssistantPanel { this.set_active_editor_index(this.prev_active_editor_index, cx); } })) - .tooltip(|cx| Tooltip::text("History", cx)) + .tooltip(|cx| Tooltip::text("Conversation History", cx)) } fn render_editor_tools(&self, cx: &mut ViewContext) -> Vec { @@ -955,12 +956,13 @@ impl AssistantPanel { } fn render_split_button(cx: &mut ViewContext) -> impl IntoElement { - IconButton::new("split_button", Icon::SplitMessage) + IconButton::new("split_button", Icon::Snip) .on_click(cx.listener(|this, _event, cx| { if let Some(active_editor) = this.active_editor() { active_editor.update(cx, |editor, cx| editor.split(&Default::default(), cx)); } })) + .icon_size(IconSize::Small) .tooltip(|cx| Tooltip::for_action("Split Message", &Split, cx)) } @@ -971,6 +973,7 @@ impl AssistantPanel { active_editor.update(cx, |editor, cx| editor.assist(&Default::default(), cx)); } })) + .icon_size(IconSize::Small) .tooltip(|cx| Tooltip::for_action("Assist", &Assist, cx)) } @@ -985,6 +988,7 @@ impl AssistantPanel { }); } })) + .icon_size(IconSize::Small) .tooltip(|cx| Tooltip::for_action("Quote Seleciton", &QuoteSelection, cx)) } @@ -993,15 +997,19 @@ impl AssistantPanel { .on_click(cx.listener(|this, _event, cx| { this.new_conversation(cx); })) + .icon_size(IconSize::Small) .tooltip(|cx| Tooltip::for_action("New Conversation", &NewConversation, cx)) } fn render_zoom_button(&self, cx: &mut ViewContext) -> impl IntoElement { let zoomed = self.zoomed; - IconButton::new("zoom_button", Icon::MagnifyingGlass) + IconButton::new("zoom_button", Icon::Maximize) .on_click(cx.listener(|this, _event, cx| { this.toggle_zoom(&ToggleZoom, cx); })) + .selected(zoomed) + .selected_icon(Icon::Minimize) + .icon_size(IconSize::Small) .tooltip(move |cx| { Tooltip::for_action(if zoomed { "Zoom Out" } else { "Zoom In" }, &ToggleZoom, cx) }) @@ -1125,16 +1133,40 @@ impl Render for AssistantPanel { .active_editor() .map(|editor| Label::new(editor.read(cx).title(cx))); - let mut header = h_stack() - .child(Self::render_hamburger_button(cx)) - .children(title); + // let mut header = h_stack() + // .p_1() + // .border_b() + // .border_color(cx.theme().colors().border_variant) + // .bg(cx.theme().colors().toolbar_background) + // .child(div().flex_1()); + + let header = TabBar::new("assistant_header") + .start_child( + h_stack() + .gap_1() + .child(Self::render_hamburger_button(cx)) + .children(title), + ) + .end_child(if self.focus_handle.contains_focused(cx) { + h_stack() + .gap_1() + .children(self.render_editor_tools(cx)) + .child(Self::render_plus_button(cx)) + .child(self.render_zoom_button(cx)) + } else { + div() + }); - if self.focus_handle.contains_focused(cx) { - header = header - .children(self.render_editor_tools(cx)) - .child(Self::render_plus_button(cx)) - .child(self.render_zoom_button(cx)); - } + // if self.focus_handle.contains_focused(cx) { + // header = header.child( + // div() + // .flex() + // .gap_1() + // .children(self.render_editor_tools(cx)) + // .child(Self::render_plus_button(cx)) + // .child(self.render_zoom_button(cx)), + // ); + // } v_stack() .size_full() diff --git a/crates/ui2/src/components/icon.rs b/crates/ui2/src/components/icon.rs index 6216acac483489f283366177fe5b6416495122c9..ca50cae7f8936e50dbc66be2def222589a571207 100644 --- a/crates/ui2/src/components/icon.rs +++ b/crates/ui2/src/components/icon.rs @@ -75,6 +75,7 @@ pub enum Icon { MagnifyingGlass, MailOpen, Maximize, + Minimize, Menu, MessageBubbles, Mic, @@ -88,7 +89,7 @@ pub enum Icon { Screen, SelectAll, Split, - SplitMessage, + Snip, Terminal, WholeWord, XCircle, @@ -156,6 +157,7 @@ impl Icon { Icon::MagnifyingGlass => "icons/magnifying_glass.svg", Icon::MailOpen => "icons/mail-open.svg", Icon::Maximize => "icons/maximize.svg", + Icon::Minimize => "icons/minimize.svg", Icon::Menu => "icons/menu.svg", Icon::MessageBubbles => "icons/conversations.svg", Icon::Mic => "icons/mic.svg", @@ -169,7 +171,7 @@ impl Icon { Icon::Screen => "icons/desktop.svg", Icon::SelectAll => "icons/select-all.svg", Icon::Split => "icons/split.svg", - Icon::SplitMessage => "icons/split_message.svg", + Icon::Snip => "icons/snip.svg", Icon::Terminal => "icons/terminal.svg", Icon::WholeWord => "icons/word_search.svg", Icon::XCircle => "icons/error.svg", From 286f654517ad64bd2a342951de14358573ae554e Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 10:57:36 -0500 Subject: [PATCH 142/644] Update assistant header --- crates/assistant2/src/assistant_panel.rs | 53 ++++++++++-------------- crates/ui2/src/components/divider.rs | 28 ++++++++++++- crates/ui2/src/components/tab.rs | 6 +-- 3 files changed, 51 insertions(+), 36 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 17a020fb9c9ed9a3a667a9126d358a06095c564e..b0b1378dbd2e3c3f91e8ed5603f49cad1635c778 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -55,7 +55,7 @@ use std::{ use theme::ThemeSettings; use ui::{ h_stack, prelude::*, v_stack, Button, ButtonLike, Icon, IconButton, IconElement, Label, TabBar, - Tooltip, + Tooltip, TAB_HEIGHT_IN_REMS, }; use util::{paths::CONVERSATIONS_DIR, post_inc, ResultExt, TryFutureExt}; use uuid::Uuid; @@ -1129,45 +1129,36 @@ impl Render for AssistantPanel { .border() .border_color(gpui::red()) } else { - let title = self - .active_editor() - .map(|editor| Label::new(editor.read(cx).title(cx))); - - // let mut header = h_stack() - // .p_1() - // .border_b() - // .border_color(cx.theme().colors().border_variant) - // .bg(cx.theme().colors().toolbar_background) - // .child(div().flex_1()); - let header = TabBar::new("assistant_header") .start_child( - h_stack() - .gap_1() - .child(Self::render_hamburger_button(cx)) - .children(title), + h_stack().gap_1().child(Self::render_hamburger_button(cx)), // .children(title), ) + .children(self.active_editor().map(|editor| { + h_stack() + .h(rems(TAB_HEIGHT_IN_REMS)) + .flex_1() + .px_2() + .child(Label::new(editor.read(cx).title(cx)).into_element()) + })) .end_child(if self.focus_handle.contains_focused(cx) { h_stack() - .gap_1() - .children(self.render_editor_tools(cx)) - .child(Self::render_plus_button(cx)) - .child(self.render_zoom_button(cx)) + .gap_2() + .child(h_stack().gap_1().children(self.render_editor_tools(cx))) + .child( + ui::Divider::vertical() + .inset() + .color(ui::DividerColor::Border), + ) + .child( + h_stack() + .gap_1() + .child(Self::render_plus_button(cx)) + .child(self.render_zoom_button(cx)), + ) } else { div() }); - // if self.focus_handle.contains_focused(cx) { - // header = header.child( - // div() - // .flex() - // .gap_1() - // .children(self.render_editor_tools(cx)) - // .child(Self::render_plus_button(cx)) - // .child(self.render_zoom_button(cx)), - // ); - // } - v_stack() .size_full() .on_action(cx.listener(|this, _: &workspace::NewFile, cx| { diff --git a/crates/ui2/src/components/divider.rs b/crates/ui2/src/components/divider.rs index cb48ce00ae24f031807d8522510aa18bc586d638..20744d6c48e94ea80312acd9bf3ef63b7a30496f 100644 --- a/crates/ui2/src/components/divider.rs +++ b/crates/ui2/src/components/divider.rs @@ -1,4 +1,4 @@ -use gpui::{Div, IntoElement}; +use gpui::{Div, Hsla, IntoElement}; use crate::prelude::*; @@ -7,9 +7,26 @@ enum DividerDirection { Vertical, } +#[derive(Default)] +pub enum DividerColor { + Border, + #[default] + BorderVariant, +} + +impl DividerColor { + pub fn hsla(self, cx: &WindowContext) -> Hsla { + match self { + DividerColor::Border => cx.theme().colors().border, + DividerColor::BorderVariant => cx.theme().colors().border_variant, + } + } +} + #[derive(IntoElement)] pub struct Divider { direction: DividerDirection, + color: DividerColor, inset: bool, } @@ -26,7 +43,7 @@ impl RenderOnce for Divider { this.w_px().h_full().when(self.inset, |this| this.my_1p5()) } }) - .bg(cx.theme().colors().border_variant) + .bg(self.color.hsla(cx)) } } @@ -34,6 +51,7 @@ impl Divider { pub fn horizontal() -> Self { Self { direction: DividerDirection::Horizontal, + color: DividerColor::default(), inset: false, } } @@ -41,6 +59,7 @@ impl Divider { pub fn vertical() -> Self { Self { direction: DividerDirection::Vertical, + color: DividerColor::default(), inset: false, } } @@ -49,4 +68,9 @@ impl Divider { self.inset = true; self } + + pub fn color(mut self, color: DividerColor) -> Self { + self.color = color; + self + } } diff --git a/crates/ui2/src/components/tab.rs b/crates/ui2/src/components/tab.rs index 8114a322e300cac465981438bf8ad02d84ca029e..7f20a923299d27caca8f30a7b5b234d8525f98eb 100644 --- a/crates/ui2/src/components/tab.rs +++ b/crates/ui2/src/components/tab.rs @@ -3,6 +3,8 @@ use gpui::{AnyElement, IntoElement, Stateful}; use smallvec::SmallVec; use std::cmp::Ordering; +pub const TAB_HEIGHT_IN_REMS: f32 = 30. / 16.; + /// The position of a [`Tab`] within a list of tabs. #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum TabPosition { @@ -94,8 +96,6 @@ impl RenderOnce for Tab { type Rendered = Stateful
; fn render(self, cx: &mut WindowContext) -> Self::Rendered { - const HEIGHT_IN_REMS: f32 = 30. / 16.; - let (text_color, tab_bg, _tab_hover_bg, _tab_active_bg) = match self.selected { false => ( cx.theme().colors().text_muted, @@ -112,7 +112,7 @@ impl RenderOnce for Tab { }; self.div - .h(rems(HEIGHT_IN_REMS)) + .h(rems(TAB_HEIGHT_IN_REMS)) .bg(tab_bg) .border_color(cx.theme().colors().border) .map(|this| match self.position { From 30b01b9bc0699763f2ea72dcd273dfe4d9da30d8 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 11:03:08 -0500 Subject: [PATCH 143/644] Update imports, tab height const --- crates/assistant2/src/assistant_panel.rs | 9 +++------ crates/ui2/src/components/tab.rs | 6 +++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index b0b1378dbd2e3c3f91e8ed5603f49cad1635c778..94be39f924ee6125e1d1a12fea35d271fe8ddc2e 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -53,10 +53,7 @@ use std::{ time::{Duration, Instant}, }; use theme::ThemeSettings; -use ui::{ - h_stack, prelude::*, v_stack, Button, ButtonLike, Icon, IconButton, IconElement, Label, TabBar, - Tooltip, TAB_HEIGHT_IN_REMS, -}; +use ui::{prelude::*, Tab, TabBar, Tooltip}; use util::{paths::CONVERSATIONS_DIR, post_inc, ResultExt, TryFutureExt}; use uuid::Uuid; use workspace::{ @@ -1129,13 +1126,13 @@ impl Render for AssistantPanel { .border() .border_color(gpui::red()) } else { - let header = TabBar::new("assistant_header") + let header = ui::TabBar::new("assistant_header") .start_child( h_stack().gap_1().child(Self::render_hamburger_button(cx)), // .children(title), ) .children(self.active_editor().map(|editor| { h_stack() - .h(rems(TAB_HEIGHT_IN_REMS)) + .h(rems(ui::Tab::HEIGHT_IN_REMS)) .flex_1() .px_2() .child(Label::new(editor.read(cx).title(cx)).into_element()) diff --git a/crates/ui2/src/components/tab.rs b/crates/ui2/src/components/tab.rs index 7f20a923299d27caca8f30a7b5b234d8525f98eb..eddfab811914b721126ccf777c9818498e405569 100644 --- a/crates/ui2/src/components/tab.rs +++ b/crates/ui2/src/components/tab.rs @@ -3,8 +3,6 @@ use gpui::{AnyElement, IntoElement, Stateful}; use smallvec::SmallVec; use std::cmp::Ordering; -pub const TAB_HEIGHT_IN_REMS: f32 = 30. / 16.; - /// The position of a [`Tab`] within a list of tabs. #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum TabPosition { @@ -50,6 +48,8 @@ impl Tab { } } + pub const HEIGHT_IN_REMS: f32 = 30. / 16.; + pub fn position(mut self, position: TabPosition) -> Self { self.position = position; self @@ -112,7 +112,7 @@ impl RenderOnce for Tab { }; self.div - .h(rems(TAB_HEIGHT_IN_REMS)) + .h(rems(Self::HEIGHT_IN_REMS)) .bg(tab_bg) .border_color(cx.theme().colors().border) .map(|this| match self.position { From ae313ff83075474d1eed8de1ac840a2eafd59710 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 11:16:59 -0500 Subject: [PATCH 144/644] Allow format_distance to take a DateTimeType --- crates/ui2/src/utils/format_distance.rs | 65 +++++++++++++++++-------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/crates/ui2/src/utils/format_distance.rs b/crates/ui2/src/utils/format_distance.rs index d157d30bbebfeb28103c9aea3cc6193253f81e93..f13e92bbe901e5538bad8566e6b2e001e8e4ff78 100644 --- a/crates/ui2/src/utils/format_distance.rs +++ b/crates/ui2/src/utils/format_distance.rs @@ -1,4 +1,23 @@ -use chrono::NaiveDateTime; +use chrono::{DateTime, Local, NaiveDateTime}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum DateTimeType { + Naive(NaiveDateTime), + Local(DateTime), +} + +impl DateTimeType { + /// Converts the DateTimeType to a NaiveDateTime. + /// + /// If the DateTimeType is already a NaiveDateTime, it will be returned as is. + /// If the DateTimeType is a DateTime, it will be converted to a NaiveDateTime. + pub fn to_naive(&self) -> NaiveDateTime { + match self { + DateTimeType::Naive(naive) => *naive, + DateTimeType::Local(local) => local.naive_local(), + } + } +} /// Calculates the distance in seconds between two NaiveDateTime objects. /// It returns a signed integer denoting the difference. If `date` is earlier than `base_date`, the returned value will be negative. @@ -108,13 +127,13 @@ fn distance_string(distance: i64, include_seconds: bool, add_suffix: bool) -> St /// ``` /// /// Output: `"There was about 3 years between the first and last crewed moon landings."` -pub fn naive_format_distance( - date: NaiveDateTime, +pub fn format_distance( + date: DateTimeType, base_date: NaiveDateTime, include_seconds: bool, add_suffix: bool, ) -> String { - let distance = distance_in_seconds(date, base_date); + let distance = distance_in_seconds(date.to_naive(), base_date); distance_string(distance, include_seconds, add_suffix) } @@ -142,14 +161,14 @@ pub fn naive_format_distance( /// ``` /// /// Output: `It's been over 54 years since Apollo 11 first landed on the moon.` -pub fn naive_format_distance_from_now( - datetime: NaiveDateTime, +pub fn format_distance_from_now( + datetime: DateTimeType, include_seconds: bool, add_suffix: bool, ) -> String { let now = chrono::offset::Local::now().naive_local(); - naive_format_distance(datetime, now, include_seconds, add_suffix) + format_distance(datetime, now, include_seconds, add_suffix) } #[cfg(test)] @@ -159,38 +178,44 @@ mod tests { #[test] fn test_naive_format_distance() { - let date = - NaiveDateTime::from_timestamp_opt(9600, 0).expect("Invalid NaiveDateTime for date"); - let base_date = - NaiveDateTime::from_timestamp_opt(0, 0).expect("Invalid NaiveDateTime for base_date"); + let date = DateTimeType::Naive( + NaiveDateTime::from_timestamp_opt(9600, 0).expect("Invalid NaiveDateTime for date"), + ); + let base_date = DateTimeType::Naive( + NaiveDateTime::from_timestamp_opt(0, 0).expect("Invalid NaiveDateTime for base_date"), + ); assert_eq!( "about 2 hours", - naive_format_distance(date, base_date, false, false) + format_distance(date, base_date.to_naive(), false, false) ); } #[test] fn test_naive_format_distance_with_suffix() { - let date = - NaiveDateTime::from_timestamp_opt(9600, 0).expect("Invalid NaiveDateTime for date"); - let base_date = - NaiveDateTime::from_timestamp_opt(0, 0).expect("Invalid NaiveDateTime for base_date"); + let date = DateTimeType::Naive( + NaiveDateTime::from_timestamp_opt(9600, 0).expect("Invalid NaiveDateTime for date"), + ); + let base_date = DateTimeType::Naive( + NaiveDateTime::from_timestamp_opt(0, 0).expect("Invalid NaiveDateTime for base_date"), + ); assert_eq!( "about 2 hours from now", - naive_format_distance(date, base_date, false, true) + format_distance(date, base_date.to_naive(), false, true) ); } #[test] fn test_naive_format_distance_from_now() { - let date = NaiveDateTime::parse_from_str("1969-07-20T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ") - .expect("Invalid NaiveDateTime for date"); + let date = DateTimeType::Naive( + NaiveDateTime::parse_from_str("1969-07-20T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ") + .expect("Invalid NaiveDateTime for date"), + ); assert_eq!( "over 54 years ago", - naive_format_distance_from_now(date, false, true) + format_distance_from_now(date, false, true) ); } From 79653d2175ed1ac8a037fb843465012203af0aa0 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 11:19:18 -0500 Subject: [PATCH 145/644] Rename format distance test names --- crates/ui2/src/utils/format_distance.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/ui2/src/utils/format_distance.rs b/crates/ui2/src/utils/format_distance.rs index f13e92bbe901e5538bad8566e6b2e001e8e4ff78..ec9a8ad5d879296467c8fcb22caf4b25ea4bfa7d 100644 --- a/crates/ui2/src/utils/format_distance.rs +++ b/crates/ui2/src/utils/format_distance.rs @@ -177,7 +177,7 @@ mod tests { use chrono::NaiveDateTime; #[test] - fn test_naive_format_distance() { + fn test_format_distance() { let date = DateTimeType::Naive( NaiveDateTime::from_timestamp_opt(9600, 0).expect("Invalid NaiveDateTime for date"), ); @@ -192,7 +192,7 @@ mod tests { } #[test] - fn test_naive_format_distance_with_suffix() { + fn test_format_distance_with_suffix() { let date = DateTimeType::Naive( NaiveDateTime::from_timestamp_opt(9600, 0).expect("Invalid NaiveDateTime for date"), ); @@ -207,7 +207,7 @@ mod tests { } #[test] - fn test_naive_format_distance_from_now() { + fn test_format_distance_from_now() { let date = DateTimeType::Naive( NaiveDateTime::parse_from_str("1969-07-20T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ") .expect("Invalid NaiveDateTime for date"), @@ -220,7 +220,7 @@ mod tests { } #[test] - fn test_naive_format_distance_string() { + fn test_format_distance_string() { assert_eq!(distance_string(3, false, false), "less than a minute"); assert_eq!(distance_string(7, false, false), "less than a minute"); assert_eq!(distance_string(13, false, false), "less than a minute"); @@ -244,7 +244,7 @@ mod tests { } #[test] - fn test_naive_format_distance_string_include_seconds() { + fn test_format_distance_string_include_seconds() { assert_eq!(distance_string(3, true, false), "less than 5 seconds"); assert_eq!(distance_string(7, true, false), "less than 10 seconds"); assert_eq!(distance_string(13, true, false), "less than 20 seconds"); From 3e6b84a726d25df9dbcb8f298e2403b40b894771 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 11:26:55 -0500 Subject: [PATCH 146/644] Wire up the middle mouse button to close tabs (#3714) This PR wires up the middle mouse button to close tabs. Right now we're doing this using `on_mouse_down`, but we need a way in GPUI2 to have an `on_click` for a mouse button other than the left one. Release Notes: - N/A --- crates/workspace2/src/pane.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 65e34c9fa5cb609136942547411dd7d2c89a330a..e1bb006c11428149d5ade09aed2db137e7e61cdb 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1493,6 +1493,14 @@ impl Pane { .on_click( cx.listener(move |pane: &mut Self, _, cx| pane.activate_item(ix, true, true, cx)), ) + // TODO: This should be a click listener with the middle mouse button instead of a mouse down listener. + .on_mouse_down( + MouseButton::Middle, + cx.listener(move |pane, _event, cx| { + pane.close_item_by_id(item_id, SaveIntent::Close, cx) + .detach_and_log_err(cx); + }), + ) .on_drag( DraggedTab { pane: cx.view().clone(), From d8a8feb45c35f910c199c94f2ae96f5ea2ecc39a Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 11:41:14 -0500 Subject: [PATCH 147/644] Add FormatDistance struct, add hide_prefix option --- crates/ui2/src/utils/format_distance.rs | 265 +++++++++++++++++++----- 1 file changed, 217 insertions(+), 48 deletions(-) diff --git a/crates/ui2/src/utils/format_distance.rs b/crates/ui2/src/utils/format_distance.rs index ec9a8ad5d879296467c8fcb22caf4b25ea4bfa7d..1586a6e155b5ddc10391c25254d2e30b1e89a598 100644 --- a/crates/ui2/src/utils/format_distance.rs +++ b/crates/ui2/src/utils/format_distance.rs @@ -19,6 +19,45 @@ impl DateTimeType { } } +pub struct FormatDistance { + date: DateTimeType, + base_date: DateTimeType, + include_seconds: bool, + add_suffix: bool, + hide_prefix: bool, +} + +impl FormatDistance { + pub fn new(date: DateTimeType, base_date: DateTimeType) -> Self { + Self { + date, + base_date, + include_seconds: false, + add_suffix: false, + hide_prefix: false, + } + } + + pub fn from_now(date: DateTimeType) -> Self { + Self::new(date, DateTimeType::Local(Local::now())) + } + + pub fn include_seconds(mut self, include_seconds: bool) -> Self { + self.include_seconds = include_seconds; + self + } + + pub fn add_suffix(mut self, add_suffix: bool) -> Self { + self.add_suffix = add_suffix; + self + } + + pub fn hide_prefix(mut self, hide_prefix: bool) -> Self { + self.hide_prefix = hide_prefix; + self + } +} + /// Calculates the distance in seconds between two NaiveDateTime objects. /// It returns a signed integer denoting the difference. If `date` is earlier than `base_date`, the returned value will be negative. /// @@ -32,7 +71,12 @@ fn distance_in_seconds(date: NaiveDateTime, base_date: NaiveDateTime) -> i64 { } /// Generates a string describing the time distance between two dates in a human-readable way. -fn distance_string(distance: i64, include_seconds: bool, add_suffix: bool) -> String { +fn distance_string( + distance: i64, + include_seconds: bool, + add_suffix: bool, + hide_prefix: bool, +) -> String { let suffix = if distance < 0 { " from now" } else { " ago" }; let distance = distance.abs(); @@ -43,53 +87,128 @@ fn distance_string(distance: i64, include_seconds: bool, add_suffix: bool) -> St let months = distance / 2_592_000; let string = if distance < 5 && include_seconds { - "less than 5 seconds".to_string() + if hide_prefix { + "5 seconds" + } else { + "less than 5 seconds" + } + .to_string() } else if distance < 10 && include_seconds { - "less than 10 seconds".to_string() + if hide_prefix { + "10 seconds" + } else { + "less than 10 seconds" + } + .to_string() } else if distance < 20 && include_seconds { - "less than 20 seconds".to_string() + if hide_prefix { + "20 seconds" + } else { + "less than 20 seconds" + } + .to_string() } else if distance < 40 && include_seconds { - "half a minute".to_string() + if hide_prefix { + "half a minute" + } else { + "half a minute" + } + .to_string() } else if distance < 60 && include_seconds { - "less than a minute".to_string() + if hide_prefix { + "a minute" + } else { + "less than a minute" + } + .to_string() } else if distance < 90 && include_seconds { "1 minute".to_string() } else if distance < 30 { - "less than a minute".to_string() + if hide_prefix { + "a minute" + } else { + "less than a minute" + } + .to_string() } else if distance < 90 { "1 minute".to_string() } else if distance < 2_700 { format!("{} minutes", minutes) } else if distance < 5_400 { - "about 1 hour".to_string() + if hide_prefix { + "1 hour" + } else { + "about 1 hour" + } + .to_string() } else if distance < 86_400 { - format!("about {} hours", hours) + if hide_prefix { + format!("{} hours", hours) + } else { + format!("about {} hours", hours) + } + .to_string() } else if distance < 172_800 { "1 day".to_string() } else if distance < 2_592_000 { format!("{} days", days) } else if distance < 5_184_000 { - "about 1 month".to_string() + if hide_prefix { + "1 month" + } else { + "about 1 month" + } + .to_string() } else if distance < 7_776_000 { - "about 2 months".to_string() + if hide_prefix { + "2 months" + } else { + "about 2 months" + } + .to_string() } else if distance < 31_540_000 { format!("{} months", months) } else if distance < 39_425_000 { - "about 1 year".to_string() + if hide_prefix { + "1 year" + } else { + "about 1 year" + } + .to_string() } else if distance < 55_195_000 { - "over 1 year".to_string() + if hide_prefix { "1 year" } else { "over 1 year" }.to_string() } else if distance < 63_080_000 { - "almost 2 years".to_string() + if hide_prefix { + "2 years" + } else { + "almost 2 years" + } + .to_string() } else { let years = distance / 31_536_000; let remaining_months = (distance % 31_536_000) / 2_592_000; if remaining_months < 3 { - format!("about {} years", years) + if hide_prefix { + format!("{} years", years) + } else { + format!("about {} years", years) + } + .to_string() } else if remaining_months < 9 { - format!("over {} years", years) + if hide_prefix { + format!("{} years", years) + } else { + format!("over {} years", years) + } + .to_string() } else { - format!("almost {} years", years + 1) + if hide_prefix { + format!("{} years", years + 1) + } else { + format!("almost {} years", years + 1) + } + .to_string() } }; @@ -132,10 +251,11 @@ pub fn format_distance( base_date: NaiveDateTime, include_seconds: bool, add_suffix: bool, + hide_prefix: bool, ) -> String { let distance = distance_in_seconds(date.to_naive(), base_date); - distance_string(distance, include_seconds, add_suffix) + distance_string(distance, include_seconds, add_suffix, hide_prefix) } /// Get the time difference between a date and now as relative human readable string. @@ -165,10 +285,11 @@ pub fn format_distance_from_now( datetime: DateTimeType, include_seconds: bool, add_suffix: bool, + hide_prefix: bool, ) -> String { let now = chrono::offset::Local::now().naive_local(); - format_distance(datetime, now, include_seconds, add_suffix) + format_distance(datetime, now, include_seconds, add_suffix, hide_prefix) } #[cfg(test)] @@ -187,7 +308,7 @@ mod tests { assert_eq!( "about 2 hours", - format_distance(date, base_date.to_naive(), false, false) + format_distance(date, base_date.to_naive(), false, false, false) ); } @@ -202,7 +323,7 @@ mod tests { assert_eq!( "about 2 hours from now", - format_distance(date, base_date.to_naive(), false, true) + format_distance(date, base_date.to_naive(), false, true, false) ); } @@ -215,41 +336,89 @@ mod tests { assert_eq!( "over 54 years ago", - format_distance_from_now(date, false, true) + format_distance_from_now(date, false, true, false) ); } #[test] fn test_format_distance_string() { - assert_eq!(distance_string(3, false, false), "less than a minute"); - assert_eq!(distance_string(7, false, false), "less than a minute"); - assert_eq!(distance_string(13, false, false), "less than a minute"); - assert_eq!(distance_string(21, false, false), "less than a minute"); - assert_eq!(distance_string(45, false, false), "1 minute"); - assert_eq!(distance_string(61, false, false), "1 minute"); - assert_eq!(distance_string(1920, false, false), "32 minutes"); - assert_eq!(distance_string(3902, false, false), "about 1 hour"); - assert_eq!(distance_string(18002, false, false), "about 5 hours"); - assert_eq!(distance_string(86470, false, false), "1 day"); - assert_eq!(distance_string(345880, false, false), "4 days"); - assert_eq!(distance_string(2764800, false, false), "about 1 month"); - assert_eq!(distance_string(5184000, false, false), "about 2 months"); - assert_eq!(distance_string(10368000, false, false), "4 months"); - assert_eq!(distance_string(34694000, false, false), "about 1 year"); - assert_eq!(distance_string(47310000, false, false), "over 1 year"); - assert_eq!(distance_string(61503000, false, false), "almost 2 years"); - assert_eq!(distance_string(160854000, false, false), "about 5 years"); - assert_eq!(distance_string(236550000, false, false), "over 7 years"); - assert_eq!(distance_string(249166000, false, false), "almost 8 years"); + assert_eq!( + distance_string(3, false, false, false), + "less than a minute" + ); + assert_eq!( + distance_string(7, false, false, false), + "less than a minute" + ); + assert_eq!( + distance_string(13, false, false, false), + "less than a minute" + ); + assert_eq!( + distance_string(21, false, false, false), + "less than a minute" + ); + assert_eq!(distance_string(45, false, false, false), "1 minute"); + assert_eq!(distance_string(61, false, false, false), "1 minute"); + assert_eq!(distance_string(1920, false, false, false), "32 minutes"); + assert_eq!(distance_string(3902, false, false, false), "about 1 hour"); + assert_eq!(distance_string(18002, false, false, false), "about 5 hours"); + assert_eq!(distance_string(86470, false, false, false), "1 day"); + assert_eq!(distance_string(345880, false, false, false), "4 days"); + assert_eq!( + distance_string(2764800, false, false, false), + "about 1 month" + ); + assert_eq!( + distance_string(5184000, false, false, false), + "about 2 months" + ); + assert_eq!(distance_string(10368000, false, false, false), "4 months"); + assert_eq!( + distance_string(34694000, false, false, false), + "about 1 year" + ); + assert_eq!( + distance_string(47310000, false, false, false), + "over 1 year" + ); + assert_eq!( + distance_string(61503000, false, false, false), + "almost 2 years" + ); + assert_eq!( + distance_string(160854000, false, false, false), + "about 5 years" + ); + assert_eq!( + distance_string(236550000, false, false, false), + "over 7 years" + ); + assert_eq!( + distance_string(249166000, false, false, false), + "almost 8 years" + ); } #[test] fn test_format_distance_string_include_seconds() { - assert_eq!(distance_string(3, true, false), "less than 5 seconds"); - assert_eq!(distance_string(7, true, false), "less than 10 seconds"); - assert_eq!(distance_string(13, true, false), "less than 20 seconds"); - assert_eq!(distance_string(21, true, false), "half a minute"); - assert_eq!(distance_string(45, true, false), "less than a minute"); - assert_eq!(distance_string(61, true, false), "1 minute"); + assert_eq!( + distance_string(3, true, false, false), + "less than 5 seconds" + ); + assert_eq!( + distance_string(7, true, false, false), + "less than 10 seconds" + ); + assert_eq!( + distance_string(13, true, false, false), + "less than 20 seconds" + ); + assert_eq!(distance_string(21, true, false, false), "half a minute"); + assert_eq!( + distance_string(45, true, false, false), + "less than a minute" + ); + assert_eq!(distance_string(61, true, false, false), "1 minute"); } } From a1085184a1432a52b2cec43e8567d47df477b3ec Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 11:57:57 -0500 Subject: [PATCH 148/644] use `to_string` to return the format distance string from FormatDistance --- crates/ui2/src/utils/format_distance.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/ui2/src/utils/format_distance.rs b/crates/ui2/src/utils/format_distance.rs index 1586a6e155b5ddc10391c25254d2e30b1e89a598..b0fce184ce64e23e1173ddcce77f3532fb0dfe5e 100644 --- a/crates/ui2/src/utils/format_distance.rs +++ b/crates/ui2/src/utils/format_distance.rs @@ -42,6 +42,16 @@ impl FormatDistance { Self::new(date, DateTimeType::Local(Local::now())) } + pub fn to_string(self) -> String { + format_distance( + self.date, + self.base_date.to_naive(), + self.include_seconds, + self.add_suffix, + self.hide_prefix, + ) + } + pub fn include_seconds(mut self, include_seconds: bool) -> Self { self.include_seconds = include_seconds; self From d8eea949eff72581f9e154667533443e2368b499 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 11:58:20 -0500 Subject: [PATCH 149/644] Update assistant panel message header, model switcher --- crates/assistant2/src/assistant_panel.rs | 45 +++++++++++++++++------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 94be39f924ee6125e1d1a12fea35d271fe8ddc2e..ca9e0ddade9828e47ea75de5e1538b7b412725f6 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -53,7 +53,11 @@ use std::{ time::{Duration, Instant}, }; use theme::ThemeSettings; -use ui::{prelude::*, Tab, TabBar, Tooltip}; +use ui::{ + prelude::*, + utils::{DateTimeType, FormatDistance}, + ButtonLike, Tab, TabBar, Tooltip, +}; use util::{paths::CONVERSATIONS_DIR, post_inc, ResultExt, TryFutureExt}; use uuid::Uuid; use workspace::{ @@ -1126,13 +1130,13 @@ impl Render for AssistantPanel { .border() .border_color(gpui::red()) } else { - let header = ui::TabBar::new("assistant_header") + let header = TabBar::new("assistant_header") .start_child( h_stack().gap_1().child(Self::render_hamburger_button(cx)), // .children(title), ) .children(self.active_editor().map(|editor| { h_stack() - .h(rems(ui::Tab::HEIGHT_IN_REMS)) + .h(rems(Tab::HEIGHT_IN_REMS)) .flex_1() .px_2() .child(Label::new(editor.read(cx).title(cx)).into_element()) @@ -2278,6 +2282,14 @@ impl ConversationEditor { } Role::System => Label::new("System").color(Color::Warning), }) + .tooltip(|cx| { + Tooltip::with_meta( + "Toggle message role", + None, + "Available roles: You (User), Assistant, System", + cx, + ) + }) .on_click({ let conversation = conversation.clone(); move |_, cx| { @@ -2292,10 +2304,23 @@ impl ConversationEditor { h_stack() .id(("message_header", message_id.0)) - .border() - .border_color(gpui::red()) + .h_12() + .gap_1() + .p_1() + .debug_bg_cyan() .child(sender) - .child(Label::new(message.sent_at.format("%I:%M%P").to_string())) + // TODO: Only show this if the message if the message has been sent + .child( + Label::new( + FormatDistance::from_now(DateTimeType::Local( + message.sent_at, + )) + .hide_prefix(true) + .add_suffix(true) + .to_string(), + ) + .color(Color::Muted), + ) .children( if let MessageStatus::Error(error) = message.status.clone() { Some( @@ -2456,6 +2481,7 @@ impl ConversationEditor { "current_model", self.conversation.read(cx).model.short_name(), ) + .style(ButtonStyle::Filled) .tooltip(move |cx| Tooltip::text("Change Model", cx)) .on_click(cx.listener(|this, _, cx| this.cycle_model(cx))) } @@ -2469,12 +2495,7 @@ impl ConversationEditor { } else { Color::Default }; - Some( - div() - .border() - .border_color(gpui::red()) - .child(Label::new(remaining_tokens.to_string()).color(remaining_tokens_color)), - ) + Some(Label::new(remaining_tokens.to_string()).color(remaining_tokens_color)) } } From e655d2434a88d6b8d2c598e492b8ae5af169aae5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 09:02:25 -0800 Subject: [PATCH 150/644] Don't stop propagation on mouse move over editor gutter --- crates/editor2/src/element.rs | 2 -- crates/workspace2/src/dock.rs | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index cf34863ba6dc364dea8370427e514ec490579292..8ccae59172db14176f53a7d1f2b539798f5c9694 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -564,8 +564,6 @@ impl EditorElement { ); } } - - cx.stop_propagation(); } else { update_go_to_definition_link(editor, None, modifiers.command, modifiers.shift, cx); hover_at(editor, None, cx); diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 3997b8f9b011f26869ec6717591994bbb52978ae..d0aba998b97895ae62359714f19522de6b2dadba 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -495,7 +495,8 @@ impl Render for Dock { }) .on_click(cx.listener(|v, e: &ClickEvent, cx| { if e.down.button == MouseButton::Left && e.down.click_count == 2 { - v.resize_active_panel(None, cx) + v.resize_active_panel(None, cx); + cx.stop_propagation(); } })) .z_index(1); From 5d95e13cc809ba872969d19998c371214ec07fb9 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Dec 2023 12:04:01 -0500 Subject: [PATCH 151/644] Update assistant editor --- crates/assistant2/src/assistant_panel.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index ca9e0ddade9828e47ea75de5e1538b7b412725f6..ec67d684da92fc85be4fcb5efecc040c783901ed 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -2304,10 +2304,9 @@ impl ConversationEditor { h_stack() .id(("message_header", message_id.0)) - .h_12() + .h_11() .gap_1() .p_1() - .debug_bg_cyan() .child(sender) // TODO: Only show this if the message if the message has been sent .child( @@ -2507,15 +2506,21 @@ impl Render for ConversationEditor { fn render(&mut self, cx: &mut ViewContext) -> Self::Element { div() .key_context("ConversationEditor") - .size_full() - .relative() .capture_action(cx.listener(ConversationEditor::cancel_last_assist)) .capture_action(cx.listener(ConversationEditor::save)) .capture_action(cx.listener(ConversationEditor::copy)) .capture_action(cx.listener(ConversationEditor::cycle_message_role)) .on_action(cx.listener(ConversationEditor::assist)) .on_action(cx.listener(ConversationEditor::split)) - .child(self.editor.clone()) + .size_full() + .relative() + .child( + div() + .size_full() + .pl_2() + .bg(cx.theme().colors().editor_background) + .child(self.editor.clone()), + ) .child( h_stack() .absolute() From 616ea131af6447b4818f1e085537fd01e29098b3 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 12:11:06 -0500 Subject: [PATCH 152/644] Style buffer search input (#3713) This PR styles the text input for the buffer search. Release Notes: - N/A --- crates/search2/src/buffer_search.rs | 58 +++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index 5db7aff73670161719188a8cff5051c4a4a46604..17dc13feaa1989f3a3d00be59483f2252ab2afb5 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -7,18 +7,21 @@ use crate::{ ToggleCaseSensitive, ToggleReplace, ToggleWholeWord, }; use collections::HashMap; -use editor::Editor; +use editor::{Editor, EditorElement, EditorStyle}; use futures::channel::oneshot; use gpui::{ - actions, div, impl_actions, red, Action, AppContext, ClickEvent, Div, EventEmitter, - FocusableView, InteractiveElement as _, IntoElement, KeyContext, ParentElement as _, Render, - Styled, Subscription, Task, View, ViewContext, VisualContext as _, WindowContext, + actions, div, impl_actions, Action, AppContext, ClickEvent, Div, EventEmitter, FocusableView, + FontStyle, FontWeight, InteractiveElement as _, IntoElement, KeyContext, ParentElement as _, + Render, Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext as _, + WhiteSpace, WindowContext, }; use project::search::SearchQuery; use serde::Deserialize; +use settings::Settings; use std::{any::Any, sync::Arc}; +use theme::ThemeSettings; -use ui::{h_stack, ButtonCommon, Clickable, Icon, IconButton, IconElement, Tooltip}; +use ui::{h_stack, prelude::*, Icon, IconButton, IconElement, Tooltip}; use util::ResultExt; use workspace::{ item::ItemHandle, @@ -63,6 +66,38 @@ pub struct BufferSearchBar { replace_enabled: bool, } +impl BufferSearchBar { + fn render_text_input(&self, editor: &View, cx: &ViewContext) -> impl IntoElement { + let settings = ThemeSettings::get_global(cx); + let text_style = TextStyle { + color: if editor.read(cx).read_only() { + cx.theme().colors().text_disabled + } else { + cx.theme().colors().text + }, + font_family: settings.ui_font.family.clone(), + font_features: settings.ui_font.features, + font_size: rems(0.875).into(), + font_weight: FontWeight::NORMAL, + font_style: FontStyle::Normal, + line_height: relative(1.3).into(), + background_color: None, + underline: None, + white_space: WhiteSpace::Normal, + }; + + EditorElement::new( + &editor, + EditorStyle { + background: cx.theme().colors().editor_background, + local_player: cx.theme().players().local(), + text: text_style, + ..Default::default() + }, + ) + } +} + impl EventEmitter for BufferSearchBar {} impl EventEmitter for BufferSearchBar {} impl Render for BufferSearchBar { @@ -207,15 +242,16 @@ impl Render for BufferSearchBar { .w_full() .p_1() .child( - div() - .flex() + h_stack() .flex_1() + .px_2() + .py_1() + .gap_2() .border_1() - .border_color(red()) - .rounded_md() - .items_center() + .border_color(cx.theme().colors().border) + .rounded_lg() .child(IconElement::new(Icon::MagnifyingGlass)) - .child(self.query_editor.clone()) + .child(self.render_text_input(&self.query_editor, cx)) .children(supported_options.case.then(|| { self.render_search_option_button( SearchOptions::CASE_SENSITIVE, From 51396344a3f549571eff54e59cd4bcf31f4abc46 Mon Sep 17 00:00:00 2001 From: Julia Date: Tue, 19 Dec 2023 12:50:06 -0500 Subject: [PATCH 153/644] Match zed1 scrollbar drag behavior Still not ideal, but we need to ship and this is more than reasonable Co-Authored-By: Antonio Scandurra --- crates/editor2/src/element.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index cf34863ba6dc364dea8370427e514ec490579292..0c9d0b46a89471022ba400845b521f3cbc4f9c59 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -1369,7 +1369,7 @@ impl EditorElement { { let y = mouse_position.y; let new_y = event.position.y; - if thumb_top < y && y < thumb_bottom { + if (track_bounds.top()..track_bounds.bottom()).contains(&y) { let mut position = editor.scroll_position(cx); position.y += (new_y - y) * (max_row as f32) / height; if position.y < 0.0 { From e08fc0bbc026e093543b3681380598ea27fa9aa3 Mon Sep 17 00:00:00 2001 From: Julia Date: Tue, 19 Dec 2023 13:00:21 -0500 Subject: [PATCH 154/644] Allow editor mouse drag selection outside interactive bounds Co-Authored-By: Antonio Scandurra --- crates/editor2/src/element.rs | 114 +++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 44 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index cf34863ba6dc364dea8370427e514ec490579292..e98c50d9edb2197e37d1756ef6458b3be5775343 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -488,7 +488,7 @@ impl EditorElement { } } - fn mouse_moved( + fn mouse_dragged( editor: &mut Editor, event: &MouseMoveEvent, position_map: &PositionMap, @@ -497,41 +497,53 @@ impl EditorElement { stacking_order: &StackingOrder, cx: &mut ViewContext, ) { - let modifiers = event.modifiers; - if editor.has_pending_selection() && event.pressed_button == Some(MouseButton::Left) { - let point_for_position = position_map.point_for_position(text_bounds, event.position); - let mut scroll_delta = gpui::Point::::default(); - let vertical_margin = position_map.line_height.min(text_bounds.size.height / 3.0); - let top = text_bounds.origin.y + vertical_margin; - let bottom = text_bounds.lower_left().y - vertical_margin; - if event.position.y < top { - scroll_delta.y = -scale_vertical_mouse_autoscroll_delta(top - event.position.y); - } - if event.position.y > bottom { - scroll_delta.y = scale_vertical_mouse_autoscroll_delta(event.position.y - bottom); - } + if !editor.has_pending_selection() { + return; + } - let horizontal_margin = position_map.line_height.min(text_bounds.size.width / 3.0); - let left = text_bounds.origin.x + horizontal_margin; - let right = text_bounds.upper_right().x - horizontal_margin; - if event.position.x < left { - scroll_delta.x = -scale_horizontal_mouse_autoscroll_delta(left - event.position.x); - } - if event.position.x > right { - scroll_delta.x = scale_horizontal_mouse_autoscroll_delta(event.position.x - right); - } + let point_for_position = position_map.point_for_position(text_bounds, event.position); + let mut scroll_delta = gpui::Point::::default(); + let vertical_margin = position_map.line_height.min(text_bounds.size.height / 3.0); + let top = text_bounds.origin.y + vertical_margin; + let bottom = text_bounds.lower_left().y - vertical_margin; + if event.position.y < top { + scroll_delta.y = -scale_vertical_mouse_autoscroll_delta(top - event.position.y); + } + if event.position.y > bottom { + scroll_delta.y = scale_vertical_mouse_autoscroll_delta(event.position.y - bottom); + } - editor.select( - SelectPhase::Update { - position: point_for_position.previous_valid, - goal_column: point_for_position.exact_unclipped.column(), - scroll_position: (position_map.snapshot.scroll_position() + scroll_delta) - .clamp(&gpui::Point::default(), &position_map.scroll_max), - }, - cx, - ); + let horizontal_margin = position_map.line_height.min(text_bounds.size.width / 3.0); + let left = text_bounds.origin.x + horizontal_margin; + let right = text_bounds.upper_right().x - horizontal_margin; + if event.position.x < left { + scroll_delta.x = -scale_horizontal_mouse_autoscroll_delta(left - event.position.x); + } + if event.position.x > right { + scroll_delta.x = scale_horizontal_mouse_autoscroll_delta(event.position.x - right); } + editor.select( + SelectPhase::Update { + position: point_for_position.previous_valid, + goal_column: point_for_position.exact_unclipped.column(), + scroll_position: (position_map.snapshot.scroll_position() + scroll_delta) + .clamp(&gpui::Point::default(), &position_map.scroll_max), + }, + cx, + ); + } + + fn mouse_moved( + editor: &mut Editor, + event: &MouseMoveEvent, + position_map: &PositionMap, + text_bounds: Bounds, + gutter_bounds: Bounds, + stacking_order: &StackingOrder, + cx: &mut ViewContext, + ) { + let modifiers = event.modifiers; let text_hovered = text_bounds.contains(&event.position); let gutter_hovered = gutter_bounds.contains(&event.position); let was_top = cx.was_top_layer(&event.position, stacking_order); @@ -2510,19 +2522,33 @@ impl EditorElement { let stacking_order = cx.stacking_order().clone(); move |event: &MouseMoveEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && interactive_bounds.visibly_contains(&event.position, cx) - { + // if editor.has_pending_selection() && event.pressed_button == Some(MouseButton::Left) { + + if phase == DispatchPhase::Bubble { editor.update(cx, |editor, cx| { - Self::mouse_moved( - editor, - event, - &position_map, - text_bounds, - gutter_bounds, - &stacking_order, - cx, - ) + if event.pressed_button == Some(MouseButton::Left) { + Self::mouse_dragged( + editor, + event, + &position_map, + text_bounds, + gutter_bounds, + &stacking_order, + cx, + ) + } + + if interactive_bounds.visibly_contains(&event.position, cx) { + Self::mouse_moved( + editor, + event, + &position_map, + text_bounds, + gutter_bounds, + &stacking_order, + cx, + ) + } }); } } From a3bab25792aa1e4cef69786e78ca0962ab08325c Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 13:16:14 -0500 Subject: [PATCH 155/644] Style contact finder (#3717) This PR styles the contact finder. Screenshot 2023-12-19 at 12 59 00 PM Release Notes: - N/A --- crates/collab_ui2/src/collab_panel.rs | 11 +--- .../src/collab_panel/contact_finder.rs | 66 +++++-------------- crates/picker2/src/picker2.rs | 42 ++++++------ 3 files changed, 40 insertions(+), 79 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 2179d82cf32b068ed2a748587ab1d455aaa573d7..cbae0763043dab56ba6cc22ef74d359c5eed72d8 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2204,14 +2204,9 @@ impl CollabPanel { .into_any_element() }), Section::Contacts => Some( - div() - .border_1() - .border_color(gpui::red()) - .child( - IconButton::new("add-contact", Icon::Plus) - .on_click(cx.listener(|this, _, cx| this.toggle_contact_finder(cx))) - .tooltip(|cx| Tooltip::text("Search for new contact", cx)), - ) + IconButton::new("add-contact", Icon::Plus) + .on_click(cx.listener(|this, _, cx| this.toggle_contact_finder(cx))) + .tooltip(|cx| Tooltip::text("Search for new contact", cx)) .into_any_element(), ), Section::Channels => Some( diff --git a/crates/collab_ui2/src/collab_panel/contact_finder.rs b/crates/collab_ui2/src/collab_panel/contact_finder.rs index 3087e6812f2afe93e2ba11a4a9bd836af8ec899a..ff7e02a909af3e9698d5126f5d0bd5c558e4685c 100644 --- a/crates/collab_ui2/src/collab_panel/contact_finder.rs +++ b/crates/collab_ui2/src/collab_panel/contact_finder.rs @@ -7,7 +7,7 @@ use gpui::{ use picker::{Picker, PickerDelegate}; use std::sync::Arc; use theme::ActiveTheme as _; -use ui::{prelude::*, Avatar}; +use ui::{prelude::*, Avatar, ListItem}; use util::{ResultExt as _, TryFutureExt}; use workspace::ModalView; @@ -23,7 +23,7 @@ impl ContactFinder { potential_contacts: Arc::from([]), selected_index: 0, }; - let picker = cx.build_view(|cx| Picker::new(delegate, cx)); + let picker = cx.build_view(|cx| Picker::new(delegate, cx).modal(false)); Self { picker } } @@ -37,16 +37,17 @@ impl ContactFinder { impl Render for ContactFinder { fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - fn render_mode_button(text: &'static str) -> AnyElement { - Label::new(text).into_any_element() - } - v_stack() + .elevation_3(cx) .child( v_stack() + .px_2() + .py_1() + .bg(cx.theme().colors().element_background) + // HACK: Prevent the background color from overflowing the parent container. + .rounded_t(px(8.)) .child(Label::new("Contacts")) - .child(h_stack().children([render_mode_button("Invite new contacts")])) - .bg(cx.theme().colors().element_background), + .child(h_stack().child(Label::new("Invite new contacts"))), ) .child(self.picker.clone()) .w(rems(34.)) @@ -72,7 +73,8 @@ impl FocusableView for ContactFinder { } impl PickerDelegate for ContactFinderDelegate { - type ListItem = Div; + type ListItem = ListItem; + fn match_count(&self) -> usize { self.potential_contacts.len() } @@ -150,46 +152,14 @@ impl PickerDelegate for ContactFinderDelegate { ContactRequestStatus::RequestAccepted => None, }; Some( - div() - .flex_1() - .justify_between() - .child(Avatar::new(user.avatar_uri.clone())) + ListItem::new(ix) + .inset(true) + .selected(selected) + .start_slot(Avatar::new(user.avatar_uri.clone())) .child(Label::new(user.github_login.clone())) - .children(icon_path.map(|icon_path| svg().path(icon_path))), + .end_slot::( + icon_path.map(|icon_path| IconElement::from_path(icon_path)), + ), ) - // todo!() - // Flex::row() - // .with_children(user.avatar.clone().map(|avatar| { - // Image::from_data(avatar) - // .with_style(theme.contact_avatar) - // .aligned() - // .left() - // })) - // .with_child( - // Label::new(user.github_login.clone(), style.label.clone()) - // .contained() - // .with_style(theme.contact_username) - // .aligned() - // .left(), - // ) - // .with_children(icon_path.map(|icon_path| { - // Svg::new(icon_path) - // .with_color(button_style.color) - // .constrained() - // .with_width(button_style.icon_width) - // .aligned() - // .contained() - // .with_style(button_style.container) - // .constrained() - // .with_width(button_style.button_width) - // .with_height(button_style.button_width) - // .aligned() - // .flex_float() - // })) - // .contained() - // .with_style(style.container) - // .constrained() - // .with_height(tabbed_modal.row_height) - // .into_any() } } diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index f7911094b5af3f3265ba5834033f784850e549a2..70180112f96bbc795d18db19869365dc227f5844 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -1,8 +1,8 @@ use editor::Editor; use gpui::{ - div, prelude::*, rems, uniform_list, AnyElement, AppContext, DismissEvent, Div, EventEmitter, - FocusHandle, FocusableView, Length, MouseButton, MouseDownEvent, Render, Task, - UniformListScrollHandle, View, ViewContext, WindowContext, + div, prelude::*, rems, uniform_list, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, + FocusableView, Length, MouseButton, MouseDownEvent, Render, Task, UniformListScrollHandle, + View, ViewContext, WindowContext, }; use std::{cmp, sync::Arc}; use ui::{prelude::*, v_stack, Color, Divider, Label}; @@ -15,6 +15,11 @@ pub struct Picker { pending_update_matches: Option>, confirm_on_update: Option, width: Option, + + /// Whether the `Picker` is rendered as a self-contained modal. + /// + /// Set this to `false` when rendering the `Picker` as part of a larger modal. + is_modal: bool, } pub trait PickerDelegate: Sized + 'static { @@ -58,6 +63,7 @@ impl Picker { pending_update_matches: None, confirm_on_update: None, width: None, + is_modal: true, }; this.update_matches("".to_string(), cx); this @@ -68,6 +74,11 @@ impl Picker { self } + pub fn modal(mut self, modal: bool) -> Self { + self.is_modal = modal; + self + } + pub fn focus(&self, cx: &mut WindowContext) { self.editor.update(cx, |editor, cx| editor.focus(cx)); } @@ -234,7 +245,11 @@ impl Render for Picker { el.w(width) }) .overflow_hidden() - .elevation_3(cx) + // This is a bit of a hack to remove the modal styling when we're rendering the `Picker` + // as a part of a modal rather than the entire modal. + // + // We should revisit how the `Picker` is styled to make it more composable. + .when(self.is_modal, |this| this.elevation_3(cx)) .on_action(cx.listener(Self::select_next)) .on_action(cx.listener(Self::select_prev)) .on_action(cx.listener(Self::select_first)) @@ -295,22 +310,3 @@ impl Render for Picker { }) } } - -pub fn simple_picker_match( - selected: bool, - cx: &mut WindowContext, - children: impl FnOnce(&mut WindowContext) -> AnyElement, -) -> AnyElement { - let colors = cx.theme().colors(); - - div() - .px_1() - .text_color(colors.text) - .text_ui() - .bg(colors.ghost_element_background) - .rounded_md() - .when(selected, |this| this.bg(colors.ghost_element_selected)) - .hover(|this| this.bg(colors.ghost_element_hover)) - .child((children)(cx)) - .into_any() -} From a4bfd0147dd30aa12003beaa9f0938e3540196bd Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 09:48:45 -0800 Subject: [PATCH 156/644] Render channel invites in collab panel, fix unused warnings --- crates/collab_ui2/src/collab_panel.rs | 841 +++--------------- .../src/collab_panel/channel_modal.rs | 1 + .../src/collab_panel/contact_finder.rs | 1 + 3 files changed, 144 insertions(+), 699 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index cbae0763043dab56ba6cc22ef74d359c5eed72d8..c58d7c47bc29ddca60fe562a80c7b591f246fca2 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -1,4 +1,3 @@ -#![allow(unused)] mod channel_modal; mod contact_finder; @@ -317,18 +316,10 @@ pub struct CollabPanel { subscriptions: Vec, collapsed_sections: Vec
, collapsed_channels: Vec, - drag_target_channel: ChannelDragTarget, workspace: WeakView, // context_menu_on_selected: bool, } -#[derive(PartialEq, Eq)] -enum ChannelDragTarget { - None, - Root, - Channel(ChannelId), -} - #[derive(Serialize, Deserialize)] struct SerializedCollabPanel { width: Option, @@ -373,7 +364,7 @@ enum ListEntry { }, IncomingRequest(Arc), OutgoingRequest(Arc), - // ChannelInvite(Arc), + ChannelInvite(Arc), Channel { channel: Arc, depth: usize, @@ -472,8 +463,6 @@ impl CollabPanel { collapsed_channels: Vec::default(), workspace: workspace.weak_handle(), client: workspace.app_state().client.clone(), - // context_menu_on_selected: true, - drag_target_channel: ChannelDragTarget::None, }; this.update_entries(false, cx); @@ -529,9 +518,6 @@ impl CollabPanel { }) } - fn contacts(&self, cx: &AppContext) -> Option>> { - Some(self.user_store.read(cx).contacts().to_owned()) - } pub async fn load( workspace: WeakView, mut cx: AsyncWindowContext, @@ -808,37 +794,37 @@ impl CollabPanel { } } - // let channel_invites = channel_store.channel_invitations(); - // if !channel_invites.is_empty() { - // self.match_candidates.clear(); - // self.match_candidates - // .extend(channel_invites.iter().enumerate().map(|(ix, channel)| { - // StringMatchCandidate { - // id: ix, - // string: channel.name.clone(), - // char_bag: channel.name.chars().collect(), - // } - // })); - // let matches = executor.block(match_strings( - // &self.match_candidates, - // &query, - // true, - // usize::MAX, - // &Default::default(), - // executor.clone(), - // )); - // request_entries.extend(matches.iter().map(|mat| { - // ListEntry::ChannelInvite(channel_invites[mat.candidate_id].clone()) - // })); - - // if !request_entries.is_empty() { - // self.entries - // .push(ListEntry::Header(Section::ChannelInvites)); - // if !self.collapsed_sections.contains(&Section::ChannelInvites) { - // self.entries.append(&mut request_entries); - // } - // } - // } + let channel_invites = channel_store.channel_invitations(); + if !channel_invites.is_empty() { + self.match_candidates.clear(); + self.match_candidates + .extend(channel_invites.iter().enumerate().map(|(ix, channel)| { + StringMatchCandidate { + id: ix, + string: channel.name.clone().into(), + char_bag: channel.name.chars().collect(), + } + })); + let matches = executor.block(match_strings( + &self.match_candidates, + &query, + true, + usize::MAX, + &Default::default(), + executor.clone(), + )); + request_entries.extend(matches.iter().map(|mat| { + ListEntry::ChannelInvite(channel_invites[mat.candidate_id].clone()) + })); + + if !request_entries.is_empty() { + self.entries + .push(ListEntry::Header(Section::ChannelInvites)); + if !self.collapsed_sections.contains(&Section::ChannelInvites) { + self.entries.append(&mut request_entries); + } + } + } } self.entries.push(ListEntry::Header(Section::Contacts)); @@ -1049,9 +1035,7 @@ impl CollabPanel { } else if is_current_user { IconButton::new("leave-call", Icon::Exit) .style(ButtonStyle::Subtle) - .on_click(cx.listener(move |this, _, cx| { - Self::leave_call(cx); - })) + .on_click(move |_, cx| Self::leave_call(cx)) .tooltip(|cx| Tooltip::text("Leave Call", cx)) .into_any_element() } else { @@ -1061,7 +1045,8 @@ impl CollabPanel { this.tooltip(move |cx| Tooltip::text(tooltip.clone(), cx)) .on_click(cx.listener(move |this, _, cx| { this.workspace - .update(cx, |workspace, cx| workspace.follow(peer_id, cx)); + .update(cx, |workspace, cx| workspace.follow(peer_id, cx)) + .ok(); })) }) } @@ -1073,7 +1058,7 @@ impl CollabPanel { host_user_id: u64, // is_current: bool, is_last: bool, - // is_selected: bool, + is_selected: bool, // theme: &theme::Theme, cx: &mut ViewContext, ) -> impl IntoElement { @@ -1084,15 +1069,16 @@ impl CollabPanel { } .into(); - let theme = cx.theme(); - ListItem::new(project_id as usize) + .selected(is_selected) .on_click(cx.listener(move |this, _, cx| { - this.workspace.update(cx, |workspace, cx| { - let app_state = workspace.app_state().clone(); - workspace::join_remote_project(project_id, host_user_id, app_state, cx) - .detach_and_log_err(cx); - }); + this.workspace + .update(cx, |workspace, cx| { + let app_state = workspace.app_state().clone(); + workspace::join_remote_project(project_id, host_user_id, app_state, cx) + .detach_and_log_err(cx); + }) + .ok(); })) .start_slot( h_stack() @@ -1102,95 +1088,19 @@ impl CollabPanel { ) .child(Label::new(project_name.clone())) .tooltip(move |cx| Tooltip::text(format!("Open {}", project_name), cx)) - - // enum JoinProject {} - // enum JoinProjectTooltip {} - - // let collab_theme = &theme.collab_panel; - // let host_avatar_width = collab_theme - // .contact_avatar - // .width - // .or(collab_theme.contact_avatar.height) - // .unwrap_or(0.); - // let tree_branch = collab_theme.tree_branch; - - // let content = - // MouseEventHandler::new::(project_id as usize, cx, |mouse_state, cx| { - // let tree_branch = *tree_branch.in_state(is_selected).style_for(mouse_state); - // let row = if is_current { - // collab_theme - // .project_row - // .in_state(true) - // .style_for(&mut Default::default()) - // } else { - // collab_theme - // .project_row - // .in_state(is_selected) - // .style_for(mouse_state) - // }; - - // Flex::row() - // .with_child(render_tree_branch( - // tree_branch, - // &row.name.text, - // is_last, - // vec2f(host_avatar_width, collab_theme.row_height), - // cx.font_cache(), - // )) - // .with_child( - // Svg::new("icons/file_icons/folder.svg") - // .with_color(collab_theme.channel_hash.color) - // .constrained() - // .with_width(collab_theme.channel_hash.width) - // .aligned() - // .left(), - // ) - // .with_child( - // Label::new(project_name.clone(), row.name.text.clone()) - // .aligned() - // .left() - // .contained() - // .with_style(row.name.container) - // .flex(1., false), - // ) - // .constrained() - // .with_height(collab_theme.row_height) - // .contained() - // .with_style(row.container) - // }); - - // if is_current { - // return content.into_any(); - // } - - // content - // .with_cursor_style(CursorStyle::PointingHand) - // .on_click(MouseButton::Left, move |_, this, cx| { - // if let Some(workspace) = this.workspace.upgrade(cx) { - // let app_state = workspace.read(cx).app_state().clone(); - // workspace::join_remote_project(project_id, host_user_id, app_state, cx) - // .detach_and_log_err(cx); - // } - // }) - // .with_tooltip::( - // project_id as usize, - // format!("Open {}", project_name), - // None, - // theme.tooltip.clone(), - // cx, - // ) - // .into_any() } fn render_participant_screen( &self, peer_id: Option, is_last: bool, + is_selected: bool, cx: &mut ViewContext, ) -> impl IntoElement { let id = peer_id.map_or(usize::MAX, |id| id.as_u64() as usize); ListItem::new(("screen", id)) + .selected(is_selected) .start_slot( h_stack() .gap_1() @@ -1200,9 +1110,11 @@ impl CollabPanel { .child(Label::new("Screen")) .when_some(peer_id, |this, _| { this.on_click(cx.listener(move |this, _, cx| { - this.workspace.update(cx, |workspace, cx| { - workspace.open_shared_screen(peer_id.unwrap(), cx) - }); + this.workspace + .update(cx, |workspace, cx| { + workspace.open_shared_screen(peer_id.unwrap(), cx) + }) + .ok(); })) .tooltip(move |cx| Tooltip::text(format!("Open shared screen"), cx)) }) @@ -1291,86 +1203,6 @@ impl CollabPanel { .tooltip(move |cx| Tooltip::text("Open Chat", cx)) } - // fn render_channel_invite( - // channel: Arc, - // channel_store: ModelHandle, - // theme: &theme::CollabPanel, - // is_selected: bool, - // cx: &mut ViewContext, - // ) -> AnyElement { - // enum Decline {} - // enum Accept {} - - // let channel_id = channel.id; - // let is_invite_pending = channel_store - // .read(cx) - // .has_pending_channel_invite_response(&channel); - // let button_spacing = theme.contact_button_spacing; - - // Flex::row() - // .with_child( - // Svg::new("icons/hash.svg") - // .with_color(theme.channel_hash.color) - // .constrained() - // .with_width(theme.channel_hash.width) - // .aligned() - // .left(), - // ) - // .with_child( - // Label::new(channel.name.clone(), theme.contact_username.text.clone()) - // .contained() - // .with_style(theme.contact_username.container) - // .aligned() - // .left() - // .flex(1., true), - // ) - // .with_child( - // MouseEventHandler::new::(channel.id as usize, cx, |mouse_state, _| { - // let button_style = if is_invite_pending { - // &theme.disabled_button - // } else { - // theme.contact_button.style_for(mouse_state) - // }; - // render_icon_button(button_style, "icons/x.svg").aligned() - // }) - // .with_cursor_style(CursorStyle::PointingHand) - // .on_click(MouseButton::Left, move |_, this, cx| { - // this.respond_to_channel_invite(channel_id, false, cx); - // }) - // .contained() - // .with_margin_right(button_spacing), - // ) - // .with_child( - // MouseEventHandler::new::(channel.id as usize, cx, |mouse_state, _| { - // let button_style = if is_invite_pending { - // &theme.disabled_button - // } else { - // theme.contact_button.style_for(mouse_state) - // }; - // render_icon_button(button_style, "icons/check.svg") - // .aligned() - // .flex_float() - // }) - // .with_cursor_style(CursorStyle::PointingHand) - // .on_click(MouseButton::Left, move |_, this, cx| { - // this.respond_to_channel_invite(channel_id, true, cx); - // }), - // ) - // .constrained() - // .with_height(theme.row_height) - // .contained() - // .with_style( - // *theme - // .contact_row - // .in_state(is_selected) - // .style_for(&mut Default::default()), - // ) - // .with_padding_left( - // theme.contact_row.default_style().padding.left + theme.channel_indent, - // ) - // .into_any() - // } - fn has_subchannels(&self, ix: usize) -> bool { self.entries.get(ix).map_or(false, |entry| { if let ListEntry::Channel { has_children, .. } = entry { @@ -1724,7 +1556,7 @@ impl CollabPanel { self.collapsed_channels.binary_search(&channel_id).is_ok() } - fn leave_call(cx: &mut ViewContext) { + fn leave_call(cx: &mut WindowContext) { ActiveCall::global(cx) .update(cx, |call, cx| call.hang_up(cx)) .detach_and_log_err(cx); @@ -1813,15 +1645,13 @@ impl CollabPanel { } } - fn start_move_channel(&mut self, channel_id: ChannelId, cx: &mut ViewContext) { + fn start_move_channel(&mut self, channel_id: ChannelId, _cx: &mut ViewContext) { self.channel_clipboard = Some(ChannelMoveClipboard { channel_id }); } - fn start_move_selected_channel(&mut self, channel_id: ChannelId, cx: &mut ViewContext) { + fn start_move_selected_channel(&mut self, _: &StartMoveChannel, cx: &mut ViewContext) { if let Some(channel) = self.selected_channel() { - self.channel_clipboard = Some(ChannelMoveClipboard { - channel_id: channel.id, - }) + self.start_move_channel(channel.id, cx); } } @@ -1900,10 +1730,6 @@ impl CollabPanel { .detach(); } - // fn remove_selected_channel(&mut self, action: &RemoveChannel, cx: &mut ViewContext) { - // self.remove_channel(action.channel_id, cx) - // } - fn remove_channel(&mut self, channel_id: ChannelId, cx: &mut ViewContext) { let channel_store = self.channel_store.clone(); if let Some(channel) = channel_store.read(cx).channel_for_id(channel_id) { @@ -1911,9 +1737,7 @@ impl CollabPanel { "Are you sure you want to remove the channel \"{}\"?", channel.name ); - let mut answer = - cx.prompt(PromptLevel::Warning, &prompt_message, &["Remove", "Cancel"]); - let window = cx.window(); + let answer = cx.prompt(PromptLevel::Warning, &prompt_message, &["Remove", "Cancel"]); cx.spawn(|this, mut cx| async move { if answer.await? == 0 { channel_store @@ -1937,8 +1761,7 @@ impl CollabPanel { "Are you sure you want to remove \"{}\" from your contacts?", github_login ); - let mut answer = cx.prompt(PromptLevel::Warning, &prompt_message, &["Remove", "Cancel"]); - let window = cx.window(); + let answer = cx.prompt(PromptLevel::Warning, &prompt_message, &["Remove", "Cancel"]); cx.spawn(|_, mut cx| async move { if answer.await? == 0 { user_store @@ -1964,18 +1787,18 @@ impl CollabPanel { .detach_and_log_err(cx); } - // fn respond_to_channel_invite( - // &mut self, - // channel_id: u64, - // accept: bool, - // cx: &mut ViewContext, - // ) { - // self.channel_store - // .update(cx, |store, cx| { - // store.respond_to_channel_invite(channel_id, accept, cx) - // }) - // .detach(); - // } + fn respond_to_channel_invite( + &mut self, + channel_id: u64, + accept: bool, + cx: &mut ViewContext, + ) { + self.channel_store + .update(cx, |store, cx| { + store.respond_to_channel_invite(channel_id, accept, cx) + }) + .detach(); + } fn call(&mut self, recipient_user_id: u64, cx: &mut ViewContext) { ActiveCall::global(cx) @@ -2096,6 +1919,9 @@ impl CollabPanel { ListEntry::ChannelEditor { depth } => { self.render_channel_editor(*depth, cx).into_any_element() } + ListEntry::ChannelInvite(channel) => self + .render_channel_invite(channel, is_selected, cx) + .into_any_element(), ListEntry::CallParticipant { user, peer_id, @@ -2114,11 +1940,12 @@ impl CollabPanel { &worktree_root_names, *host_user_id, *is_last, + is_selected, cx, ) .into_any_element(), ListEntry::ParticipantScreen { peer_id, is_last } => self - .render_participant_screen(*peer_id, *is_last, cx) + .render_participant_screen(*peer_id, *is_last, is_selected, cx) .into_any_element(), ListEntry::ChannelNotes { channel_id } => self .render_channel_notes(*channel_id, cx) @@ -2233,7 +2060,7 @@ impl CollabPanel { ListHeader::new(text) .when(can_collapse, |header| { header.toggle(Some(!is_collapsed)).on_toggle(cx.listener( - move |this, event, cx| { + move |this, _, cx| { this.toggle_section_expanded(section, cx); }, )) @@ -2265,8 +2092,9 @@ impl CollabPanel { let busy = contact.busy || calling; let user_id = contact.user.id; let github_login = SharedString::from(contact.user.github_login.clone()); - let mut item = + let item = ListItem::new(github_login.clone()) + .selected(is_selected) .on_click(cx.listener(move |this, _, cx| this.call(user_id, cx))) .child( h_stack() @@ -2330,8 +2158,8 @@ impl CollabPanel { ) -> impl IntoElement { let github_login = SharedString::from(user.github_login.clone()); let user_id = user.id; - let is_contact_request_pending = self.user_store.read(cx).is_contact_request_pending(&user); - let color = if is_contact_request_pending { + let is_response_pending = self.user_store.read(cx).is_contact_request_pending(&user); + let color = if is_response_pending { Color::Muted } else { Color::Default @@ -2363,6 +2191,7 @@ impl CollabPanel { }; ListItem::new(github_login.clone()) + .selected(is_selected) .child( h_stack() .w_full() @@ -2373,6 +2202,54 @@ impl CollabPanel { .start_slot(Avatar::new(user.avatar_uri.clone())) } + fn render_channel_invite( + &self, + channel: &Arc, + is_selected: bool, + cx: &mut ViewContext, + ) -> impl IntoElement { + let channel_id = channel.id; + let response_is_pending = self + .channel_store + .read(cx) + .has_pending_channel_invite_response(&channel); + let color = if response_is_pending { + Color::Muted + } else { + Color::Default + }; + + let controls = [ + IconButton::new("remove_contact", Icon::Close) + .on_click(cx.listener(move |this, _, cx| { + this.respond_to_channel_invite(channel_id, false, cx); + })) + .icon_color(color) + .tooltip(|cx| Tooltip::text("Decline invite", cx)), + IconButton::new("remove_contact", Icon::Check) + .on_click(cx.listener(move |this, _, cx| { + this.respond_to_contact_request(channel_id, true, cx); + })) + .icon_color(color) + .tooltip(|cx| Tooltip::text("Accept invite", cx)), + ]; + + ListItem::new(("channel-invite", channel.id as usize)) + .selected(is_selected) + .child( + h_stack() + .w_full() + .justify_between() + .child(Label::new(channel.name.clone())) + .child(h_stack().children(controls)), + ) + .start_slot( + IconElement::new(Icon::Hash) + .size(IconSize::Small) + .color(Color::Muted), + ) + } + fn render_contact_placeholder( &self, is_selected: bool, @@ -2411,7 +2288,6 @@ impl CollabPanel { .channel_for_id(channel_id) .map(|channel| channel.visibility) == Some(proto::ChannelVisibility::Public); - let other_selected = self.selected_channel().map(|channel| channel.id) == Some(channel.id); let disclosed = has_children.then(|| !self.collapsed_channels.binary_search(&channel.id).is_ok()); @@ -2423,14 +2299,10 @@ impl CollabPanel { let face_pile = if !participants.is_empty() { let extra_count = participants.len().saturating_sub(FACEPILE_LIMIT); - let user = &participants[0]; - let result = FacePile { faces: participants .iter() - .filter_map(|user| { - Some(Avatar::new(user.avatar_uri.clone()).into_any_element()) - }) + .map(|user| Avatar::new(user.avatar_uri.clone()).into_any_element()) .take(FACEPILE_LIMIT) .chain(if extra_count > 0 { // todo!() @nate - this label looks wrong. @@ -2454,7 +2326,7 @@ impl CollabPanel { .flex() .w_full() .on_drag(channel.clone(), move |channel, cx| { - cx.build_view(|cx| DraggedChannelView { + cx.build_view(|_| DraggedChannelView { channel: channel.clone(), width, }) @@ -2480,12 +2352,10 @@ impl CollabPanel { }), ) .on_click(cx.listener(move |this, _, cx| { - if this.drag_target_channel == ChannelDragTarget::None { - if is_active { - this.open_channel_notes(channel_id, cx) - } else { - this.join_channel(channel_id, cx) - } + if is_active { + this.open_channel_notes(channel_id, cx) + } else { + this.join_channel(channel_id, cx) } })) .on_secondary_mouse_down(cx.listener( @@ -2537,316 +2407,9 @@ impl CollabPanel { ), ) .tooltip(|cx| Tooltip::text("Join channel", cx)) + } - // let channel_id = channel.id; - // let collab_theme = &theme.collab_panel; - // let is_public = self - // .channel_store - // .read(cx) - // .channel_for_id(channel_id) - // .map(|channel| channel.visibility) - // == Some(proto::ChannelVisibility::Public); - // let other_selected = self.selected_channel().map(|channel| channel.id) == Some(channel.id); - // let disclosed = - // has_children.then(|| !self.collapsed_channels.binary_search(&channel.id).is_ok()); - - // enum ChannelCall {} - // enum ChannelNote {} - // enum NotesTooltip {} - // enum ChatTooltip {} - // enum ChannelTooltip {} - - // let mut is_dragged_over = false; - // if cx - // .global::>() - // .currently_dragged::(cx.window()) - // .is_some() - // && self.drag_target_channel == ChannelDragTarget::Channel(channel_id) - // { - // is_dragged_over = true; - // } - - // let has_messages_notification = channel.unseen_message_id.is_some(); - - // MouseEventHandler::new::(ix, cx, |state, cx| { - // let row_hovered = state.hovered(); - - // let mut select_state = |interactive: &Interactive| { - // if state.clicked() == Some(MouseButton::Left) && interactive.clicked.is_some() { - // interactive.clicked.as_ref().unwrap().clone() - // } else if state.hovered() || other_selected { - // interactive - // .hovered - // .as_ref() - // .unwrap_or(&interactive.default) - // .clone() - // } else { - // interactive.default.clone() - // } - // }; - - // Flex::::row() - // .with_child( - // Svg::new(if is_public { - // "icons/public.svg" - // } else { - // "icons/hash.svg" - // }) - // .with_color(collab_theme.channel_hash.color) - // .constrained() - // .with_width(collab_theme.channel_hash.width) - // .aligned() - // .left(), - // ) - // .with_child({ - // let style = collab_theme.channel_name.inactive_state(); - // Flex::row() - // .with_child( - // Label::new(channel.name.clone(), style.text.clone()) - // .contained() - // .with_style(style.container) - // .aligned() - // .left() - // .with_tooltip::( - // ix, - // "Join channel", - // None, - // theme.tooltip.clone(), - // cx, - // ), - // ) - // .with_children({ - // let participants = - // self.channel_store.read(cx).channel_participants(channel_id); - - // if !participants.is_empty() { - // let extra_count = participants.len().saturating_sub(FACEPILE_LIMIT); - - // let result = FacePile::new(collab_theme.face_overlap) - // .with_children( - // participants - // .iter() - // .filter_map(|user| { - // Some( - // Image::from_data(user.avatar.clone()?) - // .with_style(collab_theme.channel_avatar), - // ) - // }) - // .take(FACEPILE_LIMIT), - // ) - // .with_children((extra_count > 0).then(|| { - // Label::new( - // format!("+{}", extra_count), - // collab_theme.extra_participant_label.text.clone(), - // ) - // .contained() - // .with_style(collab_theme.extra_participant_label.container) - // })); - - // Some(result) - // } else { - // None - // } - // }) - // .with_spacing(8.) - // .align_children_center() - // .flex(1., true) - // }) - // .with_child( - // MouseEventHandler::new::(ix, cx, move |mouse_state, _| { - // let container_style = collab_theme - // .disclosure - // .button - // .style_for(mouse_state) - // .container; - - // if channel.unseen_message_id.is_some() { - // Svg::new("icons/conversations.svg") - // .with_color(collab_theme.channel_note_active_color) - // .constrained() - // .with_width(collab_theme.channel_hash.width) - // .contained() - // .with_style(container_style) - // .with_uniform_padding(4.) - // .into_any() - // } else if row_hovered { - // Svg::new("icons/conversations.svg") - // .with_color(collab_theme.channel_hash.color) - // .constrained() - // .with_width(collab_theme.channel_hash.width) - // .contained() - // .with_style(container_style) - // .with_uniform_padding(4.) - // .into_any() - // } else { - // Empty::new().into_any() - // } - // }) - // .on_click(MouseButton::Left, move |_, this, cx| { - // this.join_channel_chat(&JoinChannelChat { channel_id }, cx); - // }) - // .with_tooltip::( - // ix, - // "Open channel chat", - // None, - // theme.tooltip.clone(), - // cx, - // ) - // .contained() - // .with_margin_right(4.), - // ) - // .with_child( - // MouseEventHandler::new::(ix, cx, move |mouse_state, cx| { - // let container_style = collab_theme - // .disclosure - // .button - // .style_for(mouse_state) - // .container; - // if row_hovered || channel.unseen_note_version.is_some() { - // Svg::new("icons/file.svg") - // .with_color(if channel.unseen_note_version.is_some() { - // collab_theme.channel_note_active_color - // } else { - // collab_theme.channel_hash.color - // }) - // .constrained() - // .with_width(collab_theme.channel_hash.width) - // .contained() - // .with_style(container_style) - // .with_uniform_padding(4.) - // .with_margin_right(collab_theme.channel_hash.container.margin.left) - // .with_tooltip::( - // ix as usize, - // "Open channel notes", - // None, - // theme.tooltip.clone(), - // cx, - // ) - // .into_any() - // } else if has_messages_notification { - // Empty::new() - // .constrained() - // .with_width(collab_theme.channel_hash.width) - // .contained() - // .with_uniform_padding(4.) - // .with_margin_right(collab_theme.channel_hash.container.margin.left) - // .into_any() - // } else { - // Empty::new().into_any() - // } - // }) - // .on_click(MouseButton::Left, move |_, this, cx| { - // this.open_channel_notes(&OpenChannelNotes { channel_id }, cx); - // }), - // ) - // .align_children_center() - // .styleable_component() - // .disclosable( - // disclosed, - // Box::new(ToggleCollapse { - // location: channel.id.clone(), - // }), - // ) - // .with_id(ix) - // .with_style(collab_theme.disclosure.clone()) - // .element() - // .constrained() - // .with_height(collab_theme.row_height) - // .contained() - // .with_style(select_state( - // collab_theme - // .channel_row - // .in_state(is_selected || is_active || is_dragged_over), - // )) - // .with_padding_left( - // collab_theme.channel_row.default_style().padding.left - // + collab_theme.channel_indent * depth as f32, - // ) - // }) - // .on_click(MouseButton::Left, move |_, this, cx| { - // if this. - // drag_target_channel == ChannelDragTarget::None { - // if is_active { - // this.open_channel_notes(&OpenChannelNotes { channel_id }, cx) - // } else { - // this.join_channel(channel_id, cx) - // } - // } - // }) - // .on_click(MouseButton::Right, { - // let channel = channel.clone(); - // move |e, this, cx| { - // this.deploy_channel_context_menu(Some(e.position), &channel, ix, cx); - // } - // }) - // .on_up(MouseButton::Left, move |_, this, cx| { - // if let Some((_, dragged_channel)) = cx - // .global::>() - // .currently_dragged::(cx.window()) - // { - // this.channel_store - // .update(cx, |channel_store, cx| { - // channel_store.move_channel(dragged_channel.id, Some(channel_id), cx) - // }) - // .detach_and_log_err(cx) - // } - // }) - // .on_move({ - // let channel = channel.clone(); - // move |_, this, cx| { - // if let Some((_, dragged_channel)) = cx - // .global::>() - // .currently_dragged::(cx.window()) - // { - // if channel.id != dragged_channel.id { - // this.drag_target_channel = ChannelDragTarget::Channel(channel.id); - // } - // cx.notify() - // } - // } - // }) - // .as_draggable::<_, Channel>( - // channel.clone(), - // move |_, channel, cx: &mut ViewContext| { - // let theme = &theme::current(cx).collab_panel; - - // Flex::::row() - // .with_child( - // Svg::new("icons/hash.svg") - // .with_color(theme.channel_hash.color) - // .constrained() - // .with_width(theme.channel_hash.width) - // .aligned() - // .left(), - // ) - // .with_child( - // Label::new(channel.name.clone(), theme.channel_name.text.clone()) - // .contained() - // .with_style(theme.channel_name.container) - // .aligned() - // .left(), - // ) - // .align_children_center() - // .contained() - // .with_background_color( - // theme - // .container - // .background_color - // .unwrap_or(gpui::color::Color::transparent_black()), - // ) - // .contained() - // .with_padding_left( - // theme.channel_row.default_style().padding.left - // + theme.channel_indent * depth as f32, - // ) - // .into_any() - // }, - // ) - // .with_cursor_style(CursorStyle::PointingHand) - // .into_any() - } - - fn render_channel_editor(&self, depth: usize, cx: &mut ViewContext) -> impl IntoElement { + fn render_channel_editor(&self, depth: usize, _cx: &mut ViewContext) -> impl IntoElement { let item = ListItem::new("channel-editor") .inset(false) .indent_level(depth) @@ -2916,20 +2479,12 @@ impl Render for CollabPanel { .on_action(cx.listener(CollabPanel::select_prev)) .on_action(cx.listener(CollabPanel::confirm)) .on_action(cx.listener(CollabPanel::insert_space)) - // .on_action(cx.listener(CollabPanel::remove)) .on_action(cx.listener(CollabPanel::remove_selected_channel)) .on_action(cx.listener(CollabPanel::show_inline_context_menu)) - // .on_action(cx.listener(CollabPanel::new_subchannel)) - // .on_action(cx.listener(CollabPanel::invite_members)) - // .on_action(cx.listener(CollabPanel::manage_members)) .on_action(cx.listener(CollabPanel::rename_selected_channel)) - // .on_action(cx.listener(CollabPanel::rename_channel)) - // .on_action(cx.listener(CollabPanel::toggle_channel_collapsed_action)) .on_action(cx.listener(CollabPanel::collapse_selected_channel)) .on_action(cx.listener(CollabPanel::expand_selected_channel)) - // .on_action(cx.listener(CollabPanel::open_channel_notes)) - // .on_action(cx.listener(CollabPanel::join_channel_chat)) - // .on_action(cx.listener(CollabPanel::copy_channel_link)) + .on_action(cx.listener(CollabPanel::start_move_selected_channel)) .track_focus(&self.focus_handle) .size_full() .child(if self.user_store.read(cx).current_user().is_none() { @@ -2946,105 +2501,6 @@ impl Render for CollabPanel { } } -// impl View for CollabPanel { -// fn ui_name() -> &'static str { -// "CollabPanel" -// } - -// fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext) { -// if !self.has_focus { -// self.has_focus = true; -// if !self.context_menu.is_focused(cx) { -// if let Some(editing_state) = &self.channel_editing_state { -// if editing_state.pending_name().is_none() { -// cx.focus(&self.channel_name_editor); -// } else { -// cx.focus(&self.filter_editor); -// } -// } else { -// cx.focus(&self.filter_editor); -// } -// } -// cx.emit(Event::Focus); -// } -// } - -// fn focus_out(&mut self, _: gpui::AnyViewHandle, _: &mut ViewContext) { -// self.has_focus = false; -// } - -// fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement { -// let theme = &theme::current(cx).collab_panel; - -// if self.user_store.read(cx).current_user().is_none() { -// enum LogInButton {} - -// return Flex::column() -// .with_child( -// MouseEventHandler::new::(0, cx, |state, _| { -// let button = theme.log_in_button.style_for(state); -// Label::new("Sign in to collaborate", button.text.clone()) -// .aligned() -// .left() -// .contained() -// .with_style(button.container) -// }) -// .on_click(MouseButton::Left, |_, this, cx| { -// let client = this.client.clone(); -// cx.spawn(|_, cx| async move { -// client.authenticate_and_connect(true, &cx).await.log_err(); -// }) -// .detach(); -// }) -// .with_cursor_style(CursorStyle::PointingHand), -// ) -// .contained() -// .with_style(theme.container) -// .into_any(); -// } - -// enum PanelFocus {} -// MouseEventHandler::new::(0, cx, |_, cx| { -// Stack::new() -// .with_child( -// Flex::column() -// .with_child( -// Flex::row().with_child( -// ChildView::new(&self.filter_editor, cx) -// .contained() -// .with_style(theme.user_query_editor.container) -// .flex(1.0, true), -// ), -// ) -// .with_child(List::new(self.list_state.clone()).flex(1., true).into_any()) -// .contained() -// .with_style(theme.container) -// .into_any(), -// ) -// .with_children( -// (!self.context_menu_on_selected) -// .then(|| ChildView::new(&self.context_menu, cx)), -// ) -// .into_any() -// }) -// .on_click(MouseButton::Left, |_, _, cx| cx.focus_self()) -// .into_any_named("collab panel") -// } - -// fn update_keymap_context( -// &self, -// keymap: &mut gpui::keymap_matcher::KeymapContext, -// _: &AppContext, -// ) { -// Self::reset_to_default_keymap_context(keymap); -// if self.channel_editing_state.is_some() { -// keymap.add_identifier("editing"); -// } else { -// keymap.add_identifier("not_editing"); -// } -// } -// } - impl EventEmitter for CollabPanel {} impl Panel for CollabPanel { @@ -3159,11 +2615,11 @@ impl PartialEq for ListEntry { return channel_id == other_id; } } - // ListEntry::ChannelInvite(channel_1) => { - // if let ListEntry::ChannelInvite(channel_2) = other { - // return channel_1.id == channel_2.id; - // } - // } + ListEntry::ChannelInvite(channel_1) => { + if let ListEntry::ChannelInvite(channel_2) = other { + return channel_1.id == channel_2.id; + } + } ListEntry::IncomingRequest(user_1) => { if let ListEntry::IncomingRequest(user_2) = other { return user_1.id == user_2.id; @@ -3199,19 +2655,6 @@ impl PartialEq for ListEntry { } } -// fn render_icon_button(style: &IconButton, svg_path: &'static str) -> impl Element { -// Svg::new(svg_path) -// .with_color(style.color) -// .constrained() -// .with_width(style.icon_width) -// .aligned() -// .constrained() -// .with_width(style.button_width) -// .with_height(style.button_width) -// .contained() -// .with_style(style.container) -// } - struct DraggedChannelView { channel: Channel, width: Pixels, diff --git a/crates/collab_ui2/src/collab_panel/channel_modal.rs b/crates/collab_ui2/src/collab_panel/channel_modal.rs index 8636dcafe467d339986bf03ff0dea06382e20782..d903ecb086df8969e087e67b2d53b3a780d01236 100644 --- a/crates/collab_ui2/src/collab_panel/channel_modal.rs +++ b/crates/collab_ui2/src/collab_panel/channel_modal.rs @@ -1,3 +1,4 @@ +#![allow(unused)] use channel::{ChannelId, ChannelMembership, ChannelStore}; use client::{ proto::{self, ChannelRole, ChannelVisibility}, diff --git a/crates/collab_ui2/src/collab_panel/contact_finder.rs b/crates/collab_ui2/src/collab_panel/contact_finder.rs index ff7e02a909af3e9698d5126f5d0bd5c558e4685c..208727efd27132debb9f883af7c172154d2461f1 100644 --- a/crates/collab_ui2/src/collab_panel/contact_finder.rs +++ b/crates/collab_ui2/src/collab_panel/contact_finder.rs @@ -1,3 +1,4 @@ +#![allow(unused)] use client::{ContactRequestStatus, User, UserStore}; use gpui::{ div, img, svg, AnyElement, AppContext, DismissEvent, Div, Entity, EventEmitter, FocusHandle, From 80b6922de70b1b72d12030bef6ba981f2b439219 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 10:15:00 -0800 Subject: [PATCH 157/644] wip --- .../src/collab_panel/channel_modal.rs | 213 +++++------------- 1 file changed, 51 insertions(+), 162 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel/channel_modal.rs b/crates/collab_ui2/src/collab_panel/channel_modal.rs index d903ecb086df8969e087e67b2d53b3a780d01236..0b407f0647cd47662f953aaec789fcbd44475bb7 100644 --- a/crates/collab_ui2/src/collab_panel/channel_modal.rs +++ b/crates/collab_ui2/src/collab_panel/channel_modal.rs @@ -1,4 +1,3 @@ -#![allow(unused)] use channel::{ChannelId, ChannelMembership, ChannelStore}; use client::{ proto::{self, ChannelRole, ChannelVisibility}, @@ -12,7 +11,7 @@ use gpui::{ }; use picker::{Picker, PickerDelegate}; use std::sync::Arc; -use ui::prelude::*; +use ui::{prelude::*, Checkbox}; use util::TryFutureExt; use workspace::ModalView; @@ -157,167 +156,57 @@ impl Render for ChannelModal { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - v_stack().w(rems(34.)).child(self.picker.clone()) - // let theme = &theme::current(cx).collab_panel.tabbed_modal; - - // let mode = self.picker.read(cx).delegate().mode; - // let Some(channel) = self.channel_store.read(cx).channel_for_id(self.channel_id) else { - // return Empty::new().into_any(); - // }; - - // enum InviteMembers {} - // enum ManageMembers {} - - // fn render_mode_button( - // mode: Mode, - // text: &'static str, - // current_mode: Mode, - // theme: &theme::TabbedModal, - // cx: &mut ViewContext, - // ) -> AnyElement { - // let active = mode == current_mode; - // MouseEventHandler::new::(0, cx, move |state, _| { - // let contained_text = theme.tab_button.style_for(active, state); - // Label::new(text, contained_text.text.clone()) - // .contained() - // .with_style(contained_text.container.clone()) - // }) - // .on_click(MouseButton::Left, move |_, this, cx| { - // if !active { - // this.set_mode(mode, cx); - // } - // }) - // .with_cursor_style(CursorStyle::PointingHand) - // .into_any() - // } - - // fn render_visibility( - // channel_id: ChannelId, - // visibility: ChannelVisibility, - // theme: &theme::TabbedModal, - // cx: &mut ViewContext, - // ) -> AnyElement { - // enum TogglePublic {} - - // if visibility == ChannelVisibility::Members { - // return Flex::row() - // .with_child( - // MouseEventHandler::new::(0, cx, move |state, _| { - // let style = theme.visibility_toggle.style_for(state); - // Label::new(format!("{}", "Public access: OFF"), style.text.clone()) - // .contained() - // .with_style(style.container.clone()) - // }) - // .on_click(MouseButton::Left, move |_, this, cx| { - // this.channel_store - // .update(cx, |channel_store, cx| { - // channel_store.set_channel_visibility( - // channel_id, - // ChannelVisibility::Public, - // cx, - // ) - // }) - // .detach_and_log_err(cx); - // }) - // .with_cursor_style(CursorStyle::PointingHand), - // ) - // .into_any(); - // } - - // Flex::row() - // .with_child( - // MouseEventHandler::new::(0, cx, move |state, _| { - // let style = theme.visibility_toggle.style_for(state); - // Label::new(format!("{}", "Public access: ON"), style.text.clone()) - // .contained() - // .with_style(style.container.clone()) - // }) - // .on_click(MouseButton::Left, move |_, this, cx| { - // this.channel_store - // .update(cx, |channel_store, cx| { - // channel_store.set_channel_visibility( - // channel_id, - // ChannelVisibility::Members, - // cx, - // ) - // }) - // .detach_and_log_err(cx); - // }) - // .with_cursor_style(CursorStyle::PointingHand), - // ) - // .with_spacing(14.0) - // .with_child( - // MouseEventHandler::new::(1, cx, move |state, _| { - // let style = theme.channel_link.style_for(state); - // Label::new(format!("{}", "copy link"), style.text.clone()) - // .contained() - // .with_style(style.container.clone()) - // }) - // .on_click(MouseButton::Left, move |_, this, cx| { - // if let Some(channel) = - // this.channel_store.read(cx).channel_for_id(channel_id) - // { - // let item = ClipboardItem::new(channel.link()); - // cx.write_to_clipboard(item); - // } - // }) - // .with_cursor_style(CursorStyle::PointingHand), - // ) - // .into_any() - // } - - // Flex::column() - // .with_child( - // Flex::column() - // .with_child( - // Label::new(format!("#{}", channel.name), theme.title.text.clone()) - // .contained() - // .with_style(theme.title.container.clone()), - // ) - // .with_child(render_visibility(channel.id, channel.visibility, theme, cx)) - // .with_child(Flex::row().with_children([ - // render_mode_button::( - // Mode::InviteMembers, - // "Invite members", - // mode, - // theme, - // cx, - // ), - // render_mode_button::( - // Mode::ManageMembers, - // "Manage members", - // mode, - // theme, - // cx, - // ), - // ])) - // .expanded() - // .contained() - // .with_style(theme.header), - // ) - // .with_child( - // ChildView::new(&self.picker, cx) - // .contained() - // .with_style(theme.body), - // ) - // .constrained() - // .with_max_height(theme.max_height) - // .with_max_width(theme.max_width) - // .contained() - // .with_style(theme.modal) - // .into_any() + let channel_store = self.channel_store.read(cx); + let Some(channel) = channel_store.channel_for_id(self.channel_id) else { + return div(); + }; + let mode = self.picker.read(cx).delegate.mode; + + v_stack() + .bg(cx.theme().colors().elevated_surface_background) + .w(rems(34.)) + .child(Label::new(channel.name.clone())) + .child( + div() + .w_full() + .flex_row() + .child(Checkbox::new( + "is-public", + if channel.visibility == ChannelVisibility::Public { + ui::Selection::Selected + } else { + ui::Selection::Unselected + }, + )) + .child(Label::new("Public")), + ) + .child( + div() + .w_full() + .flex_row() + .child( + Button::new("manage-members", "Manage Members") + .selected(mode == Mode::ManageMembers) + .on_click(cx.listener(|this, _, cx| { + this.picker.update(cx, |picker, _| { + picker.delegate.mode = Mode::ManageMembers + }); + cx.notify(); + })), + ) + .child( + Button::new("invite-members", "Invite Members") + .selected(mode == Mode::InviteMembers) + .on_click(cx.listener(|this, _, cx| { + this.picker.update(cx, |picker, _| { + picker.delegate.mode = Mode::InviteMembers + }); + cx.notify(); + })), + ), + ) + .child(self.picker.clone()) } - - // fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext) { - // self.has_focus = true; - // if cx.is_self_focused() { - // cx.focus(&self.picker) - // } - // } - - // fn focus_out(&mut self, _: gpui::AnyViewHandle, _: &mut ViewContext) { - // self.has_focus = false; - // } } #[derive(Copy, Clone, PartialEq)] From 4e07167288879ccc8bfeaa365b90e6ca5f566d6a Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 13:49:52 -0500 Subject: [PATCH 158/644] Use `child` instead of `children` (#3718) This PR refactors some code where we were using `children` when we could have used `child` instead. Release Notes: - N/A --- crates/search2/src/project_search.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index 284875c7f5e2868b2455b89c378abc476a7bde5b..4e41c8b5a9e9758312be9df136ce08ce951227a7 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -1654,7 +1654,7 @@ impl Render for ProjectSearchBar { }; let actions_column = h_stack() .when(search.replace_enabled, |this| { - this.children([ + this.child( IconButton::new("project-search-replace-next", Icon::ReplaceNext) .on_click(cx.listener(|this, _, cx| { if let Some(search) = this.active_project_search.as_ref() { @@ -1664,6 +1664,8 @@ impl Render for ProjectSearchBar { } })) .tooltip(|cx| Tooltip::for_action("Replace next match", &ReplaceNext, cx)), + ) + .child( IconButton::new("project-search-replace-all", Icon::ReplaceAll) .on_click(cx.listener(|this, _, cx| { if let Some(search) = this.active_project_search.as_ref() { @@ -1673,7 +1675,7 @@ impl Render for ProjectSearchBar { } })) .tooltip(|cx| Tooltip::for_action("Replace all matches", &ReplaceAll, cx)), - ]) + ) }) .when_some(search.active_match_index, |mut this, index| { let index = index + 1; @@ -1684,7 +1686,7 @@ impl Render for ProjectSearchBar { } this }) - .children([ + .child( IconButton::new("project-search-prev-match", Icon::ChevronLeft) .disabled(search.active_match_index.is_none()) .on_click(cx.listener(|this, _, cx| { @@ -1697,6 +1699,8 @@ impl Render for ProjectSearchBar { .tooltip(|cx| { Tooltip::for_action("Go to previous match", &SelectPrevMatch, cx) }), + ) + .child( IconButton::new("project-search-next-match", Icon::ChevronRight) .disabled(search.active_match_index.is_none()) .on_click(cx.listener(|this, _, cx| { @@ -1707,7 +1711,8 @@ impl Render for ProjectSearchBar { } })) .tooltip(|cx| Tooltip::for_action("Go to next match", &SelectNextMatch, cx)), - ]); + ); + v_stack() .key_context(key_context) .flex_grow() From 1c3698ae20cdb2ec9aace81bb29d56f19e4f2888 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 12:02:35 -0800 Subject: [PATCH 159/644] Implement channel modal Co-authored-by: Nathan --- crates/collab_ui2/src/collab_panel.rs | 10 +- .../src/collab_panel/channel_modal.rs | 432 ++++++++---------- crates/gpui2/src/window.rs | 7 - crates/picker2/src/picker2.rs | 2 +- crates/ui2/src/components/context_menu.rs | 5 +- crates/ui2/src/components/icon.rs | 2 + 6 files changed, 214 insertions(+), 244 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index c58d7c47bc29ddca60fe562a80c7b591f246fca2..3df8f06d3b328f287086eef1e048274a8008ca71 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2167,13 +2167,13 @@ impl CollabPanel { let controls = if is_incoming { vec![ - IconButton::new("remove_contact", Icon::Close) + IconButton::new("decline-contact", Icon::Close) .on_click(cx.listener(move |this, _, cx| { this.respond_to_contact_request(user_id, false, cx); })) .icon_color(color) .tooltip(|cx| Tooltip::text("Decline invite", cx)), - IconButton::new("remove_contact", Icon::Check) + IconButton::new("accept-contact", Icon::Check) .on_click(cx.listener(move |this, _, cx| { this.respond_to_contact_request(user_id, true, cx); })) @@ -2220,15 +2220,15 @@ impl CollabPanel { }; let controls = [ - IconButton::new("remove_contact", Icon::Close) + IconButton::new("reject-invite", Icon::Close) .on_click(cx.listener(move |this, _, cx| { this.respond_to_channel_invite(channel_id, false, cx); })) .icon_color(color) .tooltip(|cx| Tooltip::text("Decline invite", cx)), - IconButton::new("remove_contact", Icon::Check) + IconButton::new("accept-invite", Icon::Check) .on_click(cx.listener(move |this, _, cx| { - this.respond_to_contact_request(channel_id, true, cx); + this.respond_to_channel_invite(channel_id, true, cx); })) .icon_color(color) .tooltip(|cx| Tooltip::text("Accept invite", cx)), diff --git a/crates/collab_ui2/src/collab_panel/channel_modal.rs b/crates/collab_ui2/src/collab_panel/channel_modal.rs index 0b407f0647cd47662f953aaec789fcbd44475bb7..f844c609cac074d6457613b81b654a8e0b1c5d3c 100644 --- a/crates/collab_ui2/src/collab_panel/channel_modal.rs +++ b/crates/collab_ui2/src/collab_panel/channel_modal.rs @@ -5,13 +5,13 @@ use client::{ }; use fuzzy::{match_strings, StringMatchCandidate}; use gpui::{ - actions, div, AppContext, ClipboardItem, DismissEvent, Div, Entity, EventEmitter, - FocusableView, Model, ParentElement, Render, Styled, Task, View, ViewContext, VisualContext, - WeakView, + actions, div, overlay, AppContext, ClipboardItem, DismissEvent, Div, EventEmitter, + FocusableView, Model, ParentElement, Render, Styled, Subscription, Task, View, ViewContext, + VisualContext, WeakView, }; use picker::{Picker, PickerDelegate}; use std::sync::Arc; -use ui::{prelude::*, Checkbox}; +use ui::{prelude::*, Avatar, Checkbox, ContextMenu, ListItem}; use util::TryFutureExt; use workspace::ModalView; @@ -25,19 +25,10 @@ actions!( ] ); -// pub fn init(cx: &mut AppContext) { -// Picker::::init(cx); -// cx.add_action(ChannelModal::toggle_mode); -// cx.add_action(ChannelModal::toggle_member_admin); -// cx.add_action(ChannelModal::remove_member); -// cx.add_action(ChannelModal::dismiss); -// } - pub struct ChannelModal { picker: View>, channel_store: Model, channel_id: ChannelId, - has_focus: bool, } impl ChannelModal { @@ -62,25 +53,19 @@ impl ChannelModal { channel_store: channel_store.clone(), channel_id, match_candidates: Vec::new(), + context_menu: None, members, mode, - // context_menu: cx.add_view(|cx| { - // let mut menu = ContextMenu::new(cx.view_id(), cx); - // menu.set_position_mode(OverlayPositionMode::Local); - // menu - // }), }, cx, ) + .modal(false) }); - let has_focus = picker.focus_handle(cx).contains_focused(cx); - Self { picker, channel_store, channel_id, - has_focus, } } @@ -126,15 +111,19 @@ impl ChannelModal { .detach(); } - fn toggle_member_admin(&mut self, _: &ToggleMemberAdmin, cx: &mut ViewContext) { - self.picker.update(cx, |picker, cx| { - picker.delegate.toggle_selected_member_admin(cx); - }) - } - - fn remove_member(&mut self, _: &RemoveMember, cx: &mut ViewContext) { - self.picker.update(cx, |picker, cx| { - picker.delegate.remove_selected_member(cx); + fn set_channel_visiblity(&mut self, selection: &Selection, cx: &mut ViewContext) { + self.channel_store.update(cx, |channel_store, cx| { + channel_store + .set_channel_visibility( + self.channel_id, + match selection { + Selection::Unselected => ChannelVisibility::Members, + Selection::Selected => ChannelVisibility::Public, + Selection::Indeterminate => return, + }, + cx, + ) + .detach_and_log_err(cx) }); } @@ -160,49 +149,79 @@ impl Render for ChannelModal { let Some(channel) = channel_store.channel_for_id(self.channel_id) else { return div(); }; + let channel_name = channel.name.clone(); + let channel_id = channel.id; + let visibility = channel.visibility; let mode = self.picker.read(cx).delegate.mode; v_stack() - .bg(cx.theme().colors().elevated_surface_background) + .key_context("ChannelModal") + .on_action(cx.listener(Self::toggle_mode)) + .on_action(cx.listener(Self::dismiss)) + .elevation_3(cx) .w(rems(34.)) - .child(Label::new(channel.name.clone())) - .child( - div() - .w_full() - .flex_row() - .child(Checkbox::new( - "is-public", - if channel.visibility == ChannelVisibility::Public { - ui::Selection::Selected - } else { - ui::Selection::Unselected - }, - )) - .child(Label::new("Public")), - ) .child( - div() - .w_full() - .flex_row() + v_stack() + .px_2() + .py_1() + .rounded_t(px(8.)) + .bg(cx.theme().colors().element_background) + .child(IconElement::new(Icon::Hash).size(IconSize::Medium)) + .child(Label::new(channel_name)) .child( - Button::new("manage-members", "Manage Members") - .selected(mode == Mode::ManageMembers) - .on_click(cx.listener(|this, _, cx| { - this.picker.update(cx, |picker, _| { - picker.delegate.mode = Mode::ManageMembers - }); - cx.notify(); - })), + h_stack() + .w_full() + .justify_between() + .child( + h_stack() + .gap_2() + .child( + Checkbox::new( + "is-public", + if visibility == ChannelVisibility::Public { + ui::Selection::Selected + } else { + ui::Selection::Unselected + }, + ) + .on_click(cx.listener(Self::set_channel_visiblity)), + ) + .child(Label::new("Public")), + ) + .children(if visibility == ChannelVisibility::Public { + Some(Button::new("copy-link", "Copy Link").on_click(cx.listener( + move |this, _, cx| { + if let Some(channel) = + this.channel_store.read(cx).channel_for_id(channel_id) + { + let item = ClipboardItem::new(channel.link()); + cx.write_to_clipboard(item); + } + }, + ))) + } else { + None + }), ) .child( - Button::new("invite-members", "Invite Members") - .selected(mode == Mode::InviteMembers) - .on_click(cx.listener(|this, _, cx| { - this.picker.update(cx, |picker, _| { - picker.delegate.mode = Mode::InviteMembers - }); - cx.notify(); - })), + div() + .w_full() + .flex() + .flex_row() + .child( + Button::new("manage-members", "Manage Members") + .selected(mode == Mode::ManageMembers) + .on_click(cx.listener(|this, _, cx| { + this.set_mode(Mode::ManageMembers, cx); + })), + ) + .child( + Button::new("invite-members", "Invite Members") + .selected(mode == Mode::InviteMembers) + .on_click(cx.listener(|this, _, cx| { + this.set_mode(Mode::InviteMembers, cx); + })), + ), ), ) .child(self.picker.clone()) @@ -226,11 +245,11 @@ pub struct ChannelModalDelegate { mode: Mode, match_candidates: Vec, members: Vec, - // context_menu: ViewHandle, + context_menu: Option<(View, Subscription)>, } impl PickerDelegate for ChannelModalDelegate { - type ListItem = Div; + type ListItem = ListItem; fn placeholder_text(&self) -> Arc { "Search collaborator by username...".into() @@ -310,11 +329,11 @@ impl PickerDelegate for ChannelModalDelegate { if let Some((selected_user, role)) = self.user_at_index(self.selected_index) { match self.mode { Mode::ManageMembers => { - self.show_context_menu(role.unwrap_or(ChannelRole::Member), cx) + self.show_context_menu(selected_user, role.unwrap_or(ChannelRole::Member), cx) } Mode::InviteMembers => match self.member_status(selected_user.id, cx) { Some(proto::channel_member::Kind::Invitee) => { - self.remove_selected_member(cx); + self.remove_member(selected_user.id, cx); } Some(proto::channel_member::Kind::AncestorMember) | None => { self.invite_member(selected_user, cx) @@ -326,11 +345,13 @@ impl PickerDelegate for ChannelModalDelegate { } fn dismissed(&mut self, cx: &mut ViewContext>) { - self.channel_modal - .update(cx, |_, cx| { - cx.emit(DismissEvent); - }) - .ok(); + if self.context_menu.is_none() { + self.channel_modal + .update(cx, |_, cx| { + cx.emit(DismissEvent); + }) + .ok(); + } } fn render_match( @@ -339,129 +360,54 @@ impl PickerDelegate for ChannelModalDelegate { selected: bool, cx: &mut ViewContext>, ) -> Option { - None - // let full_theme = &theme::current(cx); - // let theme = &full_theme.collab_panel.channel_modal; - // let tabbed_modal = &full_theme.collab_panel.tabbed_modal; - // let (user, role) = self.user_at_index(ix).unwrap(); - // let request_status = self.member_status(user.id, cx); - - // let style = tabbed_modal - // .picker - // .item - // .in_state(selected) - // .style_for(mouse_state); - - // let in_manage = matches!(self.mode, Mode::ManageMembers); - - // let mut result = Flex::row() - // .with_children(user.avatar.clone().map(|avatar| { - // Image::from_data(avatar) - // .with_style(theme.contact_avatar) - // .aligned() - // .left() - // })) - // .with_child( - // Label::new(user.github_login.clone(), style.label.clone()) - // .contained() - // .with_style(theme.contact_username) - // .aligned() - // .left(), - // ) - // .with_children({ - // (in_manage && request_status == Some(proto::channel_member::Kind::Invitee)).then( - // || { - // Label::new("Invited", theme.member_tag.text.clone()) - // .contained() - // .with_style(theme.member_tag.container) - // .aligned() - // .left() - // }, - // ) - // }) - // .with_children(if in_manage && role == Some(ChannelRole::Admin) { - // Some( - // Label::new("Admin", theme.member_tag.text.clone()) - // .contained() - // .with_style(theme.member_tag.container) - // .aligned() - // .left(), - // ) - // } else if in_manage && role == Some(ChannelRole::Guest) { - // Some( - // Label::new("Guest", theme.member_tag.text.clone()) - // .contained() - // .with_style(theme.member_tag.container) - // .aligned() - // .left(), - // ) - // } else { - // None - // }) - // .with_children({ - // let svg = match self.mode { - // Mode::ManageMembers => Some( - // Svg::new("icons/ellipsis.svg") - // .with_color(theme.member_icon.color) - // .constrained() - // .with_width(theme.member_icon.icon_width) - // .aligned() - // .constrained() - // .with_width(theme.member_icon.button_width) - // .with_height(theme.member_icon.button_width) - // .contained() - // .with_style(theme.member_icon.container), - // ), - // Mode::InviteMembers => match request_status { - // Some(proto::channel_member::Kind::Member) => Some( - // Svg::new("icons/check.svg") - // .with_color(theme.member_icon.color) - // .constrained() - // .with_width(theme.member_icon.icon_width) - // .aligned() - // .constrained() - // .with_width(theme.member_icon.button_width) - // .with_height(theme.member_icon.button_width) - // .contained() - // .with_style(theme.member_icon.container), - // ), - // Some(proto::channel_member::Kind::Invitee) => Some( - // Svg::new("icons/check.svg") - // .with_color(theme.invitee_icon.color) - // .constrained() - // .with_width(theme.invitee_icon.icon_width) - // .aligned() - // .constrained() - // .with_width(theme.invitee_icon.button_width) - // .with_height(theme.invitee_icon.button_width) - // .contained() - // .with_style(theme.invitee_icon.container), - // ), - // Some(proto::channel_member::Kind::AncestorMember) | None => None, - // }, - // }; - - // svg.map(|svg| svg.aligned().flex_float().into_any()) - // }) - // .contained() - // .with_style(style.container) - // .constrained() - // .with_height(tabbed_modal.row_height) - // .into_any(); - - // if selected { - // result = Stack::new() - // .with_child(result) - // .with_child( - // ChildView::new(&self.context_menu, cx) - // .aligned() - // .top() - // .right(), - // ) - // .into_any(); - // } - - // result + let (user, role) = self.user_at_index(ix)?; + let request_status = self.member_status(user.id, cx); + + Some( + ListItem::new(ix) + .inset(true) + .selected(selected) + .start_slot(Avatar::new(user.avatar_uri.clone())) + .child(Label::new(user.github_login.clone())) + .end_slot(h_stack().gap_2().map(|slot| { + match self.mode { + Mode::ManageMembers => slot + .children( + if request_status == Some(proto::channel_member::Kind::Invitee) { + Some(Label::new("Invited")) + } else { + None + }, + ) + .children(match role { + Some(ChannelRole::Admin) => Some(Label::new("Admin")), + Some(ChannelRole::Guest) => Some(Label::new("Guest")), + _ => None, + }) + .child(IconButton::new("ellipsis", Icon::Ellipsis)) + .children( + if let (Some((menu, _)), true) = (&self.context_menu, selected) { + Some( + overlay() + .anchor(gpui::AnchorCorner::TopLeft) + .child(menu.clone()), + ) + } else { + None + }, + ), + Mode::InviteMembers => match request_status { + Some(proto::channel_member::Kind::Invitee) => { + slot.children(Some(Label::new("Invited"))) + } + Some(proto::channel_member::Kind::Member) => { + slot.children(Some(Label::new("Member"))) + } + _ => slot, + }, + } + })), + ) } } @@ -495,21 +441,20 @@ impl ChannelModalDelegate { } } - fn toggle_selected_member_admin(&mut self, cx: &mut ViewContext>) -> Option<()> { - let (user, role) = self.user_at_index(self.selected_index)?; - let new_role = if role == Some(ChannelRole::Admin) { - ChannelRole::Member - } else { - ChannelRole::Admin - }; + fn set_user_role( + &mut self, + user_id: UserId, + new_role: ChannelRole, + cx: &mut ViewContext>, + ) -> Option<()> { let update = self.channel_store.update(cx, |store, cx| { - store.set_member_role(self.channel_id, user.id, new_role, cx) + store.set_member_role(self.channel_id, user_id, new_role, cx) }); cx.spawn(|picker, mut cx| async move { update.await?; picker.update(&mut cx, |picker, cx| { let this = &mut picker.delegate; - if let Some(member) = this.members.iter_mut().find(|m| m.user.id == user.id) { + if let Some(member) = this.members.iter_mut().find(|m| m.user.id == user_id) { member.role = new_role; } cx.focus_self(); @@ -520,9 +465,7 @@ impl ChannelModalDelegate { Some(()) } - fn remove_selected_member(&mut self, cx: &mut ViewContext>) -> Option<()> { - let (user, _) = self.user_at_index(self.selected_index)?; - let user_id = user.id; + fn remove_member(&mut self, user_id: UserId, cx: &mut ViewContext>) -> Option<()> { let update = self.channel_store.update(cx, |store, cx| { store.remove_member(self.channel_id, user_id, cx) }); @@ -546,7 +489,7 @@ impl ChannelModalDelegate { .selected_index .min(this.matching_member_indices.len().saturating_sub(1)); - cx.focus_self(); + picker.focus(cx); cx.notify(); }) }) @@ -579,24 +522,55 @@ impl ChannelModalDelegate { .detach_and_log_err(cx); } - fn show_context_menu(&mut self, role: ChannelRole, cx: &mut ViewContext>) { - // self.context_menu.update(cx, |context_menu, cx| { - // context_menu.show( - // Default::default(), - // AnchorCorner::TopRight, - // vec![ - // ContextMenuItem::action("Remove", RemoveMember), - // ContextMenuItem::action( - // if role == ChannelRole::Admin { - // "Make non-admin" - // } else { - // "Make admin" - // }, - // ToggleMemberAdmin, - // ), - // ], - // cx, - // ) - // }) + fn show_context_menu( + &mut self, + user: Arc, + role: ChannelRole, + cx: &mut ViewContext>, + ) { + let user_id = user.id; + let picker = cx.view().clone(); + let context_menu = ContextMenu::build(cx, |mut menu, _cx| { + menu = menu.entry("Remove Member", { + let picker = picker.clone(); + move |cx| { + picker.update(cx, |picker, cx| { + picker.delegate.remove_member(user_id, cx); + }) + } + }); + + let picker = picker.clone(); + match role { + ChannelRole::Admin => { + menu = menu.entry("Revoke Admin", move |cx| { + picker.update(cx, |picker, cx| { + picker + .delegate + .set_user_role(user_id, ChannelRole::Member, cx); + }) + }); + } + ChannelRole::Member => { + menu = menu.entry("Make Admin", move |cx| { + picker.update(cx, |picker, cx| { + picker + .delegate + .set_user_role(user_id, ChannelRole::Admin, cx); + }) + }); + } + _ => {} + }; + + menu + }); + cx.focus_view(&context_menu); + let subscription = cx.subscribe(&context_menu, |picker, _, _: &DismissEvent, cx| { + picker.delegate.context_menu = None; + picker.focus(cx); + cx.notify(); + }); + self.context_menu = Some((context_menu, subscription)); } } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 71799a6e00d5975cf12085131547a0f7c5af7cb3..f7ebddd0fea2b725e45d798b1a75e1d76ed3b5f7 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -2662,13 +2662,6 @@ impl<'a, V: 'static> ViewContext<'a, V> { self.defer(|view, cx| view.focus_handle(cx).focus(cx)) } - pub fn dismiss_self(&mut self) - where - V: ManagedView, - { - self.defer(|_, cx| cx.emit(DismissEvent)) - } - pub fn listener( &self, f: impl Fn(&mut V, &E, &mut ViewContext) + 'static, diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 70180112f96bbc795d18db19869365dc227f5844..8a75996f482c2c692adf95eed1015ef783d8ee1f 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -239,7 +239,7 @@ impl Render for Picker { ); div() - .key_context("picker") + .key_context("Picker") .size_full() .when_some(self.width, |el, width| { el.w(width) diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 250272b19882f031ab7af438bf3cfea7906bcec8..8fce15d1c69d0fcf97f8ac1757874be4884950b6 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -72,11 +72,11 @@ impl ContextMenu { pub fn entry( mut self, label: impl Into, - on_click: impl Fn(&mut WindowContext) + 'static, + handler: impl Fn(&mut WindowContext) + 'static, ) -> Self { self.items.push(ContextMenuItem::Entry { label: label.into(), - handler: Rc::new(on_click), + handler: Rc::new(handler), icon: None, action: None, }); @@ -114,6 +114,7 @@ impl ContextMenu { pub fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext) { cx.emit(DismissEvent); + cx.emit(DismissEvent); } fn select_first(&mut self, _: &SelectFirst, cx: &mut ViewContext) { diff --git a/crates/ui2/src/components/icon.rs b/crates/ui2/src/components/icon.rs index ca50cae7f8936e50dbc66be2def222589a571207..a168f97a50f047fbf8d338a779c46f6cfef57639 100644 --- a/crates/ui2/src/components/icon.rs +++ b/crates/ui2/src/components/icon.rs @@ -51,6 +51,7 @@ pub enum Icon { CopilotDisabled, Dash, Disconnected, + Ellipsis, Envelope, ExternalLink, ExclamationTriangle, @@ -133,6 +134,7 @@ impl Icon { Icon::CopilotDisabled => "icons/copilot_disabled.svg", Icon::Dash => "icons/dash.svg", Icon::Disconnected => "icons/disconnected.svg", + Icon::Ellipsis => "icons/ellipsis.svg", Icon::Envelope => "icons/feedback.svg", Icon::ExclamationTriangle => "icons/warning.svg", Icon::ExternalLink => "icons/external_link.svg", From a9b1273e2bd9d446bd11b7f35b2792f4ef6b0d53 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 12:06:47 -0800 Subject: [PATCH 160/644] Clean up commented code Co-authored-by: Nathan --- crates/collab_ui2/src/collab_panel.rs | 316 +++----------------------- 1 file changed, 34 insertions(+), 282 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 3df8f06d3b328f287086eef1e048274a8008ca71..b7dd24b9ab5fc0b4eea338316fac95060c468d47 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -1,128 +1,45 @@ mod channel_modal; mod contact_finder; -// use crate::{ -// channel_view::{self, ChannelView}, -// chat_panel::ChatPanel, -// face_pile::FacePile, -// panel_settings, CollaborationPanelSettings, -// }; -// use anyhow::Result; -// use call::ActiveCall; -// use channel::{Channel, ChannelEvent, ChannelId, ChannelStore}; -// use channel_modal::ChannelModal; -// use client::{ -// proto::{self, PeerId}, -// Client, Contact, User, UserStore, -// }; +use self::channel_modal::ChannelModal; +use crate::{ + channel_view::ChannelView, chat_panel::ChatPanel, face_pile::FacePile, + CollaborationPanelSettings, +}; +use call::ActiveCall; +use channel::{Channel, ChannelEvent, ChannelId, ChannelStore}; +use client::{Client, Contact, User, UserStore}; use contact_finder::ContactFinder; +use db::kvp::KEY_VALUE_STORE; +use editor::Editor; +use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt}; +use fuzzy::{match_strings, StringMatchCandidate}; +use gpui::{ + actions, canvas, div, fill, list, overlay, point, prelude::*, px, serde_json, AnyElement, + AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div, EventEmitter, + FocusHandle, Focusable, FocusableView, InteractiveElement, IntoElement, ListOffset, ListState, + Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Render, RenderOnce, + SharedString, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, +}; use menu::{Cancel, Confirm, SelectNext, SelectPrev}; +use project::{Fs, Project}; use rpc::proto::{self, PeerId}; +use serde_derive::{Deserialize, Serialize}; +use settings::{Settings, SettingsStore}; use smallvec::SmallVec; +use std::{mem, sync::Arc}; use theme::{ActiveTheme, ThemeSettings}; -// use context_menu::{ContextMenu, ContextMenuItem}; -// use db::kvp::KEY_VALUE_STORE; -// use drag_and_drop::{DragAndDrop, Draggable}; -// use editor::{Cancel, Editor}; -// use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt}; -// use futures::StreamExt; -// use fuzzy::{match_strings, StringMatchCandidate}; -// use gpui::{ -// actions, -// elements::{ -// Canvas, ChildView, Component, ContainerStyle, Empty, Flex, Image, Label, List, ListOffset, -// ListState, MouseEventHandler, Orientation, OverlayPositionMode, Padding, ParentElement, -// SafeStylable, Stack, Svg, -// }, -// fonts::TextStyle, -// geometry::{ -// rect::RectF, -// vector::{vec2f, Vector2F}, -// }, -// impl_actions, -// platform::{CursorStyle, MouseButton, PromptLevel}, -// serde_json, AnyElement, AppContext, AsyncAppContext, ClipboardItem, Element, Entity, FontCache, -// ModelHandle, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, -// }; -// use menu::{Confirm, SelectNext, SelectPrev}; -// use project::{Fs, Project}; -// use serde_derive::{Deserialize, Serialize}; -// use settings::SettingsStore; -// use std::{borrow::Cow, hash::Hash, mem, sync::Arc}; -// use theme::{components::ComponentExt, IconButton, Interactive}; -// use util::{maybe, ResultExt, TryFutureExt}; -// use workspace::{ -// dock::{DockPosition, Panel}, -// item::ItemHandle, -// FollowNextCollaborator, Workspace, -// }; - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// struct ToggleCollapse { -// location: ChannelId, -// } - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// struct NewChannel { -// location: ChannelId, -// } - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// struct RenameChannel { -// channel_id: ChannelId, -// } - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// struct ToggleSelectedIx { -// ix: usize, -// } - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// struct RemoveChannel { -// channel_id: ChannelId, -// } - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// struct InviteMembers { -// channel_id: ChannelId, -// } - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// struct ManageMembers { -// channel_id: ChannelId, -// } - -#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)] -pub struct OpenChannelNotes { - pub channel_id: ChannelId, -} - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// pub struct JoinChannelCall { -// pub channel_id: u64, -// } - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// pub struct JoinChannelChat { -// pub channel_id: u64, -// } - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// pub struct CopyChannelLink { -// pub channel_id: u64, -// } - -// #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// struct StartMoveChannelFor { -// channel_id: ChannelId, -// } - -// #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// struct MoveChannel { -// to: ChannelId, -// } - -impl_actions!(collab_panel, [OpenChannelNotes]); +use ui::prelude::*; +use ui::{ + h_stack, v_stack, Avatar, Button, Color, ContextMenu, Icon, IconButton, IconElement, IconSize, + Label, ListHeader, ListItem, Tooltip, +}; +use util::{maybe, ResultExt, TryFutureExt}; +use workspace::{ + dock::{DockPosition, Panel, PanelEvent}, + notifications::NotifyResultExt, + Workspace, +}; actions!( collab_panel, @@ -138,25 +55,6 @@ actions!( ] ); -// impl_actions!( -// collab_panel, -// [ -// RemoveChannel, -// NewChannel, -// InviteMembers, -// ManageMembers, -// RenameChannel, -// ToggleCollapse, -// OpenChannelNotes, -// JoinChannelCall, -// JoinChannelChat, -// CopyChannelLink, -// StartMoveChannelFor, -// MoveChannel, -// ToggleSelectedIx -// ] -// ); - #[derive(Debug, Copy, Clone, PartialEq, Eq)] struct ChannelMoveClipboard { channel_id: ChannelId, @@ -164,44 +62,6 @@ struct ChannelMoveClipboard { const COLLABORATION_PANEL_KEY: &'static str = "CollaborationPanel"; -use std::{mem, sync::Arc}; - -use call::ActiveCall; -use channel::{Channel, ChannelEvent, ChannelId, ChannelStore}; -use client::{Client, Contact, User, UserStore}; -use db::kvp::KEY_VALUE_STORE; -use editor::Editor; -use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt}; -use fuzzy::{match_strings, StringMatchCandidate}; -use gpui::{ - actions, canvas, div, fill, impl_actions, list, overlay, point, prelude::*, px, serde_json, - AnyElement, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div, - EventEmitter, FocusHandle, Focusable, FocusableView, InteractiveElement, IntoElement, - ListOffset, ListState, Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, - Render, RenderOnce, SharedString, Styled, Subscription, Task, View, ViewContext, VisualContext, - WeakView, -}; -use project::{Fs, Project}; -use serde_derive::{Deserialize, Serialize}; -use settings::{Settings, SettingsStore}; -use ui::prelude::*; -use ui::{ - h_stack, v_stack, Avatar, Button, Color, ContextMenu, Icon, IconButton, IconElement, IconSize, - Label, ListHeader, ListItem, Tooltip, -}; -use util::{maybe, ResultExt, TryFutureExt}; -use workspace::{ - dock::{DockPosition, Panel, PanelEvent}, - notifications::NotifyResultExt, - Workspace, -}; - -use crate::channel_view::ChannelView; -use crate::chat_panel::ChatPanel; -use crate::{face_pile::FacePile, CollaborationPanelSettings}; - -use self::channel_modal::ChannelModal; - pub fn init(cx: &mut AppContext) { cx.observe_new_views(|workspace: &mut Workspace, _| { workspace.register_action(|workspace, _: &ToggleFocus, cx| { @@ -209,69 +69,6 @@ pub fn init(cx: &mut AppContext) { }); }) .detach(); - // contact_finder::init(cx); - // channel_modal::init(cx); - // channel_view::init(cx); - - // cx.add_action(CollabPanel::cancel); - // cx.add_action(CollabPanel::select_next); - // cx.add_action(CollabPanel::select_prev); - // cx.add_action(CollabPanel::confirm); - // cx.add_action(CollabPanel::insert_space); - // cx.add_action(CollabPanel::remove); - // cx.add_action(CollabPanel::remove_selected_channel); - // cx.add_action(CollabPanel::show_inline_context_menu); - // cx.add_action(CollabPanel::new_subchannel); - // cx.add_action(CollabPanel::invite_members); - // cx.add_action(CollabPanel::manage_members); - // cx.add_action(CollabPanel::rename_selected_channel); - // cx.add_action(CollabPanel::rename_channel); - // cx.add_action(CollabPanel::toggle_channel_collapsed_action); - // cx.add_action(CollabPanel::collapse_selected_channel); - // cx.add_action(CollabPanel::expand_selected_channel); - // cx.add_action(CollabPanel::open_channel_notes); - // cx.add_action(CollabPanel::join_channel_chat); - // cx.add_action(CollabPanel::copy_channel_link); - - // cx.add_action( - // |panel: &mut CollabPanel, action: &ToggleSelectedIx, cx: &mut ViewContext| { - // if panel.selection.take() != Some(action.ix) { - // panel.selection = Some(action.ix) - // } - - // cx.notify(); - // }, - // ); - - // cx.add_action( - // |panel: &mut CollabPanel, _: &MoveSelected, cx: &mut ViewContext| { - // let Some(clipboard) = panel.channel_clipboard.take() else { - // return; - // }; - // let Some(selected_channel) = panel.selected_channel() else { - // return; - // }; - - // panel - // .channel_store - // .update(cx, |channel_store, cx| { - // channel_store.move_channel(clipboard.channel_id, Some(selected_channel.id), cx) - // }) - // .detach_and_log_err(cx) - // }, - // ); - - // cx.add_action( - // |panel: &mut CollabPanel, action: &MoveChannel, cx: &mut ViewContext| { - // if let Some(clipboard) = panel.channel_clipboard.take() { - // panel.channel_store.update(cx, |channel_store, cx| { - // channel_store - // .move_channel(clipboard.channel_id, Some(action.to), cx) - // .detach_and_log_err(cx) - // }) - // } - // }, - // ); } #[derive(Debug)] @@ -317,7 +114,6 @@ pub struct CollabPanel { collapsed_sections: Vec
, collapsed_channels: Vec, workspace: WeakView, - // context_menu_on_selected: bool, } #[derive(Serialize, Deserialize)] @@ -326,13 +122,6 @@ struct SerializedCollabPanel { collapsed_channels: Option>, } -// #[derive(Debug)] -// pub enum Event { -// DockPositionChanged, -// Focus, -// Dismissed, -// } - #[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord)] enum Section { ActiveCall, @@ -1131,40 +920,6 @@ impl CollabPanel { } } - // fn render_contact_placeholder( - // &self, - // theme: &theme::CollabPanel, - // is_selected: bool, - // cx: &mut ViewContext, - // ) -> AnyElement { - // enum AddContacts {} - // MouseEventHandler::new::(0, cx, |state, _| { - // let style = theme.list_empty_state.style_for(is_selected, state); - // Flex::row() - // .with_child( - // Svg::new("icons/plus.svg") - // .with_color(theme.list_empty_icon.color) - // .constrained() - // .with_width(theme.list_empty_icon.width) - // .aligned() - // .left(), - // ) - // .with_child( - // Label::new("Add a contact", style.text.clone()) - // .contained() - // .with_style(theme.list_empty_label_container), - // ) - // .align_children_center() - // .contained() - // .with_style(style.container) - // .into_any() - // }) - // .on_click(MouseButton::Left, |_, this, cx| { - // this.toggle_contact_finder(cx); - // }) - // .into_any() - // } - fn render_channel_notes( &self, channel_id: ChannelId, @@ -1752,9 +1507,6 @@ impl CollabPanel { } } - // // Should move to the filter editor if clicking on it - // // Should move selection to the channel editor if activating it - fn remove_contact(&mut self, user_id: u64, github_login: &str, cx: &mut ViewContext) { let user_store = self.user_store.clone(); let prompt_message = format!( From 7bc9319871d5519369b95a67a5bb4343bb091d2d Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 16:01:03 -0500 Subject: [PATCH 161/644] Apply padding at the toolbar level (#3720) This PR adjusts the padding in the toolbar to be applied within the toolbar itself. Previously the different elements within the toolbar were applying their own padding, which led to inconsistencies. Release Notes: - N/A --- crates/search2/src/buffer_search.rs | 1 - crates/search2/src/project_search.rs | 2 -- crates/workspace2/src/toolbar.rs | 3 ++- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index 17dc13feaa1989f3a3d00be59483f2252ab2afb5..ebaf111e6061c9b9ca032774c9fd1c85f31b552f 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -240,7 +240,6 @@ impl Render for BufferSearchBar { this.on_action(cx.listener(Self::toggle_whole_word)) }) .w_full() - .p_1() .child( h_stack() .flex_1() diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index 4e41c8b5a9e9758312be9df136ce08ce951227a7..af8ac418347a9b5f9e06888dd3bac3e8c4b8a143 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -1716,8 +1716,6 @@ impl Render for ProjectSearchBar { v_stack() .key_context(key_context) .flex_grow() - .p_1() - .m_2() .gap_2() .on_action(cx.listener(|this, _: &ToggleFilters, cx| { this.toggle_filters(cx); diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index 1c60b8967f4b3553905b706b2038e077954be2b3..cd25582f36cbd397688a500e85c0e405865dae63 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -103,6 +103,8 @@ impl Render for Toolbar { let secondary_item = self.secondary_items().next().map(|item| item.to_any()); v_stack() + .p_1() + .gap_2() .border_b() .border_color(cx.theme().colors().border_variant) .bg(cx.theme().colors().toolbar_background) @@ -112,7 +114,6 @@ impl Render for Toolbar { .when(self.left_items().count() > 0, |this| { this.child( h_stack() - .p_1() .flex_1() .justify_start() .children(self.left_items().map(|item| item.to_any())), From a9fe108dbb22b631bc81d24335c72ed295056ef2 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 16:21:58 -0500 Subject: [PATCH 162/644] Fix typo in "Quote Selection" tooltip (#3721) This PR fixes a typo in the "Quote Selection" tooltip. Release Notes: - N/A --- crates/assistant2/src/assistant_panel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index ec67d684da92fc85be4fcb5efecc040c783901ed..7b15619758679b5e9246780813de63f0f1371261 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -990,7 +990,7 @@ impl AssistantPanel { } })) .icon_size(IconSize::Small) - .tooltip(|cx| Tooltip::for_action("Quote Seleciton", &QuoteSelection, cx)) + .tooltip(|cx| Tooltip::for_action("Quote Selection", &QuoteSelection, cx)) } fn render_plus_button(cx: &mut ViewContext) -> impl IntoElement { From 825a8f0927c17baa14b67c8d5ea1d212e2294350 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 18 Dec 2023 19:15:54 +0200 Subject: [PATCH 163/644] Initial fix of the z-index Co-Authored-By: Antonio Scandurra Co-Authored-By: Nathan Sobo --- crates/gpui2/src/elements/div.rs | 12 +- crates/gpui2/src/scene.rs | 165 ++++++++++++++------ crates/gpui2/src/window.rs | 75 +++++++-- crates/ui2/src/components/list/list_item.rs | 4 +- crates/workspace2/src/toolbar.rs | 2 + 5 files changed, 187 insertions(+), 71 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 0d477fc62d76c1c24371ad811f6e8143b05f627c..6e9c95e19f4268e929a09d8eae671ebf7831fcff 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1447,9 +1447,15 @@ impl Interactivity { cx.on_action(action_type, listener) } - f(style, scroll_offset.unwrap_or_default(), cx) - }, - ); + cx.with_z_index(style.z_index.unwrap_or(0), |cx| { + if style.background.as_ref().is_some_and(|fill| { + fill.color().is_some_and(|color| !color.is_transparent()) + }) { + cx.add_opaque_layer(bounds) + }f(style, scroll_offset.unwrap_or_default(), cx) + }) + }, + ); if let Some(group) = self.group.as_ref() { GroupBounds::pop(group, cx); diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index 68c068dfe98473872024097d3ca1745866fc66eb..15a4a37d5b1b6d67e0d6be53e75a6e2a772e1d1c 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -857,55 +857,116 @@ impl Bounds { } } -// #[cfg(test)] -// mod tests { -// use crate::{point, size}; - -// use super::*; -// use smallvec::smallvec; - -// #[test] -// fn test_scene() { -// let mut scene = SceneBuilder::new(); -// assert_eq!(scene.layers_by_order.len(), 0); - -// scene.insert(&smallvec![1].into(), quad()); -// scene.insert(&smallvec![2].into(), shadow()); -// scene.insert(&smallvec![3].into(), quad()); - -// let mut batches_count = 0; -// for _ in scene.build().batches() { -// batches_count += 1; -// } -// assert_eq!(batches_count, 3); -// } - -// fn quad() -> Quad { -// Quad { -// order: 0, -// bounds: Bounds { -// origin: point(ScaledPixels(0.), ScaledPixels(0.)), -// size: size(ScaledPixels(100.), ScaledPixels(100.)), -// }, -// content_mask: Default::default(), -// background: Default::default(), -// border_color: Default::default(), -// corner_radii: Default::default(), -// border_widths: Default::default(), -// } -// } - -// fn shadow() -> Shadow { -// Shadow { -// order: Default::default(), -// bounds: Bounds { -// origin: point(ScaledPixels(0.), ScaledPixels(0.)), -// size: size(ScaledPixels(100.), ScaledPixels(100.)), -// }, -// corner_radii: Default::default(), -// content_mask: Default::default(), -// color: Default::default(), -// blur_radius: Default::default(), -// } -// } -// } +#[cfg(test)] +mod tests { + use super::*; + use crate::{point, px, size, Size}; + use smallvec::smallvec; + + // todo!() + // #[test] + // fn test_scene() { + // let mut scene = SceneBuilder::default(); + // assert_eq!(scene.layers_by_order.len(), 0); + + // // div with z_index(1) + // // glyph with z_index(1) + // // div with z_index(1) + // // glyph with z_index(1) + + // scene.insert( + // &smallvec![1].into(), + // quad( + // point(px(0.), px(0.)), + // size(px(100.), px(100.)), + // crate::black(), + // ), + // ); + // scene.insert( + // &smallvec![1, 1].into(), + // sprite( + // point(px(0.), px(0.)), + // size(px(10.), px(10.)), + // crate::white(), + // ), + // ); + // scene.insert( + // &smallvec![1].into(), + // quad( + // point(px(10.), px(10.)), + // size(px(20.), px(20.)), + // crate::green(), + // ), + // ); + // scene.insert( + // &smallvec![1, 1].into(), + // sprite(point(px(15.), px(15.)), size(px(5.), px(5.)), crate::blue()), + // ); + + // assert!(!scene.layers_by_order.is_empty()); + + // for batch in scene.build().batches() { + // println!("new batch"); + // match batch { + // PrimitiveBatch::Quads(quads) => { + // for quad in quads { + // if quad.background == crate::black() { + // println!(" black quad"); + // } else if quad.background == crate::green() { + // println!(" green quad"); + // } else { + // todo!(" ((( bad quad"); + // } + // } + // } + // PrimitiveBatch::MonochromeSprites { sprites, .. } => { + // for sprite in sprites { + // if sprite.color == crate::white() { + // println!(" white sprite"); + // } else if sprite.color == crate::blue() { + // println!(" blue sprite"); + // } else { + // todo!(" ((( bad sprite") + // } + // } + // } + // _ => todo!(), + // } + // } + // } + + fn quad(origin: Point, size: Size, background: Hsla) -> Quad { + Quad { + order: 0, + bounds: Bounds { origin, size }.scale(1.), + background, + content_mask: ContentMask { + bounds: Bounds { origin, size }, + } + .scale(1.), + border_color: Default::default(), + corner_radii: Default::default(), + border_widths: Default::default(), + } + } + + fn sprite(origin: Point, size: Size, color: Hsla) -> MonochromeSprite { + MonochromeSprite { + order: 0, + bounds: Bounds { origin, size }.scale(1.), + content_mask: ContentMask { + bounds: Bounds { origin, size }, + } + .scale(1.), + color, + tile: AtlasTile { + texture_id: AtlasTextureId { + index: 0, + kind: crate::AtlasTextureKind::Monochrome, + }, + tile_id: crate::TileId(0), + bounds: Default::default(), + }, + } + } +} diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index f7ebddd0fea2b725e45d798b1a75e1d76ed3b5f7..5d06cfe1a540a2e931e6295504f3235f7e6ba5fd 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -39,24 +39,36 @@ use std::{ Arc, }, }; -use util::ResultExt; +use util::{post_inc, ResultExt}; const ACTIVE_DRAG_Z_INDEX: u8 = 1; /// A global stacking order, which is created by stacking successive z-index values. /// Each z-index will always be interpreted in the context of its parent z-index. -#[derive(Deref, DerefMut, Clone, Debug, Ord, PartialOrd, PartialEq, Eq)] +#[derive(Deref, DerefMut, Clone, Ord, PartialOrd, PartialEq, Eq, Default)] pub struct StackingOrder { #[deref] #[deref_mut] - z_indices: SmallVec<[u8; 64]>, + context_stack: SmallVec<[StackingContext; 64]>, } -impl Default for StackingOrder { - fn default() -> Self { - StackingOrder { - z_indices: SmallVec::new(), +#[derive(Clone, Ord, PartialOrd, PartialEq, Eq)] +pub struct StackingContext { + // TODO kb use u16 and/or try to push the `id` above into the stacking order + z_index: u8, + id: u16, +} + +impl std::fmt::Debug for StackingOrder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut stacks = self.context_stack.iter().peekable(); + while let Some(z_index) = stacks.next() { + write!(f, "{}.{}", z_index.z_index, z_index.id)?; + if stacks.peek().is_some() { + write!(f, "->")?; + } } + Ok(()) } } @@ -284,6 +296,7 @@ pub(crate) struct Frame { pub(crate) scene_builder: SceneBuilder, pub(crate) depth_map: Vec<(StackingOrder, Bounds)>, pub(crate) z_index_stack: StackingOrder, + pub(crate) stacking_context_id_stack: Vec, content_mask_stack: Vec>, element_offset_stack: Vec>, } @@ -297,6 +310,7 @@ impl Frame { dispatch_tree, scene_builder: SceneBuilder::default(), z_index_stack: StackingOrder::default(), + stacking_context_id_stack: vec![0], depth_map: Default::default(), content_mask_stack: Vec::new(), element_offset_stack: Vec::new(), @@ -308,6 +322,8 @@ impl Frame { self.mouse_listeners.values_mut().for_each(Vec::clear); self.dispatch_tree.clear(); self.depth_map.clear(); + self.stacking_context_id_stack.clear(); + self.stacking_context_id_stack.push(0); } fn focus_path(&self) -> SmallVec<[FocusId; 8]> { @@ -931,8 +947,20 @@ impl<'a> WindowContext<'a> { /// Called during painting to invoke the given closure in a new stacking context. The given /// z-index is interpreted relative to the previous call to `stack`. pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - self.window.next_frame.z_index_stack.push(z_index); + let id = post_inc( + self.window + .next_frame + .stacking_context_id_stack + .last_mut() + .unwrap(), + ); + self.window.next_frame.stacking_context_id_stack.push(0); + self.window + .next_frame + .z_index_stack + .push(StackingContext { z_index, id }); let result = f(self); + self.window.next_frame.stacking_context_id_stack.pop(); self.window.next_frame.z_index_stack.pop(); result } @@ -2046,6 +2074,30 @@ pub trait BorrowWindow: BorrowMut + BorrowMut { result } + /// Called during painting to invoke the given closure in a new stacking context. The given + /// z-index is interpreted relative to the previous call to `stack`. + fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { + let id = post_inc( + self.window_mut() + .next_frame + .stacking_context_id_stack + .last_mut() + .unwrap(), + ); + self.window_mut() + .next_frame + .stacking_context_id_stack + .push(0); + self.window_mut() + .next_frame + .z_index_stack + .push(StackingContext { z_index, id }); + let result = f(self); + self.window_mut().next_frame.stacking_context_id_stack.pop(); + self.window_mut().next_frame.z_index_stack.pop(); + result + } + /// Update the global element offset relative to the current offset. This is used to implement /// scrolling. fn with_element_offset( @@ -2269,13 +2321,6 @@ impl<'a, V: 'static> ViewContext<'a, V> { &mut self.window_cx } - pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - self.window.next_frame.z_index_stack.push(z_index); - let result = f(self); - self.window.next_frame.z_index_stack.pop(); - result - } - pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext) + 'static) where V: 'static, diff --git a/crates/ui2/src/components/list/list_item.rs b/crates/ui2/src/components/list/list_item.rs index bdb5c2b854f2cfb7a04cbd70334d81a4daab98c4..a6f99350534c7767baf73f1758c4b7c2e6c5ace4 100644 --- a/crates/ui2/src/components/list/list_item.rs +++ b/crates/ui2/src/components/list/list_item.rs @@ -129,6 +129,7 @@ impl RenderOnce for ListItem { fn render(self, cx: &mut WindowContext) -> Self::Rendered { h_stack() .id(self.id) + .bg(gpui::green()) .w_full() .relative() // When an item is inset draw the indent spacing outside of the item @@ -171,7 +172,8 @@ impl RenderOnce for ListItem { }) }) .when_some(self.on_click, |this, on_click| { - this.cursor_pointer().on_click(on_click) + this.cursor_copy() + .on_click(move |event, cx| on_click(dbg!(event), cx)) }) .when_some(self.on_secondary_mouse_down, |this, on_mouse_down| { this.on_mouse_down(MouseButton::Right, move |event, cx| { diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index cd25582f36cbd397688a500e85c0e405865dae63..f83879a64ed5536f1602571c00e59dd1a18bc611 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -105,6 +105,8 @@ impl Render for Toolbar { v_stack() .p_1() .gap_2() + // todo!() use a proper constant here (ask Marshall & Nate) + .z_index(80) .border_b() .border_color(cx.theme().colors().border_variant) .bg(cx.theme().colors().toolbar_background) From 8f1c5375efa1ee8829f18755391da59d3b1cbaf8 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 19 Dec 2023 12:30:57 +0200 Subject: [PATCH 164/644] Fix more z-index and rendering issues Co-Authored-By: Antonio Scandurra --- crates/collab_ui2/src/collab_titlebar_item.rs | 1 + crates/ui2/src/components/context_menu.rs | 36 ++++++++++++++----- crates/ui2/src/components/list/list_item.rs | 5 ++- crates/ui2/src/components/tab_bar.rs | 1 + 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 023b77ab8f340a8f46e306aa0578c4037090cdd0..914e5c7bb64b08c9dc45337df8af4a78b9255aeb 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -68,6 +68,7 @@ impl Render for CollabTitlebarItem { h_stack() .id("titlebar") + .z_index(160) .justify_between() .w_full() .h(rems(1.75)) diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 8fce15d1c69d0fcf97f8ac1757874be4884950b6..84c66f3534e05da1f55b3dc7630aa6871bee8313 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -3,8 +3,8 @@ use crate::{ ListSeparator, ListSubHeader, }; use gpui::{ - px, Action, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, - IntoElement, Render, Subscription, View, VisualContext, + px, Action, AnyElement, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, + FocusableView, IntoElement, Render, Subscription, View, VisualContext, }; use menu::{SelectFirst, SelectLast, SelectNext, SelectPrev}; use std::{rc::Rc, time::Duration}; @@ -18,6 +18,9 @@ pub enum ContextMenuItem { handler: Rc, action: Option>, }, + CustomEntry { + entry_render: Box AnyElement>, + }, } pub struct ContextMenu { @@ -83,6 +86,16 @@ impl ContextMenu { self } + pub fn custom_entry( + mut self, + entry_render: impl Fn(&mut WindowContext) -> AnyElement + 'static, + ) -> Self { + self.items.push(ContextMenuItem::CustomEntry { + entry_render: Box::new(entry_render), + }); + self + } + pub fn action(mut self, label: impl Into, action: Box) -> Self { self.items.push(ContextMenuItem::Entry { label: label.into(), @@ -230,9 +243,9 @@ impl Render for ContextMenu { el }) .flex_none() - .child( - List::new().children(self.items.iter().enumerate().map( - |(ix, item)| match item { + .child(List::new().children(self.items.iter_mut().enumerate().map( + |(ix, item)| { + match item { ContextMenuItem::Separator => ListSeparator.into_any_element(), ContextMenuItem::Header(header) => { ListSubHeader::new(header.clone()).into_any_element() @@ -255,7 +268,7 @@ impl Render for ContextMenu { Label::new(label.clone()).into_any_element() }; - ListItem::new(label.clone()) + ListItem::new(ix) .inset(true) .selected(Some(ix) == self.selected_index) .on_click(move |_, cx| handler(cx)) @@ -271,9 +284,14 @@ impl Render for ContextMenu { ) .into_any_element() } - }, - )), - ), + ContextMenuItem::CustomEntry { entry_render } => ListItem::new(ix) + .inset(true) + .selected(Some(ix) == self.selected_index) + .child(entry_render(cx)) + .into_any_element(), + } + }, + ))), ) } } diff --git a/crates/ui2/src/components/list/list_item.rs b/crates/ui2/src/components/list/list_item.rs index a6f99350534c7767baf73f1758c4b7c2e6c5ace4..e8689030c36220894c1de3c0ea258fbb7f4e8246 100644 --- a/crates/ui2/src/components/list/list_item.rs +++ b/crates/ui2/src/components/list/list_item.rs @@ -129,7 +129,6 @@ impl RenderOnce for ListItem { fn render(self, cx: &mut WindowContext) -> Self::Rendered { h_stack() .id(self.id) - .bg(gpui::green()) .w_full() .relative() // When an item is inset draw the indent spacing outside of the item @@ -172,8 +171,8 @@ impl RenderOnce for ListItem { }) }) .when_some(self.on_click, |this, on_click| { - this.cursor_copy() - .on_click(move |event, cx| on_click(dbg!(event), cx)) + this.cursor_pointer() + .on_click(move |event, cx| on_click(event, cx)) }) .when_some(self.on_secondary_mouse_down, |this, on_mouse_down| { this.on_mouse_down(MouseButton::Right, move |event, cx| { diff --git a/crates/ui2/src/components/tab_bar.rs b/crates/ui2/src/components/tab_bar.rs index 7cff2f51bd80f4dc38df6b9e2423d1627024ea33..b10ffd1c630a3b0099190235328bbc43f8564854 100644 --- a/crates/ui2/src/components/tab_bar.rs +++ b/crates/ui2/src/components/tab_bar.rs @@ -96,6 +96,7 @@ impl RenderOnce for TabBar { div() .id(self.id) + .z_index(120) .group("tab_bar") .flex() .flex_none() From f6d31917c15d1328991ccae317964190b309f1ff Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 19 Dec 2023 17:05:39 +0200 Subject: [PATCH 165/644] Optimize stack id in-memory layout --- crates/gpui2/src/scene.rs | 226 ++++++++++++++++++------------------- crates/gpui2/src/window.rs | 66 ++++------- 2 files changed, 136 insertions(+), 156 deletions(-) diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index 15a4a37d5b1b6d67e0d6be53e75a6e2a772e1d1c..517632ed79d0f21d880502c0a92385aa01692ecf 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -857,116 +857,116 @@ impl Bounds { } } -#[cfg(test)] -mod tests { - use super::*; - use crate::{point, px, size, Size}; - use smallvec::smallvec; - - // todo!() - // #[test] - // fn test_scene() { - // let mut scene = SceneBuilder::default(); - // assert_eq!(scene.layers_by_order.len(), 0); - - // // div with z_index(1) - // // glyph with z_index(1) - // // div with z_index(1) - // // glyph with z_index(1) - - // scene.insert( - // &smallvec![1].into(), - // quad( - // point(px(0.), px(0.)), - // size(px(100.), px(100.)), - // crate::black(), - // ), - // ); - // scene.insert( - // &smallvec![1, 1].into(), - // sprite( - // point(px(0.), px(0.)), - // size(px(10.), px(10.)), - // crate::white(), - // ), - // ); - // scene.insert( - // &smallvec![1].into(), - // quad( - // point(px(10.), px(10.)), - // size(px(20.), px(20.)), - // crate::green(), - // ), - // ); - // scene.insert( - // &smallvec![1, 1].into(), - // sprite(point(px(15.), px(15.)), size(px(5.), px(5.)), crate::blue()), - // ); - - // assert!(!scene.layers_by_order.is_empty()); - - // for batch in scene.build().batches() { - // println!("new batch"); - // match batch { - // PrimitiveBatch::Quads(quads) => { - // for quad in quads { - // if quad.background == crate::black() { - // println!(" black quad"); - // } else if quad.background == crate::green() { - // println!(" green quad"); - // } else { - // todo!(" ((( bad quad"); - // } - // } - // } - // PrimitiveBatch::MonochromeSprites { sprites, .. } => { - // for sprite in sprites { - // if sprite.color == crate::white() { - // println!(" white sprite"); - // } else if sprite.color == crate::blue() { - // println!(" blue sprite"); - // } else { - // todo!(" ((( bad sprite") - // } - // } - // } - // _ => todo!(), - // } - // } - // } - - fn quad(origin: Point, size: Size, background: Hsla) -> Quad { - Quad { - order: 0, - bounds: Bounds { origin, size }.scale(1.), - background, - content_mask: ContentMask { - bounds: Bounds { origin, size }, - } - .scale(1.), - border_color: Default::default(), - corner_radii: Default::default(), - border_widths: Default::default(), - } - } - - fn sprite(origin: Point, size: Size, color: Hsla) -> MonochromeSprite { - MonochromeSprite { - order: 0, - bounds: Bounds { origin, size }.scale(1.), - content_mask: ContentMask { - bounds: Bounds { origin, size }, - } - .scale(1.), - color, - tile: AtlasTile { - texture_id: AtlasTextureId { - index: 0, - kind: crate::AtlasTextureKind::Monochrome, - }, - tile_id: crate::TileId(0), - bounds: Default::default(), - }, - } - } -} +// todo!() +// #[cfg(test)] +// mod tests { +// use super::*; +// use crate::{point, px, size, Size}; +// use smallvec::smallvec; + +// #[test] +// fn test_scene() { +// let mut scene = SceneBuilder::default(); +// assert_eq!(scene.layers_by_order.len(), 0); + +// // div with z_index(1) +// // glyph with z_index(1) +// // div with z_index(1) +// // glyph with z_index(1) + +// scene.insert( +// &smallvec![1].into(), +// quad( +// point(px(0.), px(0.)), +// size(px(100.), px(100.)), +// crate::black(), +// ), +// ); +// scene.insert( +// &smallvec![1, 1].into(), +// sprite( +// point(px(0.), px(0.)), +// size(px(10.), px(10.)), +// crate::white(), +// ), +// ); +// scene.insert( +// &smallvec![1].into(), +// quad( +// point(px(10.), px(10.)), +// size(px(20.), px(20.)), +// crate::green(), +// ), +// ); +// scene.insert( +// &smallvec![1, 1].into(), +// sprite(point(px(15.), px(15.)), size(px(5.), px(5.)), crate::blue()), +// ); + +// assert!(!scene.layers_by_order.is_empty()); + +// for batch in scene.build().batches() { +// println!("new batch"); +// match batch { +// PrimitiveBatch::Quads(quads) => { +// for quad in quads { +// if quad.background == crate::black() { +// println!(" black quad"); +// } else if quad.background == crate::green() { +// println!(" green quad"); +// } else { +// todo!(" ((( bad quad"); +// } +// } +// } +// PrimitiveBatch::MonochromeSprites { sprites, .. } => { +// for sprite in sprites { +// if sprite.color == crate::white() { +// println!(" white sprite"); +// } else if sprite.color == crate::blue() { +// println!(" blue sprite"); +// } else { +// todo!(" ((( bad sprite") +// } +// } +// } +// _ => todo!(), +// } +// } +// } + +// fn quad(origin: Point, size: Size, background: Hsla) -> Quad { +// Quad { +// order: 0, +// bounds: Bounds { origin, size }.scale(1.), +// background, +// content_mask: ContentMask { +// bounds: Bounds { origin, size }, +// } +// .scale(1.), +// border_color: Default::default(), +// corner_radii: Default::default(), +// border_widths: Default::default(), +// } +// } + +// fn sprite(origin: Point, size: Size, color: Hsla) -> MonochromeSprite { +// MonochromeSprite { +// order: 0, +// bounds: Bounds { origin, size }.scale(1.), +// content_mask: ContentMask { +// bounds: Bounds { origin, size }, +// } +// .scale(1.), +// color, +// tile: AtlasTile { +// texture_id: AtlasTextureId { +// index: 0, +// kind: crate::AtlasTextureKind::Monochrome, +// }, +// tile_id: crate::TileId(0), +// bounds: Default::default(), +// }, +// } +// } +// } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 5d06cfe1a540a2e931e6295504f3235f7e6ba5fd..ddda9f030267a504f44cf1518b6f5ba865f0e3d2 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -39,7 +39,7 @@ use std::{ Arc, }, }; -use util::{post_inc, ResultExt}; +use util::ResultExt; const ACTIVE_DRAG_Z_INDEX: u8 = 1; @@ -49,25 +49,21 @@ const ACTIVE_DRAG_Z_INDEX: u8 = 1; pub struct StackingOrder { #[deref] #[deref_mut] - context_stack: SmallVec<[StackingContext; 64]>, -} - -#[derive(Clone, Ord, PartialOrd, PartialEq, Eq)] -pub struct StackingContext { - // TODO kb use u16 and/or try to push the `id` above into the stacking order - z_index: u8, - id: u16, + context_stack: SmallVec<[u8; 64]>, + id: u32, } impl std::fmt::Debug for StackingOrder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut stacks = self.context_stack.iter().peekable(); + write!(f, "[({}): ", self.id)?; while let Some(z_index) = stacks.next() { - write!(f, "{}.{}", z_index.z_index, z_index.id)?; + write!(f, "{z_index}")?; if stacks.peek().is_some() { write!(f, "->")?; } } + write!(f, "]")?; Ok(()) } } @@ -296,7 +292,7 @@ pub(crate) struct Frame { pub(crate) scene_builder: SceneBuilder, pub(crate) depth_map: Vec<(StackingOrder, Bounds)>, pub(crate) z_index_stack: StackingOrder, - pub(crate) stacking_context_id_stack: Vec, + pub(crate) next_stacking_order_id: u32, content_mask_stack: Vec>, element_offset_stack: Vec>, } @@ -310,7 +306,7 @@ impl Frame { dispatch_tree, scene_builder: SceneBuilder::default(), z_index_stack: StackingOrder::default(), - stacking_context_id_stack: vec![0], + next_stacking_order_id: 0, depth_map: Default::default(), content_mask_stack: Vec::new(), element_offset_stack: Vec::new(), @@ -322,8 +318,7 @@ impl Frame { self.mouse_listeners.values_mut().for_each(Vec::clear); self.dispatch_tree.clear(); self.depth_map.clear(); - self.stacking_context_id_stack.clear(); - self.stacking_context_id_stack.push(0); + self.next_stacking_order_id = 0; } fn focus_path(&self) -> SmallVec<[FocusId; 8]> { @@ -947,20 +942,14 @@ impl<'a> WindowContext<'a> { /// Called during painting to invoke the given closure in a new stacking context. The given /// z-index is interpreted relative to the previous call to `stack`. pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - let id = post_inc( - self.window - .next_frame - .stacking_context_id_stack - .last_mut() - .unwrap(), - ); - self.window.next_frame.stacking_context_id_stack.push(0); - self.window - .next_frame - .z_index_stack - .push(StackingContext { z_index, id }); + let new_stacking_order_id = self.window.next_frame.next_stacking_order_id; + let new_next_stacking_order_id = new_stacking_order_id + 1; + + self.window.next_frame.next_stacking_order_id = 0; + self.window.next_frame.z_index_stack.id = new_stacking_order_id; + self.window.next_frame.z_index_stack.push(z_index); let result = f(self); - self.window.next_frame.stacking_context_id_stack.pop(); + self.window.next_frame.next_stacking_order_id = new_next_stacking_order_id; self.window.next_frame.z_index_stack.pop(); result } @@ -2077,23 +2066,14 @@ pub trait BorrowWindow: BorrowMut + BorrowMut { /// Called during painting to invoke the given closure in a new stacking context. The given /// z-index is interpreted relative to the previous call to `stack`. fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - let id = post_inc( - self.window_mut() - .next_frame - .stacking_context_id_stack - .last_mut() - .unwrap(), - ); - self.window_mut() - .next_frame - .stacking_context_id_stack - .push(0); - self.window_mut() - .next_frame - .z_index_stack - .push(StackingContext { z_index, id }); + let new_stacking_order_id = self.window_mut().next_frame.next_stacking_order_id; + let new_next_stacking_order_id = new_stacking_order_id + 1; + + self.window_mut().next_frame.next_stacking_order_id = 0; + self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id; + self.window_mut().next_frame.z_index_stack.push(z_index); let result = f(self); - self.window_mut().next_frame.stacking_context_id_stack.pop(); + self.window_mut().next_frame.next_stacking_order_id = new_next_stacking_order_id; self.window_mut().next_frame.z_index_stack.pop(); result } From 097640e7c5b81e3bad28b98fa81e99ae6c364439 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 16:32:57 -0500 Subject: [PATCH 166/644] Fix typo in `ButtonCommon` doc comment (#3722) This PR fixes a small typo in the doc comments for `ButtonCommon`. Was waiting to roll this up into another PR, but it never ended up happening. Release Notes: - N/A --- crates/ui2/src/components/button/button_like.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ui2/src/components/button/button_like.rs b/crates/ui2/src/components/button/button_like.rs index bd4e9cd523d7d4f407f07e9cb501dc53e6f2aad7..19fa2b48a4c4768473df078c161873a55d488498 100644 --- a/crates/ui2/src/components/button/button_like.rs +++ b/crates/ui2/src/components/button/button_like.rs @@ -10,7 +10,7 @@ pub trait ButtonCommon: Clickable + Disableable { /// The visual style of the button. /// - /// Mosty commonly will be [`ButtonStyle::Subtle`], or [`ButtonStyle::Filled`] + /// Most commonly will be [`ButtonStyle::Subtle`], or [`ButtonStyle::Filled`] /// for an emphasized button. fn style(self, style: ButtonStyle) -> Self; From cf12d62fc5283ba0c0c2f8c482ef9a2cc20e704a Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 19 Dec 2023 23:36:32 +0200 Subject: [PATCH 167/644] Tidy up z-index handling Co-Authored-By: Antonio Scandurra --- crates/collab_ui2/src/collab_titlebar_item.rs | 2 +- crates/gpui2/src/elements/div.rs | 17 +-- crates/gpui2/src/elements/img.rs | 2 +- crates/gpui2/src/scene.rs | 114 ------------------ crates/gpui2/src/window.rs | 24 +--- crates/terminal_view2/src/terminal_element.rs | 10 +- crates/ui2/src/components/context_menu.rs | 36 ++---- crates/ui2/src/components/list/list_item.rs | 3 +- crates/ui2/src/components/tab_bar.rs | 2 +- crates/workspace2/src/toolbar.rs | 3 +- 10 files changed, 31 insertions(+), 182 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 914e5c7bb64b08c9dc45337df8af4a78b9255aeb..17ee5087bb0e4ec28771e8d4a1cef7616f790a6e 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -68,7 +68,7 @@ impl Render for CollabTitlebarItem { h_stack() .id("titlebar") - .z_index(160) + .z_index(160) // todo!("z-index") .justify_between() .w_full() .h(rems(1.75)) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 6e9c95e19f4268e929a09d8eae671ebf7831fcff..57fd3d6a8af274d305d37dbc4d2d62baba8ccbd3 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1448,14 +1448,15 @@ impl Interactivity { } cx.with_z_index(style.z_index.unwrap_or(0), |cx| { - if style.background.as_ref().is_some_and(|fill| { - fill.color().is_some_and(|color| !color.is_transparent()) - }) { - cx.add_opaque_layer(bounds) - }f(style, scroll_offset.unwrap_or_default(), cx) - }) - }, - ); + if style.background.as_ref().is_some_and(|fill| { + fill.color().is_some_and(|color| !color.is_transparent()) + }) { + cx.add_opaque_layer(bounds) + } + f(style, scroll_offset.unwrap_or_default(), cx) + }) + }, + ); if let Some(group) = self.group.as_ref() { GroupBounds::pop(group, cx); diff --git a/crates/gpui2/src/elements/img.rs b/crates/gpui2/src/elements/img.rs index 4f81f604c8d3799923b9fb76742019cb1724c0b5..ab7b8d914094b677b647123074883611665d263b 100644 --- a/crates/gpui2/src/elements/img.rs +++ b/crates/gpui2/src/elements/img.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use crate::{ - point, size, Bounds, DevicePixels, Element, ImageData, InteractiveElement, + point, size, BorrowWindow, Bounds, DevicePixels, Element, ImageData, InteractiveElement, InteractiveElementState, Interactivity, IntoElement, LayoutId, Pixels, SharedString, Size, StyleRefinement, Styled, WindowContext, }; diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index 517632ed79d0f21d880502c0a92385aa01692ecf..811b2b6e30897f4fe23913e879608c02a26b98bd 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -856,117 +856,3 @@ impl Bounds { .expect("Polygon should not be empty") } } - -// todo!() -// #[cfg(test)] -// mod tests { -// use super::*; -// use crate::{point, px, size, Size}; -// use smallvec::smallvec; - -// #[test] -// fn test_scene() { -// let mut scene = SceneBuilder::default(); -// assert_eq!(scene.layers_by_order.len(), 0); - -// // div with z_index(1) -// // glyph with z_index(1) -// // div with z_index(1) -// // glyph with z_index(1) - -// scene.insert( -// &smallvec![1].into(), -// quad( -// point(px(0.), px(0.)), -// size(px(100.), px(100.)), -// crate::black(), -// ), -// ); -// scene.insert( -// &smallvec![1, 1].into(), -// sprite( -// point(px(0.), px(0.)), -// size(px(10.), px(10.)), -// crate::white(), -// ), -// ); -// scene.insert( -// &smallvec![1].into(), -// quad( -// point(px(10.), px(10.)), -// size(px(20.), px(20.)), -// crate::green(), -// ), -// ); -// scene.insert( -// &smallvec![1, 1].into(), -// sprite(point(px(15.), px(15.)), size(px(5.), px(5.)), crate::blue()), -// ); - -// assert!(!scene.layers_by_order.is_empty()); - -// for batch in scene.build().batches() { -// println!("new batch"); -// match batch { -// PrimitiveBatch::Quads(quads) => { -// for quad in quads { -// if quad.background == crate::black() { -// println!(" black quad"); -// } else if quad.background == crate::green() { -// println!(" green quad"); -// } else { -// todo!(" ((( bad quad"); -// } -// } -// } -// PrimitiveBatch::MonochromeSprites { sprites, .. } => { -// for sprite in sprites { -// if sprite.color == crate::white() { -// println!(" white sprite"); -// } else if sprite.color == crate::blue() { -// println!(" blue sprite"); -// } else { -// todo!(" ((( bad sprite") -// } -// } -// } -// _ => todo!(), -// } -// } -// } - -// fn quad(origin: Point, size: Size, background: Hsla) -> Quad { -// Quad { -// order: 0, -// bounds: Bounds { origin, size }.scale(1.), -// background, -// content_mask: ContentMask { -// bounds: Bounds { origin, size }, -// } -// .scale(1.), -// border_color: Default::default(), -// corner_radii: Default::default(), -// border_widths: Default::default(), -// } -// } - -// fn sprite(origin: Point, size: Size, color: Hsla) -> MonochromeSprite { -// MonochromeSprite { -// order: 0, -// bounds: Bounds { origin, size }.scale(1.), -// content_mask: ContentMask { -// bounds: Bounds { origin, size }, -// } -// .scale(1.), -// color, -// tile: AtlasTile { -// texture_id: AtlasTextureId { -// index: 0, -// kind: crate::AtlasTextureKind::Monochrome, -// }, -// tile_id: crate::TileId(0), -// bounds: Default::default(), -// }, -// } -// } -// } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index ddda9f030267a504f44cf1518b6f5ba865f0e3d2..1b2669b40c5cc4d95018ab6ec4a827d551b79dac 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -39,7 +39,7 @@ use std::{ Arc, }, }; -use util::ResultExt; +use util::{post_inc, ResultExt}; const ACTIVE_DRAG_Z_INDEX: u8 = 1; @@ -939,21 +939,6 @@ impl<'a> WindowContext<'a> { self.window.requested_cursor_style = Some(style) } - /// Called during painting to invoke the given closure in a new stacking context. The given - /// z-index is interpreted relative to the previous call to `stack`. - pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - let new_stacking_order_id = self.window.next_frame.next_stacking_order_id; - let new_next_stacking_order_id = new_stacking_order_id + 1; - - self.window.next_frame.next_stacking_order_id = 0; - self.window.next_frame.z_index_stack.id = new_stacking_order_id; - self.window.next_frame.z_index_stack.push(z_index); - let result = f(self); - self.window.next_frame.next_stacking_order_id = new_next_stacking_order_id; - self.window.next_frame.z_index_stack.pop(); - result - } - /// Called during painting to track which z-index is on top at each pixel position pub fn add_opaque_layer(&mut self, bounds: Bounds) { let stacking_order = self.window.next_frame.z_index_stack.clone(); @@ -2066,14 +2051,11 @@ pub trait BorrowWindow: BorrowMut + BorrowMut { /// Called during painting to invoke the given closure in a new stacking context. The given /// z-index is interpreted relative to the previous call to `stack`. fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - let new_stacking_order_id = self.window_mut().next_frame.next_stacking_order_id; - let new_next_stacking_order_id = new_stacking_order_id + 1; - - self.window_mut().next_frame.next_stacking_order_id = 0; + let new_stacking_order_id = + post_inc(&mut self.window_mut().next_frame.next_stacking_order_id); self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id; self.window_mut().next_frame.z_index_stack.push(z_index); let result = f(self); - self.window_mut().next_frame.next_stacking_order_id = new_next_stacking_order_id; self.window_mut().next_frame.z_index_stack.pop(); result } diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index e9335a4220312d33eeb1fcab4670661d3f037ba3..07910896f31320d108e45490e3aab70c06a76fb1 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -1,11 +1,11 @@ use editor::{Cursor, HighlightedRange, HighlightedRangeLine}; use gpui::{ black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace, - Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, FontStyle, - FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, Interactivity, - IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels, - PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled, - TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, + BorrowWindow, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, + FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, + Interactivity, IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, + Pixels, PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, + Styled, TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, }; use itertools::Itertools; use language::CursorShape; diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 84c66f3534e05da1f55b3dc7630aa6871bee8313..8fce15d1c69d0fcf97f8ac1757874be4884950b6 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -3,8 +3,8 @@ use crate::{ ListSeparator, ListSubHeader, }; use gpui::{ - px, Action, AnyElement, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, - FocusableView, IntoElement, Render, Subscription, View, VisualContext, + px, Action, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, + IntoElement, Render, Subscription, View, VisualContext, }; use menu::{SelectFirst, SelectLast, SelectNext, SelectPrev}; use std::{rc::Rc, time::Duration}; @@ -18,9 +18,6 @@ pub enum ContextMenuItem { handler: Rc, action: Option>, }, - CustomEntry { - entry_render: Box AnyElement>, - }, } pub struct ContextMenu { @@ -86,16 +83,6 @@ impl ContextMenu { self } - pub fn custom_entry( - mut self, - entry_render: impl Fn(&mut WindowContext) -> AnyElement + 'static, - ) -> Self { - self.items.push(ContextMenuItem::CustomEntry { - entry_render: Box::new(entry_render), - }); - self - } - pub fn action(mut self, label: impl Into, action: Box) -> Self { self.items.push(ContextMenuItem::Entry { label: label.into(), @@ -243,9 +230,9 @@ impl Render for ContextMenu { el }) .flex_none() - .child(List::new().children(self.items.iter_mut().enumerate().map( - |(ix, item)| { - match item { + .child( + List::new().children(self.items.iter().enumerate().map( + |(ix, item)| match item { ContextMenuItem::Separator => ListSeparator.into_any_element(), ContextMenuItem::Header(header) => { ListSubHeader::new(header.clone()).into_any_element() @@ -268,7 +255,7 @@ impl Render for ContextMenu { Label::new(label.clone()).into_any_element() }; - ListItem::new(ix) + ListItem::new(label.clone()) .inset(true) .selected(Some(ix) == self.selected_index) .on_click(move |_, cx| handler(cx)) @@ -284,14 +271,9 @@ impl Render for ContextMenu { ) .into_any_element() } - ContextMenuItem::CustomEntry { entry_render } => ListItem::new(ix) - .inset(true) - .selected(Some(ix) == self.selected_index) - .child(entry_render(cx)) - .into_any_element(), - } - }, - ))), + }, + )), + ), ) } } diff --git a/crates/ui2/src/components/list/list_item.rs b/crates/ui2/src/components/list/list_item.rs index e8689030c36220894c1de3c0ea258fbb7f4e8246..bdb5c2b854f2cfb7a04cbd70334d81a4daab98c4 100644 --- a/crates/ui2/src/components/list/list_item.rs +++ b/crates/ui2/src/components/list/list_item.rs @@ -171,8 +171,7 @@ impl RenderOnce for ListItem { }) }) .when_some(self.on_click, |this, on_click| { - this.cursor_pointer() - .on_click(move |event, cx| on_click(event, cx)) + this.cursor_pointer().on_click(on_click) }) .when_some(self.on_secondary_mouse_down, |this, on_mouse_down| { this.on_mouse_down(MouseButton::Right, move |event, cx| { diff --git a/crates/ui2/src/components/tab_bar.rs b/crates/ui2/src/components/tab_bar.rs index b10ffd1c630a3b0099190235328bbc43f8564854..d2e6e9518bdae89bd31506f1c1d8fad4660881fa 100644 --- a/crates/ui2/src/components/tab_bar.rs +++ b/crates/ui2/src/components/tab_bar.rs @@ -96,7 +96,7 @@ impl RenderOnce for TabBar { div() .id(self.id) - .z_index(120) + .z_index(120) // todo!("z-index") .group("tab_bar") .flex() .flex_none() diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index f83879a64ed5536f1602571c00e59dd1a18bc611..7436232b04e556ebe8ed648363908471512d1585 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -105,8 +105,7 @@ impl Render for Toolbar { v_stack() .p_1() .gap_2() - // todo!() use a proper constant here (ask Marshall & Nate) - .z_index(80) + .z_index(80) // todo!("z-index") .border_b() .border_color(cx.theme().colors().border_variant) .bg(cx.theme().colors().toolbar_background) From 1b09862384e84169c84bd7047bfbd21df7392c50 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 14:11:59 -0800 Subject: [PATCH 168/644] Restrcit context for some editor bindings that don't apply to single-line editors --- assets/keymaps/default.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index b8d3711132b1063543e7554b88d014df21460361..5d700006393ea27a4e46348f08866ab3197f8215 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -502,7 +502,7 @@ } }, { - "context": "Editor", + "context": "Editor && mode == full", "bindings": { "alt-enter": "editor::OpenExcerpts", "cmd-f8": "editor::GoToHunk", From 901795bcb98b9d85cfab42c95368e792122e7ca0 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 14:12:29 -0800 Subject: [PATCH 169/644] Don't reset the collab panel when it loses focus --- crates/collab_ui2/src/collab_panel.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index b7dd24b9ab5fc0b4eea338316fac95060c468d47..28d1b12beafb62c71718a6df68f1bff94e9616cc 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -199,12 +199,6 @@ impl CollabPanel { .iter() .position(|entry| !matches!(entry, ListEntry::Header(_))); } - } else if let editor::EditorEvent::Blurred = event { - let query = this.filter_editor.read(cx).text(cx); - if query.is_empty() { - this.selection.take(); - this.update_entries(true, cx); - } } }) .detach(); From afd3bf77467849d3f0aad3639ce7ef9f720e3be0 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 14:12:45 -0800 Subject: [PATCH 170/644] Add missing selected state and keyboard action for some collab panel items --- crates/collab_ui2/src/collab_panel.rs | 107 +++++++++++------- .../src/collab_panel/contact_finder.rs | 6 +- 2 files changed, 69 insertions(+), 44 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 28d1b12beafb62c71718a6df68f1bff94e9616cc..35e2f8d7ed210dc3cfb2fbe59d1d399a3f2683b9 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -804,8 +804,9 @@ impl CollabPanel { user: &Arc, peer_id: Option, is_pending: bool, + is_selected: bool, cx: &mut ViewContext, - ) -> impl IntoElement { + ) -> ListItem { let is_current_user = self.user_store.read(cx).current_user().map(|user| user.id) == Some(user.id); let tooltip = format!("Follow {}", user.github_login); @@ -813,6 +814,7 @@ impl CollabPanel { ListItem::new(SharedString::from(user.github_login.clone())) .start_slot(Avatar::new(user.avatar_uri.clone())) .child(Label::new(user.github_login.clone())) + .selected(is_selected) .end_slot(if is_pending { Label::new("Calling").color(Color::Muted).into_any_element() } else if is_current_user { @@ -839,10 +841,8 @@ impl CollabPanel { project_id: u64, worktree_root_names: &[String], host_user_id: u64, - // is_current: bool, is_last: bool, is_selected: bool, - // theme: &theme::Theme, cx: &mut ViewContext, ) -> impl IntoElement { let project_name: SharedString = if worktree_root_names.is_empty() { @@ -917,9 +917,11 @@ impl CollabPanel { fn render_channel_notes( &self, channel_id: ChannelId, + is_selected: bool, cx: &mut ViewContext, ) -> impl IntoElement { ListItem::new("channel-notes") + .selected(is_selected) .on_click(cx.listener(move |this, _, cx| { this.open_channel_notes(channel_id, cx); })) @@ -936,9 +938,11 @@ impl CollabPanel { fn render_channel_chat( &self, channel_id: ChannelId, + is_selected: bool, cx: &mut ViewContext, ) -> impl IntoElement { ListItem::new("channel-chat") + .selected(is_selected) .on_click(cx.listener(move |this, _, cx| { this.join_channel_chat(channel_id, cx); })) @@ -1136,32 +1140,32 @@ impl CollabPanel { self.call(contact.user.id, cx); } } - // ListEntry::ParticipantProject { - // project_id, - // host_user_id, - // .. - // } => { - // if let Some(workspace) = self.workspace.upgrade(cx) { - // let app_state = workspace.read(cx).app_state().clone(); - // workspace::join_remote_project( - // *project_id, - // *host_user_id, - // app_state, - // cx, - // ) - // .detach_and_log_err(cx); - // } - // } - // ListEntry::ParticipantScreen { peer_id, .. } => { - // let Some(peer_id) = peer_id else { - // return; - // }; - // if let Some(workspace) = self.workspace.upgrade(cx) { - // workspace.update(cx, |workspace, cx| { - // workspace.open_shared_screen(*peer_id, cx) - // }); - // } - // } + ListEntry::ParticipantProject { + project_id, + host_user_id, + .. + } => { + if let Some(workspace) = self.workspace.upgrade() { + let app_state = workspace.read(cx).app_state().clone(); + workspace::join_remote_project( + *project_id, + *host_user_id, + app_state, + cx, + ) + .detach_and_log_err(cx); + } + } + ListEntry::ParticipantScreen { peer_id, .. } => { + let Some(peer_id) = peer_id else { + return; + }; + if let Some(workspace) = self.workspace.upgrade() { + workspace.update(cx, |workspace, cx| { + workspace.open_shared_screen(*peer_id, cx) + }); + } + } ListEntry::Channel { channel, .. } => { let is_active = maybe!({ let call_channel = ActiveCall::global(cx) @@ -1180,7 +1184,30 @@ impl CollabPanel { } } ListEntry::ContactPlaceholder => self.toggle_contact_finder(cx), - _ => {} + ListEntry::CallParticipant { user, peer_id, .. } => { + if Some(user) == self.user_store.read(cx).current_user().as_ref() { + Self::leave_call(cx); + } else if let Some(peer_id) = peer_id { + self.workspace + .update(cx, |workspace, cx| workspace.follow(*peer_id, cx)) + .ok(); + } + } + ListEntry::IncomingRequest(user) => { + self.respond_to_contact_request(user.id, true, cx) + } + ListEntry::ChannelInvite(channel) => { + self.respond_to_channel_invite(channel.id, true, cx) + } + ListEntry::ChannelNotes { channel_id } => { + self.open_channel_notes(*channel_id, cx) + } + ListEntry::ChannelChat { channel_id } => { + self.join_channel_chat(*channel_id, cx) + } + + ListEntry::OutgoingRequest(_) => {} + ListEntry::ChannelEditor { .. } => {} } } } @@ -1673,7 +1700,7 @@ impl CollabPanel { peer_id, is_pending, } => self - .render_call_participant(user, *peer_id, *is_pending, cx) + .render_call_participant(user, *peer_id, *is_pending, is_selected, cx) .into_any_element(), ListEntry::ParticipantProject { project_id, @@ -1694,11 +1721,11 @@ impl CollabPanel { .render_participant_screen(*peer_id, *is_last, is_selected, cx) .into_any_element(), ListEntry::ChannelNotes { channel_id } => self - .render_channel_notes(*channel_id, cx) + .render_channel_notes(*channel_id, is_selected, cx) + .into_any_element(), + ListEntry::ChannelChat { channel_id } => self + .render_channel_chat(*channel_id, is_selected, cx) .into_any_element(), - ListEntry::ChannelChat { channel_id } => { - self.render_channel_chat(*channel_id, cx).into_any_element() - } } } @@ -1953,7 +1980,7 @@ impl CollabPanel { channel: &Arc, is_selected: bool, cx: &mut ViewContext, - ) -> impl IntoElement { + ) -> ListItem { let channel_id = channel.id; let response_is_pending = self .channel_store @@ -2000,7 +2027,7 @@ impl CollabPanel { &self, is_selected: bool, cx: &mut ViewContext, - ) -> impl IntoElement { + ) -> ListItem { ListItem::new("contact-placeholder") .child(IconElement::new(Icon::Plus)) .child(Label::new("Add a Contact")) @@ -2087,9 +2114,8 @@ impl CollabPanel { })) .child( ListItem::new(channel_id as usize) - // Offset the indent depth by one to give us room to show the disclosure. + // Add one level of depth for the disclosure arrow. .indent_level(depth + 1) - .indent_step_size(cx.rem_size() * 14.0 / 16.0) // @todo()! @nate this is to step over the disclosure toggle .selected(is_selected || is_active) .toggle(disclosed) .on_toggle( @@ -2158,7 +2184,8 @@ impl CollabPanel { fn render_channel_editor(&self, depth: usize, _cx: &mut ViewContext) -> impl IntoElement { let item = ListItem::new("channel-editor") .inset(false) - .indent_level(depth) + // Add one level of depth for the disclosure arrow. + .indent_level(depth + 1) .start_slot( IconElement::new(Icon::Hash) .size(IconSize::Small) diff --git a/crates/collab_ui2/src/collab_panel/contact_finder.rs b/crates/collab_ui2/src/collab_panel/contact_finder.rs index 208727efd27132debb9f883af7c172154d2461f1..31d836279b6a17d4b119dcad0d562d66388f30ac 100644 --- a/crates/collab_ui2/src/collab_panel/contact_finder.rs +++ b/crates/collab_ui2/src/collab_panel/contact_finder.rs @@ -1,9 +1,7 @@ -#![allow(unused)] use client::{ContactRequestStatus, User, UserStore}; use gpui::{ - div, img, svg, AnyElement, AppContext, DismissEvent, Div, Entity, EventEmitter, FocusHandle, - FocusableView, Img, IntoElement, Model, ParentElement as _, Render, Styled, Task, View, - ViewContext, VisualContext, WeakView, + AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Model, + ParentElement as _, Render, Styled, Task, View, ViewContext, VisualContext, WeakView, }; use picker::{Picker, PickerDelegate}; use std::sync::Arc; From 547ad77243709f3c9e10c4dfb23da781b9565dab Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 17:45:42 -0500 Subject: [PATCH 171/644] Style tab drop targets for project entries (#3725) This PR styles the drop targets when dragging a project entry onto a tab or the tab bar. I also adjusted the existing tab drop targets to use the `drop_target_background` from the theme. Release Notes: - N/A --- crates/workspace2/src/pane.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index e1bb006c11428149d5ade09aed2db137e7e61cdb..6b498124e371b67eaa5bd64ac26b5e95d3f4929d 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1511,8 +1511,8 @@ impl Pane { }, |tab, cx| cx.build_view(|_| tab.clone()), ) - .drag_over::(|tab| tab.bg(cx.theme().colors().tab_active_background)) - .drag_over::(|tab| tab.bg(gpui::red())) + .drag_over::(|tab| tab.bg(cx.theme().colors().drop_target_background)) + .drag_over::(|tab| tab.bg(cx.theme().colors().drop_target_background)) .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { this.drag_split_direction = None; this.handle_tab_drop(dragged_tab, ix, cx) @@ -1664,9 +1664,11 @@ impl Pane { .h_full() .flex_grow() .drag_over::(|bar| { - bar.bg(cx.theme().colors().tab_active_background) + bar.bg(cx.theme().colors().drop_target_background) + }) + .drag_over::(|bar| { + bar.bg(cx.theme().colors().drop_target_background) }) - .drag_over::(|bar| bar.bg(gpui::red())) .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { this.drag_split_direction = None; this.handle_tab_drop(dragged_tab, this.items.len(), cx) From 53b76e3e4d0946128b271875358efd974e0716de Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 18:06:21 -0500 Subject: [PATCH 172/644] Style pane drop targets (#3726) This PR styles the pane drop targets using the `drop_target_background` color from the theme. We do have to adjust the alpha channel of the color so that it doesn't obscure the contents of the buffer. Release Notes: - N/A --- crates/workspace2/src/pane.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 6b498124e371b67eaa5bd64ac26b5e95d3f4929d..4d0d4653090ad4ba0e993f21d67d1b6cceaa7553 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1817,9 +1817,6 @@ impl Render for Pane { type Element = Focusable
; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - let mut drag_target_color = cx.theme().colors().text; - drag_target_color.a = 0.5; - v_stack() .key_context("Pane") .track_focus(&self.focus_handle) @@ -1922,7 +1919,10 @@ impl Render for Pane { div() .invisible() .absolute() - .bg(drag_target_color) + .bg(theme::color_alpha( + cx.theme().colors().drop_target_background, + 0.75, + )) .group_drag_over::("", |style| style.visible()) .group_drag_over::("", |style| style.visible()) .on_drop(cx.listener(move |this, dragged_tab, cx| { From a0224b975b7e05beb730bb775185c15e982f2cf4 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 18:24:52 -0500 Subject: [PATCH 173/644] Use `link_text_hover` for go-to-definition links --- crates/editor2/src/link_go_to_definition.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor2/src/link_go_to_definition.rs b/crates/editor2/src/link_go_to_definition.rs index 60c966d4c7cf68ea0e420ee3d7270be1d671cbff..ef171277975eda27ef352012079fb872d16178f0 100644 --- a/crates/editor2/src/link_go_to_definition.rs +++ b/crates/editor2/src/link_go_to_definition.rs @@ -491,7 +491,7 @@ pub fn show_link_definition( thickness: px(1.), ..Default::default() }), - color: Some(gpui::red()), + color: Some(cx.theme().colors().link_text_hover), ..Default::default() }; let highlight_range = From afcf6c685230d6731334b4ec2013de88f8c481b6 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 19 Dec 2023 18:29:27 -0500 Subject: [PATCH 174/644] Map `textLink.activeForeground` from VS Code to `link_text_hover` --- crates/theme2/src/themes/ayu.rs | 3 +++ crates/theme2/src/themes/gruvbox.rs | 6 ++++++ crates/theme2/src/themes/noctis.rs | 11 +++++++++++ crates/theme2/src/themes/nord.rs | 1 + crates/theme2/src/themes/rose_pine.rs | 3 +++ crates/theme2/src/themes/synthwave_84.rs | 1 + crates/theme_importer/src/theme_printer.rs | 10 ++++++++++ crates/theme_importer/src/vscode/converter.rs | 4 ++++ crates/theme_importer/src/vscode/theme.rs | 7 +++++++ 9 files changed, 46 insertions(+) diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index 79aed9e1b5fbf69751454b7c8ef09e9ae40b1b94..9c977234b98802a6932cd89bfa79e7e39e2b9739 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -70,6 +70,7 @@ pub fn ayu() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0x9e75c7ff).into()), terminal_ansi_cyan: Some(rgba(0x46ba94ff).into()), terminal_ansi_white: Some(rgba(0xc7c7c7ff).into()), + link_text_hover: Some(rgba(0xffaa33ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -379,6 +380,7 @@ pub fn ayu() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xdabafaff).into()), terminal_ansi_cyan: Some(rgba(0x90e1c6ff).into()), terminal_ansi_white: Some(rgba(0xc7c7c7ff).into()), + link_text_hover: Some(rgba(0xffcc66ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -688,6 +690,7 @@ pub fn ayu() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xcda1faff).into()), terminal_ansi_cyan: Some(rgba(0x90e1c6ff).into()), terminal_ansi_white: Some(rgba(0xc7c7c7ff).into()), + link_text_hover: Some(rgba(0xe6b450ff).into()), ..Default::default() }, status: StatusColorsRefinement { diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index 35f5b31aa2328156d15468251c36cba2462d00e1..abce861f91dc81e4a58a51bba25ab4a35afeaf4e 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -70,6 +70,7 @@ pub fn gruvbox() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), terminal_ansi_white: Some(rgba(0xa89984ff).into()), + link_text_hover: Some(rgba(0x458588ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -365,6 +366,7 @@ pub fn gruvbox() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), terminal_ansi_white: Some(rgba(0xa89984ff).into()), + link_text_hover: Some(rgba(0x458588ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -660,6 +662,7 @@ pub fn gruvbox() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), terminal_ansi_white: Some(rgba(0xa89984ff).into()), + link_text_hover: Some(rgba(0x458588ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -955,6 +958,7 @@ pub fn gruvbox() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), terminal_ansi_white: Some(rgba(0x7c6f64ff).into()), + link_text_hover: Some(rgba(0x458588ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -1250,6 +1254,7 @@ pub fn gruvbox() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), terminal_ansi_white: Some(rgba(0x7c6f64ff).into()), + link_text_hover: Some(rgba(0x458588ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -1545,6 +1550,7 @@ pub fn gruvbox() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), terminal_ansi_white: Some(rgba(0x7c6f64ff).into()), + link_text_hover: Some(rgba(0x458588ff).into()), ..Default::default() }, status: StatusColorsRefinement { diff --git a/crates/theme2/src/themes/noctis.rs b/crates/theme2/src/themes/noctis.rs index 273b52a34ac294955ca8afb4d4a9c610367374d5..ca1601df99ad16592300cbee25c0bc6da303a621 100644 --- a/crates/theme2/src/themes/noctis.rs +++ b/crates/theme2/src/themes/noctis.rs @@ -71,6 +71,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), terminal_ansi_white: Some(rgba(0xaec3d0ff).into()), + link_text_hover: Some(rgba(0x49ace9ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -351,6 +352,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), terminal_ansi_white: Some(rgba(0xb9acb0ff).into()), + link_text_hover: Some(rgba(0xf18eb0ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -631,6 +633,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xff5792ff).into()), terminal_ansi_cyan: Some(rgba(0x00bdd6ff).into()), terminal_ansi_white: Some(rgba(0x8ca6a6ff).into()), + link_text_hover: Some(rgba(0x00c6e0ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -911,6 +914,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xff5792ff).into()), terminal_ansi_cyan: Some(rgba(0x00bdd6ff).into()), terminal_ansi_white: Some(rgba(0x8ca6a6ff).into()), + link_text_hover: Some(rgba(0x00c6e0ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -1191,6 +1195,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xff5792ff).into()), terminal_ansi_cyan: Some(rgba(0x00bdd6ff).into()), terminal_ansi_white: Some(rgba(0x8ca6a6ff).into()), + link_text_hover: Some(rgba(0x00c6e0ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -1471,6 +1476,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xc28097ff).into()), terminal_ansi_cyan: Some(rgba(0x72b7c0ff).into()), terminal_ansi_white: Some(rgba(0xc5cdd3ff).into()), + link_text_hover: Some(rgba(0x5998c0ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -1751,6 +1757,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), terminal_ansi_white: Some(rgba(0xb2cacdff).into()), + link_text_hover: Some(rgba(0x40d4e7ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -2031,6 +2038,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), terminal_ansi_white: Some(rgba(0xb2cacdff).into()), + link_text_hover: Some(rgba(0x40d4e7ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -2311,6 +2319,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), terminal_ansi_white: Some(rgba(0xb2cacdff).into()), + link_text_hover: Some(rgba(0x40d4e7ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -2591,6 +2600,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), terminal_ansi_white: Some(rgba(0xb6b3ccff).into()), + link_text_hover: Some(rgba(0x998ef1ff).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -2871,6 +2881,7 @@ pub fn noctis() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), terminal_ansi_white: Some(rgba(0xbfafcfff).into()), + link_text_hover: Some(rgba(0xbf8ef1ff).into()), ..Default::default() }, status: StatusColorsRefinement { diff --git a/crates/theme2/src/themes/nord.rs b/crates/theme2/src/themes/nord.rs index 83fafa7a8740ced232d082018c21bdbbeafb4b08..c44076c1f85079cb207c5518c9468e000f40ef93 100644 --- a/crates/theme2/src/themes/nord.rs +++ b/crates/theme2/src/themes/nord.rs @@ -70,6 +70,7 @@ pub fn nord() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xb48eadff).into()), terminal_ansi_cyan: Some(rgba(0x88c0d0ff).into()), terminal_ansi_white: Some(rgba(0xe5e9f0ff).into()), + link_text_hover: Some(rgba(0x88c0d0ff).into()), ..Default::default() }, status: StatusColorsRefinement { diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index 51e3a2451c8bf2f69218cc0fb7f823d99acce154..828838530f4650cce4e468437927748784d3f997 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -70,6 +70,7 @@ pub fn rose_pine() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xc4a7e7ff).into()), terminal_ansi_cyan: Some(rgba(0xebbcbaff).into()), terminal_ansi_white: Some(rgba(0xe0def4ff).into()), + link_text_hover: Some(rgba(0xc4a7e7e6).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -332,6 +333,7 @@ pub fn rose_pine() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0xc4a7e7ff).into()), terminal_ansi_cyan: Some(rgba(0xea9a97ff).into()), terminal_ansi_white: Some(rgba(0xe0def4ff).into()), + link_text_hover: Some(rgba(0xc4a7e7e6).into()), ..Default::default() }, status: StatusColorsRefinement { @@ -594,6 +596,7 @@ pub fn rose_pine() -> UserThemeFamily { terminal_ansi_magenta: Some(rgba(0x907aa9ff).into()), terminal_ansi_cyan: Some(rgba(0xd7827eff).into()), terminal_ansi_white: Some(rgba(0x575279ff).into()), + link_text_hover: Some(rgba(0x907aa9e6).into()), ..Default::default() }, status: StatusColorsRefinement { diff --git a/crates/theme2/src/themes/synthwave_84.rs b/crates/theme2/src/themes/synthwave_84.rs index 4f62732d7f139e720d357a6fac6192c267f4e776..d7a0ef41a0228abf015c87720d244f2faa6bc433 100644 --- a/crates/theme2/src/themes/synthwave_84.rs +++ b/crates/theme2/src/themes/synthwave_84.rs @@ -54,6 +54,7 @@ pub fn synthwave_84() -> UserThemeFamily { terminal_ansi_blue: Some(rgba(0x03edf9ff).into()), terminal_ansi_magenta: Some(rgba(0xff7edbff).into()), terminal_ansi_cyan: Some(rgba(0x03edf9ff).into()), + link_text_hover: Some(rgba(0xff7edbff).into()), ..Default::default() }, status: StatusColorsRefinement { diff --git a/crates/theme_importer/src/theme_printer.rs b/crates/theme_importer/src/theme_printer.rs index 13123d854f99a7c32763f695182d6ac73c0a8d14..eb304ff90d406be5d8d1d4e66c3782376908a10c 100644 --- a/crates/theme_importer/src/theme_printer.rs +++ b/crates/theme_importer/src/theme_printer.rs @@ -270,6 +270,16 @@ impl<'a> Debug for ThemeColorsRefinementPrinter<'a> { ("terminal_ansi_magenta", self.0.terminal_ansi_magenta), ("terminal_ansi_cyan", self.0.terminal_ansi_cyan), ("terminal_ansi_white", self.0.terminal_ansi_white), + ("headline", self.0.headline), + ("paragraph", self.0.paragraph), + ("link_text", self.0.link_text), + ("link_text_hover", self.0.link_text_hover), + ("link_uri", self.0.link_uri), + ("inline_code_background", self.0.inline_code_background), + ("inline_code_border", self.0.inline_code_border), + ("code_block_background", self.0.code_block_background), + ("code_block_border", self.0.code_block_border), + ("emphasis", self.0.emphasis), ]; f.write_str("ThemeColorsRefinement {")?; diff --git a/crates/theme_importer/src/vscode/converter.rs b/crates/theme_importer/src/vscode/converter.rs index f5a606b329dfe65b2ba94468b80c9b11a1e0d621..8ade4937311f25c93604e70122161a06771e2304 100644 --- a/crates/theme_importer/src/vscode/converter.rs +++ b/crates/theme_importer/src/vscode/converter.rs @@ -217,6 +217,10 @@ impl VsCodeThemeConverter { .tab_inactive_foreground .as_ref() .traverse(|color| try_parse_color(&color))?, + link_text_hover: vscode_colors + .text_link_active_foreground + .as_ref() + .traverse(|color| try_parse_color(&color))?, tab_bar_background: vscode_colors .editor_group_header_tabs_background .as_ref() diff --git a/crates/theme_importer/src/vscode/theme.rs b/crates/theme_importer/src/vscode/theme.rs index f8e2c98da5a2475fd394e4994ccf0e0867c478d2..0c59a04c48f25c30cb77583a2c9822f04b7e4f5f 100644 --- a/crates/theme_importer/src/vscode/theme.rs +++ b/crates/theme_importer/src/vscode/theme.rs @@ -154,6 +154,13 @@ pub struct VsCodeColors { )] pub terminal_ansi_white: Option, + #[serde( + default, + rename = "textLink.activeForeground", + deserialize_with = "empty_string_as_none" + )] + pub text_link_active_foreground: Option, + #[serde( default, rename = "focusBorder", From 0390fb1449da8ee7585443353c2f6d8ae24b1098 Mon Sep 17 00:00:00 2001 From: Julia Date: Tue, 19 Dec 2023 18:38:25 -0500 Subject: [PATCH 175/644] Reintroduce LSP diagnostic/status message Co-Authored-By: Antonio Scandurra --- .../src/activity_indicator.rs | 4 ++-- crates/diagnostics2/src/items.rs | 22 ++++++++++++++++--- crates/workspace2/src/pane.rs | 17 ++++++++++++++ crates/workspace2/src/status_bar.rs | 9 ++++++++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/crates/activity_indicator2/src/activity_indicator.rs b/crates/activity_indicator2/src/activity_indicator.rs index e4a5b01ba6bdb276f00d20f3f7748b771c2b2ed8..f83517e0618316a5407f5ab6a9bc3cabc653033a 100644 --- a/crates/activity_indicator2/src/activity_indicator.rs +++ b/crates/activity_indicator2/src/activity_indicator.rs @@ -10,7 +10,7 @@ use language::{LanguageRegistry, LanguageServerBinaryStatus}; use project::{LanguageServerProgress, Project}; use smallvec::SmallVec; use std::{cmp::Reverse, fmt::Write, sync::Arc}; -use ui::h_stack; +use ui::{h_stack, Label}; use util::ResultExt; use workspace::{item::ItemHandle, StatusItemView, Workspace}; @@ -324,7 +324,7 @@ impl Render for ActivityIndicator { result .children(content.icon.map(|icon| svg().path(icon))) - .child(SharedString::from(content.message)) + .child(Label::new(SharedString::from(content.message))) } } diff --git a/crates/diagnostics2/src/items.rs b/crates/diagnostics2/src/items.rs index 92b0641deae4d049fda3d968cf88b28568b50d41..28bbe7aedc29c84578f5d01abd7d06febb51ac95 100644 --- a/crates/diagnostics2/src/items.rs +++ b/crates/diagnostics2/src/items.rs @@ -1,13 +1,13 @@ use collections::HashSet; use editor::{Editor, GoToDiagnostic}; use gpui::{ - rems, Div, EventEmitter, InteractiveElement, ParentElement, Render, Stateful, + rems, Div, EventEmitter, InteractiveElement, IntoElement, ParentElement, Render, Stateful, StatefulInteractiveElement, Styled, Subscription, View, ViewContext, WeakView, }; use language::Diagnostic; use lsp::LanguageServerId; use theme::ActiveTheme; -use ui::{h_stack, Color, Icon, IconElement, Label, Tooltip}; +use ui::{h_stack, Button, Clickable, Color, Icon, IconElement, Label, Tooltip}; use workspace::{item::ItemHandle, StatusItemView, ToolbarItemEvent, Workspace}; use crate::ProjectDiagnosticsEditor; @@ -43,13 +43,28 @@ impl Render for DiagnosticIndicator { .child(Label::new(warning_count.to_string())), }; + let status = if !self.in_progress_checks.is_empty() { + Some(Label::new("Checking…").into_any_element()) + } else if let Some(diagnostic) = &self.current_diagnostic { + let message = diagnostic.message.split('\n').next().unwrap().to_string(); + Some( + Button::new("diagnostic_message", message) + .on_click(cx.listener(|this, _, cx| { + this.go_to_next_diagnostic(&GoToDiagnostic, cx); + })) + .into_any_element(), + ) + } else { + None + }; + h_stack() .id("diagnostic-indicator") .on_action(cx.listener(Self::go_to_next_diagnostic)) .rounded_md() .flex_none() .h(rems(1.375)) - .px_1() + .px_6() .cursor_pointer() .bg(cx.theme().colors().ghost_element_background) .hover(|style| style.bg(cx.theme().colors().ghost_element_hover)) @@ -63,6 +78,7 @@ impl Render for DiagnosticIndicator { } })) .child(diagnostic_indicator) + .children(status) } } diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index e1bb006c11428149d5ade09aed2db137e7e61cdb..dcf4ed0811650ce85d961cee0fabd433f219c593 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -789,6 +789,7 @@ impl Pane { } self.update_toolbar(cx); + self.update_status_bar(cx); if focus_item { self.focus_active_item(cx); @@ -1450,6 +1451,22 @@ impl Pane { }); } + fn update_status_bar(&mut self, cx: &mut ViewContext) { + let Ok(status_bar) = self + .workspace + .update(cx, |workspace, _| workspace.status_bar.clone()) + else { + return; + }; + + let pane = cx.view().clone(); + cx.window_context().defer(move |cx| { + status_bar.update(cx, move |status_bar, cx| { + status_bar.set_active_pane(&pane, cx); + }); + }); + } + fn render_tab( &self, ix: usize, diff --git a/crates/workspace2/src/status_bar.rs b/crates/workspace2/src/status_bar.rs index ba571d6e0ad3c70bc64139e90e64f9c59314bfc7..f4e4ac9508dc4fae74913c5eefb59c39802b38e7 100644 --- a/crates/workspace2/src/status_bar.rs +++ b/crates/workspace2/src/status_bar.rs @@ -83,6 +83,9 @@ impl StatusBar { where T: 'static + StatusItemView, { + let active_pane_item = self.active_pane.read(cx).active_item(); + item.set_active_pane_item(active_pane_item.as_deref(), cx); + self.left_items.push(Box::new(item)); cx.notify(); } @@ -119,6 +122,9 @@ impl StatusBar { ) where T: 'static + StatusItemView, { + let active_pane_item = self.active_pane.read(cx).active_item(); + item.set_active_pane_item(active_pane_item.as_deref(), cx); + if position < self.left_items.len() { self.left_items.insert(position + 1, Box::new(item)) } else { @@ -141,6 +147,9 @@ impl StatusBar { where T: 'static + StatusItemView, { + let active_pane_item = self.active_pane.read(cx).active_item(); + item.set_active_pane_item(active_pane_item.as_deref(), cx); + self.right_items.push(Box::new(item)); cx.notify(); } From 3fccc648d66b2c3b8588a5a40434b7621e031ed8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 15:41:00 -0800 Subject: [PATCH 176/644] Fix layout of diagnostic blocks --- crates/diagnostics2/src/diagnostics.rs | 23 +++-- crates/editor2/src/editor.rs | 122 ++++++++++++------------- 2 files changed, 72 insertions(+), 73 deletions(-) diff --git a/crates/diagnostics2/src/diagnostics.rs b/crates/diagnostics2/src/diagnostics.rs index 1001ed880e0a8495c38aa497130f64c6802a1bd6..8103231ede627616cd0c47b3f74125704c6fa5bf 100644 --- a/crates/diagnostics2/src/diagnostics.rs +++ b/crates/diagnostics2/src/diagnostics.rs @@ -14,9 +14,9 @@ use editor::{ use futures::future::try_join_all; use gpui::{ actions, div, AnyElement, AnyView, AppContext, Context, Div, EventEmitter, FocusHandle, - Focusable, FocusableView, InteractiveElement, IntoElement, Model, ParentElement, Render, - SharedString, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, - WindowContext, + Focusable, FocusableView, HighlightStyle, InteractiveElement, IntoElement, Model, + ParentElement, Render, SharedString, Styled, StyledText, Subscription, Task, View, ViewContext, + VisualContext, WeakView, WindowContext, }; use language::{ Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection, @@ -36,7 +36,7 @@ use std::{ }; use theme::ActiveTheme; pub use toolbar_controls::ToolbarControls; -use ui::{h_stack, prelude::*, HighlightedLabel, Icon, IconElement, Label}; +use ui::{h_stack, prelude::*, Icon, IconElement, Label}; use util::TryFutureExt; use workspace::{ item::{BreadcrumbText, Item, ItemEvent, ItemHandle}, @@ -785,8 +785,10 @@ impl Item for ProjectDiagnosticsEditor { } fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock { - let (message, highlights) = highlight_diagnostic_message(Vec::new(), &diagnostic.message); - Arc::new(move |_| { + let (message, code_ranges) = highlight_diagnostic_message(&diagnostic); + let message: SharedString = message.into(); + Arc::new(move |cx| { + let highlight_style: HighlightStyle = cx.theme().colors().text_accent.into(); h_stack() .id("diagnostic header") .py_2() @@ -809,7 +811,14 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock { .child( h_stack() .gap_1() - .child(HighlightedLabel::new(message.clone(), highlights.clone())) + .child( + StyledText::new(message.clone()).with_highlights( + &cx.text_style(), + code_ranges + .iter() + .map(|range| (range.clone(), highlight_style)), + ), + ) .when_some(diagnostic.code.as_ref(), |stack, code| { stack.child(Label::new(format!("({code})")).color(Color::Muted)) }), diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 379c66df5765af6ded325df600c4e6b8bc805e0c..58f8e857a9a167219b5e1cdeec5a2bbb1b5b62f9 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -9719,90 +9719,80 @@ impl InvalidationRegion for SnippetState { } } -// impl Deref for EditorStyle { -// type Target = theme::Editor; - -// fn deref(&self) -> &Self::Target { -// &self.theme -// } -// } - pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> RenderBlock { - let mut highlighted_lines = Vec::new(); - - for (index, line) in diagnostic.message.lines().enumerate() { - let line = match &diagnostic.source { - Some(source) if index == 0 => { - let source_highlight = Vec::from_iter(0..source.len()); - highlight_diagnostic_message(source_highlight, &format!("{source}: {line}")) - } + let (text_without_backticks, code_ranges) = highlight_diagnostic_message(&diagnostic); - _ => highlight_diagnostic_message(Vec::new(), line), - }; - highlighted_lines.push(line); - } Arc::new(move |cx: &mut BlockContext| { - let copy_id: SharedString = format!("copy-{}", cx.block_id.clone()).to_string().into(); + let color = Some(cx.theme().colors().text_accent); + let group_id: SharedString = cx.block_id.to_string().into(); // TODO: Nate: We should tint the background of the block with the severity color // We need to extend the theme before we can do this - v_stack() + h_stack() .id(cx.block_id) + .group(group_id.clone()) .relative() + .pl(cx.anchor_x) .size_full() - .bg(gpui::red()) - .children(highlighted_lines.iter().map(|(line, highlights)| { - let group_id = cx.block_id.to_string(); - h_stack() - .group(group_id.clone()) - .gap_2() - .absolute() - .left(cx.anchor_x) - .px_1p5() - .child(HighlightedLabel::new(line.clone(), highlights.clone())) - .child( - div().z_index(1).child( - IconButton::new(copy_id.clone(), Icon::Copy) - .icon_color(Color::Muted) - .size(ButtonSize::Compact) - .style(ButtonStyle::Transparent) - .visible_on_hover(group_id) - .on_click(cx.listener({ - let message = diagnostic.message.clone(); - move |_, _, cx| { - cx.write_to_clipboard(ClipboardItem::new(message.clone())) - } - })) - .tooltip(|cx| Tooltip::text("Copy diagnostic message", cx)), - ), - ) - })) + .gap_2() + .child( + StyledText::new(text_without_backticks.clone()).with_highlights( + &cx.text_style(), + code_ranges.iter().map(|range| { + ( + range.clone(), + HighlightStyle { + color, + ..Default::default() + }, + ) + }), + ), + ) + .child( + IconButton::new(("copy-block", cx.block_id), Icon::Copy) + .icon_color(Color::Muted) + .size(ButtonSize::Compact) + .style(ButtonStyle::Transparent) + .visible_on_hover(group_id) + .on_click(cx.listener({ + let message = diagnostic.message.clone(); + move |_, _, cx| cx.write_to_clipboard(ClipboardItem::new(message.clone())) + })) + .tooltip(|cx| Tooltip::text("Copy diagnostic message", cx)), + ) .into_any_element() }) } -pub fn highlight_diagnostic_message( - initial_highlights: Vec, - message: &str, -) -> (String, Vec) { - let mut message_without_backticks = String::new(); +pub fn highlight_diagnostic_message(diagnostic: &Diagnostic) -> (SharedString, Vec>) { + let mut text_without_backticks = String::new(); + let mut code_ranges = Vec::new(); + + if let Some(source) = &diagnostic.source { + text_without_backticks.push_str(&source); + code_ranges.push(0..source.len()); + text_without_backticks.push_str(": "); + } + let mut prev_offset = 0; - let mut inside_block = false; - let mut highlights = initial_highlights; - for (match_ix, (offset, _)) in message + let mut in_code_block = false; + for (ix, _) in diagnostic + .message .match_indices('`') - .chain([(message.len(), "")]) - .enumerate() + .chain([(diagnostic.message.len(), "")]) { - message_without_backticks.push_str(&message[prev_offset..offset]); - if inside_block { - highlights.extend(prev_offset - match_ix..offset - match_ix); + let prev_len = text_without_backticks.len(); + text_without_backticks.push_str(&diagnostic.message[prev_offset..ix]); + prev_offset = ix + 1; + if in_code_block { + code_ranges.push(prev_len..text_without_backticks.len()); + in_code_block = false; + } else { + in_code_block = true; } - - inside_block = !inside_block; - prev_offset = offset + 1; } - (message_without_backticks, highlights) + (text_without_backticks.into(), code_ranges) } pub fn diagnostic_style( From c81e89a4f40af9d8d095a014601480ed2cc73f95 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Dec 2023 17:04:42 -0800 Subject: [PATCH 177/644] Ensure that new view observers are called by WindowContext::replace_root_view --- crates/gpui2/src/window.rs | 9 ++------- crates/workspace2/src/workspace2.rs | 5 ----- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 1b2669b40c5cc4d95018ab6ec4a827d551b79dac..365338611b60757bced2b473a67f3323c0fbf9b9 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1926,14 +1926,9 @@ impl VisualContext for WindowContext<'_> { where V: 'static + Render, { - let slot = self.app.entities.reserve(); - let view = View { - model: slot.clone(), - }; - let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view); - let entity = build_view(&mut cx); - self.entities.insert(slot, entity); + let view = self.build_view(build_view); self.window.root_view = Some(view.clone().into()); + self.notify(); view } diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 4f911d1073d4ac6273deed1707fb0758d0969de4..95b05f314e73b7bffdd798423fca5d599fe965eb 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -600,11 +600,6 @@ impl Workspace { let modal_layer = cx.build_view(|_| ModalLayer::new()); - // todo!() - // cx.update_default_global::, _, _>(|drag_and_drop, _| { - // drag_and_drop.register_container(weak_handle.clone()); - // }); - let mut active_call = None; if cx.has_global::>() { let call = cx.global::>().clone(); From 00927db7115c9b11f118c9c14dcce785ea243cdd Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 20 Dec 2023 11:21:55 +0100 Subject: [PATCH 178/644] Fix sluggish experience when dragging tabs The problem was caused by a missing call to `WindowContext::notify` when moving the mouse. Actually, we *did* notify as part of a `MouseMoveEvent` listener registered in `Interactivity` but that code path was never exercised because we were clearing the `pending_mouse_down`. This commit fixes the issue by automatically redrawing the window in gpui when there is an active drag and the mouse moves. --- crates/gpui2/src/elements/div.rs | 11 +++++------ crates/gpui2/src/window.rs | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 57fd3d6a8af274d305d37dbc4d2d62baba8ccbd3..fa1eb9e5b63454d0a3fa370913e094f30c3ad68c 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1186,14 +1186,13 @@ impl Interactivity { cx.on_mouse_event({ let pending_mouse_down = pending_mouse_down.clone(); move |event: &MouseMoveEvent, phase, cx| { - let mut pending_mouse_down = pending_mouse_down.borrow_mut(); + if phase == DispatchPhase::Capture { + return; + } + let mut pending_mouse_down = pending_mouse_down.borrow_mut(); if let Some(mouse_down) = pending_mouse_down.clone() { - if cx.active_drag.is_some() { - if phase == DispatchPhase::Capture { - cx.notify(); - } - } else if phase == DispatchPhase::Bubble + if !cx.has_active_drag() && (event.position - mouse_down.position).magnitude() > DRAG_THRESHOLD { diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 365338611b60757bced2b473a67f3323c0fbf9b9..cc435bf0b2463c311f8b0833003c054ee4341f27 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1516,15 +1516,24 @@ impl<'a> WindowContext<'a> { } } - if self.app.propagate_event && event.downcast_ref::().is_some() { - self.active_drag = None; - } - self.window .rendered_frame .mouse_listeners .insert(event.type_id(), handlers); } + + if self.app.propagate_event && self.has_active_drag() { + if event.is::() { + // If this was a mouse move event, redraw the window so that the + // active drag can follow the mouse cursor. + self.notify(); + } else if event.is::() { + // If this was a mouse up event, cancel the active drag and redraw + // the window. + self.active_drag = None; + self.notify(); + } + } } fn dispatch_key_event(&mut self, event: &dyn Any) { From 2f57a3ccfb74d663588d0792d88144d03fe22977 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 20 Dec 2023 12:47:53 +0100 Subject: [PATCH 179/644] Popover buttons titlebar (#3732) Migrate project picker/vcs menu to use popover_menu. Release Notes: - N/A --- crates/collab_ui2/src/collab_titlebar_item.rs | 84 ++++++++----------- .../recent_projects2/src/recent_projects.rs | 43 ++++++---- crates/vcs_menu2/src/lib.rs | 78 +++++++++-------- 3 files changed, 106 insertions(+), 99 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 17ee5087bb0e4ec28771e8d4a1cef7616f790a6e..9359ff41d8fdba6bed1e64fc597285c8618c05a5 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -3,10 +3,10 @@ use auto_update::AutoUpdateStatus; use call::{ActiveCall, ParticipantLocation, Room}; use client::{proto::PeerId, Client, ParticipantIndex, User, UserStore}; use gpui::{ - actions, canvas, div, overlay, point, px, rems, Action, AnyElement, AppContext, DismissEvent, - Div, Element, FocusableView, Hsla, InteractiveElement, IntoElement, Model, ParentElement, Path, - Render, Stateful, StatefulInteractiveElement, Styled, Subscription, View, ViewContext, - VisualContext, WeakView, WindowBounds, + actions, canvas, div, point, px, rems, Action, AnyElement, AppContext, Div, Element, Hsla, + InteractiveElement, IntoElement, Model, ParentElement, Path, Render, Stateful, + StatefulInteractiveElement, Styled, Subscription, View, ViewContext, VisualContext, WeakView, + WindowBounds, }; use project::{Project, RepositoryEntry}; use recent_projects::RecentProjects; @@ -52,8 +52,8 @@ pub struct CollabTitlebarItem { user_store: Model, client: Arc, workspace: WeakView, - branch_popover: Option>, - project_popover: Option, + branch_popover: Option<(View, Subscription)>, + project_popover: Option<(View, Subscription)>, _subscriptions: Vec, } @@ -329,9 +329,8 @@ impl CollabTitlebarItem { }; let name = util::truncate_and_trailoff(name, MAX_PROJECT_NAME_LENGTH); - - div() - .child( + popover_menu("project_name_trigger") + .trigger( Button::new("project_name_trigger", name) .style(ButtonStyle::Subtle) .tooltip(move |cx| Tooltip::text("Recent Projects", cx)) @@ -339,16 +338,12 @@ impl CollabTitlebarItem { this.toggle_project_menu(&ToggleProjectMenu, cx); })), ) - .children(self.project_popover.as_ref().map(|popover| { - overlay().child( - div() - .min_w_56() - .on_mouse_down_out(cx.listener_for(&popover.picker, |picker, _, cx| { - picker.cancel(&Default::default(), cx) - })) - .child(popover.picker.clone()), - ) - })) + .when_some( + self.project_popover + .as_ref() + .map(|(project, _)| project.clone()), + |this, project| this.menu(move |_| project.clone()), + ) } pub fn render_project_branch(&self, cx: &mut ViewContext) -> Option { @@ -366,10 +361,9 @@ impl CollabTitlebarItem { .as_ref() .and_then(RepositoryEntry::branch) .map(|branch| util::truncate_and_trailoff(&branch, MAX_BRANCH_NAME_LENGTH))?; - Some( - div() - .child( + popover_menu("project_branch_trigger") + .trigger( Button::new("project_branch_trigger", branch_name) .color(Color::Muted) .style(ButtonStyle::Subtle) @@ -381,11 +375,16 @@ impl CollabTitlebarItem { cx, ) }) - .on_click( - cx.listener(|this, _, cx| this.toggle_vcs_menu(&ToggleVcsMenu, cx)), - ), + .on_click(cx.listener(|this, _, cx| { + this.toggle_vcs_menu(&ToggleVcsMenu, cx); + })), ) - .children(self.render_branches_popover_host()), + .when_some( + self.branch_popover + .as_ref() + .map(|(branch, _)| branch.clone()), + |this, branch| this.menu(move |_| branch.clone()), + ), ) } @@ -461,29 +460,19 @@ impl CollabTitlebarItem { .log_err(); } - fn render_branches_popover_host<'a>(&'a self) -> Option { - self.branch_popover.as_ref().map(|child| { - overlay() - .child(div().min_w_64().child(child.clone())) - .into_any() - }) - } - pub fn toggle_vcs_menu(&mut self, _: &ToggleVcsMenu, cx: &mut ViewContext) { if self.branch_popover.take().is_none() { if let Some(workspace) = self.workspace.upgrade() { let Some(view) = build_branch_list(workspace, cx).log_err() else { return; }; - cx.subscribe(&view, |this, _, _, cx| { - this.branch_popover = None; - cx.notify(); - }) - .detach(); self.project_popover.take(); let focus_handle = view.focus_handle(cx); cx.focus(&focus_handle); - self.branch_popover = Some(view); + let subscription = cx.subscribe(&view, |this, _, _, _| { + this.branch_popover.take(); + }); + self.branch_popover = Some((view, subscription)); } } @@ -491,8 +480,8 @@ impl CollabTitlebarItem { } pub fn toggle_project_menu(&mut self, _: &ToggleProjectMenu, cx: &mut ViewContext) { - let workspace = self.workspace.clone(); if self.project_popover.take().is_none() { + let workspace = self.workspace.clone(); cx.spawn(|this, mut cx| async move { let workspaces = WORKSPACE_DB .recent_workspaces_on_disk() @@ -506,16 +495,13 @@ impl CollabTitlebarItem { this.update(&mut cx, move |this, cx| { let view = RecentProjects::open_popover(workspace, workspaces, cx); - cx.subscribe(&view.picker, |this, _, _: &DismissEvent, cx| { - this.project_popover = None; - cx.notify(); - }) - .detach(); let focus_handle = view.focus_handle(cx); cx.focus(&focus_handle); - // todo!() - //this.branch_popover.take(); - this.project_popover = Some(view); + this.branch_popover.take(); + let subscription = cx.subscribe(&view, |this, _, _, _| { + this.project_popover.take(); + }); + this.project_popover = Some((view, subscription)); cx.notify(); }) .log_err(); diff --git a/crates/recent_projects2/src/recent_projects.rs b/crates/recent_projects2/src/recent_projects.rs index 3ecf1180af535ea23190bd41ad2c8dd0e329810d..13790a5b23ee47ff4cb343fab2fbe26b70cb16d0 100644 --- a/crates/recent_projects2/src/recent_projects.rs +++ b/crates/recent_projects2/src/recent_projects.rs @@ -3,8 +3,8 @@ mod projects; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ - AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Result, Task, View, - ViewContext, WeakView, + AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Result, Subscription, + Task, View, ViewContext, WeakView, }; use highlighted_workspace_location::HighlightedWorkspaceLocation; use ordered_float::OrderedFloat; @@ -23,17 +23,22 @@ pub fn init(cx: &mut AppContext) { cx.observe_new_views(RecentProjects::register).detach(); } -#[derive(Clone)] pub struct RecentProjects { pub picker: View>, + rem_width: f32, + _subscription: Subscription, } impl ModalView for RecentProjects {} impl RecentProjects { - fn new(delegate: RecentProjectsDelegate, cx: &mut WindowContext<'_>) -> Self { + fn new(delegate: RecentProjectsDelegate, rem_width: f32, cx: &mut ViewContext) -> Self { + let picker = cx.build_view(|cx| Picker::new(delegate, cx)); + let _subscription = cx.subscribe(&picker, |_, _, _, cx| cx.emit(DismissEvent)); Self { - picker: cx.build_view(|cx| Picker::new(delegate, cx)), + picker, + rem_width, + _subscription, } } @@ -76,9 +81,7 @@ impl RecentProjects { let delegate = RecentProjectsDelegate::new(weak_workspace, workspace_locations, true); - let modal = RecentProjects::new(delegate, cx); - cx.subscribe(&modal.picker, |_, _, _, cx| cx.emit(DismissEvent)) - .detach(); + let modal = RecentProjects::new(delegate, 34., cx); modal }); } else { @@ -94,11 +97,14 @@ impl RecentProjects { workspace: WeakView, workspaces: Vec, cx: &mut WindowContext<'_>, - ) -> Self { - Self::new( - RecentProjectsDelegate::new(workspace, workspaces, false), - cx, - ) + ) -> View { + cx.build_view(|cx| { + Self::new( + RecentProjectsDelegate::new(workspace, workspaces, false), + 20., + cx, + ) + }) } } @@ -113,8 +119,15 @@ impl FocusableView for RecentProjects { impl Render for RecentProjects { type Element = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { - v_stack().w(rems(34.)).child(self.picker.clone()) + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + v_stack() + .w(rems(self.rem_width)) + .child(self.picker.clone()) + .on_mouse_down_out(cx.listener(|this, _, cx| { + this.picker.update(cx, |this, cx| { + this.cancel(&Default::default(), cx); + }) + })) } } diff --git a/crates/vcs_menu2/src/lib.rs b/crates/vcs_menu2/src/lib.rs index ca3b685aa60ad93f63cc2ba203fa52a184ff564b..1483a2e81e8c6fe6470ed1b264cc4ff2a18a2a06 100644 --- a/crates/vcs_menu2/src/lib.rs +++ b/crates/vcs_menu2/src/lib.rs @@ -3,8 +3,8 @@ use fs::repository::Branch; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ actions, rems, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, - ParentElement, Render, SharedString, Styled, Task, View, ViewContext, VisualContext, - WindowContext, + InteractiveElement, ParentElement, Render, SharedString, Styled, Subscription, Task, View, + ViewContext, VisualContext, WindowContext, }; use picker::{Picker, PickerDelegate}; use std::sync::Arc; @@ -18,31 +18,61 @@ pub fn init(cx: &mut AppContext) { // todo!() po cx.observe_new_views(|workspace: &mut Workspace, _| { workspace.register_action(|workspace, action, cx| { - ModalBranchList::toggle_modal(workspace, action, cx).log_err(); + BranchList::toggle_modal(workspace, action, cx).log_err(); }); }) .detach(); } -pub type BranchList = Picker; -pub struct ModalBranchList { +pub struct BranchList { pub picker: View>, + rem_width: f32, + _subscription: Subscription, } -impl ModalView for ModalBranchList {} -impl EventEmitter for ModalBranchList {} +impl BranchList { + fn new(delegate: BranchListDelegate, rem_width: f32, cx: &mut ViewContext) -> Self { + let picker = cx.build_view(|cx| Picker::new(delegate, cx)); + let _subscription = cx.subscribe(&picker, |_, _, _, cx| cx.emit(DismissEvent)); + Self { + picker, + rem_width, + _subscription, + } + } + fn toggle_modal( + workspace: &mut Workspace, + _: &OpenRecent, + cx: &mut ViewContext, + ) -> Result<()> { + // Modal branch picker has a longer trailoff than a popover one. + let delegate = BranchListDelegate::new(workspace, cx.view().clone(), 70, cx)?; + workspace.toggle_modal(cx, |cx| BranchList::new(delegate, 34., cx)); -impl FocusableView for ModalBranchList { + Ok(()) + } +} +impl ModalView for BranchList {} +impl EventEmitter for BranchList {} + +impl FocusableView for BranchList { fn focus_handle(&self, cx: &AppContext) -> FocusHandle { self.picker.focus_handle(cx) } } -impl Render for ModalBranchList { +impl Render for BranchList { type Element = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { - v_stack().w(rems(34.)).child(self.picker.clone()) + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + v_stack() + .w(rems(self.rem_width)) + .child(self.picker.clone()) + .on_mouse_down_out(cx.listener(|this, _, cx| { + this.picker.update(cx, |this, cx| { + this.cancel(&Default::default(), cx); + }) + })) } } @@ -53,29 +83,7 @@ pub fn build_branch_list( let delegate = workspace.update(cx, |workspace, cx| { BranchListDelegate::new(workspace, cx.view().clone(), 29, cx) })?; - - Ok(cx.build_view(|cx| Picker::new(delegate, cx))) -} - -impl ModalBranchList { - fn toggle_modal( - workspace: &mut Workspace, - _: &OpenRecent, - cx: &mut ViewContext, - ) -> Result<()> { - // Modal branch picker has a longer trailoff than a popover one. - let delegate = BranchListDelegate::new(workspace, cx.view().clone(), 70, cx)?; - workspace.toggle_modal(cx, |cx| { - let modal = ModalBranchList { - picker: cx.build_view(|cx| Picker::new(delegate, cx)), - }; - cx.subscribe(&modal.picker, |_, _, _, cx| cx.emit(DismissEvent)) - .detach(); - modal - }); - - Ok(()) - } + Ok(cx.build_view(move |cx| BranchList::new(delegate, 20., cx))) } pub struct BranchListDelegate { @@ -116,7 +124,7 @@ impl BranchListDelegate { }) } - fn display_error_toast(&self, message: String, cx: &mut ViewContext) { + fn display_error_toast(&self, message: String, cx: &mut WindowContext<'_>) { const GIT_CHECKOUT_FAILURE_ID: usize = 2048; self.workspace.update(cx, |model, ctx| { model.show_toast(Toast::new(GIT_CHECKOUT_FAILURE_ID, message), ctx) From 5781cf6604fe70931147673256d5735ccb6572ae Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 20 Dec 2023 13:59:33 +0100 Subject: [PATCH 180/644] Use `InteractiveBounds` everywhere we change the cursor style --- crates/editor2/src/element.rs | 14 +++++++++++--- crates/gpui2/src/elements/text.rs | 7 +++---- crates/workspace2/src/pane_group.rs | 12 ++++++++---- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 7fc5244b92758024d8cf5df8afeca54d29d81d68..8031bc5db60923b2470f723035c4df801cdd164e 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -884,7 +884,11 @@ impl EditorElement { bounds: text_bounds, }), |cx| { - if text_bounds.contains(&cx.mouse_position()) { + let interactive_text_bounds = InteractiveBounds { + bounds: text_bounds, + stacking_order: cx.stacking_order().clone(), + }; + if interactive_text_bounds.visibly_contains(&cx.mouse_position(), cx) { if self .editor .read(cx) @@ -1361,8 +1365,12 @@ impl EditorElement { )); } + let interactive_track_bounds = InteractiveBounds { + bounds: track_bounds, + stacking_order: cx.stacking_order().clone(), + }; let mut mouse_position = cx.mouse_position(); - if track_bounds.contains(&mouse_position) { + if interactive_track_bounds.visibly_contains(&mouse_position, cx) { cx.set_cursor_style(CursorStyle::Arrow); } @@ -1392,7 +1400,7 @@ impl EditorElement { cx.stop_propagation(); } else { editor.scroll_manager.set_is_dragging_scrollbar(false, cx); - if track_bounds.contains(&event.position) { + if interactive_track_bounds.visibly_contains(&event.position, cx) { editor.scroll_manager.show_scrollbar(cx); } } diff --git a/crates/gpui2/src/elements/text.rs b/crates/gpui2/src/elements/text.rs index 175a79c19a512832c7c70571780adb6268b91ab2..7716d81536117a6213133db7cdf8377f94f1f647 100644 --- a/crates/gpui2/src/elements/text.rs +++ b/crates/gpui2/src/elements/text.rs @@ -358,14 +358,13 @@ impl Element for InteractiveText { fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { if let Some(click_listener) = self.click_listener.take() { - if let Some(ix) = state - .text_state - .index_for_position(bounds, cx.mouse_position()) - { + let mouse_position = cx.mouse_position(); + if let Some(ix) = state.text_state.index_for_position(bounds, mouse_position) { if self .clickable_ranges .iter() .any(|range| range.contains(&ix)) + && cx.was_top_layer(&mouse_position, cx.stacking_order()) { cx.set_cursor_style(crate::CursorStyle::PointingHand) } diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index 7416b72331b094ceeba92c0f32971c93d6dca33a..06bd506e56e68b0a6932c18f3cb1ee190f45ab40 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -564,9 +564,9 @@ mod element { use std::{cell::RefCell, iter, rc::Rc, sync::Arc}; use gpui::{ - px, relative, Along, AnyElement, Axis, Bounds, CursorStyle, Element, IntoElement, - MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, Size, Style, - WindowContext, + px, relative, Along, AnyElement, Axis, Bounds, CursorStyle, Element, InteractiveBounds, + IntoElement, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, + Size, Style, WindowContext, }; use parking_lot::Mutex; use smallvec::SmallVec; @@ -717,7 +717,11 @@ mod element { }; cx.with_z_index(3, |cx| { - if handle_bounds.contains(&cx.mouse_position()) { + let interactive_handle_bounds = InteractiveBounds { + bounds: handle_bounds, + stacking_order: cx.stacking_order().clone(), + }; + if interactive_handle_bounds.visibly_contains(&cx.mouse_position(), cx) { cx.set_cursor_style(match axis { Axis::Vertical => CursorStyle::ResizeUpDown, Axis::Horizontal => CursorStyle::ResizeLeftRight, From 8273865fa39e0a7e83cb3ec7ee6d3f35ef198da6 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 20 Dec 2023 14:00:12 +0100 Subject: [PATCH 181/644] Introduce `InteractiveElement::capture_any_mouse_{down,up}` --- crates/gpui2/src/elements/div.rs | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index fa1eb9e5b63454d0a3fa370913e094f30c3ad68c..908b302dfc1cd28f6ff873eff215d583d1b489f4 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -62,6 +62,18 @@ impl Interactivity { })); } + pub fn capture_any_mouse_down( + &mut self, + listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, + ) { + self.mouse_down_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Capture && bounds.visibly_contains(&event.position, cx) { + (listener)(event, cx) + } + })); + } + pub fn on_any_mouse_down( &mut self, listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, @@ -90,6 +102,18 @@ impl Interactivity { })); } + pub fn capture_any_mouse_up( + &mut self, + listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static, + ) { + self.mouse_up_listeners + .push(Box::new(move |event, bounds, phase, cx| { + if phase == DispatchPhase::Capture && bounds.visibly_contains(&event.position, cx) { + (listener)(event, cx) + } + })); + } + pub fn on_any_mouse_up( &mut self, listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static, @@ -384,6 +408,14 @@ pub trait InteractiveElement: Sized { self } + fn capture_any_mouse_down( + mut self, + listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, + ) -> Self { + self.interactivity().capture_any_mouse_down(listener); + self + } + fn on_any_mouse_down( mut self, listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, @@ -401,6 +433,14 @@ pub trait InteractiveElement: Sized { self } + fn capture_any_mouse_up( + mut self, + listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static, + ) -> Self { + self.interactivity().capture_any_mouse_up(listener); + self + } + fn on_mouse_down_out( mut self, listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static, From 390ccbc6ad26068af1ce963eefb94961ebeee3b5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 20 Dec 2023 14:00:47 +0100 Subject: [PATCH 182/644] Disable focus when disconnecting from host --- crates/gpui2/src/window.rs | 13 ++++++++++++- crates/workspace2/src/workspace2.rs | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index cc435bf0b2463c311f8b0833003c054ee4341f27..07be281f0aafede051b21ef9f4486fd3d8525246 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -273,6 +273,7 @@ pub struct Window { pub(crate) drawing: bool, activation_observers: SubscriberSet<(), AnyObserver>, pub(crate) focus: Option, + focus_enabled: bool, #[cfg(any(test, feature = "test-support"))] pub(crate) focus_invalidated: bool, @@ -420,6 +421,7 @@ impl Window { drawing: false, activation_observers: SubscriberSet::new(), focus: None, + focus_enabled: true, #[cfg(any(test, feature = "test-support"))] focus_invalidated: false, @@ -496,7 +498,7 @@ impl<'a> WindowContext<'a> { /// Move focus to the element associated with the given `FocusHandle`. pub fn focus(&mut self, handle: &FocusHandle) { - if self.window.focus == Some(handle.id) { + if !self.window.focus_enabled || self.window.focus == Some(handle.id) { return; } @@ -516,10 +518,19 @@ impl<'a> WindowContext<'a> { /// Remove focus from all elements within this context's window. pub fn blur(&mut self) { + if !self.window.focus_enabled { + return; + } + self.window.focus = None; self.notify(); } + pub fn disable_focus(&mut self) { + self.blur(); + self.window.focus_enabled = false; + } + pub fn dispatch_action(&mut self, action: Box) { let focus_handle = self.focused(); diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 95b05f314e73b7bffdd798423fca5d599fe965eb..a5acd1c1c7a8b835a89b782934c95fbeaf92e062 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -502,7 +502,7 @@ impl Workspace { project::Event::DisconnectedFromHost => { this.update_window_edited(cx); - cx.blur(); + cx.disable_focus(); } project::Event::Closed => { From 57f3a882fe50fdc22dbf4317549e6222b0a735ea Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 20 Dec 2023 14:07:01 +0100 Subject: [PATCH 183/644] Render disconnected overlay when project becomes readonly --- crates/workspace2/src/workspace2.rs | 95 +++++++++++++++++++---------- 1 file changed, 63 insertions(+), 32 deletions(-) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index a5acd1c1c7a8b835a89b782934c95fbeaf92e062..797e95088d89970f5759efee28b14e5237325f3b 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -25,12 +25,13 @@ use futures::{ Future, FutureExt, StreamExt, }; use gpui::{ - actions, canvas, div, impl_actions, point, size, Action, AnyModel, AnyView, AnyWeakView, - AnyWindowHandle, AppContext, AsyncAppContext, AsyncWindowContext, Bounds, Context, Div, - DragMoveEvent, Entity, EntityId, EventEmitter, FocusHandle, FocusableView, GlobalPixels, - InteractiveElement, KeyContext, ManagedView, Model, ModelContext, ParentElement, - PathPromptOptions, Pixels, Point, PromptLevel, Render, Size, Styled, Subscription, Task, View, - ViewContext, VisualContext, WeakView, WindowBounds, WindowContext, WindowHandle, WindowOptions, + actions, canvas, div, impl_actions, point, size, Action, AnyElement, AnyModel, AnyView, + AnyWeakView, AnyWindowHandle, AppContext, AsyncAppContext, AsyncWindowContext, BorrowWindow, + Bounds, Context, Div, DragMoveEvent, Element, Entity, EntityId, EventEmitter, FocusHandle, + FocusableView, GlobalPixels, InteractiveElement, IntoElement, KeyContext, LayoutId, + ManagedView, Model, ModelContext, ParentElement, PathPromptOptions, Pixels, Point, PromptLevel, + Render, Size, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, + WindowBounds, WindowContext, WindowHandle, WindowOptions, }; use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem}; use itertools::Itertools; @@ -64,6 +65,7 @@ use std::{ use theme::{ActiveTheme, ThemeSettings}; pub use toolbar::{Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView}; pub use ui; +use ui::Label; use util::ResultExt; use uuid::Uuid; pub use workspace_settings::{AutosaveSetting, WorkspaceSettings}; @@ -2519,32 +2521,6 @@ impl Workspace { } } - // fn render_disconnected_overlay( - // &self, - // cx: &mut ViewContext, - // ) -> Option> { - // if self.project.read(cx).is_read_only() { - // enum DisconnectedOverlay {} - // Some( - // MouseEventHandler::new::(0, cx, |_, cx| { - // let theme = &theme::current(cx); - // Label::new( - // "Your connection to the remote project has been lost.", - // theme.workspace.disconnected_overlay.text.clone(), - // ) - // .aligned() - // .contained() - // .with_style(theme.workspace.disconnected_overlay.container) - // }) - // .with_cursor_style(CursorStyle::Arrow) - // .capture_all() - // .into_any_named("disconnected overlay"), - // ) - // } else { - // None - // } - // } - fn render_notifications(&self, _cx: &ViewContext) -> Option
{ if self.notifications.is_empty() { None @@ -3661,6 +3637,11 @@ impl Render for Workspace { })), ) .child(self.status_bar.clone()) + .children(if self.project.read(cx).is_read_only() { + Some(DisconnectedOverlay) + } else { + None + }) } } @@ -4284,6 +4265,56 @@ fn parse_pixel_size_env_var(value: &str) -> Option> { Some(size((width as f64).into(), (height as f64).into())) } +struct DisconnectedOverlay; + +impl Element for DisconnectedOverlay { + type State = AnyElement; + + fn layout( + &mut self, + _: Option, + cx: &mut WindowContext, + ) -> (LayoutId, Self::State) { + let mut background = cx.theme().colors().elevated_surface_background; + background.fade_out(0.2); + let mut overlay = div() + .bg(background) + .absolute() + .left_0() + .top_0() + .size_full() + .flex() + .items_center() + .justify_center() + .capture_any_mouse_down(|_, cx| cx.stop_propagation()) + .capture_any_mouse_up(|_, cx| cx.stop_propagation()) + .child(Label::new( + "Your connection to the remote project has been lost.", + )) + .into_any(); + (overlay.layout(cx), overlay) + } + + fn paint(&mut self, bounds: Bounds, overlay: &mut Self::State, cx: &mut WindowContext) { + cx.with_z_index(u8::MAX, |cx| { + cx.add_opaque_layer(bounds); + overlay.paint(cx); + }) + } +} + +impl IntoElement for DisconnectedOverlay { + type Element = Self; + + fn element_id(&self) -> Option { + None + } + + fn into_element(self) -> Self::Element { + self + } +} + #[cfg(test)] mod tests { use std::{cell::RefCell, rc::Rc}; From 6e1ba645f3e73fe0e867d27b2152d853ef74a2ab Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 20 Dec 2023 14:17:15 +0100 Subject: [PATCH 184/644] Show button as selected if screen sharing is on --- crates/collab_ui2/src/collab_titlebar_item.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 9359ff41d8fdba6bed1e64fc597285c8618c05a5..ae664859192e2bbb635d1f4552f604106bc61b54 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -176,6 +176,7 @@ impl Render for CollabTitlebarItem { let is_shared = self.project.read(cx).is_shared(); let is_muted = room.is_muted(cx); let is_deafened = room.is_deafened().unwrap_or(false); + let is_screen_sharing = room.is_screen_sharing(); this.child( Button::new( @@ -225,7 +226,7 @@ impl Render for CollabTitlebarItem { }, ) .style(ButtonStyle::Subtle) - .selected(is_deafened.clone()) + .selected(is_deafened) .tooltip(move |cx| { Tooltip::with_meta("Deafen Audio", None, "Mic will be muted", cx) }) @@ -234,6 +235,7 @@ impl Render for CollabTitlebarItem { .child( IconButton::new("screen-share", ui::Icon::Screen) .style(ButtonStyle::Subtle) + .selected(is_screen_sharing) .on_click(move |_, cx| { crate::toggle_screen_sharing(&Default::default(), cx) }), From 12bb13b9fc73cb099c565b33b89a64479990fec7 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 08:20:00 -0700 Subject: [PATCH 185/644] Perform a bounds check when allocating in the arena This ensures we don't invoke undefined behavior when overflowing. Co-Authored-By: Antonio --- crates/gpui2/src/arena.rs | 53 ++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index c99f09d29f46e33117698cfc8ffbacaa239c9e9e..5992baf06e1366bfa0aa0ddeb3a09c1c39b95f6a 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -2,13 +2,13 @@ use std::{ alloc, cell::Cell, ops::{Deref, DerefMut}, - ptr::{self, NonNull}, + ptr, rc::Rc, }; struct ArenaElement { - value: NonNull, - drop: unsafe fn(NonNull), + value: *mut u8, + drop: unsafe fn(*mut u8), } impl Drop for ArenaElement { @@ -21,8 +21,9 @@ impl Drop for ArenaElement { } pub struct Arena { - start: NonNull, - offset: usize, + start: *mut u8, + end: *mut u8, + offset: *mut u8, elements: Vec, valid: Rc>, } @@ -31,10 +32,12 @@ impl Arena { pub fn new(size_in_bytes: usize) -> Self { unsafe { let layout = alloc::Layout::from_size_align(size_in_bytes, 1).unwrap(); - let ptr = alloc::alloc(layout); + let start = alloc::alloc(layout); + let end = start.add(size_in_bytes); Self { - start: NonNull::new_unchecked(ptr), - offset: 0, + start, + end, + offset: start, elements: Vec::new(), valid: Rc::new(Cell::new(true)), } @@ -45,7 +48,7 @@ impl Arena { self.valid.set(false); self.valid = Rc::new(Cell::new(true)); self.elements.clear(); - self.offset = 0; + self.offset = self.start; } #[inline(always)] @@ -58,24 +61,28 @@ impl Arena { ptr::write(ptr, f()); } - unsafe fn drop(ptr: NonNull) { - std::ptr::drop_in_place(ptr.cast::().as_ptr()); + unsafe fn drop(ptr: *mut u8) { + std::ptr::drop_in_place(ptr.cast::()); } unsafe { let layout = alloc::Layout::new::().pad_to_align(); - let ptr = NonNull::new_unchecked(self.start.as_ptr().add(self.offset).cast::()); - inner_writer(ptr.as_ptr(), f); + let next_offset = self.offset.add(layout.size()); + assert!(next_offset <= self.end); + let result = ArenaRef { + ptr: self.offset.cast(), + valid: self.valid.clone(), + }; + + inner_writer(result.ptr, f); self.elements.push(ArenaElement { - value: ptr.cast(), + value: self.offset, drop: drop::, }); - self.offset += layout.size(); - ArenaRef { - ptr, - valid: self.valid.clone(), - } + self.offset = next_offset; + + result } } } @@ -87,7 +94,7 @@ impl Drop for Arena { } pub struct ArenaRef { - ptr: NonNull, + ptr: *mut T, valid: Rc>, } @@ -104,7 +111,7 @@ impl ArenaRef { #[inline(always)] pub fn map(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaRef { ArenaRef { - ptr: unsafe { NonNull::new_unchecked(f(&mut *self)) }, + ptr: f(&mut self), valid: self.valid, } } @@ -123,7 +130,7 @@ impl Deref for ArenaRef { #[inline(always)] fn deref(&self) -> &Self::Target { self.validate(); - unsafe { self.ptr.as_ref() } + unsafe { &*self.ptr } } } @@ -131,7 +138,7 @@ impl DerefMut for ArenaRef { #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { self.validate(); - unsafe { self.ptr.as_mut() } + unsafe { &mut *self.ptr } } } From 5b29c89e1ce333e298138988844d5080c8a33abf Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 08:55:18 -0700 Subject: [PATCH 186/644] Clear pending click state when dragging Once a drag starts, we won't fire click listeners or style any elements as active. Co-Authored-By: Antonio --- crates/gpui2/src/elements/div.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 908b302dfc1cd28f6ff873eff215d583d1b489f4..d5284c02a166911fbc536f152ef53586e2bbe54a 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -919,6 +919,15 @@ impl Interactivity { ) -> (LayoutId, InteractiveElementState) { let mut element_state = element_state.unwrap_or_default(); + if cx.has_active_drag() { + if let Some(pending_mouse_down) = element_state.pending_mouse_down.as_ref() { + *pending_mouse_down.borrow_mut() = None; + } + if let Some(clicked_state) = element_state.clicked_state.as_ref() { + *clicked_state.borrow_mut() = ElementClickedState::default(); + } + } + // Ensure we store a focus handle in our element state if we're focusable. // If there's an explicit focus handle we're tracking, use that. Otherwise // create a new handle and store it in the element state, which lives for as @@ -1204,7 +1213,7 @@ impl Interactivity { .get_or_insert_with(Default::default) .clone(); - let active_state = element_state + let clicked_state = element_state .clicked_state .get_or_insert_with(Default::default) .clone(); @@ -1237,7 +1246,7 @@ impl Interactivity { > DRAG_THRESHOLD { if let Some((drag_value, drag_listener)) = drag_listener.take() { - *active_state.borrow_mut() = ElementClickedState::default(); + *clicked_state.borrow_mut() = ElementClickedState::default(); let cursor_offset = event.position - bounds.origin; let drag = (drag_listener)(drag_value.as_ref(), cx); cx.active_drag = Some(AnyDrag { @@ -1384,14 +1393,14 @@ impl Interactivity { } } - let active_state = element_state + let clicked_state = element_state .clicked_state .get_or_insert_with(Default::default) .clone(); - if active_state.borrow().is_clicked() { + if clicked_state.borrow().is_clicked() { cx.on_mouse_event(move |_: &MouseUpEvent, phase, cx| { if phase == DispatchPhase::Capture { - *active_state.borrow_mut() = ElementClickedState::default(); + *clicked_state.borrow_mut() = ElementClickedState::default(); cx.notify(); } }); @@ -1407,7 +1416,7 @@ impl Interactivity { .map_or(false, |bounds| bounds.contains(&down.position)); let element = interactive_bounds.visibly_contains(&down.position, cx); if group || element { - *active_state.borrow_mut() = ElementClickedState { group, element }; + *clicked_state.borrow_mut() = ElementClickedState { group, element }; cx.notify(); } } From 229b5aa8f79976520be4883bfb01859f5e821e36 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 10:57:15 -0500 Subject: [PATCH 187/644] Style links in terminal (#3736) This PR styles links in the terminal using the colors from the theme. Release Notes: - N/A --- crates/terminal_view2/src/terminal_element.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index 07910896f31320d108e45490e3aab70c06a76fb1..f30c1cf1bc186f3d9f121739f6a00bdf59fb0c75 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -395,13 +395,13 @@ impl TerminalElement { let theme = cx.theme().clone(); let link_style = HighlightStyle { - color: Some(gpui::blue()), + color: Some(theme.colors().link_text_hover), font_weight: None, font_style: None, background_color: None, underline: Some(UnderlineStyle { thickness: px(1.0), - color: Some(gpui::red()), + color: Some(theme.colors().link_text_hover), wavy: false, }), fade_out: None, From 64925231b0b3a6a40da37fd8d9b124bc3a6abaad Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 14 Dec 2023 15:20:49 +0200 Subject: [PATCH 188/644] Create a new crate --- Cargo.lock | 23 + Cargo.toml | 1 + crates/language_tools2/Cargo.toml | 33 + crates/language_tools2/src/language_tools.rs | 15 + crates/language_tools2/src/lsp_log.rs | 1023 +++++++++++++++++ crates/language_tools2/src/lsp_log_tests.rs | 109 ++ .../language_tools2/src/syntax_tree_view.rs | 677 +++++++++++ 7 files changed, 1881 insertions(+) create mode 100644 crates/language_tools2/Cargo.toml create mode 100644 crates/language_tools2/src/language_tools.rs create mode 100644 crates/language_tools2/src/lsp_log.rs create mode 100644 crates/language_tools2/src/lsp_log_tests.rs create mode 100644 crates/language_tools2/src/syntax_tree_view.rs diff --git a/Cargo.lock b/Cargo.lock index cb0d54022f2d4233285fd66735a21625064cb38f..4f418a1813837cdb60f325305aa223a4b1a8a41e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4990,6 +4990,29 @@ dependencies = [ "workspace", ] +[[package]] +name = "language_tools2" +version = "0.1.0" +dependencies = [ + "anyhow", + "client2", + "collections", + "editor2", + "env_logger 0.9.3", + "futures 0.3.28", + "gpui2", + "language2", + "lsp2", + "project2", + "serde", + "settings2", + "theme2", + "tree-sitter", + "unindent", + "util", + "workspace2", +] + [[package]] name = "lazy_static" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index 3b453527b89dca285b303c9ddd89d5bcc6792310..42432a8a2a0f6fa3d713769f7b7c14f962d02520 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,6 +64,7 @@ members = [ "crates/language_selector", "crates/language_selector2", "crates/language_tools", + "crates/language_tools2", "crates/live_kit_client", "crates/live_kit_server", "crates/lsp", diff --git a/crates/language_tools2/Cargo.toml b/crates/language_tools2/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..ca3ede2ef9a1e80e32afedec15bf8c0bdf02afbc --- /dev/null +++ b/crates/language_tools2/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "language_tools2" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +path = "src/language_tools.rs" +doctest = false + +[dependencies] +collections = { path = "../collections" } +editor = { package = "editor2", path = "../editor2" } +settings = { package = "settings2", path = "../settings2" } +theme = { package = "theme2", path = "../theme2" } +language = { package = "language2", path = "../language2" } +project = { package = "project2", path = "../project2" } +workspace = { package = "workspace2", path = "../workspace2" } +gpui = { package = "gpui2", path = "../gpui2" } +util = { path = "../util" } +lsp = { package = "lsp2", path = "../lsp2" } +futures.workspace = true +serde.workspace = true +anyhow.workspace = true +tree-sitter.workspace = true + +[dev-dependencies] +client = { package = "client2", path = "../client2", features = ["test-support"] } +editor = { package = "editor2", path = "../editor2", features = ["test-support"] } +gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] } +util = { path = "../util", features = ["test-support"] } +env_logger.workspace = true +unindent.workspace = true diff --git a/crates/language_tools2/src/language_tools.rs b/crates/language_tools2/src/language_tools.rs new file mode 100644 index 0000000000000000000000000000000000000000..0a1f31f03fe82eece9911a9ecc474cd714a364c4 --- /dev/null +++ b/crates/language_tools2/src/language_tools.rs @@ -0,0 +1,15 @@ +mod lsp_log; +mod syntax_tree_view; + +#[cfg(test)] +mod lsp_log_tests; + +use gpui::AppContext; + +pub use lsp_log::{LogStore, LspLogToolbarItemView, LspLogView}; +pub use syntax_tree_view::{SyntaxTreeToolbarItemView, SyntaxTreeView}; + +pub fn init(cx: &mut AppContext) { + lsp_log::init(cx); + syntax_tree_view::init(cx); +} diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs new file mode 100644 index 0000000000000000000000000000000000000000..9f27c62a04a001a15ba5f4d7142505fc4e32290b --- /dev/null +++ b/crates/language_tools2/src/lsp_log.rs @@ -0,0 +1,1023 @@ +use collections::{HashMap, VecDeque}; +use editor::{Editor, MoveToEnd}; +use futures::{channel::mpsc, StreamExt}; +use gpui::{ + actions, + elements::{ + AnchorCorner, ChildView, Empty, Flex, Label, MouseEventHandler, Overlay, OverlayFitMode, + ParentElement, Stack, + }, + platform::{CursorStyle, MouseButton}, + AnyElement, AppContext, Element, Entity, Model, ModelContext, Subscription, View, View, + ViewContext, WeakModel, +}; +use language::{LanguageServerId, LanguageServerName}; +use lsp::IoKind; +use project::{search::SearchQuery, Project}; +use std::{borrow::Cow, sync::Arc}; +use theme::{ui, Theme}; +use workspace::{ + item::{Item, ItemHandle}, + searchable::{SearchableItem, SearchableItemHandle}, + ToolbarItemLocation, ToolbarItemView, Workspace, WorkspaceCreated, +}; + +const SEND_LINE: &str = "// Send:"; +const RECEIVE_LINE: &str = "// Receive:"; +const MAX_STORED_LOG_ENTRIES: usize = 2000; + +pub struct LogStore { + projects: HashMap, ProjectState>, + io_tx: mpsc::UnboundedSender<(WeakModel, LanguageServerId, IoKind, String)>, +} + +struct ProjectState { + servers: HashMap, + _subscriptions: [gpui::Subscription; 2], +} + +struct LanguageServerState { + log_messages: VecDeque, + rpc_state: Option, + _io_logs_subscription: Option, + _lsp_logs_subscription: Option, +} + +struct LanguageServerRpcState { + rpc_messages: VecDeque, + last_message_kind: Option, +} + +pub struct LspLogView { + pub(crate) editor: View, + editor_subscription: Subscription, + log_store: Model, + current_server_id: Option, + is_showing_rpc_trace: bool, + project: Model, + _log_store_subscriptions: Vec, +} + +pub struct LspLogToolbarItemView { + log_view: Option>, + _log_view_subscription: Option, + menu_open: bool, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +enum MessageKind { + Send, + Receive, +} + +#[derive(Clone, Debug, PartialEq)] +pub(crate) struct LogMenuItem { + pub server_id: LanguageServerId, + pub server_name: LanguageServerName, + pub worktree_root_name: String, + pub rpc_trace_enabled: bool, + pub rpc_trace_selected: bool, + pub logs_selected: bool, +} + +actions!(debug, [OpenLanguageServerLogs]); + +pub fn init(cx: &mut AppContext) { + let log_store = cx.add_model(|cx| LogStore::new(cx)); + + cx.subscribe_global::({ + let log_store = log_store.clone(); + move |event, cx| { + let workspace = &event.0; + if let Some(workspace) = workspace.upgrade(cx) { + let project = workspace.read(cx).project().clone(); + if project.read(cx).is_local() { + log_store.update(cx, |store, cx| { + store.add_project(&project, cx); + }); + } + } + } + }) + .detach(); + + cx.add_action( + move |workspace: &mut Workspace, _: &OpenLanguageServerLogs, cx: _| { + let project = workspace.project().read(cx); + if project.is_local() { + workspace.add_item( + Box::new(cx.add_view(|cx| { + LspLogView::new(workspace.project().clone(), log_store.clone(), cx) + })), + cx, + ); + } + }, + ); +} + +impl LogStore { + pub fn new(cx: &mut ModelContext) -> Self { + let (io_tx, mut io_rx) = mpsc::unbounded(); + let this = Self { + projects: HashMap::default(), + io_tx, + }; + cx.spawn_weak(|this, mut cx| async move { + while let Some((project, server_id, io_kind, message)) = io_rx.next().await { + if let Some(this) = this.upgrade(&cx) { + this.update(&mut cx, |this, cx| { + this.on_io(project, server_id, io_kind, &message, cx); + }); + } + } + anyhow::Ok(()) + }) + .detach(); + this + } + + pub fn add_project(&mut self, project: &Model, cx: &mut ModelContext) { + let weak_project = project.downgrade(); + self.projects.insert( + weak_project, + ProjectState { + servers: HashMap::default(), + _subscriptions: [ + cx.observe_release(&project, move |this, _, _| { + this.projects.remove(&weak_project); + }), + cx.subscribe(project, |this, project, event, cx| match event { + project::Event::LanguageServerAdded(id) => { + this.add_language_server(&project, *id, cx); + } + project::Event::LanguageServerRemoved(id) => { + this.remove_language_server(&project, *id, cx); + } + project::Event::LanguageServerLog(id, message) => { + this.add_language_server_log(&project, *id, message, cx); + } + _ => {} + }), + ], + }, + ); + } + + fn add_language_server( + &mut self, + project: &Model, + id: LanguageServerId, + cx: &mut ModelContext, + ) -> Option<&mut LanguageServerState> { + let project_state = self.projects.get_mut(&project.downgrade())?; + let server_state = project_state.servers.entry(id).or_insert_with(|| { + cx.notify(); + LanguageServerState { + rpc_state: None, + log_messages: VecDeque::with_capacity(MAX_STORED_LOG_ENTRIES), + _io_logs_subscription: None, + _lsp_logs_subscription: None, + } + }); + + let server = project.read(cx).language_server_for_id(id); + if let Some(server) = server.as_deref() { + if server.has_notification_handler::() { + // Another event wants to re-add the server that was already added and subscribed to, avoid doing it again. + return Some(server_state); + } + } + + let weak_project = project.downgrade(); + let io_tx = self.io_tx.clone(); + server_state._io_logs_subscription = server.as_ref().map(|server| { + server.on_io(move |io_kind, message| { + io_tx + .unbounded_send((weak_project, id, io_kind, message.to_string())) + .ok(); + }) + }); + let this = cx.weak_handle(); + let weak_project = project.downgrade(); + server_state._lsp_logs_subscription = server.map(|server| { + let server_id = server.server_id(); + server.on_notification::({ + move |params, mut cx| { + if let Some((project, this)) = + weak_project.upgrade(&mut cx).zip(this.upgrade(&mut cx)) + { + this.update(&mut cx, |this, cx| { + this.add_language_server_log(&project, server_id, ¶ms.message, cx); + }); + } + } + }) + }); + Some(server_state) + } + + fn add_language_server_log( + &mut self, + project: &Model, + id: LanguageServerId, + message: &str, + cx: &mut ModelContext, + ) -> Option<()> { + let language_server_state = match self + .projects + .get_mut(&project.downgrade())? + .servers + .get_mut(&id) + { + Some(existing_state) => existing_state, + None => self.add_language_server(&project, id, cx)?, + }; + + let log_lines = &mut language_server_state.log_messages; + while log_lines.len() >= MAX_STORED_LOG_ENTRIES { + log_lines.pop_front(); + } + let message = message.trim(); + log_lines.push_back(message.to_string()); + cx.emit(Event::NewServerLogEntry { + id, + entry: message.to_string(), + is_rpc: false, + }); + cx.notify(); + Some(()) + } + + fn remove_language_server( + &mut self, + project: &Model, + id: LanguageServerId, + cx: &mut ModelContext, + ) -> Option<()> { + let project_state = self.projects.get_mut(&project.downgrade())?; + project_state.servers.remove(&id); + cx.notify(); + Some(()) + } + + fn server_logs( + &self, + project: &Model, + server_id: LanguageServerId, + ) -> Option<&VecDeque> { + let weak_project = project.downgrade(); + let project_state = self.projects.get(&weak_project)?; + let server_state = project_state.servers.get(&server_id)?; + Some(&server_state.log_messages) + } + + fn enable_rpc_trace_for_language_server( + &mut self, + project: &Model, + server_id: LanguageServerId, + ) -> Option<&mut LanguageServerRpcState> { + let weak_project = project.downgrade(); + let project_state = self.projects.get_mut(&weak_project)?; + let server_state = project_state.servers.get_mut(&server_id)?; + let rpc_state = server_state + .rpc_state + .get_or_insert_with(|| LanguageServerRpcState { + rpc_messages: VecDeque::with_capacity(MAX_STORED_LOG_ENTRIES), + last_message_kind: None, + }); + Some(rpc_state) + } + + pub fn disable_rpc_trace_for_language_server( + &mut self, + project: &Model, + server_id: LanguageServerId, + _: &mut ModelContext, + ) -> Option<()> { + let project = project.downgrade(); + let project_state = self.projects.get_mut(&project)?; + let server_state = project_state.servers.get_mut(&server_id)?; + server_state.rpc_state.take(); + Some(()) + } + + fn on_io( + &mut self, + project: WeakModel, + language_server_id: LanguageServerId, + io_kind: IoKind, + message: &str, + cx: &mut ModelContext, + ) -> Option<()> { + let is_received = match io_kind { + IoKind::StdOut => true, + IoKind::StdIn => false, + IoKind::StdErr => { + let project = project.upgrade(cx)?; + let message = format!("stderr: {}", message.trim()); + self.add_language_server_log(&project, language_server_id, &message, cx); + return Some(()); + } + }; + + let state = self + .projects + .get_mut(&project)? + .servers + .get_mut(&language_server_id)? + .rpc_state + .as_mut()?; + let kind = if is_received { + MessageKind::Receive + } else { + MessageKind::Send + }; + + let rpc_log_lines = &mut state.rpc_messages; + if state.last_message_kind != Some(kind) { + let line_before_message = match kind { + MessageKind::Send => SEND_LINE, + MessageKind::Receive => RECEIVE_LINE, + }; + rpc_log_lines.push_back(line_before_message.to_string()); + cx.emit(Event::NewServerLogEntry { + id: language_server_id, + entry: line_before_message.to_string(), + is_rpc: true, + }); + } + + while rpc_log_lines.len() >= MAX_STORED_LOG_ENTRIES { + rpc_log_lines.pop_front(); + } + let message = message.trim(); + rpc_log_lines.push_back(message.to_string()); + cx.emit(Event::NewServerLogEntry { + id: language_server_id, + entry: message.to_string(), + is_rpc: true, + }); + cx.notify(); + Some(()) + } +} + +impl LspLogView { + pub fn new( + project: Model, + log_store: Model, + cx: &mut ViewContext, + ) -> Self { + let server_id = log_store + .read(cx) + .projects + .get(&project.downgrade()) + .and_then(|project| project.servers.keys().copied().next()); + let model_changes_subscription = cx.observe(&log_store, |this, store, cx| { + (|| -> Option<()> { + let project_state = store.read(cx).projects.get(&this.project.downgrade())?; + if let Some(current_lsp) = this.current_server_id { + if !project_state.servers.contains_key(¤t_lsp) { + if let Some(server) = project_state.servers.iter().next() { + if this.is_showing_rpc_trace { + this.show_rpc_trace_for_server(*server.0, cx) + } else { + this.show_logs_for_server(*server.0, cx) + } + } else { + this.current_server_id = None; + this.editor.update(cx, |editor, cx| { + editor.set_read_only(false); + editor.clear(cx); + editor.set_read_only(true); + }); + cx.notify(); + } + } + } else { + if let Some(server) = project_state.servers.iter().next() { + if this.is_showing_rpc_trace { + this.show_rpc_trace_for_server(*server.0, cx) + } else { + this.show_logs_for_server(*server.0, cx) + } + } + } + + Some(()) + })(); + + cx.notify(); + }); + let events_subscriptions = cx.subscribe(&log_store, |log_view, _, e, cx| match e { + Event::NewServerLogEntry { id, entry, is_rpc } => { + if log_view.current_server_id == Some(*id) { + if (*is_rpc && log_view.is_showing_rpc_trace) + || (!*is_rpc && !log_view.is_showing_rpc_trace) + { + log_view.editor.update(cx, |editor, cx| { + editor.set_read_only(false); + editor.handle_input(entry.trim(), cx); + editor.handle_input("\n", cx); + editor.set_read_only(true); + }); + } + } + } + }); + let (editor, editor_subscription) = Self::editor_for_logs(String::new(), cx); + let mut this = Self { + editor, + editor_subscription, + project, + log_store, + current_server_id: None, + is_showing_rpc_trace: false, + _log_store_subscriptions: vec![model_changes_subscription, events_subscriptions], + }; + if let Some(server_id) = server_id { + this.show_logs_for_server(server_id, cx); + } + this + } + + fn editor_for_logs( + log_contents: String, + cx: &mut ViewContext, + ) -> (View, Subscription) { + let editor = cx.add_view(|cx| { + let mut editor = Editor::multi_line(None, cx); + editor.set_text(log_contents, cx); + editor.move_to_end(&MoveToEnd, cx); + editor.set_read_only(true); + editor + }); + let editor_subscription = cx.subscribe(&editor, |_, _, event, cx| cx.emit(event.clone())); + (editor, editor_subscription) + } + + pub(crate) fn menu_items<'a>(&'a self, cx: &'a AppContext) -> Option> { + let log_store = self.log_store.read(cx); + let state = log_store.projects.get(&self.project.downgrade())?; + let mut rows = self + .project + .read(cx) + .language_servers() + .filter_map(|(server_id, language_server_name, worktree_id)| { + let worktree = self.project.read(cx).worktree_for_id(worktree_id, cx)?; + let state = state.servers.get(&server_id)?; + Some(LogMenuItem { + server_id, + server_name: language_server_name, + worktree_root_name: worktree.read(cx).root_name().to_string(), + rpc_trace_enabled: state.rpc_state.is_some(), + rpc_trace_selected: self.is_showing_rpc_trace + && self.current_server_id == Some(server_id), + logs_selected: !self.is_showing_rpc_trace + && self.current_server_id == Some(server_id), + }) + }) + .chain( + self.project + .read(cx) + .supplementary_language_servers() + .filter_map(|(&server_id, (name, _))| { + let state = state.servers.get(&server_id)?; + Some(LogMenuItem { + server_id, + server_name: name.clone(), + worktree_root_name: "supplementary".to_string(), + rpc_trace_enabled: state.rpc_state.is_some(), + rpc_trace_selected: self.is_showing_rpc_trace + && self.current_server_id == Some(server_id), + logs_selected: !self.is_showing_rpc_trace + && self.current_server_id == Some(server_id), + }) + }), + ) + .collect::>(); + rows.sort_by_key(|row| row.server_id); + rows.dedup_by_key(|row| row.server_id); + Some(rows) + } + + fn show_logs_for_server(&mut self, server_id: LanguageServerId, cx: &mut ViewContext) { + let log_contents = self + .log_store + .read(cx) + .server_logs(&self.project, server_id) + .map(log_contents); + if let Some(log_contents) = log_contents { + self.current_server_id = Some(server_id); + self.is_showing_rpc_trace = false; + let (editor, editor_subscription) = Self::editor_for_logs(log_contents, cx); + self.editor = editor; + self.editor_subscription = editor_subscription; + cx.notify(); + } + } + + fn show_rpc_trace_for_server( + &mut self, + server_id: LanguageServerId, + cx: &mut ViewContext, + ) { + let rpc_log = self.log_store.update(cx, |log_store, _| { + log_store + .enable_rpc_trace_for_language_server(&self.project, server_id) + .map(|state| log_contents(&state.rpc_messages)) + }); + if let Some(rpc_log) = rpc_log { + self.current_server_id = Some(server_id); + self.is_showing_rpc_trace = true; + let (editor, editor_subscription) = Self::editor_for_logs(rpc_log, cx); + let language = self.project.read(cx).languages().language_for_name("JSON"); + editor + .read(cx) + .buffer() + .read(cx) + .as_singleton() + .expect("log buffer should be a singleton") + .update(cx, |_, cx| { + cx.spawn_weak({ + let buffer = cx.handle(); + |_, mut cx| async move { + let language = language.await.ok(); + buffer.update(&mut cx, |buffer, cx| { + buffer.set_language(language, cx); + }); + } + }) + .detach(); + }); + + self.editor = editor; + self.editor_subscription = editor_subscription; + cx.notify(); + } + } + + fn toggle_rpc_trace_for_server( + &mut self, + server_id: LanguageServerId, + enabled: bool, + cx: &mut ViewContext, + ) { + self.log_store.update(cx, |log_store, cx| { + if enabled { + log_store.enable_rpc_trace_for_language_server(&self.project, server_id); + } else { + log_store.disable_rpc_trace_for_language_server(&self.project, server_id, cx); + } + }); + if !enabled && Some(server_id) == self.current_server_id { + self.show_logs_for_server(server_id, cx); + cx.notify(); + } + } +} + +fn log_contents(lines: &VecDeque) -> String { + let (a, b) = lines.as_slices(); + let log_contents = a.join("\n"); + if b.is_empty() { + log_contents + } else { + log_contents + "\n" + &b.join("\n") + } +} + +impl View for LspLogView { + fn ui_name() -> &'static str { + "LspLogView" + } + + fn render(&mut self, cx: &mut ViewContext) -> AnyElement { + ChildView::new(&self.editor, cx).into_any() + } + + fn focus_in(&mut self, _: gpui::AnyView, cx: &mut ViewContext) { + if cx.is_self_focused() { + cx.focus(&self.editor); + } + } +} + +impl Item for LspLogView { + fn tab_content( + &self, + _: Option, + style: &theme::Tab, + _: &AppContext, + ) -> AnyElement { + Label::new("LSP Logs", style.label.clone()).into_any() + } + + fn as_searchable(&self, handle: &View) -> Option> { + Some(Box::new(handle.clone())) + } +} + +impl SearchableItem for LspLogView { + type Match = ::Match; + + fn to_search_event( + &mut self, + event: &Self::Event, + cx: &mut ViewContext, + ) -> Option { + self.editor + .update(cx, |editor, cx| editor.to_search_event(event, cx)) + } + + fn clear_matches(&mut self, cx: &mut ViewContext) { + self.editor.update(cx, |e, cx| e.clear_matches(cx)) + } + + fn update_matches(&mut self, matches: Vec, cx: &mut ViewContext) { + self.editor + .update(cx, |e, cx| e.update_matches(matches, cx)) + } + + fn query_suggestion(&mut self, cx: &mut ViewContext) -> String { + self.editor.update(cx, |e, cx| e.query_suggestion(cx)) + } + + fn activate_match( + &mut self, + index: usize, + matches: Vec, + cx: &mut ViewContext, + ) { + self.editor + .update(cx, |e, cx| e.activate_match(index, matches, cx)) + } + + fn select_matches(&mut self, matches: Vec, cx: &mut ViewContext) { + self.editor + .update(cx, |e, cx| e.select_matches(matches, cx)) + } + + fn find_matches( + &mut self, + query: Arc, + cx: &mut ViewContext, + ) -> gpui::Task> { + self.editor.update(cx, |e, cx| e.find_matches(query, cx)) + } + + fn replace(&mut self, _: &Self::Match, _: &SearchQuery, _: &mut ViewContext) { + // Since LSP Log is read-only, it doesn't make sense to support replace operation. + } + fn supported_options() -> workspace::searchable::SearchOptions { + workspace::searchable::SearchOptions { + case: true, + word: true, + regex: true, + // LSP log is read-only. + replacement: false, + } + } + fn active_match_index( + &mut self, + matches: Vec, + cx: &mut ViewContext, + ) -> Option { + self.editor + .update(cx, |e, cx| e.active_match_index(matches, cx)) + } +} + +impl ToolbarItemView for LspLogToolbarItemView { + fn set_active_pane_item( + &mut self, + active_pane_item: Option<&dyn ItemHandle>, + cx: &mut ViewContext, + ) -> workspace::ToolbarItemLocation { + self.menu_open = false; + if let Some(item) = active_pane_item { + if let Some(log_view) = item.downcast::() { + self.log_view = Some(log_view.clone()); + self._log_view_subscription = Some(cx.observe(&log_view, |_, _, cx| { + cx.notify(); + })); + return ToolbarItemLocation::PrimaryLeft { + flex: Some((1., false)), + }; + } + } + self.log_view = None; + self._log_view_subscription = None; + ToolbarItemLocation::Hidden + } +} + +impl View for LspLogToolbarItemView { + fn ui_name() -> &'static str { + "LspLogView" + } + + fn render(&mut self, cx: &mut ViewContext) -> AnyElement { + let theme = theme::current(cx).clone(); + let Some(log_view) = self.log_view.as_ref() else { + return Empty::new().into_any(); + }; + let (menu_rows, current_server_id) = log_view.update(cx, |log_view, cx| { + let menu_rows = log_view.menu_items(cx).unwrap_or_default(); + let current_server_id = log_view.current_server_id; + (menu_rows, current_server_id) + }); + + let current_server = current_server_id.and_then(|current_server_id| { + if let Ok(ix) = menu_rows.binary_search_by_key(¤t_server_id, |e| e.server_id) { + Some(menu_rows[ix].clone()) + } else { + None + } + }); + let server_selected = current_server.is_some(); + + enum LspLogScroll {} + enum Menu {} + let lsp_menu = Stack::new() + .with_child(Self::render_language_server_menu_header( + current_server, + &theme, + cx, + )) + .with_children(if self.menu_open { + Some( + Overlay::new( + MouseEventHandler::new::(0, cx, move |_, cx| { + Flex::column() + .scrollable::(0, None, cx) + .with_children(menu_rows.into_iter().map(|row| { + Self::render_language_server_menu_item( + row.server_id, + row.server_name, + &row.worktree_root_name, + row.rpc_trace_enabled, + row.logs_selected, + row.rpc_trace_selected, + &theme, + cx, + ) + })) + .contained() + .with_style(theme.toolbar_dropdown_menu.container) + .constrained() + .with_width(400.) + .with_height(400.) + }) + .on_down_out(MouseButton::Left, |_, this, cx| { + this.menu_open = false; + cx.notify() + }), + ) + .with_hoverable(true) + .with_fit_mode(OverlayFitMode::SwitchAnchor) + .with_anchor_corner(AnchorCorner::TopLeft) + .with_z_index(999) + .aligned() + .bottom() + .left(), + ) + } else { + None + }) + .aligned() + .left() + .clipped(); + + enum LspCleanupButton {} + let log_cleanup_button = + MouseEventHandler::new::(1, cx, |state, cx| { + let theme = theme::current(cx).clone(); + let style = theme + .workspace + .toolbar + .toggleable_text_tool + .in_state(server_selected) + .style_for(state); + Label::new("Clear", style.text.clone()) + .aligned() + .contained() + .with_style(style.container) + .constrained() + .with_height(theme.toolbar_dropdown_menu.row_height / 6.0 * 5.0) + }) + .on_click(MouseButton::Left, move |_, this, cx| { + if let Some(log_view) = this.log_view.as_ref() { + log_view.update(cx, |log_view, cx| { + log_view.editor.update(cx, |editor, cx| { + editor.set_read_only(false); + editor.clear(cx); + editor.set_read_only(true); + }); + }) + } + }) + .with_cursor_style(CursorStyle::PointingHand) + .aligned() + .right(); + + Flex::row() + .with_child(lsp_menu) + .with_child(log_cleanup_button) + .contained() + .aligned() + .left() + .into_any_named("lsp log controls") + } +} + +const RPC_MESSAGES: &str = "RPC Messages"; +const SERVER_LOGS: &str = "Server Logs"; + +impl LspLogToolbarItemView { + pub fn new() -> Self { + Self { + menu_open: false, + log_view: None, + _log_view_subscription: None, + } + } + + fn toggle_menu(&mut self, cx: &mut ViewContext) { + self.menu_open = !self.menu_open; + cx.notify(); + } + + fn toggle_logging_for_server( + &mut self, + id: LanguageServerId, + enabled: bool, + cx: &mut ViewContext, + ) { + if let Some(log_view) = &self.log_view { + log_view.update(cx, |log_view, cx| { + log_view.toggle_rpc_trace_for_server(id, enabled, cx); + if !enabled && Some(id) == log_view.current_server_id { + log_view.show_logs_for_server(id, cx); + cx.notify(); + } + }); + } + cx.notify(); + } + + fn show_logs_for_server(&mut self, id: LanguageServerId, cx: &mut ViewContext) { + if let Some(log_view) = &self.log_view { + log_view.update(cx, |view, cx| view.show_logs_for_server(id, cx)); + self.menu_open = false; + cx.notify(); + } + } + + fn show_rpc_trace_for_server(&mut self, id: LanguageServerId, cx: &mut ViewContext) { + if let Some(log_view) = &self.log_view { + log_view.update(cx, |view, cx| view.show_rpc_trace_for_server(id, cx)); + self.menu_open = false; + cx.notify(); + } + } + + fn render_language_server_menu_header( + current_server: Option, + theme: &Arc, + cx: &mut ViewContext, + ) -> impl Element { + enum ToggleMenu {} + MouseEventHandler::new::(0, cx, move |state, _| { + let label: Cow = current_server + .and_then(|row| { + Some( + format!( + "{} ({}) - {}", + row.server_name.0, + row.worktree_root_name, + if row.rpc_trace_selected { + RPC_MESSAGES + } else { + SERVER_LOGS + }, + ) + .into(), + ) + }) + .unwrap_or_else(|| "No server selected".into()); + let style = theme.toolbar_dropdown_menu.header.style_for(state); + Label::new(label, style.text.clone()) + .contained() + .with_style(style.container) + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_click(MouseButton::Left, move |_, view, cx| { + view.toggle_menu(cx); + }) + } + + fn render_language_server_menu_item( + id: LanguageServerId, + name: LanguageServerName, + worktree_root_name: &str, + rpc_trace_enabled: bool, + logs_selected: bool, + rpc_trace_selected: bool, + theme: &Arc, + cx: &mut ViewContext, + ) -> impl Element { + enum ActivateLog {} + enum ActivateRpcTrace {} + enum LanguageServerCheckbox {} + + Flex::column() + .with_child({ + let style = &theme.toolbar_dropdown_menu.section_header; + Label::new( + format!("{} ({})", name.0, worktree_root_name), + style.text.clone(), + ) + .contained() + .with_style(style.container) + .constrained() + .with_height(theme.toolbar_dropdown_menu.row_height) + }) + .with_child( + MouseEventHandler::new::(id.0, cx, move |state, _| { + let style = theme + .toolbar_dropdown_menu + .item + .in_state(logs_selected) + .style_for(state); + Label::new(SERVER_LOGS, style.text.clone()) + .contained() + .with_style(style.container) + .constrained() + .with_height(theme.toolbar_dropdown_menu.row_height) + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_click(MouseButton::Left, move |_, view, cx| { + view.show_logs_for_server(id, cx); + }), + ) + .with_child( + MouseEventHandler::new::(id.0, cx, move |state, cx| { + let style = theme + .toolbar_dropdown_menu + .item + .in_state(rpc_trace_selected) + .style_for(state); + Flex::row() + .with_child( + Label::new(RPC_MESSAGES, style.text.clone()) + .constrained() + .with_height(theme.toolbar_dropdown_menu.row_height), + ) + .with_child( + ui::checkbox_with_label::( + Empty::new(), + &theme.welcome.checkbox, + rpc_trace_enabled, + id.0, + cx, + move |this, enabled, cx| { + this.toggle_logging_for_server(id, enabled, cx); + }, + ) + .flex_float(), + ) + .align_children_center() + .contained() + .with_style(style.container) + .constrained() + .with_height(theme.toolbar_dropdown_menu.row_height) + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_click(MouseButton::Left, move |_, view, cx| { + view.show_rpc_trace_for_server(id, cx); + }), + ) + } +} + +pub enum Event { + NewServerLogEntry { + id: LanguageServerId, + entry: String, + is_rpc: bool, + }, +} + +impl Entity for LogStore { + type Event = Event; +} + +impl Entity for LspLogView { + type Event = editor::Event; +} + +impl Entity for LspLogToolbarItemView { + type Event = (); +} diff --git a/crates/language_tools2/src/lsp_log_tests.rs b/crates/language_tools2/src/lsp_log_tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..967e8a33824d75152472f3b4614b94c7a6d1671b --- /dev/null +++ b/crates/language_tools2/src/lsp_log_tests.rs @@ -0,0 +1,109 @@ +// todo!("TODO kb") +// use std::sync::Arc; + +// use crate::lsp_log::LogMenuItem; + +// use super::*; +// use futures::StreamExt; +// use gpui::{serde_json::json, TestAppContext}; +// use language::{tree_sitter_rust, FakeLspAdapter, Language, LanguageConfig, LanguageServerName}; +// use project::{FakeFs, Project}; +// use settings::SettingsStore; + +// #[gpui::test] +// async fn test_lsp_logs(cx: &mut TestAppContext) { +// if std::env::var("RUST_LOG").is_ok() { +// env_logger::init(); +// } + +// init_test(cx); + +// let mut rust_language = Language::new( +// LanguageConfig { +// name: "Rust".into(), +// path_suffixes: vec!["rs".to_string()], +// ..Default::default() +// }, +// Some(tree_sitter_rust::language()), +// ); +// let mut fake_rust_servers = rust_language +// .set_fake_lsp_adapter(Arc::new(FakeLspAdapter { +// name: "the-rust-language-server", +// ..Default::default() +// })) +// .await; + +// let fs = FakeFs::new(cx.background()); +// fs.insert_tree( +// "/the-root", +// json!({ +// "test.rs": "", +// "package.json": "", +// }), +// ) +// .await; +// let project = Project::test(fs.clone(), ["/the-root".as_ref()], cx).await; +// project.update(cx, |project, _| { +// project.languages().add(Arc::new(rust_language)); +// }); + +// let log_store = cx.add_model(|cx| LogStore::new(cx)); +// log_store.update(cx, |store, cx| store.add_project(&project, cx)); + +// let _rust_buffer = project +// .update(cx, |project, cx| { +// project.open_local_buffer("/the-root/test.rs", cx) +// }) +// .await +// .unwrap(); + +// let mut language_server = fake_rust_servers.next().await.unwrap(); +// language_server +// .receive_notification::() +// .await; + +// let log_view = cx +// .add_window(|cx| LspLogView::new(project.clone(), log_store.clone(), cx)) +// .root(cx); + +// language_server.notify::(lsp::LogMessageParams { +// message: "hello from the server".into(), +// typ: lsp::MessageType::INFO, +// }); +// cx.foreground().run_until_parked(); + +// log_view.read_with(cx, |view, cx| { +// assert_eq!( +// view.menu_items(cx).unwrap(), +// &[LogMenuItem { +// server_id: language_server.server.server_id(), +// server_name: LanguageServerName("the-rust-language-server".into()), +// worktree_root_name: project +// .read(cx) +// .worktrees(cx) +// .next() +// .unwrap() +// .read(cx) +// .root_name() +// .to_string(), +// rpc_trace_enabled: false, +// rpc_trace_selected: false, +// logs_selected: true, +// }] +// ); +// assert_eq!(view.editor.read(cx).text(cx), "hello from the server\n"); +// }); +// } + +// fn init_test(cx: &mut gpui::TestAppContext) { +// cx.foreground().forbid_parking(); + +// cx.update(|cx| { +// cx.set_global(SettingsStore::test(cx)); +// theme::init((), cx); +// language::init(cx); +// client::init_settings(cx); +// Project::init_settings(cx); +// editor::init_settings(cx); +// }); +// } diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs new file mode 100644 index 0000000000000000000000000000000000000000..7eaaab013002b26938732010c2ebb256e44a6cc2 --- /dev/null +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -0,0 +1,677 @@ +use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId}; +use gpui::{ + actions, + elements::{ + AnchorCorner, Empty, Flex, Label, MouseEventHandler, Overlay, OverlayFitMode, + ParentElement, ScrollTarget, Stack, UniformList, UniformListState, + }, + fonts::TextStyle, + AppContext, CursorStyle, Element, Entity, Model, MouseButton, View, View, ViewContext, + WeakView, +}; +use language::{Buffer, OwnedSyntaxLayerInfo, SyntaxLayerInfo}; +use std::{mem, ops::Range, sync::Arc}; +use theme::{Theme, ThemeSettings}; +use tree_sitter::{Node, TreeCursor}; +use workspace::{ + item::{Item, ItemHandle}, + ToolbarItemLocation, ToolbarItemView, Workspace, +}; + +actions!(debug, [OpenSyntaxTreeView]); + +pub fn init(cx: &mut AppContext) { + cx.add_action( + move |workspace: &mut Workspace, _: &OpenSyntaxTreeView, cx: _| { + let active_item = workspace.active_item(cx); + let workspace_handle = workspace.weak_handle(); + let syntax_tree_view = + cx.build_view(|cx| SyntaxTreeView::new(workspace_handle, active_item, cx)); + workspace.add_item(Box::new(syntax_tree_view), cx); + }, + ); +} + +pub struct SyntaxTreeView { + workspace_handle: WeakView, + editor: Option, + mouse_y: Option, + line_height: Option, + list_state: UniformListState, + selected_descendant_ix: Option, + hovered_descendant_ix: Option, +} + +pub struct SyntaxTreeToolbarItemView { + tree_view: Option>, + subscription: Option, + menu_open: bool, +} + +struct EditorState { + editor: ViewHandle, + active_buffer: Option, + _subscription: gpui::Subscription, +} + +#[derive(Clone)] +struct BufferState { + buffer: Model, + excerpt_id: ExcerptId, + active_layer: Option, +} + +impl SyntaxTreeView { + pub fn new( + workspace_handle: WeakView, + active_item: Option>, + cx: &mut ViewContext, + ) -> Self { + let mut this = Self { + workspace_handle: workspace_handle.clone(), + list_state: UniformListState::default(), + editor: None, + mouse_y: None, + line_height: None, + hovered_descendant_ix: None, + selected_descendant_ix: None, + }; + + this.workspace_updated(active_item, cx); + cx.observe( + &workspace_handle.upgrade(cx).unwrap(), + |this, workspace, cx| { + this.workspace_updated(workspace.read(cx).active_item(cx), cx); + }, + ) + .detach(); + + this + } + + fn workspace_updated( + &mut self, + active_item: Option>, + cx: &mut ViewContext, + ) { + if let Some(item) = active_item { + if item.id() != cx.view_id() { + if let Some(editor) = item.act_as::(cx) { + self.set_editor(editor, cx); + } + } + } + } + + fn set_editor(&mut self, editor: ViewHandle, cx: &mut ViewContext) { + if let Some(state) = &self.editor { + if state.editor == editor { + return; + } + editor.update(cx, |editor, cx| { + editor.clear_background_highlights::(cx) + }); + } + + let subscription = cx.subscribe(&editor, |this, _, event, cx| { + let did_reparse = match event { + editor::Event::Reparsed => true, + editor::Event::SelectionsChanged { .. } => false, + _ => return, + }; + this.editor_updated(did_reparse, cx); + }); + + self.editor = Some(EditorState { + editor, + _subscription: subscription, + active_buffer: None, + }); + self.editor_updated(true, cx); + } + + fn editor_updated(&mut self, did_reparse: bool, cx: &mut ViewContext) -> Option<()> { + // Find which excerpt the cursor is in, and the position within that excerpted buffer. + let editor_state = self.editor.as_mut()?; + let editor = &editor_state.editor.read(cx); + let selection_range = editor.selections.last::(cx).range(); + let multibuffer = editor.buffer().read(cx); + let (buffer, range, excerpt_id) = multibuffer + .range_to_buffer_ranges(selection_range, cx) + .pop()?; + + // If the cursor has moved into a different excerpt, retrieve a new syntax layer + // from that buffer. + let buffer_state = editor_state + .active_buffer + .get_or_insert_with(|| BufferState { + buffer: buffer.clone(), + excerpt_id, + active_layer: None, + }); + let mut prev_layer = None; + if did_reparse { + prev_layer = buffer_state.active_layer.take(); + } + if buffer_state.buffer != buffer || buffer_state.excerpt_id != buffer_state.excerpt_id { + buffer_state.buffer = buffer.clone(); + buffer_state.excerpt_id = excerpt_id; + buffer_state.active_layer = None; + } + + let layer = match &mut buffer_state.active_layer { + Some(layer) => layer, + None => { + let snapshot = buffer.read(cx).snapshot(); + let layer = if let Some(prev_layer) = prev_layer { + let prev_range = prev_layer.node().byte_range(); + snapshot + .syntax_layers() + .filter(|layer| layer.language == &prev_layer.language) + .min_by_key(|layer| { + let range = layer.node().byte_range(); + ((range.start as i64) - (prev_range.start as i64)).abs() + + ((range.end as i64) - (prev_range.end as i64)).abs() + })? + } else { + snapshot.syntax_layers().next()? + }; + buffer_state.active_layer.insert(layer.to_owned()) + } + }; + + // Within the active layer, find the syntax node under the cursor, + // and scroll to it. + let mut cursor = layer.node().walk(); + while cursor.goto_first_child_for_byte(range.start).is_some() { + if !range.is_empty() && cursor.node().end_byte() == range.start { + cursor.goto_next_sibling(); + } + } + + // Ascend to the smallest ancestor that contains the range. + loop { + let node_range = cursor.node().byte_range(); + if node_range.start <= range.start && node_range.end >= range.end { + break; + } + if !cursor.goto_parent() { + break; + } + } + + let descendant_ix = cursor.descendant_index(); + self.selected_descendant_ix = Some(descendant_ix); + self.list_state.scroll_to(ScrollTarget::Show(descendant_ix)); + + cx.notify(); + Some(()) + } + + fn handle_click(&mut self, y: f32, cx: &mut ViewContext) -> Option<()> { + let line_height = self.line_height?; + let ix = ((self.list_state.scroll_top() + y) / line_height) as usize; + + self.update_editor_with_range_for_descendant_ix(ix, cx, |editor, mut range, cx| { + // Put the cursor at the beginning of the node. + mem::swap(&mut range.start, &mut range.end); + + editor.change_selections(Some(Autoscroll::newest()), cx, |selections| { + selections.select_ranges(vec![range]); + }); + }); + Some(()) + } + + fn hover_state_changed(&mut self, cx: &mut ViewContext) { + if let Some((y, line_height)) = self.mouse_y.zip(self.line_height) { + let ix = ((self.list_state.scroll_top() + y) / line_height) as usize; + if self.hovered_descendant_ix != Some(ix) { + self.hovered_descendant_ix = Some(ix); + self.update_editor_with_range_for_descendant_ix(ix, cx, |editor, range, cx| { + editor.clear_background_highlights::(cx); + editor.highlight_background::( + vec![range], + |theme| theme.editor.document_highlight_write_background, + cx, + ); + }); + cx.notify(); + } + } + } + + fn update_editor_with_range_for_descendant_ix( + &self, + descendant_ix: usize, + cx: &mut ViewContext, + mut f: impl FnMut(&mut Editor, Range, &mut ViewContext), + ) -> Option<()> { + let editor_state = self.editor.as_ref()?; + let buffer_state = editor_state.active_buffer.as_ref()?; + let layer = buffer_state.active_layer.as_ref()?; + + // Find the node. + let mut cursor = layer.node().walk(); + cursor.goto_descendant(descendant_ix); + let node = cursor.node(); + let range = node.byte_range(); + + // Build a text anchor range. + let buffer = buffer_state.buffer.read(cx); + let range = buffer.anchor_before(range.start)..buffer.anchor_after(range.end); + + // Build a multibuffer anchor range. + let multibuffer = editor_state.editor.read(cx).buffer(); + let multibuffer = multibuffer.read(cx).snapshot(cx); + let excerpt_id = buffer_state.excerpt_id; + let range = multibuffer.anchor_in_excerpt(excerpt_id, range.start) + ..multibuffer.anchor_in_excerpt(excerpt_id, range.end); + + // Update the editor with the anchor range. + editor_state.editor.update(cx, |editor, cx| { + f(editor, range, cx); + }); + Some(()) + } + + fn render_node( + cursor: &TreeCursor, + depth: u32, + selected: bool, + hovered: bool, + list_hovered: bool, + style: &TextStyle, + editor_theme: &theme::Editor, + cx: &AppContext, + ) -> gpui::AnyElement { + let node = cursor.node(); + let mut range_style = style.clone(); + let em_width = style.em_width(cx.font_cache()); + let gutter_padding = (em_width * editor_theme.gutter_padding_factor).round(); + + range_style.color = editor_theme.line_number; + + let mut anonymous_node_style = style.clone(); + let string_color = editor_theme + .syntax + .highlights + .iter() + .find_map(|(name, style)| (name == "string").then(|| style.color)?); + let property_color = editor_theme + .syntax + .highlights + .iter() + .find_map(|(name, style)| (name == "property").then(|| style.color)?); + if let Some(color) = string_color { + anonymous_node_style.color = color; + } + + let mut row = Flex::row(); + if let Some(field_name) = cursor.field_name() { + let mut field_style = style.clone(); + if let Some(color) = property_color { + field_style.color = color; + } + + row.add_children([ + Label::new(field_name, field_style), + Label::new(": ", style.clone()), + ]); + } + + return row + .with_child( + if node.is_named() { + Label::new(node.kind(), style.clone()) + } else { + Label::new(format!("\"{}\"", node.kind()), anonymous_node_style) + } + .contained() + .with_margin_right(em_width), + ) + .with_child(Label::new(format_node_range(node), range_style)) + .contained() + .with_background_color(if selected { + editor_theme.selection.selection + } else if hovered && list_hovered { + editor_theme.active_line_background + } else { + Default::default() + }) + .with_padding_left(gutter_padding + depth as f32 * 18.0) + .into_any(); + } +} + +impl Entity for SyntaxTreeView { + type Event = (); +} + +impl View for SyntaxTreeView { + fn ui_name() -> &'static str { + "SyntaxTreeView" + } + + fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement { + let settings = settings::get::(cx); + let font_family_id = settings.buffer_font_family; + let font_family_name = cx.font_cache().family_name(font_family_id).unwrap(); + let font_properties = Default::default(); + let font_id = cx + .font_cache() + .select_font(font_family_id, &font_properties) + .unwrap(); + let font_size = settings.buffer_font_size(cx); + + let editor_theme = settings.theme.editor.clone(); + let style = TextStyle { + color: editor_theme.text_color, + font_family_name, + font_family_id, + font_id, + font_size, + font_properties: Default::default(), + underline: Default::default(), + soft_wrap: false, + }; + + let line_height = cx.font_cache().line_height(font_size); + if Some(line_height) != self.line_height { + self.line_height = Some(line_height); + self.hover_state_changed(cx); + } + + if let Some(layer) = self + .editor + .as_ref() + .and_then(|editor| editor.active_buffer.as_ref()) + .and_then(|buffer| buffer.active_layer.as_ref()) + { + let layer = layer.clone(); + let theme = editor_theme.clone(); + return MouseEventHandler::new::(0, cx, move |state, cx| { + let list_hovered = state.hovered(); + UniformList::new( + self.list_state.clone(), + layer.node().descendant_count(), + cx, + move |this, range, items, cx| { + let mut cursor = layer.node().walk(); + let mut descendant_ix = range.start as usize; + cursor.goto_descendant(descendant_ix); + let mut depth = cursor.depth(); + let mut visited_children = false; + while descendant_ix < range.end { + if visited_children { + if cursor.goto_next_sibling() { + visited_children = false; + } else if cursor.goto_parent() { + depth -= 1; + } else { + break; + } + } else { + items.push(Self::render_node( + &cursor, + depth, + Some(descendant_ix) == this.selected_descendant_ix, + Some(descendant_ix) == this.hovered_descendant_ix, + list_hovered, + &style, + &theme, + cx, + )); + descendant_ix += 1; + if cursor.goto_first_child() { + depth += 1; + } else { + visited_children = true; + } + } + } + }, + ) + }) + .on_move(move |event, this, cx| { + let y = event.position.y() - event.region.origin_y(); + this.mouse_y = Some(y); + this.hover_state_changed(cx); + }) + .on_click(MouseButton::Left, move |event, this, cx| { + let y = event.position.y() - event.region.origin_y(); + this.handle_click(y, cx); + }) + .contained() + .with_background_color(editor_theme.background) + .into_any(); + } + + Empty::new().into_any() + } +} + +impl Item for SyntaxTreeView { + fn tab_content( + &self, + _: Option, + style: &theme::Tab, + _: &AppContext, + ) -> gpui::AnyElement { + Label::new("Syntax Tree", style.label.clone()).into_any() + } + + fn clone_on_split( + &self, + _workspace_id: workspace::WorkspaceId, + cx: &mut ViewContext, + ) -> Option + where + Self: Sized, + { + let mut clone = Self::new(self.workspace_handle.clone(), None, cx); + if let Some(editor) = &self.editor { + clone.set_editor(editor.editor.clone(), cx) + } + Some(clone) + } +} + +impl SyntaxTreeToolbarItemView { + pub fn new() -> Self { + Self { + menu_open: false, + tree_view: None, + subscription: None, + } + } + + fn render_menu( + &mut self, + cx: &mut ViewContext<'_, '_, Self>, + ) -> Option> { + let theme = theme::current(cx).clone(); + let tree_view = self.tree_view.as_ref()?; + let tree_view = tree_view.read(cx); + + let editor_state = tree_view.editor.as_ref()?; + let buffer_state = editor_state.active_buffer.as_ref()?; + let active_layer = buffer_state.active_layer.clone()?; + let active_buffer = buffer_state.buffer.read(cx).snapshot(); + + enum Menu {} + + Some( + Stack::new() + .with_child(Self::render_header(&theme, &active_layer, cx)) + .with_children(self.menu_open.then(|| { + Overlay::new( + MouseEventHandler::new::(0, cx, move |_, cx| { + Flex::column() + .with_children(active_buffer.syntax_layers().enumerate().map( + |(ix, layer)| { + Self::render_menu_item(&theme, &active_layer, layer, ix, cx) + }, + )) + .contained() + .with_style(theme.toolbar_dropdown_menu.container) + .constrained() + .with_width(400.) + .with_height(400.) + }) + .on_down_out(MouseButton::Left, |_, this, cx| { + this.menu_open = false; + cx.notify() + }), + ) + .with_hoverable(true) + .with_fit_mode(OverlayFitMode::SwitchAnchor) + .with_anchor_corner(AnchorCorner::TopLeft) + .with_z_index(999) + .aligned() + .bottom() + .left() + })) + .aligned() + .left() + .clipped() + .into_any(), + ) + } + + fn toggle_menu(&mut self, cx: &mut ViewContext) { + self.menu_open = !self.menu_open; + cx.notify(); + } + + fn select_layer(&mut self, layer_ix: usize, cx: &mut ViewContext) -> Option<()> { + let tree_view = self.tree_view.as_ref()?; + tree_view.update(cx, |view, cx| { + let editor_state = view.editor.as_mut()?; + let buffer_state = editor_state.active_buffer.as_mut()?; + let snapshot = buffer_state.buffer.read(cx).snapshot(); + let layer = snapshot.syntax_layers().nth(layer_ix)?; + buffer_state.active_layer = Some(layer.to_owned()); + view.selected_descendant_ix = None; + self.menu_open = false; + cx.notify(); + Some(()) + }) + } + + fn render_header( + theme: &Arc, + active_layer: &OwnedSyntaxLayerInfo, + cx: &mut ViewContext, + ) -> impl Element { + enum ToggleMenu {} + MouseEventHandler::new::(0, cx, move |state, _| { + let style = theme.toolbar_dropdown_menu.header.style_for(state); + Flex::row() + .with_child( + Label::new(active_layer.language.name().to_string(), style.text.clone()) + .contained() + .with_margin_right(style.secondary_text_spacing), + ) + .with_child(Label::new( + format_node_range(active_layer.node()), + style + .secondary_text + .clone() + .unwrap_or_else(|| style.text.clone()), + )) + .contained() + .with_style(style.container) + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_click(MouseButton::Left, move |_, view, cx| { + view.toggle_menu(cx); + }) + } + + fn render_menu_item( + theme: &Arc, + active_layer: &OwnedSyntaxLayerInfo, + layer: SyntaxLayerInfo, + layer_ix: usize, + cx: &mut ViewContext, + ) -> impl Element { + enum ActivateLayer {} + MouseEventHandler::new::(layer_ix, cx, move |state, _| { + let is_selected = layer.node() == active_layer.node(); + let style = theme + .toolbar_dropdown_menu + .item + .in_state(is_selected) + .style_for(state); + Flex::row() + .with_child( + Label::new(layer.language.name().to_string(), style.text.clone()) + .contained() + .with_margin_right(style.secondary_text_spacing), + ) + .with_child(Label::new( + format_node_range(layer.node()), + style + .secondary_text + .clone() + .unwrap_or_else(|| style.text.clone()), + )) + .contained() + .with_style(style.container) + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_click(MouseButton::Left, move |_, view, cx| { + view.select_layer(layer_ix, cx); + }) + } +} + +fn format_node_range(node: Node) -> String { + let start = node.start_position(); + let end = node.end_position(); + format!( + "[{}:{} - {}:{}]", + start.row + 1, + start.column + 1, + end.row + 1, + end.column + 1, + ) +} + +impl Entity for SyntaxTreeToolbarItemView { + type Event = (); +} + +impl View for SyntaxTreeToolbarItemView { + fn ui_name() -> &'static str { + "SyntaxTreeToolbarItemView" + } + + fn render(&mut self, cx: &mut ViewContext<'_, '_, Self>) -> gpui::AnyElement { + self.render_menu(cx) + .unwrap_or_else(|| Empty::new().into_any()) + } +} + +impl ToolbarItemView for SyntaxTreeToolbarItemView { + fn set_active_pane_item( + &mut self, + active_pane_item: Option<&dyn ItemHandle>, + cx: &mut ViewContext, + ) -> workspace::ToolbarItemLocation { + self.menu_open = false; + if let Some(item) = active_pane_item { + if let Some(view) = item.downcast::() { + self.tree_view = Some(view.clone()); + self.subscription = Some(cx.observe(&view, |_, _, cx| cx.notify())); + return ToolbarItemLocation::PrimaryLeft { + flex: Some((1., false)), + }; + } + } + self.tree_view = None; + self.subscription = None; + ToolbarItemLocation::Hidden + } +} From 676a07270e24dfdce4c6445308efe5f694bbc0f7 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 11:17:02 +0200 Subject: [PATCH 189/644] First fixes --- crates/language_tools2/src/lsp_log.rs | 56 ++++++-------- .../language_tools2/src/syntax_tree_view.rs | 73 ++++++++----------- 2 files changed, 52 insertions(+), 77 deletions(-) diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 9f27c62a04a001a15ba5f4d7142505fc4e32290b..6e433ba8a64e0bcd9469bf96306b81c3025e947b 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -2,24 +2,19 @@ use collections::{HashMap, VecDeque}; use editor::{Editor, MoveToEnd}; use futures::{channel::mpsc, StreamExt}; use gpui::{ - actions, - elements::{ - AnchorCorner, ChildView, Empty, Flex, Label, MouseEventHandler, Overlay, OverlayFitMode, - ParentElement, Stack, - }, - platform::{CursorStyle, MouseButton}, - AnyElement, AppContext, Element, Entity, Model, ModelContext, Subscription, View, View, - ViewContext, WeakModel, + actions, AnchorCorner, AnyElement, AppContext, Context, CursorStyle, Element, Empty, Entity, + Model, ModelContext, MouseButton, Overlay, OverlayFitMode, Subscription, View, ViewContext, + VisualContext, WeakModel, }; use language::{LanguageServerId, LanguageServerName}; use lsp::IoKind; use project::{search::SearchQuery, Project}; use std::{borrow::Cow, sync::Arc}; -use theme::{ui, Theme}; +use theme::Theme; use workspace::{ item::{Item, ItemHandle}, searchable::{SearchableItem, SearchableItemHandle}, - ToolbarItemLocation, ToolbarItemView, Workspace, WorkspaceCreated, + ToolbarItemLocation, ToolbarItemView, Workspace, }; const SEND_LINE: &str = "// Send:"; @@ -83,37 +78,29 @@ pub(crate) struct LogMenuItem { actions!(debug, [OpenLanguageServerLogs]); pub fn init(cx: &mut AppContext) { - let log_store = cx.add_model(|cx| LogStore::new(cx)); - - cx.subscribe_global::({ - let log_store = log_store.clone(); - move |event, cx| { - let workspace = &event.0; - if let Some(workspace) = workspace.upgrade(cx) { - let project = workspace.read(cx).project().clone(); - if project.read(cx).is_local() { - log_store.update(cx, |store, cx| { - store.add_project(&project, cx); - }); - } - } + let log_store = cx.build_model(|cx| LogStore::new(cx)); + + cx.observe_new_views(|workspace: &mut Workspace, cx| { + let project = workspace.project(); + if project.read(cx).is_local() { + log_store.update(cx, |store, cx| { + store.add_project(&project, cx); + }); } - }) - .detach(); - cx.add_action( - move |workspace: &mut Workspace, _: &OpenLanguageServerLogs, cx: _| { + workspace.register_action(|workspace, _: &OpenLanguageServerLogs, cx| { let project = workspace.project().read(cx); if project.is_local() { workspace.add_item( - Box::new(cx.add_view(|cx| { + Box::new(cx.build_view(|cx| { LspLogView::new(workspace.project().clone(), log_store.clone(), cx) })), cx, ); } - }, - ); + }); + }) + .detach(); } impl LogStore { @@ -204,8 +191,7 @@ impl LogStore { let server_id = server.server_id(); server.on_notification::({ move |params, mut cx| { - if let Some((project, this)) = - weak_project.upgrade(&mut cx).zip(this.upgrade(&mut cx)) + if let Some((project, this)) = weak_project.upgrade().zip(this.upgrade(&mut cx)) { this.update(&mut cx, |this, cx| { this.add_language_server_log(&project, server_id, ¶ms.message, cx); @@ -314,7 +300,7 @@ impl LogStore { IoKind::StdOut => true, IoKind::StdIn => false, IoKind::StdErr => { - let project = project.upgrade(cx)?; + let project = project.upgrade()?; let message = format!("stderr: {}", message.trim()); self.add_language_server_log(&project, language_server_id, &message, cx); return Some(()); @@ -446,7 +432,7 @@ impl LspLogView { log_contents: String, cx: &mut ViewContext, ) -> (View, Subscription) { - let editor = cx.add_view(|cx| { + let editor = cx.build_view(|cx| { let mut editor = Editor::multi_line(None, cx); editor.set_text(log_contents, cx); editor.move_to_end(&MoveToEnd, cx); diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index 7eaaab013002b26938732010c2ebb256e44a6cc2..80ff211176598539538bd3d8cd490feb7f2ef5cd 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -1,35 +1,32 @@ use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId}; use gpui::{ - actions, - elements::{ - AnchorCorner, Empty, Flex, Label, MouseEventHandler, Overlay, OverlayFitMode, - ParentElement, ScrollTarget, Stack, UniformList, UniformListState, - }, - fonts::TextStyle, - AppContext, CursorStyle, Element, Entity, Model, MouseButton, View, View, ViewContext, - WeakView, + actions, AnchorCorner, AppContext, CursorStyle, Div, Element, Empty, Entity, Focusable, Model, + MouseButton, Overlay, OverlayFitMode, ParentElement, Render, TextStyle, UniformList, + UniformListState, View, ViewContext, VisualContext, WeakView, }; use language::{Buffer, OwnedSyntaxLayerInfo, SyntaxLayerInfo}; use std::{mem, ops::Range, sync::Arc}; -use theme::{Theme, ThemeSettings}; +use theme::{ActiveTheme, Theme, ThemeSettings}; use tree_sitter::{Node, TreeCursor}; use workspace::{ item::{Item, ItemHandle}, + ui::v_stack, ToolbarItemLocation, ToolbarItemView, Workspace, }; actions!(debug, [OpenSyntaxTreeView]); pub fn init(cx: &mut AppContext) { - cx.add_action( - move |workspace: &mut Workspace, _: &OpenSyntaxTreeView, cx: _| { + cx.observe_new_views(|workspace: &mut Workspace, _| { + workspace.register_action(|workspace, _: &OpenSyntaxTreeView, cx| { let active_item = workspace.active_item(cx); let workspace_handle = workspace.weak_handle(); let syntax_tree_view = cx.build_view(|cx| SyntaxTreeView::new(workspace_handle, active_item, cx)); workspace.add_item(Box::new(syntax_tree_view), cx); - }, - ); + }); + }) + .detach(); } pub struct SyntaxTreeView { @@ -49,7 +46,7 @@ pub struct SyntaxTreeToolbarItemView { } struct EditorState { - editor: ViewHandle, + editor: View, active_buffer: Option, _subscription: gpui::Subscription, } @@ -79,7 +76,7 @@ impl SyntaxTreeView { this.workspace_updated(active_item, cx); cx.observe( - &workspace_handle.upgrade(cx).unwrap(), + &workspace_handle.upgrade().unwrap(), |this, workspace, cx| { this.workspace_updated(workspace.read(cx).active_item(cx), cx); }, @@ -95,7 +92,7 @@ impl SyntaxTreeView { cx: &mut ViewContext, ) { if let Some(item) = active_item { - if item.id() != cx.view_id() { + if item.item_id() != cx.entity_id() { if let Some(editor) = item.act_as::(cx) { self.set_editor(editor, cx); } @@ -103,7 +100,7 @@ impl SyntaxTreeView { } } - fn set_editor(&mut self, editor: ViewHandle, cx: &mut ViewContext) { + fn set_editor(&mut self, editor: View, cx: &mut ViewContext) { if let Some(state) = &self.editor { if state.editor == editor { return; @@ -115,8 +112,8 @@ impl SyntaxTreeView { let subscription = cx.subscribe(&editor, |this, _, event, cx| { let did_reparse = match event { - editor::Event::Reparsed => true, - editor::Event::SelectionsChanged { .. } => false, + editor::EditorEvent::Reparsed => true, + editor::EditorEvent::SelectionsChanged { .. } => false, _ => return, }; this.editor_updated(did_reparse, cx); @@ -490,7 +487,7 @@ impl SyntaxTreeToolbarItemView { &mut self, cx: &mut ViewContext<'_, '_, Self>, ) -> Option> { - let theme = theme::current(cx).clone(); + let theme = cx.theme().clone(); let tree_view = self.tree_view.as_ref()?; let tree_view = tree_view.read(cx); @@ -502,12 +499,12 @@ impl SyntaxTreeToolbarItemView { enum Menu {} Some( - Stack::new() - .with_child(Self::render_header(&theme, &active_layer, cx)) - .with_children(self.menu_open.then(|| { - Overlay::new( - MouseEventHandler::new::(0, cx, move |_, cx| { - Flex::column() + v_stack() + .child(Self::render_header(&theme, &active_layer, cx)) + .children(self.menu_open.then(|| { + overlay( + mouse_event_handler::(0, cx, move |_, cx| { + v_stack() .with_children(active_buffer.syntax_layers().enumerate().map( |(ix, layer)| { Self::render_menu_item(&theme, &active_layer, layer, ix, cx) @@ -525,16 +522,9 @@ impl SyntaxTreeToolbarItemView { }), ) .with_hoverable(true) - .with_fit_mode(OverlayFitMode::SwitchAnchor) - .with_anchor_corner(AnchorCorner::TopLeft) - .with_z_index(999) - .aligned() - .bottom() - .left() + .with_fit_content() + .into_any() })) - .aligned() - .left() - .clipped() .into_any(), ) } @@ -639,14 +629,13 @@ fn format_node_range(node: Node) -> String { ) } -impl Entity for SyntaxTreeToolbarItemView { - type Event = (); -} +impl Render for SyntaxTreeToolbarItemView { + type Element = Focusable
; -impl View for SyntaxTreeToolbarItemView { - fn ui_name() -> &'static str { - "SyntaxTreeToolbarItemView" - } + // todo!() + // fn ui_name() -> &'static str { + // "SyntaxTreeToolbarItemView" + // } fn render(&mut self, cx: &mut ViewContext<'_, '_, Self>) -> gpui::AnyElement { self.render_menu(cx) From 75074c329792d72ac53b2db0ae13c56e345d1466 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 15:32:09 +0200 Subject: [PATCH 190/644] Apply more fixes to the visual part --- Cargo.lock | 1 + crates/editor2/src/editor.rs | 13 +- crates/language_tools2/Cargo.toml | 1 + crates/language_tools2/src/lsp_log.rs | 388 ++++++++---------- .../language_tools2/src/syntax_tree_view.rs | 361 +++++++--------- 5 files changed, 335 insertions(+), 429 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f418a1813837cdb60f325305aa223a4b1a8a41e..7237ab6905db5a5aadfa1c4613114c3f12ae6bca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5008,6 +5008,7 @@ dependencies = [ "settings2", "theme2", "tree-sitter", + "ui2", "unindent", "util", "workspace2", diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 58f8e857a9a167219b5e1cdeec5a2bbb1b5b62f9..81158c5351052d450a0b329e03a09bc1dc305eac 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -1652,14 +1652,11 @@ impl Editor { Self::new(EditorMode::SingleLine, buffer, None, cx) } - // pub fn multi_line( - // field_editor_style: Option>, - // cx: &mut ViewContext, - // ) -> Self { - // let buffer = cx.build_model(|cx| Buffer::new(0, cx.model_id() as u64, String::new())); - // let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); - // Self::new(EditorMode::Full, buffer, None, field_editor_style, cx) - // } + pub fn multi_line(cx: &mut ViewContext) -> Self { + let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new())); + let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); + Self::new(EditorMode::Full, buffer, None, cx) + } pub fn auto_height(max_lines: usize, cx: &mut ViewContext) -> Self { let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new())); diff --git a/crates/language_tools2/Cargo.toml b/crates/language_tools2/Cargo.toml index ca3ede2ef9a1e80e32afedec15bf8c0bdf02afbc..bf5202cda9959556a5d225c8b1ce01591d7c8eac 100644 --- a/crates/language_tools2/Cargo.toml +++ b/crates/language_tools2/Cargo.toml @@ -17,6 +17,7 @@ language = { package = "language2", path = "../language2" } project = { package = "project2", path = "../project2" } workspace = { package = "workspace2", path = "../workspace2" } gpui = { package = "gpui2", path = "../gpui2" } +ui = { package = "ui2", path = "../ui2" } util = { path = "../util" } lsp = { package = "lsp2", path = "../lsp2" } futures.workspace = true diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 6e433ba8a64e0bcd9469bf96306b81c3025e947b..ca4f25e177fc3204ea155600d184d76c50bdfa08 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -1,20 +1,22 @@ use collections::{HashMap, VecDeque}; -use editor::{Editor, MoveToEnd}; +use editor::{Editor, EditorElement, EditorEvent, MoveToEnd}; use futures::{channel::mpsc, StreamExt}; use gpui::{ - actions, AnchorCorner, AnyElement, AppContext, Context, CursorStyle, Element, Empty, Entity, - Model, ModelContext, MouseButton, Overlay, OverlayFitMode, Subscription, View, ViewContext, - VisualContext, WeakModel, + actions, div, overlay, red, AnchorCorner, AnyElement, AppContext, Context, CursorStyle, Div, + EventEmitter, FocusHandle, FocusableView, InteractiveElement, IntoElement, Model, ModelContext, + MouseButton, OverlayFitMode, ParentElement, Render, Styled, Subscription, View, ViewContext, + VisualContext, WeakModel, WindowContext, }; use language::{LanguageServerId, LanguageServerName}; use lsp::IoKind; use project::{search::SearchQuery, Project}; use std::{borrow::Cow, sync::Arc}; -use theme::Theme; +use theme::{ActiveTheme, Theme}; +use ui::{h_stack, v_stack, Label}; use workspace::{ item::{Item, ItemHandle}, - searchable::{SearchableItem, SearchableItemHandle}, - ToolbarItemLocation, ToolbarItemView, Workspace, + searchable::{SearchEvent, SearchableItem, SearchableItemHandle}, + ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, }; const SEND_LINE: &str = "// Send:"; @@ -50,6 +52,7 @@ pub struct LspLogView { current_server_id: Option, is_showing_rpc_trace: bool, project: Model, + focus_handle: FocusHandle, _log_store_subscriptions: Vec, } @@ -110,9 +113,9 @@ impl LogStore { projects: HashMap::default(), io_tx, }; - cx.spawn_weak(|this, mut cx| async move { + cx.spawn(|this, mut cx| async move { while let Some((project, server_id, io_kind, message)) = io_rx.next().await { - if let Some(this) = this.upgrade(&cx) { + if let Some(this) = this.upgrade() { this.update(&mut cx, |this, cx| { this.on_io(project, server_id, io_kind, &message, cx); }); @@ -120,7 +123,7 @@ impl LogStore { } anyhow::Ok(()) }) - .detach(); + .detach_and_log_err(cx); this } @@ -131,7 +134,7 @@ impl LogStore { ProjectState { servers: HashMap::default(), _subscriptions: [ - cx.observe_release(&project, move |this, _, _| { + cx.observe_release(project, move |this, _, _| { this.projects.remove(&weak_project); }), cx.subscribe(project, |this, project, event, cx| match event { @@ -185,14 +188,13 @@ impl LogStore { .ok(); }) }); - let this = cx.weak_handle(); + let this = cx.handle().downgrade(); let weak_project = project.downgrade(); server_state._lsp_logs_subscription = server.map(|server| { let server_id = server.server_id(); server.on_notification::({ move |params, mut cx| { - if let Some((project, this)) = weak_project.upgrade().zip(this.upgrade(&mut cx)) - { + if let Some((project, this)) = weak_project.upgrade().zip(this.upgrade()) { this.update(&mut cx, |this, cx| { this.add_language_server_log(&project, server_id, ¶ms.message, cx); }); @@ -413,14 +415,25 @@ impl LspLogView { } }); let (editor, editor_subscription) = Self::editor_for_logs(String::new(), cx); + + let focus_handle = cx.focus_handle(); + let focus_subscription = cx.on_focus(&focus_handle, |log_view, cx| { + cx.focus_view(&log_view.editor); + }); + let mut this = Self { + focus_handle, editor, editor_subscription, project, log_store, current_server_id: None, is_showing_rpc_trace: false, - _log_store_subscriptions: vec![model_changes_subscription, events_subscriptions], + _log_store_subscriptions: vec![ + model_changes_subscription, + events_subscriptions, + focus_subscription, + ], }; if let Some(server_id) = server_id { this.show_logs_for_server(server_id, cx); @@ -433,13 +446,18 @@ impl LspLogView { cx: &mut ViewContext, ) -> (View, Subscription) { let editor = cx.build_view(|cx| { - let mut editor = Editor::multi_line(None, cx); + let mut editor = Editor::multi_line(cx); editor.set_text(log_contents, cx); editor.move_to_end(&MoveToEnd, cx); editor.set_read_only(true); editor }); - let editor_subscription = cx.subscribe(&editor, |_, _, event, cx| cx.emit(event.clone())); + let editor_subscription = cx.subscribe( + &editor, + |_, _, event: &EditorEvent, cx: &mut ViewContext<'_, LspLogView>| { + cx.emit(event.clone()) + }, + ); (editor, editor_subscription) } @@ -526,7 +544,7 @@ impl LspLogView { .as_singleton() .expect("log buffer should be a singleton") .update(cx, |_, cx| { - cx.spawn_weak({ + cx.spawn({ let buffer = cx.handle(); |_, mut cx| async move { let language = language.await.ok(); @@ -574,30 +592,34 @@ fn log_contents(lines: &VecDeque) -> String { } } -impl View for LspLogView { - fn ui_name() -> &'static str { - "LspLogView" - } +impl Render for LspLogView { + // todo!() + // fn ui_name() -> &'static str { + // "LspLogView" + // } - fn render(&mut self, cx: &mut ViewContext) -> AnyElement { - ChildView::new(&self.editor, cx).into_any() + type Element = EditorElement; + + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + self.editor.update(cx, |editor, cx| editor.render(cx)) } +} - fn focus_in(&mut self, _: gpui::AnyView, cx: &mut ViewContext) { - if cx.is_self_focused() { - cx.focus(&self.editor); - } +impl FocusableView for LspLogView { + fn focus_handle(&self, _: &AppContext) -> FocusHandle { + self.focus_handle.clone() } } impl Item for LspLogView { - fn tab_content( - &self, - _: Option, - style: &theme::Tab, - _: &AppContext, - ) -> AnyElement { - Label::new("LSP Logs", style.label.clone()).into_any() + type Event = EditorEvent; + + fn to_item_events(event: &Self::Event, f: impl FnMut(workspace::item::ItemEvent)) { + Editor::to_item_events(event, f) + } + + fn tab_content(&self, _: Option, _: bool, _: &WindowContext<'_>) -> AnyElement { + Label::new("LSP Logs").into_any_element() } fn as_searchable(&self, handle: &View) -> Option> { @@ -608,15 +630,6 @@ impl Item for LspLogView { impl SearchableItem for LspLogView { type Match = ::Match; - fn to_search_event( - &mut self, - event: &Self::Event, - cx: &mut ViewContext, - ) -> Option { - self.editor - .update(cx, |editor, cx| editor.to_search_event(event, cx)) - } - fn clear_matches(&mut self, cx: &mut ViewContext) { self.editor.update(cx, |e, cx| e.clear_matches(cx)) } @@ -675,6 +688,8 @@ impl SearchableItem for LspLogView { } } +impl EventEmitter for LspLogToolbarItemView {} + impl ToolbarItemView for LspLogToolbarItemView { fn set_active_pane_item( &mut self, @@ -688,9 +703,7 @@ impl ToolbarItemView for LspLogToolbarItemView { self._log_view_subscription = Some(cx.observe(&log_view, |_, _, cx| { cx.notify(); })); - return ToolbarItemLocation::PrimaryLeft { - flex: Some((1., false)), - }; + return ToolbarItemLocation::PrimaryLeft; } } self.log_view = None; @@ -699,15 +712,17 @@ impl ToolbarItemView for LspLogToolbarItemView { } } -impl View for LspLogToolbarItemView { - fn ui_name() -> &'static str { - "LspLogView" - } +impl Render for LspLogToolbarItemView { + type Element = Div; + // todo!() + // fn ui_name() -> &'static str { + // "LspLogView" + // } - fn render(&mut self, cx: &mut ViewContext) -> AnyElement { - let theme = theme::current(cx).clone(); + fn render(&mut self, cx: &mut ViewContext) -> Div { + let theme = cx.theme().clone(); let Some(log_view) = self.log_view.as_ref() else { - return Empty::new().into_any(); + return div(); }; let (menu_rows, current_server_id) = log_view.update(cx, |log_view, cx| { let menu_rows = log_view.menu_items(cx).unwrap_or_default(); @@ -726,19 +741,15 @@ impl View for LspLogToolbarItemView { enum LspLogScroll {} enum Menu {} - let lsp_menu = Stack::new() - .with_child(Self::render_language_server_menu_header( - current_server, - &theme, - cx, - )) - .with_children(if self.menu_open { + let lsp_menu = h_stack() + .child(Self::render_language_server_menu_header(current_server, cx)) + .children(if self.menu_open { Some( - Overlay::new( - MouseEventHandler::new::(0, cx, move |_, cx| { - Flex::column() + overlay() + .child( + v_stack() .scrollable::(0, None, cx) - .with_children(menu_rows.into_iter().map(|row| { + .children(menu_rows.into_iter().map(|row| { Self::render_language_server_menu_item( row.server_id, row.server_name, @@ -750,51 +761,27 @@ impl View for LspLogToolbarItemView { cx, ) })) - .contained() - .with_style(theme.toolbar_dropdown_menu.container) - .constrained() - .with_width(400.) - .with_height(400.) - }) - .on_down_out(MouseButton::Left, |_, this, cx| { - this.menu_open = false; - cx.notify() - }), - ) - .with_hoverable(true) - .with_fit_mode(OverlayFitMode::SwitchAnchor) - .with_anchor_corner(AnchorCorner::TopLeft) - .with_z_index(999) - .aligned() - .bottom() - .left(), + .on_down_out(MouseButton::Left, |_, this, cx| { + this.menu_open = false; + cx.notify() + }), + ) + .with_hoverable(true) + .with_fit_mode(OverlayFitMode::SwitchAnchor) + .with_anchor_corner(AnchorCorner::TopLeft) + .with_z_index(999) + .bottom() + .left(), ) } else { None - }) - .aligned() - .left() - .clipped(); + }); enum LspCleanupButton {} - let log_cleanup_button = - MouseEventHandler::new::(1, cx, |state, cx| { - let theme = theme::current(cx).clone(); - let style = theme - .workspace - .toolbar - .toggleable_text_tool - .in_state(server_selected) - .style_for(state); - Label::new("Clear", style.text.clone()) - .aligned() - .contained() - .with_style(style.container) - .constrained() - .with_height(theme.toolbar_dropdown_menu.row_height / 6.0 * 5.0) - }) - .on_click(MouseButton::Left, move |_, this, cx| { - if let Some(log_view) = this.log_view.as_ref() { + let log_cleanup_button = div() + .child(Label::new("Clear")) + .on_mouse_down(MouseButton::Left, move |_, cx| { + if let Some(log_view) = self.log_view.as_ref() { log_view.update(cx, |log_view, cx| { log_view.editor.update(cx, |editor, cx| { editor.set_read_only(false); @@ -804,17 +791,13 @@ impl View for LspLogToolbarItemView { }) } }) - .with_cursor_style(CursorStyle::PointingHand) - .aligned() - .right(); - - Flex::row() - .with_child(lsp_menu) - .with_child(log_cleanup_button) - .contained() - .aligned() - .left() - .into_any_named("lsp log controls") + .cursor(CursorStyle::PointingHand); + + h_stack() + .child(lsp_menu) + .child(log_cleanup_button) + .border_1() + .border_color(red()) } } @@ -871,37 +854,37 @@ impl LspLogToolbarItemView { fn render_language_server_menu_header( current_server: Option, - theme: &Arc, cx: &mut ViewContext, - ) -> impl Element { + ) -> Div { + let view = cx.view().clone(); enum ToggleMenu {} - MouseEventHandler::new::(0, cx, move |state, _| { - let label: Cow = current_server - .and_then(|row| { - Some( - format!( - "{} ({}) - {}", - row.server_name.0, - row.worktree_root_name, - if row.rpc_trace_selected { - RPC_MESSAGES - } else { - SERVER_LOGS - }, - ) - .into(), + let label: Cow = current_server + .and_then(|row| { + Some( + format!( + "{} ({}) - {}", + row.server_name.0, + row.worktree_root_name, + if row.rpc_trace_selected { + RPC_MESSAGES + } else { + SERVER_LOGS + }, ) + .into(), + ) + }) + .unwrap_or_else(|| "No server selected".into()); + div() + .child(Label::new(label)) + .cursor(CursorStyle::PointingHand) + .on_mouse_down(MouseButton::Left, move |_, cx| { + view.update(cx, |view, cx| { + view.toggle_menu(cx); }) - .unwrap_or_else(|| "No server selected".into()); - let style = theme.toolbar_dropdown_menu.header.style_for(state); - Label::new(label, style.text.clone()) - .contained() - .with_style(style.container) - }) - .with_cursor_style(CursorStyle::PointingHand) - .on_click(MouseButton::Left, move |_, view, cx| { - view.toggle_menu(cx); - }) + }) + .border_1() + .border_color(red()) } fn render_language_server_menu_item( @@ -913,78 +896,52 @@ impl LspLogToolbarItemView { rpc_trace_selected: bool, theme: &Arc, cx: &mut ViewContext, - ) -> impl Element { + ) -> Div { enum ActivateLog {} enum ActivateRpcTrace {} enum LanguageServerCheckbox {} - Flex::column() - .with_child({ - let style = &theme.toolbar_dropdown_menu.section_header; - Label::new( - format!("{} ({})", name.0, worktree_root_name), - style.text.clone(), - ) - .contained() - .with_style(style.container) - .constrained() - .with_height(theme.toolbar_dropdown_menu.row_height) - }) - .with_child( - MouseEventHandler::new::(id.0, cx, move |state, _| { - let style = theme - .toolbar_dropdown_menu - .item - .in_state(logs_selected) - .style_for(state); - Label::new(SERVER_LOGS, style.text.clone()) - .contained() - .with_style(style.container) - .constrained() - .with_height(theme.toolbar_dropdown_menu.row_height) - }) - .with_cursor_style(CursorStyle::PointingHand) - .on_click(MouseButton::Left, move |_, view, cx| { - view.show_logs_for_server(id, cx); - }), + let view = cx.view().clone(); + + v_stack() + .child(Label::new(format!("{} ({})", name.0, worktree_root_name))) + .child( + div() + .child(Label::new(SERVER_LOGS)) + .cursor(CursorStyle::PointingHand) + .on_mouse_down(MouseButton::Left, move |_, cx| { + view.update(cx, |view, cx| { + view.show_logs_for_server(id, cx); + }) + }), ) - .with_child( - MouseEventHandler::new::(id.0, cx, move |state, cx| { - let style = theme - .toolbar_dropdown_menu - .item - .in_state(rpc_trace_selected) - .style_for(state); - Flex::row() - .with_child( - Label::new(RPC_MESSAGES, style.text.clone()) - .constrained() - .with_height(theme.toolbar_dropdown_menu.row_height), - ) - .with_child( - ui::checkbox_with_label::( - Empty::new(), - &theme.welcome.checkbox, - rpc_trace_enabled, - id.0, - cx, - move |this, enabled, cx| { - this.toggle_logging_for_server(id, enabled, cx); - }, - ) - .flex_float(), + .child( + h_stack() + .child(Label::new(RPC_MESSAGES)) + .child( + ui::checkbox_with_label::( + div(), + &theme.welcome.checkbox, + rpc_trace_enabled, + id.0, + cx, + move |this, enabled, cx| { + this.toggle_logging_for_server(id, enabled, cx); + }, ) - .align_children_center() - .contained() - .with_style(style.container) - .constrained() - .with_height(theme.toolbar_dropdown_menu.row_height) - }) - .with_cursor_style(CursorStyle::PointingHand) - .on_click(MouseButton::Left, move |_, view, cx| { - view.show_rpc_trace_for_server(id, cx); - }), + .flex_float(), + ) + .border_1() + .border_color(red()) + .cursor(CursorStyle::PointingHand) + .on_mouse_down(MouseButton::Left, move |_, cx| { + view.update(cx, |view, cx| { + view.show_rpc_trace_for_server(id, cx); + }) + }), ) + .border_1() + .border_color(red()) } } @@ -996,14 +953,7 @@ pub enum Event { }, } -impl Entity for LogStore { - type Event = Event; -} - -impl Entity for LspLogView { - type Event = editor::Event; -} - -impl Entity for LspLogToolbarItemView { - type Event = (); -} +impl EventEmitter for LogStore {} +impl EventEmitter for LspLogView {} +impl EventEmitter for LspLogView {} +impl EventEmitter for LspLogView {} diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index 80ff211176598539538bd3d8cd490feb7f2ef5cd..7efd5f572323d08a8c2c9b9e675eeedee2fd5964 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -1,17 +1,20 @@ use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId}; use gpui::{ - actions, AnchorCorner, AppContext, CursorStyle, Div, Element, Empty, Entity, Focusable, Model, - MouseButton, Overlay, OverlayFitMode, ParentElement, Render, TextStyle, UniformList, - UniformListState, View, ViewContext, VisualContext, WeakView, + actions, div, overlay, red, uniform_list, AnyElement, AppContext, CursorStyle, Div, + EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model, + MouseButton, ParentElement, Render, Styled, TextStyle, UniformListState, View, ViewContext, + VisualContext, WeakView, WindowContext, }; use language::{Buffer, OwnedSyntaxLayerInfo, SyntaxLayerInfo}; -use std::{mem, ops::Range, sync::Arc}; -use theme::{ActiveTheme, Theme, ThemeSettings}; +use settings::Settings; +use std::{mem, ops::Range}; +use theme::{ActiveTheme, ThemeSettings}; use tree_sitter::{Node, TreeCursor}; +use ui::{h_stack, Label}; use workspace::{ item::{Item, ItemHandle}, ui::v_stack, - ToolbarItemLocation, ToolbarItemView, Workspace, + ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, }; actions!(debug, [OpenSyntaxTreeView]); @@ -37,6 +40,7 @@ pub struct SyntaxTreeView { list_state: UniformListState, selected_descendant_ix: Option, hovered_descendant_ix: Option, + focus_handle: FocusHandle, } pub struct SyntaxTreeToolbarItemView { @@ -72,6 +76,7 @@ impl SyntaxTreeView { line_height: None, hovered_descendant_ix: None, selected_descendant_ix: None, + focus_handle: cx.focus_handle(), }; this.workspace_updated(active_item, cx); @@ -229,7 +234,7 @@ impl SyntaxTreeView { editor.clear_background_highlights::(cx); editor.highlight_background::( vec![range], - |theme| theme.editor.document_highlight_write_background, + |theme| theme.editor_document_highlight_write_background, cx, ); }); @@ -281,10 +286,10 @@ impl SyntaxTreeView { style: &TextStyle, editor_theme: &theme::Editor, cx: &AppContext, - ) -> gpui::AnyElement { + ) -> Div { let node = cursor.node(); let mut range_style = style.clone(); - let em_width = style.em_width(cx.font_cache()); + let em_width = style.em_width(cx.text_system()); let gutter_padding = (em_width * editor_theme.gutter_padding_factor).round(); range_style.color = editor_theme.line_number; @@ -304,64 +309,54 @@ impl SyntaxTreeView { anonymous_node_style.color = color; } - let mut row = Flex::row(); + let mut row = h_stack(); if let Some(field_name) = cursor.field_name() { let mut field_style = style.clone(); if let Some(color) = property_color { field_style.color = color; } - row.add_children([ - Label::new(field_name, field_style), - Label::new(": ", style.clone()), - ]); + row = row.children([Label::new(field_name), Label::new(": ")]); } return row - .with_child( + .child( if node.is_named() { - Label::new(node.kind(), style.clone()) + Label::new(node.kind()) } else { - Label::new(format!("\"{}\"", node.kind()), anonymous_node_style) - } - .contained() - .with_margin_right(em_width), + Label::new(format!("\"{}\"", node.kind())) + }, // todo!() + // .margin(em_width), ) - .with_child(Label::new(format_node_range(node), range_style)) - .contained() - .with_background_color(if selected { + .child(Label::new(format_node_range(node))) + .text_bg(if selected { editor_theme.selection.selection } else if hovered && list_hovered { editor_theme.active_line_background } else { - Default::default() + Hsla::default() }) - .with_padding_left(gutter_padding + depth as f32 * 18.0) - .into_any(); + // todo!() + // .padding(gutter_padding + depth as f32 * 18.0) + .border_1() + .border_color(red()); } } -impl Entity for SyntaxTreeView { - type Event = (); -} +impl Render for SyntaxTreeView { + // todo!() + // fn ui_name() -> &'static str { + // "SyntaxTreeView" + // } -impl View for SyntaxTreeView { - fn ui_name() -> &'static str { - "SyntaxTreeView" - } + type Element = Div; - fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement { - let settings = settings::get::(cx); - let font_family_id = settings.buffer_font_family; - let font_family_name = cx.font_cache().family_name(font_family_id).unwrap(); - let font_properties = Default::default(); - let font_id = cx - .font_cache() - .select_font(font_family_id, &font_properties) - .unwrap(); + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Div { + let settings = ThemeSettings::get_global(cx); + let font = settings.buffer_font; let font_size = settings.buffer_font_size(cx); - let editor_theme = settings.theme.editor.clone(); + let editor_theme = settings.active_theme; let style = TextStyle { color: editor_theme.text_color, font_family_name, @@ -370,10 +365,16 @@ impl View for SyntaxTreeView { font_size, font_properties: Default::default(), underline: Default::default(), - soft_wrap: false, + font_family: todo!(), + font_features: todo!(), + line_height: todo!(), + font_weight: todo!(), + font_style: todo!(), + background_color: todo!(), + white_space: todo!(), }; - let line_height = cx.font_cache().line_height(font_size); + let line_height = cx.text_system().line_height(font_size); if Some(line_height) != self.line_height { self.line_height = Some(line_height); self.hover_state_changed(cx); @@ -387,90 +388,95 @@ impl View for SyntaxTreeView { { let layer = layer.clone(); let theme = editor_theme.clone(); - return MouseEventHandler::new::(0, cx, move |state, cx| { - let list_hovered = state.hovered(); - UniformList::new( - self.list_state.clone(), - layer.node().descendant_count(), - cx, - move |this, range, items, cx| { - let mut cursor = layer.node().walk(); - let mut descendant_ix = range.start as usize; - cursor.goto_descendant(descendant_ix); - let mut depth = cursor.depth(); - let mut visited_children = false; - while descendant_ix < range.end { - if visited_children { - if cursor.goto_next_sibling() { - visited_children = false; - } else if cursor.goto_parent() { - depth -= 1; - } else { - break; - } + + let list_hovered = state.hovered(); + uniform_list( + self.list_state.clone(), + layer.node().descendant_count(), + cx, + move |this, range, items, cx| { + let mut cursor = layer.node().walk(); + let mut descendant_ix = range.start as usize; + cursor.goto_descendant(descendant_ix); + let mut depth = cursor.depth(); + let mut visited_children = false; + while descendant_ix < range.end { + if visited_children { + if cursor.goto_next_sibling() { + visited_children = false; + } else if cursor.goto_parent() { + depth -= 1; } else { - items.push(Self::render_node( - &cursor, - depth, - Some(descendant_ix) == this.selected_descendant_ix, - Some(descendant_ix) == this.hovered_descendant_ix, - list_hovered, - &style, - &theme, - cx, - )); - descendant_ix += 1; - if cursor.goto_first_child() { - depth += 1; - } else { - visited_children = true; - } + break; + } + } else { + items.push(Self::render_node( + &cursor, + depth, + Some(descendant_ix) == this.selected_descendant_ix, + Some(descendant_ix) == this.hovered_descendant_ix, + list_hovered, + &style, + &theme, + cx, + )); + descendant_ix += 1; + if cursor.goto_first_child() { + depth += 1; + } else { + visited_children = true; } } - }, - ) - }) + } + }, + ) .on_move(move |event, this, cx| { let y = event.position.y() - event.region.origin_y(); this.mouse_y = Some(y); this.hover_state_changed(cx); }) - .on_click(MouseButton::Left, move |event, this, cx| { + .on_mouse_down(MouseButton::Left, move |event, cx| { let y = event.position.y() - event.region.origin_y(); - this.handle_click(y, cx); - }) - .contained() - .with_background_color(editor_theme.background) - .into_any(); + self.handle_click(y, cx); + }); } - Empty::new().into_any() + div() + } +} + +impl EventEmitter<()> for SyntaxTreeView {} + +impl FocusableView for SyntaxTreeView { + fn focus_handle(&self, _: &AppContext) -> gpui::FocusHandle { + self.focus_handle.clone() } } impl Item for SyntaxTreeView { - fn tab_content( - &self, - _: Option, - style: &theme::Tab, - _: &AppContext, - ) -> gpui::AnyElement { - Label::new("Syntax Tree", style.label.clone()).into_any() + type Event = (); + + fn to_item_events(_: &Self::Event, _: impl FnMut(workspace::item::ItemEvent)) {} + + fn tab_content(&self, _: Option, _: bool, _: &WindowContext<'_>) -> AnyElement { + Label::new("Syntax Tree").into_any_element() } fn clone_on_split( &self, - _workspace_id: workspace::WorkspaceId, + _: workspace::WorkspaceId, cx: &mut ViewContext, - ) -> Option + ) -> Option> where Self: Sized, { - let mut clone = Self::new(self.workspace_handle.clone(), None, cx); - if let Some(editor) = &self.editor { - clone.set_editor(editor.editor.clone(), cx) - } - Some(clone) + Some(cx.build_view(|cx| { + let mut clone = Self::new(self.workspace_handle.clone(), None, cx); + if let Some(editor) = &self.editor { + clone.set_editor(editor.editor.clone(), cx) + } + clone + })) } } @@ -483,10 +489,7 @@ impl SyntaxTreeToolbarItemView { } } - fn render_menu( - &mut self, - cx: &mut ViewContext<'_, '_, Self>, - ) -> Option> { + fn render_menu(&mut self, cx: &mut ViewContext<'_, Self>) -> Option
{ let theme = cx.theme().clone(); let tree_view = self.tree_view.as_ref()?; let tree_view = tree_view.read(cx); @@ -496,36 +499,23 @@ impl SyntaxTreeToolbarItemView { let active_layer = buffer_state.active_layer.clone()?; let active_buffer = buffer_state.buffer.read(cx).snapshot(); - enum Menu {} - Some( v_stack() - .child(Self::render_header(&theme, &active_layer, cx)) + .child(Self::render_header(&active_layer, cx)) .children(self.menu_open.then(|| { - overlay( - mouse_event_handler::(0, cx, move |_, cx| { - v_stack() - .with_children(active_buffer.syntax_layers().enumerate().map( - |(ix, layer)| { - Self::render_menu_item(&theme, &active_layer, layer, ix, cx) - }, - )) - .contained() - .with_style(theme.toolbar_dropdown_menu.container) - .constrained() - .with_width(400.) - .with_height(400.) - }) - .on_down_out(MouseButton::Left, |_, this, cx| { - this.menu_open = false; - cx.notify() - }), + overlay().child( + v_stack() + .children(active_buffer.syntax_layers().enumerate().map( + |(ix, layer)| Self::render_menu_item(&active_layer, layer, ix, cx), + )) + .on_mouse_down_out(|e, cx| { + if e.button == MouseButton::Left { + self.menu_open = false; + cx.notify() + } + }), ) - .with_hoverable(true) - .with_fit_content() - .into_any() - })) - .into_any(), + })), ) } @@ -549,71 +539,39 @@ impl SyntaxTreeToolbarItemView { }) } - fn render_header( - theme: &Arc, - active_layer: &OwnedSyntaxLayerInfo, - cx: &mut ViewContext, - ) -> impl Element { - enum ToggleMenu {} - MouseEventHandler::new::(0, cx, move |state, _| { - let style = theme.toolbar_dropdown_menu.header.style_for(state); - Flex::row() - .with_child( - Label::new(active_layer.language.name().to_string(), style.text.clone()) - .contained() - .with_margin_right(style.secondary_text_spacing), - ) - .with_child(Label::new( - format_node_range(active_layer.node()), - style - .secondary_text - .clone() - .unwrap_or_else(|| style.text.clone()), - )) - .contained() - .with_style(style.container) - }) - .with_cursor_style(CursorStyle::PointingHand) - .on_click(MouseButton::Left, move |_, view, cx| { - view.toggle_menu(cx); - }) + fn render_header(active_layer: &OwnedSyntaxLayerInfo, cx: &mut ViewContext) -> Div { + let view = cx.view().clone(); + h_stack() + .child(Label::new(active_layer.language.name())) + .child(Label::new(format_node_range(active_layer.node()))) + .on_mouse_down(MouseButton::Left, move |_, cx| { + view.update(cx, |view, cx| view.toggle_menu(cx)); + }) + .cursor(CursorStyle::PointingHand) + .border_1() + .border_color(red()) } fn render_menu_item( - theme: &Arc, active_layer: &OwnedSyntaxLayerInfo, layer: SyntaxLayerInfo, layer_ix: usize, cx: &mut ViewContext, - ) -> impl Element { - enum ActivateLayer {} - MouseEventHandler::new::(layer_ix, cx, move |state, _| { - let is_selected = layer.node() == active_layer.node(); - let style = theme - .toolbar_dropdown_menu - .item - .in_state(is_selected) - .style_for(state); - Flex::row() - .with_child( - Label::new(layer.language.name().to_string(), style.text.clone()) - .contained() - .with_margin_right(style.secondary_text_spacing), - ) - .with_child(Label::new( - format_node_range(layer.node()), - style - .secondary_text - .clone() - .unwrap_or_else(|| style.text.clone()), - )) - .contained() - .with_style(style.container) - }) - .with_cursor_style(CursorStyle::PointingHand) - .on_click(MouseButton::Left, move |_, view, cx| { - view.select_layer(layer_ix, cx); - }) + ) -> Div { + // todo!() styling + let _is_selected = layer.node() == active_layer.node(); + let view = cx.view().clone(); + h_stack() + .child(Label::new(layer.language.name().to_string())) + .child(Label::new(format_node_range(layer.node()))) + .cursor(CursorStyle::PointingHand) + .on_mouse_down(MouseButton::Left, move |_, cx| { + view.update(cx, |view, cx| { + view.select_layer(layer_ix, cx); + }) + }) + .border_1() + .border_color(red()) } } @@ -630,33 +588,32 @@ fn format_node_range(node: Node) -> String { } impl Render for SyntaxTreeToolbarItemView { - type Element = Focusable
; + type Element = Div; // todo!() // fn ui_name() -> &'static str { // "SyntaxTreeToolbarItemView" // } - fn render(&mut self, cx: &mut ViewContext<'_, '_, Self>) -> gpui::AnyElement { - self.render_menu(cx) - .unwrap_or_else(|| Empty::new().into_any()) + fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> Div { + self.render_menu(cx).unwrap_or_else(|| div()) } } +impl EventEmitter for SyntaxTreeToolbarItemView {} + impl ToolbarItemView for SyntaxTreeToolbarItemView { fn set_active_pane_item( &mut self, active_pane_item: Option<&dyn ItemHandle>, cx: &mut ViewContext, - ) -> workspace::ToolbarItemLocation { + ) -> ToolbarItemLocation { self.menu_open = false; if let Some(item) = active_pane_item { if let Some(view) = item.downcast::() { self.tree_view = Some(view.clone()); self.subscription = Some(cx.observe(&view, |_, _, cx| cx.notify())); - return ToolbarItemLocation::PrimaryLeft { - flex: Some((1., false)), - }; + return ToolbarItemLocation::PrimaryLeft; } } self.tree_view = None; From 8471a5f80b04dfcebdb701a4c1958cef63152e65 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 17:04:24 +0200 Subject: [PATCH 191/644] Finish all but the styling --- crates/gpui2/src/elements/uniform_list.rs | 8 + crates/language_tools2/src/lsp_log.rs | 170 +++++++++--------- .../language_tools2/src/syntax_tree_view.rs | 146 +++++++-------- 3 files changed, 168 insertions(+), 156 deletions(-) diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 7fba7ef47777553ae6e5e36ab8e20f5e01869360..e8587683d691143358263306403187439a52c68a 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -91,6 +91,14 @@ impl UniformListScrollHandle { } } } + + pub fn scroll_top(&self) -> Pixels { + if let Some(state) = &*self.0.borrow() { + -state.scroll_offset.borrow().y + } else { + Pixels::ZERO + } + } } impl Styled for UniformList { diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index ca4f25e177fc3204ea155600d184d76c50bdfa08..3c3df41442e983dc5045e22c5173e0e033e22a1b 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -2,17 +2,16 @@ use collections::{HashMap, VecDeque}; use editor::{Editor, EditorElement, EditorEvent, MoveToEnd}; use futures::{channel::mpsc, StreamExt}; use gpui::{ - actions, div, overlay, red, AnchorCorner, AnyElement, AppContext, Context, CursorStyle, Div, - EventEmitter, FocusHandle, FocusableView, InteractiveElement, IntoElement, Model, ModelContext, - MouseButton, OverlayFitMode, ParentElement, Render, Styled, Subscription, View, ViewContext, - VisualContext, WeakModel, WindowContext, + actions, div, overlay, red, AnyElement, AppContext, Context, CursorStyle, Div, EventEmitter, + FocusHandle, FocusableView, InteractiveElement, IntoElement, Model, ModelContext, MouseButton, + MouseDownEvent, ParentElement, Render, Styled, Subscription, View, ViewContext, VisualContext, + WeakModel, WindowContext, }; use language::{LanguageServerId, LanguageServerName}; use lsp::IoKind; use project::{search::SearchQuery, Project}; use std::{borrow::Cow, sync::Arc}; -use theme::{ActiveTheme, Theme}; -use ui::{h_stack, v_stack, Label}; +use ui::{h_stack, v_stack, Checkbox, Label}; use workspace::{ item::{Item, ItemHandle}, searchable::{SearchEvent, SearchableItem, SearchableItemHandle}, @@ -83,7 +82,7 @@ actions!(debug, [OpenLanguageServerLogs]); pub fn init(cx: &mut AppContext) { let log_store = cx.build_model(|cx| LogStore::new(cx)); - cx.observe_new_views(|workspace: &mut Workspace, cx| { + cx.observe_new_views(move |workspace: &mut Workspace, cx| { let project = workspace.project(); if project.read(cx).is_local() { log_store.update(cx, |store, cx| { @@ -91,7 +90,8 @@ pub fn init(cx: &mut AppContext) { }); } - workspace.register_action(|workspace, _: &OpenLanguageServerLogs, cx| { + let log_store = log_store.clone(); + workspace.register_action(move |workspace, _: &OpenLanguageServerLogs, cx| { let project = workspace.project().read(cx); if project.is_local() { workspace.add_item( @@ -118,7 +118,7 @@ impl LogStore { if let Some(this) = this.upgrade() { this.update(&mut cx, |this, cx| { this.on_io(project, server_id, io_kind, &message, cx); - }); + })?; } } anyhow::Ok(()) @@ -130,7 +130,7 @@ impl LogStore { pub fn add_project(&mut self, project: &Model, cx: &mut ModelContext) { let weak_project = project.downgrade(); self.projects.insert( - weak_project, + project.downgrade(), ProjectState { servers: HashMap::default(), _subscriptions: [ @@ -184,7 +184,7 @@ impl LogStore { server_state._io_logs_subscription = server.as_ref().map(|server| { server.on_io(move |io_kind, message| { io_tx - .unbounded_send((weak_project, id, io_kind, message.to_string())) + .unbounded_send((weak_project.clone(), id, io_kind, message.to_string())) .ok(); }) }); @@ -197,7 +197,8 @@ impl LogStore { if let Some((project, this)) = weak_project.upgrade().zip(this.upgrade()) { this.update(&mut cx, |this, cx| { this.add_language_server_log(&project, server_id, ¶ms.message, cx); - }); + }) + .ok(); } } }) @@ -550,10 +551,10 @@ impl LspLogView { let language = language.await.ok(); buffer.update(&mut cx, |buffer, cx| { buffer.set_language(language, cx); - }); + }) } }) - .detach(); + .detach_and_log_err(cx); }); self.editor = editor; @@ -720,7 +721,6 @@ impl Render for LspLogToolbarItemView { // } fn render(&mut self, cx: &mut ViewContext) -> Div { - let theme = cx.theme().clone(); let Some(log_view) = self.log_view.as_ref() else { return div(); }; @@ -737,60 +737,60 @@ impl Render for LspLogToolbarItemView { None } }); - let server_selected = current_server.is_some(); + // todo!() styling + let _server_selected = current_server.is_some(); - enum LspLogScroll {} - enum Menu {} let lsp_menu = h_stack() .child(Self::render_language_server_menu_header(current_server, cx)) .children(if self.menu_open { Some( - overlay() - .child( - v_stack() - .scrollable::(0, None, cx) - .children(menu_rows.into_iter().map(|row| { - Self::render_language_server_menu_item( - row.server_id, - row.server_name, - &row.worktree_root_name, - row.rpc_trace_enabled, - row.logs_selected, - row.rpc_trace_selected, - &theme, - cx, - ) - })) - .on_down_out(MouseButton::Left, |_, this, cx| { + overlay().child( + v_stack() + // todo!() + // .scrollable::(0, None, cx) + .children(menu_rows.into_iter().map(|row| { + Self::render_language_server_menu_item( + row.server_id, + row.server_name, + &row.worktree_root_name, + row.rpc_trace_enabled, + row.logs_selected, + row.rpc_trace_selected, + cx, + ) + })) + .on_mouse_down_out(cx.listener(|this, event: &MouseDownEvent, cx| { + if event.button == MouseButton::Left { this.menu_open = false; cx.notify() - }), - ) - .with_hoverable(true) - .with_fit_mode(OverlayFitMode::SwitchAnchor) - .with_anchor_corner(AnchorCorner::TopLeft) - .with_z_index(999) - .bottom() - .left(), + } + })), + ), // todo!() + // .with_hoverable(true) + // .with_fit_mode(OverlayFitMode::SwitchAnchor) + // .with_anchor_corner(AnchorCorner::TopLeft) + // .with_z_index(999), ) } else { None }); - enum LspCleanupButton {} let log_cleanup_button = div() .child(Label::new("Clear")) - .on_mouse_down(MouseButton::Left, move |_, cx| { - if let Some(log_view) = self.log_view.as_ref() { - log_view.update(cx, |log_view, cx| { - log_view.editor.update(cx, |editor, cx| { - editor.set_read_only(false); - editor.clear(cx); - editor.set_read_only(true); - }); - }) - } - }) + .on_mouse_down( + MouseButton::Left, + cx.listener(move |this, _, cx| { + if let Some(log_view) = this.log_view.as_ref() { + log_view.update(cx, |log_view, cx| { + log_view.editor.update(cx, |editor, cx| { + editor.set_read_only(false); + editor.clear(cx); + editor.set_read_only(true); + }); + }) + } + }), + ) .cursor(CursorStyle::PointingHand); h_stack() @@ -856,8 +856,6 @@ impl LspLogToolbarItemView { current_server: Option, cx: &mut ViewContext, ) -> Div { - let view = cx.view().clone(); - enum ToggleMenu {} let label: Cow = current_server .and_then(|row| { Some( @@ -878,11 +876,12 @@ impl LspLogToolbarItemView { div() .child(Label::new(label)) .cursor(CursorStyle::PointingHand) - .on_mouse_down(MouseButton::Left, move |_, cx| { - view.update(cx, |view, cx| { + .on_mouse_down( + MouseButton::Left, + cx.listener(move |view, _, cx| { view.toggle_menu(cx); - }) - }) + }), + ) .border_1() .border_color(red()) } @@ -892,53 +891,52 @@ impl LspLogToolbarItemView { name: LanguageServerName, worktree_root_name: &str, rpc_trace_enabled: bool, - logs_selected: bool, - rpc_trace_selected: bool, - theme: &Arc, + // todo!() styling + _logs_selected: bool, + _rpc_trace_selected: bool, cx: &mut ViewContext, ) -> Div { - enum ActivateLog {} - enum ActivateRpcTrace {} - enum LanguageServerCheckbox {} - - let view = cx.view().clone(); - v_stack() .child(Label::new(format!("{} ({})", name.0, worktree_root_name))) .child( div() .child(Label::new(SERVER_LOGS)) .cursor(CursorStyle::PointingHand) - .on_mouse_down(MouseButton::Left, move |_, cx| { - view.update(cx, |view, cx| { + .on_mouse_down( + MouseButton::Left, + cx.listener(move |view, _, cx| { view.show_logs_for_server(id, cx); - }) - }), + }), + ), ) .child( h_stack() .child(Label::new(RPC_MESSAGES)) .child( - ui::checkbox_with_label::( - div(), - &theme.welcome.checkbox, - rpc_trace_enabled, + Checkbox::new( id.0, - cx, - move |this, enabled, cx| { - this.toggle_logging_for_server(id, enabled, cx); + if rpc_trace_enabled { + ui::Selection::Selected + } else { + ui::Selection::Unselected }, ) - .flex_float(), + .on_click(cx.listener( + move |this, selection, cx| { + let enabled = matches!(selection, ui::Selection::Selected); + this.toggle_logging_for_server(id, enabled, cx); + }, + )), ) .border_1() .border_color(red()) .cursor(CursorStyle::PointingHand) - .on_mouse_down(MouseButton::Left, move |_, cx| { - view.update(cx, |view, cx| { + .on_mouse_down( + MouseButton::Left, + cx.listener(move |view, _, cx| { view.show_rpc_trace_for_server(id, cx); - }) - }), + }), + ), ) .border_1() .border_color(red()) diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index 7efd5f572323d08a8c2c9b9e675eeedee2fd5964..9c8ec0ee043ceb99d1569d6f67c8b829a023feef 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -2,13 +2,13 @@ use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId}; use gpui::{ actions, div, overlay, red, uniform_list, AnyElement, AppContext, CursorStyle, Div, EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model, - MouseButton, ParentElement, Render, Styled, TextStyle, UniformListState, View, ViewContext, - VisualContext, WeakView, WindowContext, + MouseButton, MouseDownEvent, MouseMoveEvent, ParentElement, Pixels, Render, Styled, TextStyle, + UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext, }; use language::{Buffer, OwnedSyntaxLayerInfo, SyntaxLayerInfo}; use settings::Settings; use std::{mem, ops::Range}; -use theme::{ActiveTheme, ThemeSettings}; +use theme::{Theme, ThemeSettings}; use tree_sitter::{Node, TreeCursor}; use ui::{h_stack, Label}; use workspace::{ @@ -35,9 +35,9 @@ pub fn init(cx: &mut AppContext) { pub struct SyntaxTreeView { workspace_handle: WeakView, editor: Option, - mouse_y: Option, - line_height: Option, - list_state: UniformListState, + mouse_y: Option, + line_height: Option, + list_scroll_handle: UniformListScrollHandle, selected_descendant_ix: Option, hovered_descendant_ix: Option, focus_handle: FocusHandle, @@ -70,7 +70,7 @@ impl SyntaxTreeView { ) -> Self { let mut this = Self { workspace_handle: workspace_handle.clone(), - list_state: UniformListState::default(), + list_scroll_handle: UniformListScrollHandle::new(), editor: None, mouse_y: None, line_height: None, @@ -204,15 +204,15 @@ impl SyntaxTreeView { let descendant_ix = cursor.descendant_index(); self.selected_descendant_ix = Some(descendant_ix); - self.list_state.scroll_to(ScrollTarget::Show(descendant_ix)); + self.list_scroll_handle.scroll_to_item(descendant_ix); cx.notify(); Some(()) } - fn handle_click(&mut self, y: f32, cx: &mut ViewContext) -> Option<()> { + fn handle_click(&mut self, y: Pixels, cx: &mut ViewContext) -> Option<()> { let line_height = self.line_height?; - let ix = ((self.list_state.scroll_top() + y) / line_height) as usize; + let ix = ((self.list_scroll_handle.scroll_top() + y) / line_height) as usize; self.update_editor_with_range_for_descendant_ix(ix, cx, |editor, mut range, cx| { // Put the cursor at the beginning of the node. @@ -227,7 +227,7 @@ impl SyntaxTreeView { fn hover_state_changed(&mut self, cx: &mut ViewContext) { if let Some((y, line_height)) = self.mouse_y.zip(self.line_height) { - let ix = ((self.list_state.scroll_top() + y) / line_height) as usize; + let ix = ((self.list_scroll_handle.scroll_top() + y) / line_height) as usize; if self.hovered_descendant_ix != Some(ix) { self.hovered_descendant_ix = Some(ix); self.update_editor_with_range_for_descendant_ix(ix, cx, |editor, range, cx| { @@ -279,29 +279,39 @@ impl SyntaxTreeView { fn render_node( cursor: &TreeCursor, - depth: u32, + _depth: u32, selected: bool, hovered: bool, list_hovered: bool, style: &TextStyle, - editor_theme: &theme::Editor, - cx: &AppContext, + editor_theme: &Theme, + _cx: &AppContext, ) -> Div { + let editor_colors = editor_theme.colors(); let node = cursor.node(); let mut range_style = style.clone(); - let em_width = style.em_width(cx.text_system()); - let gutter_padding = (em_width * editor_theme.gutter_padding_factor).round(); - - range_style.color = editor_theme.line_number; + // todo!() styling + // let font_id = cx.text_system().font_id(&style.text.font()).unwrap(); + // let font_size = style.text.font_size.to_pixels(cx.rem_size()); + // let line_height = style.text.line_height_in_pixels(cx.rem_size()); + // let em_width = cx + // .text_system() + // .typographic_bounds(font_id, font_size, 'm') + // .unwrap() + // .size + // .width; + // let gutter_padding = (em_width * editor_theme.gutter_padding_factor).round(); + + range_style.color = editor_colors.editor_line_number; let mut anonymous_node_style = style.clone(); let string_color = editor_theme - .syntax + .syntax() .highlights .iter() .find_map(|(name, style)| (name == "string").then(|| style.color)?); let property_color = editor_theme - .syntax + .syntax() .highlights .iter() .find_map(|(name, style)| (name == "property").then(|| style.color)?); @@ -330,9 +340,9 @@ impl SyntaxTreeView { ) .child(Label::new(format_node_range(node))) .text_bg(if selected { - editor_theme.selection.selection + editor_colors.element_selected } else if hovered && list_hovered { - editor_theme.active_line_background + editor_colors.element_active } else { Hsla::default() }) @@ -344,37 +354,25 @@ impl SyntaxTreeView { } impl Render for SyntaxTreeView { - // todo!() - // fn ui_name() -> &'static str { - // "SyntaxTreeView" - // } - type Element = Div; fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Div { let settings = ThemeSettings::get_global(cx); - let font = settings.buffer_font; + let font = settings.buffer_font.clone(); let font_size = settings.buffer_font_size(cx); - let editor_theme = settings.active_theme; + let editor_theme = settings.active_theme.clone(); + let editor_colors = editor_theme.colors(); let style = TextStyle { - color: editor_theme.text_color, - font_family_name, - font_family_id, - font_id, - font_size, - font_properties: Default::default(), - underline: Default::default(), - font_family: todo!(), - font_features: todo!(), - line_height: todo!(), - font_weight: todo!(), - font_style: todo!(), - background_color: todo!(), - white_space: todo!(), + color: editor_colors.text, + font_family: font.family, + font_features: font.features, + font_weight: font.weight, + font_style: font.style, + ..Default::default() }; - let line_height = cx.text_system().line_height(font_size); + let line_height = cx.text_style().line_height_in_pixels(font_size); if Some(line_height) != self.line_height { self.line_height = Some(line_height); self.hover_state_changed(cx); @@ -389,12 +387,15 @@ impl Render for SyntaxTreeView { let layer = layer.clone(); let theme = editor_theme.clone(); - let list_hovered = state.hovered(); + // todo!() + // let list_hovered = state.hovered(); + let list_hovered = false; uniform_list( - self.list_state.clone(), + cx.view().clone(), + "SyntaxTreeView", layer.node().descendant_count(), - cx, - move |this, range, items, cx| { + move |this, range, cx| { + let mut items = Vec::new(); let mut cursor = layer.node().walk(); let mut descendant_ix = range.start as usize; cursor.goto_descendant(descendant_ix); @@ -428,17 +429,21 @@ impl Render for SyntaxTreeView { } } } + items }, ) - .on_move(move |event, this, cx| { - let y = event.position.y() - event.region.origin_y(); - this.mouse_y = Some(y); - this.hover_state_changed(cx); - }) - .on_mouse_down(MouseButton::Left, move |event, cx| { - let y = event.position.y() - event.region.origin_y(); - self.handle_click(y, cx); - }); + .track_scroll(self.list_scroll_handle.clone()) + .on_mouse_move(cx.listener(move |tree_view, event: &MouseMoveEvent, cx| { + tree_view.mouse_y = Some(event.position.y); + tree_view.hover_state_changed(cx); + })) + .on_mouse_down( + MouseButton::Left, + cx.listener(move |tree_view, event: &MouseDownEvent, cx| { + tree_view.handle_click(event.position.y, cx); + }), + ) + .text_bg(editor_colors.background); } div() @@ -490,7 +495,6 @@ impl SyntaxTreeToolbarItemView { } fn render_menu(&mut self, cx: &mut ViewContext<'_, Self>) -> Option
{ - let theme = cx.theme().clone(); let tree_view = self.tree_view.as_ref()?; let tree_view = tree_view.read(cx); @@ -508,12 +512,12 @@ impl SyntaxTreeToolbarItemView { .children(active_buffer.syntax_layers().enumerate().map( |(ix, layer)| Self::render_menu_item(&active_layer, layer, ix, cx), )) - .on_mouse_down_out(|e, cx| { + .on_mouse_down_out(cx.listener(|this, e: &MouseDownEvent, cx| { if e.button == MouseButton::Left { - self.menu_open = false; + this.menu_open = false; cx.notify() } - }), + })), ) })), ) @@ -540,13 +544,15 @@ impl SyntaxTreeToolbarItemView { } fn render_header(active_layer: &OwnedSyntaxLayerInfo, cx: &mut ViewContext) -> Div { - let view = cx.view().clone(); h_stack() .child(Label::new(active_layer.language.name())) .child(Label::new(format_node_range(active_layer.node()))) - .on_mouse_down(MouseButton::Left, move |_, cx| { - view.update(cx, |view, cx| view.toggle_menu(cx)); - }) + .on_mouse_down( + MouseButton::Left, + cx.listener(move |view, _, cx| { + view.toggle_menu(cx); + }), + ) .cursor(CursorStyle::PointingHand) .border_1() .border_color(red()) @@ -560,16 +566,16 @@ impl SyntaxTreeToolbarItemView { ) -> Div { // todo!() styling let _is_selected = layer.node() == active_layer.node(); - let view = cx.view().clone(); h_stack() .child(Label::new(layer.language.name().to_string())) .child(Label::new(format_node_range(layer.node()))) .cursor(CursorStyle::PointingHand) - .on_mouse_down(MouseButton::Left, move |_, cx| { - view.update(cx, |view, cx| { + .on_mouse_down( + MouseButton::Left, + cx.listener(move |view, _, cx| { view.select_layer(layer_ix, cx); - }) - }) + }), + ) .border_1() .border_color(red()) } From 7e6dac383e380370d38381def811d5e47192776b Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 17:14:52 +0200 Subject: [PATCH 192/644] Uncomment tests --- crates/language_tools2/src/lsp_log_tests.rs | 190 ++++++++++---------- 1 file changed, 94 insertions(+), 96 deletions(-) diff --git a/crates/language_tools2/src/lsp_log_tests.rs b/crates/language_tools2/src/lsp_log_tests.rs index 967e8a33824d75152472f3b4614b94c7a6d1671b..93e869369afa57bec6c14af6d1929b920dbf7345 100644 --- a/crates/language_tools2/src/lsp_log_tests.rs +++ b/crates/language_tools2/src/lsp_log_tests.rs @@ -1,109 +1,107 @@ -// todo!("TODO kb") -// use std::sync::Arc; +use std::sync::Arc; -// use crate::lsp_log::LogMenuItem; +use crate::lsp_log::LogMenuItem; -// use super::*; -// use futures::StreamExt; -// use gpui::{serde_json::json, TestAppContext}; -// use language::{tree_sitter_rust, FakeLspAdapter, Language, LanguageConfig, LanguageServerName}; -// use project::{FakeFs, Project}; -// use settings::SettingsStore; +use super::*; +use futures::StreamExt; +use gpui::{serde_json::json, Context, TestAppContext, VisualTestContext}; +use language::{tree_sitter_rust, FakeLspAdapter, Language, LanguageConfig, LanguageServerName}; +use project::{FakeFs, Project}; +use settings::SettingsStore; -// #[gpui::test] -// async fn test_lsp_logs(cx: &mut TestAppContext) { -// if std::env::var("RUST_LOG").is_ok() { -// env_logger::init(); -// } +#[gpui::test] +async fn test_lsp_logs(cx: &mut TestAppContext) { + if std::env::var("RUST_LOG").is_ok() { + env_logger::init(); + } -// init_test(cx); + init_test(cx); -// let mut rust_language = Language::new( -// LanguageConfig { -// name: "Rust".into(), -// path_suffixes: vec!["rs".to_string()], -// ..Default::default() -// }, -// Some(tree_sitter_rust::language()), -// ); -// let mut fake_rust_servers = rust_language -// .set_fake_lsp_adapter(Arc::new(FakeLspAdapter { -// name: "the-rust-language-server", -// ..Default::default() -// })) -// .await; + let mut rust_language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_rust_servers = rust_language + .set_fake_lsp_adapter(Arc::new(FakeLspAdapter { + name: "the-rust-language-server", + ..Default::default() + })) + .await; -// let fs = FakeFs::new(cx.background()); -// fs.insert_tree( -// "/the-root", -// json!({ -// "test.rs": "", -// "package.json": "", -// }), -// ) -// .await; -// let project = Project::test(fs.clone(), ["/the-root".as_ref()], cx).await; -// project.update(cx, |project, _| { -// project.languages().add(Arc::new(rust_language)); -// }); + let fs = FakeFs::new(cx.background_executor.clone()); + fs.insert_tree( + "/the-root", + json!({ + "test.rs": "", + "package.json": "", + }), + ) + .await; + let project = Project::test(fs.clone(), ["/the-root".as_ref()], cx).await; + project.update(cx, |project, _| { + project.languages().add(Arc::new(rust_language)); + }); -// let log_store = cx.add_model(|cx| LogStore::new(cx)); -// log_store.update(cx, |store, cx| store.add_project(&project, cx)); + let log_store = cx.build_model(|cx| LogStore::new(cx)); + log_store.update(cx, |store, cx| store.add_project(&project, cx)); -// let _rust_buffer = project -// .update(cx, |project, cx| { -// project.open_local_buffer("/the-root/test.rs", cx) -// }) -// .await -// .unwrap(); + let _rust_buffer = project + .update(cx, |project, cx| { + project.open_local_buffer("/the-root/test.rs", cx) + }) + .await + .unwrap(); -// let mut language_server = fake_rust_servers.next().await.unwrap(); -// language_server -// .receive_notification::() -// .await; + let mut language_server = fake_rust_servers.next().await.unwrap(); + language_server + .receive_notification::() + .await; -// let log_view = cx -// .add_window(|cx| LspLogView::new(project.clone(), log_store.clone(), cx)) -// .root(cx); + let window = cx.add_window(|cx| LspLogView::new(project.clone(), log_store.clone(), cx)); + let log_view = window.root(cx).unwrap(); + let mut cx = VisualTestContext::from_window(*window, cx); -// language_server.notify::(lsp::LogMessageParams { -// message: "hello from the server".into(), -// typ: lsp::MessageType::INFO, -// }); -// cx.foreground().run_until_parked(); + language_server.notify::(lsp::LogMessageParams { + message: "hello from the server".into(), + typ: lsp::MessageType::INFO, + }); + cx.executor().run_until_parked(); -// log_view.read_with(cx, |view, cx| { -// assert_eq!( -// view.menu_items(cx).unwrap(), -// &[LogMenuItem { -// server_id: language_server.server.server_id(), -// server_name: LanguageServerName("the-rust-language-server".into()), -// worktree_root_name: project -// .read(cx) -// .worktrees(cx) -// .next() -// .unwrap() -// .read(cx) -// .root_name() -// .to_string(), -// rpc_trace_enabled: false, -// rpc_trace_selected: false, -// logs_selected: true, -// }] -// ); -// assert_eq!(view.editor.read(cx).text(cx), "hello from the server\n"); -// }); -// } + log_view.update(&mut cx, |view, cx| { + assert_eq!( + view.menu_items(cx).unwrap(), + &[LogMenuItem { + server_id: language_server.server.server_id(), + server_name: LanguageServerName("the-rust-language-server".into()), + worktree_root_name: project + .read(cx) + .worktrees() + .next() + .unwrap() + .read(cx) + .root_name() + .to_string(), + rpc_trace_enabled: false, + rpc_trace_selected: false, + logs_selected: true, + }] + ); + assert_eq!(view.editor.read(cx).text(cx), "hello from the server\n"); + }); +} -// fn init_test(cx: &mut gpui::TestAppContext) { -// cx.foreground().forbid_parking(); - -// cx.update(|cx| { -// cx.set_global(SettingsStore::test(cx)); -// theme::init((), cx); -// language::init(cx); -// client::init_settings(cx); -// Project::init_settings(cx); -// editor::init_settings(cx); -// }); -// } +fn init_test(cx: &mut gpui::TestAppContext) { + cx.update(|cx| { + let settings_store = SettingsStore::test(cx); + cx.set_global(settings_store); + theme::init(theme::LoadThemes::JustBase, cx); + language::init(cx); + client::init_settings(cx); + Project::init_settings(cx); + editor::init_settings(cx); + }); +} From c1f8929e43d17f2cf595de4f7cf7e66b8c9ff6f2 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 17:28:07 +0200 Subject: [PATCH 193/644] Add new panels into zed2 --- Cargo.lock | 1 + crates/zed2/Cargo.toml | 2 +- crates/zed2/src/main.rs | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7237ab6905db5a5aadfa1c4613114c3f12ae6bca..3226037d51a40f06b24ed0ede79e2ee211c2ed43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12198,6 +12198,7 @@ dependencies = [ "journal2", "language2", "language_selector2", + "language_tools2", "lazy_static", "libc", "log", diff --git a/crates/zed2/Cargo.toml b/crates/zed2/Cargo.toml index 6646eb5ffc3b47141f1bac1df6a7c4f6658f7f8c..8cc333348462e327d8bf9eded5ef3d72de46f382 100644 --- a/crates/zed2/Cargo.toml +++ b/crates/zed2/Cargo.toml @@ -47,7 +47,7 @@ language = { package = "language2", path = "../language2" } language_selector = { package = "language_selector2", path = "../language_selector2" } lsp = { package = "lsp2", path = "../lsp2" } menu = { package = "menu2", path = "../menu2" } -# language_tools = { path = "../language_tools" } +language_tools = { package = "language_tools2", path = "../language_tools2" } node_runtime = { path = "../node_runtime" } notifications = { package = "notifications2", path = "../notifications2" } assistant = { package = "assistant2", path = "../assistant2" } diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index ca8cd7a2a2a1d608c5c0821aa748de5539c47cd7..f4d9aa2510f4739659f4749fd877d9ea8de76c98 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -217,8 +217,7 @@ fn main() { // journal2::init(app_state.clone(), cx); language_selector::init(cx); theme_selector::init(cx); - // activity_indicator::init(cx); - // language_tools::init(cx); + language_tools::init(cx); call::init(app_state.client.clone(), app_state.user_store.clone(), cx); notifications::init(app_state.client.clone(), app_state.user_store.clone(), cx); collab_ui::init(&app_state, cx); From 3586bf8b6ba2b275ccaa2f95dca10b45a5845cfa Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 17:38:52 +0200 Subject: [PATCH 194/644] Display something --- crates/language_tools2/src/lsp_log.rs | 10 ++++++++-- crates/language_tools2/src/syntax_tree_view.rs | 18 ++++++++++++++---- crates/zed2/src/zed2.rs | 11 +++++------ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 3c3df41442e983dc5045e22c5173e0e033e22a1b..06cdaf3bf93d5f9070dcbc600d6c78d18dca5640 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -741,11 +741,13 @@ impl Render for LspLogToolbarItemView { let _server_selected = current_server.is_some(); let lsp_menu = h_stack() + .size_full() .child(Self::render_language_server_menu_header(current_server, cx)) .children(if self.menu_open { Some( overlay().child( v_stack() + .size_full() // todo!() // .scrollable::(0, None, cx) .children(menu_rows.into_iter().map(|row| { @@ -769,11 +771,11 @@ impl Render for LspLogToolbarItemView { // .with_hoverable(true) // .with_fit_mode(OverlayFitMode::SwitchAnchor) // .with_anchor_corner(AnchorCorner::TopLeft) - // .with_z_index(999), ) } else { None - }); + }) + .z_index(99); let log_cleanup_button = div() .child(Label::new("Clear")) @@ -794,6 +796,7 @@ impl Render for LspLogToolbarItemView { .cursor(CursorStyle::PointingHand); h_stack() + .size_full() .child(lsp_menu) .child(log_cleanup_button) .border_1() @@ -897,6 +900,7 @@ impl LspLogToolbarItemView { cx: &mut ViewContext, ) -> Div { v_stack() + .size_full() .child(Label::new(format!("{} ({})", name.0, worktree_root_name))) .child( div() @@ -911,6 +915,7 @@ impl LspLogToolbarItemView { ) .child( h_stack() + .size_full() .child(Label::new(RPC_MESSAGES)) .child( Checkbox::new( @@ -940,6 +945,7 @@ impl LspLogToolbarItemView { ) .border_1() .border_color(red()) + .bg(red()) } } diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index 9c8ec0ee043ceb99d1569d6f67c8b829a023feef..4c9e7529c5cde073d369aeb5716fa65e9933b117 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -319,7 +319,7 @@ impl SyntaxTreeView { anonymous_node_style.color = color; } - let mut row = h_stack(); + let mut row = h_stack().size_full(); if let Some(field_name) = cursor.field_name() { let mut field_style = style.clone(); if let Some(color) = property_color { @@ -378,6 +378,8 @@ impl Render for SyntaxTreeView { self.hover_state_changed(cx); } + let mut rendered = div(); + if let Some(layer) = self .editor .as_ref() @@ -390,7 +392,7 @@ impl Render for SyntaxTreeView { // todo!() // let list_hovered = state.hovered(); let list_hovered = false; - uniform_list( + let list = uniform_list( cx.view().clone(), "SyntaxTreeView", layer.node().descendant_count(), @@ -444,9 +446,11 @@ impl Render for SyntaxTreeView { }), ) .text_bg(editor_colors.background); + + rendered = rendered.child(list); } - div() + rendered } } @@ -505,10 +509,12 @@ impl SyntaxTreeToolbarItemView { Some( v_stack() + .size_full() .child(Self::render_header(&active_layer, cx)) .children(self.menu_open.then(|| { overlay().child( v_stack() + .size_full() .children(active_buffer.syntax_layers().enumerate().map( |(ix, layer)| Self::render_menu_item(&active_layer, layer, ix, cx), )) @@ -519,7 +525,8 @@ impl SyntaxTreeToolbarItemView { } })), ) - })), + })) + .z_index(99), ) } @@ -545,6 +552,7 @@ impl SyntaxTreeToolbarItemView { fn render_header(active_layer: &OwnedSyntaxLayerInfo, cx: &mut ViewContext) -> Div { h_stack() + .size_full() .child(Label::new(active_layer.language.name())) .child(Label::new(format_node_range(active_layer.node()))) .on_mouse_down( @@ -567,6 +575,7 @@ impl SyntaxTreeToolbarItemView { // todo!() styling let _is_selected = layer.node() == active_layer.node(); h_stack() + .size_full() .child(Label::new(layer.language.name().to_string())) .child(Label::new(format_node_range(layer.node()))) .cursor(CursorStyle::PointingHand) @@ -578,6 +587,7 @@ impl SyntaxTreeToolbarItemView { ) .border_1() .border_color(red()) + .bg(red()) } } diff --git a/crates/zed2/src/zed2.rs b/crates/zed2/src/zed2.rs index 27e32fff179819fb79f87af303a4f996bc295b26..aa21a3e9955defc8cb623b163851ecd8156dc5c5 100644 --- a/crates/zed2/src/zed2.rs +++ b/crates/zed2/src/zed2.rs @@ -429,12 +429,11 @@ fn initialize_pane(workspace: &mut Workspace, pane: &View, cx: &mut ViewCo toolbar.add_item(diagnostic_editor_controls, cx); let project_search_bar = cx.build_view(|_| ProjectSearchBar::new()); toolbar.add_item(project_search_bar, cx); - // let lsp_log_item = - // cx.add_view(|_| language_tools::LspLogToolbarItemView::new()); - // toolbar.add_item(lsp_log_item, cx); - // let syntax_tree_item = cx - // .add_view(|_| language_tools::SyntaxTreeToolbarItemView::new()); - // toolbar.add_item(syntax_tree_item, cx); + let lsp_log_item = cx.build_view(|_| language_tools::LspLogToolbarItemView::new()); + toolbar.add_item(lsp_log_item, cx); + let syntax_tree_item = + cx.build_view(|_| language_tools::SyntaxTreeToolbarItemView::new()); + toolbar.add_item(syntax_tree_item, cx); }) }); } From 6a90a76bf2353ea03a86523e287495234cc5b56b Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 15 Dec 2023 23:50:20 +0200 Subject: [PATCH 195/644] Use stock gpui2 ui components --- crates/language_tools2/src/lsp_log.rs | 183 +++++++----------- .../language_tools2/src/syntax_tree_view.rs | 143 ++++---------- crates/ui2/src/components/context_menu.rs | 2 +- 3 files changed, 114 insertions(+), 214 deletions(-) diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 06cdaf3bf93d5f9070dcbc600d6c78d18dca5640..3cff408280f0c345121822f0521424c4b5ece1cc 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -2,16 +2,18 @@ use collections::{HashMap, VecDeque}; use editor::{Editor, EditorElement, EditorEvent, MoveToEnd}; use futures::{channel::mpsc, StreamExt}; use gpui::{ - actions, div, overlay, red, AnyElement, AppContext, Context, CursorStyle, Div, EventEmitter, - FocusHandle, FocusableView, InteractiveElement, IntoElement, Model, ModelContext, MouseButton, - MouseDownEvent, ParentElement, Render, Styled, Subscription, View, ViewContext, VisualContext, + actions, div, red, AnchorCorner, AnyElement, AppContext, Context, CursorStyle, Div, + EventEmitter, FocusHandle, FocusableView, InteractiveElement, IntoElement, Model, ModelContext, + MouseButton, ParentElement, Render, Styled, Subscription, View, ViewContext, VisualContext, WeakModel, WindowContext, }; use language::{LanguageServerId, LanguageServerName}; use lsp::IoKind; use project::{search::SearchQuery, Project}; use std::{borrow::Cow, sync::Arc}; -use ui::{h_stack, v_stack, Checkbox, Label}; +use ui::{ + h_stack, popover_menu, v_stack, Button, Checkbox, Clickable, ContextMenu, Divider, Label, +}; use workspace::{ item::{Item, ItemHandle}, searchable::{SearchEvent, SearchableItem, SearchableItemHandle}, @@ -58,7 +60,6 @@ pub struct LspLogView { pub struct LspLogToolbarItemView { log_view: Option>, _log_view_subscription: Option, - menu_open: bool, } #[derive(Copy, Clone, PartialEq, Eq)] @@ -594,11 +595,6 @@ fn log_contents(lines: &VecDeque) -> String { } impl Render for LspLogView { - // todo!() - // fn ui_name() -> &'static str { - // "LspLogView" - // } - type Element = EditorElement; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { @@ -697,7 +693,6 @@ impl ToolbarItemView for LspLogToolbarItemView { active_pane_item: Option<&dyn ItemHandle>, cx: &mut ViewContext, ) -> workspace::ToolbarItemLocation { - self.menu_open = false; if let Some(item) = active_pane_item { if let Some(log_view) = item.downcast::() { self.log_view = Some(log_view.clone()); @@ -715,13 +710,9 @@ impl ToolbarItemView for LspLogToolbarItemView { impl Render for LspLogToolbarItemView { type Element = Div; - // todo!() - // fn ui_name() -> &'static str { - // "LspLogView" - // } - fn render(&mut self, cx: &mut ViewContext) -> Div { - let Some(log_view) = self.log_view.as_ref() else { + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + let Some(log_view) = self.log_view.clone() else { return div(); }; let (menu_rows, current_server_id) = log_view.update(cx, |log_view, cx| { @@ -737,70 +728,63 @@ impl Render for LspLogToolbarItemView { None } }); - // todo!() styling - let _server_selected = current_server.is_some(); - let lsp_menu = h_stack() - .size_full() - .child(Self::render_language_server_menu_header(current_server, cx)) - .children(if self.menu_open { - Some( - overlay().child( - v_stack() - .size_full() - // todo!() - // .scrollable::(0, None, cx) - .children(menu_rows.into_iter().map(|row| { - Self::render_language_server_menu_item( - row.server_id, - row.server_name, - &row.worktree_root_name, - row.rpc_trace_enabled, - row.logs_selected, - row.rpc_trace_selected, - cx, - ) - })) - .on_mouse_down_out(cx.listener(|this, event: &MouseDownEvent, cx| { - if event.button == MouseButton::Left { - this.menu_open = false; - cx.notify() - } - })), - ), // todo!() - // .with_hoverable(true) - // .with_fit_mode(OverlayFitMode::SwitchAnchor) - // .with_anchor_corner(AnchorCorner::TopLeft) - ) - } else { - None - }) - .z_index(99); - - let log_cleanup_button = div() - .child(Label::new("Clear")) - .on_mouse_down( - MouseButton::Left, - cx.listener(move |this, _, cx| { - if let Some(log_view) = this.log_view.as_ref() { - log_view.update(cx, |log_view, cx| { - log_view.editor.update(cx, |editor, cx| { - editor.set_read_only(false); - editor.clear(cx); - editor.set_read_only(true); - }); - }) + let lsp_menu = popover_menu("LspLogView") + .anchor(AnchorCorner::TopLeft) + .trigger(Self::render_language_server_menu_header(current_server)) + .menu(move |cx| { + let menu_rows = menu_rows.clone(); + let log_view = log_view.clone(); + ContextMenu::build(cx, move |mut menu, cx| { + for row in menu_rows { + menu = menu + .header(format!( + "{} ({})", + row.server_name.0, row.worktree_root_name + )) + .entry( + format!("{SERVER_LOGS} ({})", row.server_name.0), + |cx| { + dbg!("????????????????????"); + }, // cx.handler_for(&log_view, move |view, cx| { + // // todo!() why does not it work??? + // dbg!("~~~~~~~~~~~~~~~~~~~~~~~~~~??@@@#", row.server_id); + // view.show_logs_for_server(row.server_id, cx) + // }), + ) + // TODO kb custom element with checkbox & toggle logging for server + .entry( + format!("{RPC_MESSAGES} ({})", row.server_name.0), + |cx| { + dbg!("?????????????@@@@@@@@@@@@@@@"); + }, // cx.handler_for(&log_view, move |view, cx| { + // view.show_rpc_trace_for_server(row.server_id, cx) + // }), + ) } - }), - ) - .cursor(CursorStyle::PointingHand); + menu + }) + }); - h_stack() - .size_full() - .child(lsp_menu) - .child(log_cleanup_button) - .border_1() - .border_color(red()) + h_stack().size_full().child(lsp_menu).child( + div() + .child( + Button::new("clear_log_button", "Clear").on_click(cx.listener( + |this, _, cx| { + if let Some(log_view) = this.log_view.as_ref() { + log_view.update(cx, |log_view, cx| { + log_view.editor.update(cx, |editor, cx| { + editor.set_read_only(false); + editor.clear(cx); + editor.set_read_only(true); + }); + }) + } + }, + )), + ) + .ml_2(), + ) } } @@ -810,17 +794,11 @@ const SERVER_LOGS: &str = "Server Logs"; impl LspLogToolbarItemView { pub fn new() -> Self { Self { - menu_open: false, log_view: None, _log_view_subscription: None, } } - fn toggle_menu(&mut self, cx: &mut ViewContext) { - self.menu_open = !self.menu_open; - cx.notify(); - } - fn toggle_logging_for_server( &mut self, id: LanguageServerId, @@ -842,7 +820,6 @@ impl LspLogToolbarItemView { fn show_logs_for_server(&mut self, id: LanguageServerId, cx: &mut ViewContext) { if let Some(log_view) = &self.log_view { log_view.update(cx, |view, cx| view.show_logs_for_server(id, cx)); - self.menu_open = false; cx.notify(); } } @@ -850,19 +827,16 @@ impl LspLogToolbarItemView { fn show_rpc_trace_for_server(&mut self, id: LanguageServerId, cx: &mut ViewContext) { if let Some(log_view) = &self.log_view { log_view.update(cx, |view, cx| view.show_rpc_trace_for_server(id, cx)); - self.menu_open = false; cx.notify(); } } - fn render_language_server_menu_header( - current_server: Option, - cx: &mut ViewContext, - ) -> Div { - let label: Cow = current_server - .and_then(|row| { - Some( - format!( + fn render_language_server_menu_header(current_server: Option) -> Button { + Button::new( + "language_server_menu_header", + current_server + .and_then(|row| { + Some(Cow::Owned(format!( "{} ({}) - {}", row.server_name.0, row.worktree_root_name, @@ -871,22 +845,10 @@ impl LspLogToolbarItemView { } else { SERVER_LOGS }, - ) - .into(), - ) - }) - .unwrap_or_else(|| "No server selected".into()); - div() - .child(Label::new(label)) - .cursor(CursorStyle::PointingHand) - .on_mouse_down( - MouseButton::Left, - cx.listener(move |view, _, cx| { - view.toggle_menu(cx); - }), - ) - .border_1() - .border_color(red()) + ))) + }) + .unwrap_or_else(|| "No server selected".into()), + ) } fn render_language_server_menu_item( @@ -894,7 +856,6 @@ impl LspLogToolbarItemView { name: LanguageServerName, worktree_root_name: &str, rpc_trace_enabled: bool, - // todo!() styling _logs_selected: bool, _rpc_trace_selected: bool, cx: &mut ViewContext, diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index 4c9e7529c5cde073d369aeb5716fa65e9933b117..9b205cb28bddeaf2af016329fea045e206f0c65d 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -1,20 +1,19 @@ use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId}; use gpui::{ - actions, div, overlay, red, uniform_list, AnyElement, AppContext, CursorStyle, Div, - EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model, - MouseButton, MouseDownEvent, MouseMoveEvent, ParentElement, Pixels, Render, Styled, TextStyle, - UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext, + actions, div, rems, uniform_list, AnyElement, AppContext, Div, EventEmitter, FocusHandle, + FocusableView, Hsla, InteractiveElement, IntoElement, Model, MouseButton, MouseDownEvent, + MouseMoveEvent, ParentElement, Pixels, Render, Styled, TextStyle, UniformListScrollHandle, + View, ViewContext, VisualContext, WeakView, WindowContext, }; -use language::{Buffer, OwnedSyntaxLayerInfo, SyntaxLayerInfo}; +use language::{Buffer, OwnedSyntaxLayerInfo}; use settings::Settings; use std::{mem, ops::Range}; use theme::{Theme, ThemeSettings}; use tree_sitter::{Node, TreeCursor}; -use ui::{h_stack, Label}; +use ui::{h_stack, popover_menu, ButtonLike, ContextMenu, Label, PopoverMenu}; use workspace::{ item::{Item, ItemHandle}, - ui::v_stack, - ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, + SplitDirection, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, }; actions!(debug, [OpenSyntaxTreeView]); @@ -26,7 +25,7 @@ pub fn init(cx: &mut AppContext) { let workspace_handle = workspace.weak_handle(); let syntax_tree_view = cx.build_view(|cx| SyntaxTreeView::new(workspace_handle, active_item, cx)); - workspace.add_item(Box::new(syntax_tree_view), cx); + workspace.split_item(SplitDirection::Right, Box::new(syntax_tree_view), cx) }); }) .detach(); @@ -46,7 +45,6 @@ pub struct SyntaxTreeView { pub struct SyntaxTreeToolbarItemView { tree_view: Option>, subscription: Option, - menu_open: bool, } struct EditorState { @@ -279,7 +277,7 @@ impl SyntaxTreeView { fn render_node( cursor: &TreeCursor, - _depth: u32, + depth: u32, selected: bool, hovered: bool, list_hovered: bool, @@ -290,18 +288,6 @@ impl SyntaxTreeView { let editor_colors = editor_theme.colors(); let node = cursor.node(); let mut range_style = style.clone(); - // todo!() styling - // let font_id = cx.text_system().font_id(&style.text.font()).unwrap(); - // let font_size = style.text.font_size.to_pixels(cx.rem_size()); - // let line_height = style.text.line_height_in_pixels(cx.rem_size()); - // let em_width = cx - // .text_system() - // .typographic_bounds(font_id, font_size, 'm') - // .unwrap() - // .size - // .width; - // let gutter_padding = (em_width * editor_theme.gutter_padding_factor).round(); - range_style.color = editor_colors.editor_line_number; let mut anonymous_node_style = style.clone(); @@ -335,8 +321,7 @@ impl SyntaxTreeView { Label::new(node.kind()) } else { Label::new(format!("\"{}\"", node.kind())) - }, // todo!() - // .margin(em_width), + }, ) .child(Label::new(format_node_range(node))) .text_bg(if selected { @@ -346,10 +331,10 @@ impl SyntaxTreeView { } else { Hsla::default() }) - // todo!() + // todo!() does not work + .ml(rems(depth as f32 * 180.0)) // .padding(gutter_padding + depth as f32 * 18.0) - .border_1() - .border_color(red()); + ; } } @@ -389,8 +374,6 @@ impl Render for SyntaxTreeView { let layer = layer.clone(); let theme = editor_theme.clone(); - // todo!() - // let list_hovered = state.hovered(); let list_hovered = false; let list = uniform_list( cx.view().clone(), @@ -434,6 +417,7 @@ impl Render for SyntaxTreeView { items }, ) + // todo!() does scroll either editor or the tree .track_scroll(self.list_scroll_handle.clone()) .on_mouse_move(cx.listener(move |tree_view, event: &MouseMoveEvent, cx| { tree_view.mouse_y = Some(event.position.y); @@ -492,13 +476,12 @@ impl Item for SyntaxTreeView { impl SyntaxTreeToolbarItemView { pub fn new() -> Self { Self { - menu_open: false, tree_view: None, subscription: None, } } - fn render_menu(&mut self, cx: &mut ViewContext<'_, Self>) -> Option
{ + fn render_menu(&mut self, cx: &mut ViewContext<'_, Self>) -> Option> { let tree_view = self.tree_view.as_ref()?; let tree_view = tree_view.read(cx); @@ -507,34 +490,30 @@ impl SyntaxTreeToolbarItemView { let active_layer = buffer_state.active_layer.clone()?; let active_buffer = buffer_state.buffer.read(cx).snapshot(); + let view = cx.view().clone(); Some( - v_stack() - .size_full() - .child(Self::render_header(&active_layer, cx)) - .children(self.menu_open.then(|| { - overlay().child( - v_stack() - .size_full() - .children(active_buffer.syntax_layers().enumerate().map( - |(ix, layer)| Self::render_menu_item(&active_layer, layer, ix, cx), - )) - .on_mouse_down_out(cx.listener(|this, e: &MouseDownEvent, cx| { - if e.button == MouseButton::Left { - this.menu_open = false; - cx.notify() - } - })), - ) - })) - .z_index(99), + popover_menu("Syntax Tree") + .trigger(Self::render_header(&active_layer)) + .menu(move |cx| { + ContextMenu::build(cx, |mut menu, cx| { + for (layer_ix, layer) in active_buffer.syntax_layers().enumerate() { + menu = menu.entry( + format!( + "{} {}", + layer.language.name(), + format_node_range(layer.node()) + ), + cx.handler_for(&view, move |view, cx| { + view.select_layer(layer_ix, cx); + }), + ); + } + menu + }) + }), ) } - fn toggle_menu(&mut self, cx: &mut ViewContext) { - self.menu_open = !self.menu_open; - cx.notify(); - } - fn select_layer(&mut self, layer_ix: usize, cx: &mut ViewContext) -> Option<()> { let tree_view = self.tree_view.as_ref()?; tree_view.update(cx, |view, cx| { @@ -544,50 +523,15 @@ impl SyntaxTreeToolbarItemView { let layer = snapshot.syntax_layers().nth(layer_ix)?; buffer_state.active_layer = Some(layer.to_owned()); view.selected_descendant_ix = None; - self.menu_open = false; cx.notify(); Some(()) }) } - fn render_header(active_layer: &OwnedSyntaxLayerInfo, cx: &mut ViewContext) -> Div { - h_stack() - .size_full() + fn render_header(active_layer: &OwnedSyntaxLayerInfo) -> ButtonLike { + ButtonLike::new("syntax tree header") .child(Label::new(active_layer.language.name())) .child(Label::new(format_node_range(active_layer.node()))) - .on_mouse_down( - MouseButton::Left, - cx.listener(move |view, _, cx| { - view.toggle_menu(cx); - }), - ) - .cursor(CursorStyle::PointingHand) - .border_1() - .border_color(red()) - } - - fn render_menu_item( - active_layer: &OwnedSyntaxLayerInfo, - layer: SyntaxLayerInfo, - layer_ix: usize, - cx: &mut ViewContext, - ) -> Div { - // todo!() styling - let _is_selected = layer.node() == active_layer.node(); - h_stack() - .size_full() - .child(Label::new(layer.language.name().to_string())) - .child(Label::new(format_node_range(layer.node()))) - .cursor(CursorStyle::PointingHand) - .on_mouse_down( - MouseButton::Left, - cx.listener(move |view, _, cx| { - view.select_layer(layer_ix, cx); - }), - ) - .border_1() - .border_color(red()) - .bg(red()) } } @@ -604,15 +548,11 @@ fn format_node_range(node: Node) -> String { } impl Render for SyntaxTreeToolbarItemView { - type Element = Div; - - // todo!() - // fn ui_name() -> &'static str { - // "SyntaxTreeToolbarItemView" - // } + type Element = PopoverMenu; - fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> Div { - self.render_menu(cx).unwrap_or_else(|| div()) + fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> PopoverMenu { + self.render_menu(cx) + .unwrap_or_else(|| popover_menu("Empty Syntax Tree")) } } @@ -624,7 +564,6 @@ impl ToolbarItemView for SyntaxTreeToolbarItemView { active_pane_item: Option<&dyn ItemHandle>, cx: &mut ViewContext, ) -> ToolbarItemLocation { - self.menu_open = false; if let Some(item) = active_pane_item { if let Some(view) = item.downcast::() { self.tree_view = Some(view.clone()); diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 8fce15d1c69d0fcf97f8ac1757874be4884950b6..4e3c03ad80a1ab1f66b84d69685a0d5260401fda 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -9,7 +9,7 @@ use gpui::{ use menu::{SelectFirst, SelectLast, SelectNext, SelectPrev}; use std::{rc::Rc, time::Duration}; -pub enum ContextMenuItem { +enum ContextMenuItem { Separator, Header(SharedString), Entry { From 7b83d65debcba1c1b4967be88843b98a9f8f200d Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 18 Dec 2023 19:15:54 +0200 Subject: [PATCH 196/644] Remove temporary imports, fix syntax_tree_view --- crates/gpui2/src/elements/div.rs | 39 ++-- crates/gpui2/src/elements/uniform_list.rs | 5 + crates/language_tools2/src/lsp_log.rs | 190 +++++++----------- .../language_tools2/src/syntax_tree_view.rs | 30 ++- 4 files changed, 124 insertions(+), 140 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 908b302dfc1cd28f6ff873eff215d583d1b489f4..24784d695c69983e69b94726a514f6890e5f5a30 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1427,8 +1427,16 @@ impl Interactivity { let line_height = cx.line_height(); let scroll_max = (content_size - bounds.size).max(&Size::default()); let interactive_bounds = interactive_bounds.clone(); - + let id = self.element_id.clone(); cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { + if id == Some(ElementId::Name("SyntaxTreeView".into())) { + dbg!( + &overflow, + event.position, + &interactive_bounds, + interactive_bounds.visibly_contains(&event.position, cx) + ); + } if phase == DispatchPhase::Bubble && interactive_bounds.visibly_contains(&event.position, cx) { @@ -1442,9 +1450,15 @@ impl Interactivity { } if overflow.y == Overflow::Scroll { - scroll_offset.y = - (scroll_offset.y + delta.y).clamp(-scroll_max.height, px(0.)); + if id == Some(ElementId::Name("SyntaxTreeView".into())) { + println!("prev scroll offset: {old_scroll_offset:?}, scroll_max: {scroll_max:?}, delta:{delta:?}"); + } + scroll_offset.y = + (scroll_offset.y + delta.y).clamp(-scroll_max.height, px(0.)); + if id == Some(ElementId::Name("SyntaxTreeView".into())) { + println!("new scroll offset: {scroll_offset:?}, scroll_max: {scroll_max:?}, delta:{delta:?}"); } + } if *scroll_offset != old_scroll_offset { cx.notify(); @@ -1487,15 +1501,16 @@ impl Interactivity { } cx.with_z_index(style.z_index.unwrap_or(0), |cx| { - if style.background.as_ref().is_some_and(|fill| { - fill.color().is_some_and(|color| !color.is_transparent()) - }) { - cx.add_opaque_layer(bounds) - } - f(style, scroll_offset.unwrap_or_default(), cx) - }) - }, - ); + if style.background.as_ref().is_some_and(|fill| { + fill.color().is_some_and(|color| !color.is_transparent()) + }) { + cx.add_opaque_layer(bounds) + } + + f(style, scroll_offset.unwrap_or_default(), cx) + }) + }, + ); if let Some(group) = self.group.as_ref() { GroupBounds::pop(group, cx); diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index e8587683d691143358263306403187439a52c68a..016f0160247e5931580a41d35f5052cf1f7df30d 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -127,6 +127,7 @@ impl Element for UniformList { .map(|s| s.item_size) .unwrap_or_else(|| self.measure_item(None, cx)); + let element_id = self.interactivity.element_id.clone(); let (layout_id, interactive) = self.interactivity .layout(state.map(|s| s.interactive), cx, |style, cx| { @@ -143,6 +144,10 @@ impl Element for UniformList { item_size.width } }); + + if element_id == Some(ElementId::Name("SyntaxTreeView".into())) { + dbg!(known_dimensions, available_space.height); + } let height = match available_space.height { AvailableSpace::Definite(height) => desired_height.min(height), AvailableSpace::MinContent | AvailableSpace::MaxContent => { diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 3cff408280f0c345121822f0521424c4b5ece1cc..9a8ec9f71aef31430187e6f8e320373eef6aa337 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -2,18 +2,16 @@ use collections::{HashMap, VecDeque}; use editor::{Editor, EditorElement, EditorEvent, MoveToEnd}; use futures::{channel::mpsc, StreamExt}; use gpui::{ - actions, div, red, AnchorCorner, AnyElement, AppContext, Context, CursorStyle, Div, - EventEmitter, FocusHandle, FocusableView, InteractiveElement, IntoElement, Model, ModelContext, - MouseButton, ParentElement, Render, Styled, Subscription, View, ViewContext, VisualContext, - WeakModel, WindowContext, + actions, div, AnchorCorner, AnyElement, AppContext, Context, Div, EventEmitter, FocusHandle, + FocusableView, InteractiveElement, IntoElement, Model, ModelContext, MouseButton, + ParentElement, Render, Styled, Subscription, View, ViewContext, VisualContext, WeakModel, + WindowContext, }; use language::{LanguageServerId, LanguageServerName}; use lsp::IoKind; use project::{search::SearchQuery, Project}; use std::{borrow::Cow, sync::Arc}; -use ui::{ - h_stack, popover_menu, v_stack, Button, Checkbox, Clickable, ContextMenu, Divider, Label, -}; +use ui::{h_stack, popover_menu, Button, Checkbox, Clickable, ContextMenu, Label, Selection}; use workspace::{ item::{Item, ItemHandle}, searchable::{SearchEvent, SearchableItem, SearchableItemHandle}, @@ -729,38 +727,86 @@ impl Render for LspLogToolbarItemView { } }); + let log_toolbar_view = cx.view().clone(); let lsp_menu = popover_menu("LspLogView") .anchor(AnchorCorner::TopLeft) - .trigger(Self::render_language_server_menu_header(current_server)) + .trigger(Button::new( + "language_server_menu_header", + current_server + .and_then(|row| { + Some(Cow::Owned(format!( + "{} ({}) - {}", + row.server_name.0, + row.worktree_root_name, + if row.rpc_trace_selected { + RPC_MESSAGES + } else { + SERVER_LOGS + }, + ))) + }) + .unwrap_or_else(|| "No server selected".into()), + )) .menu(move |cx| { let menu_rows = menu_rows.clone(); let log_view = log_view.clone(); + let log_toolbar_view = log_toolbar_view.clone(); ContextMenu::build(cx, move |mut menu, cx| { - for row in menu_rows { + for (ix, row) in menu_rows.into_iter().enumerate() { menu = menu .header(format!( "{} ({})", row.server_name.0, row.worktree_root_name )) .entry( - format!("{SERVER_LOGS} ({})", row.server_name.0), - |cx| { - dbg!("????????????????????"); - }, // cx.handler_for(&log_view, move |view, cx| { - // // todo!() why does not it work??? - // dbg!("~~~~~~~~~~~~~~~~~~~~~~~~~~??@@@#", row.server_id); - // view.show_logs_for_server(row.server_id, cx) - // }), - ) - // TODO kb custom element with checkbox & toggle logging for server - .entry( - format!("{RPC_MESSAGES} ({})", row.server_name.0), - |cx| { - dbg!("?????????????@@@@@@@@@@@@@@@"); - }, // cx.handler_for(&log_view, move |view, cx| { - // view.show_rpc_trace_for_server(row.server_id, cx) - // }), + SERVER_LOGS, + cx.handler_for(&log_view, move |view, cx| { + view.show_logs_for_server(row.server_id, cx) + }), ) + .custom_entry({ + let log_view = log_view.clone(); + let log_toolbar_view = log_toolbar_view.clone(); + move |cx| { + h_stack() + .w_full() + .justify_between() + .child(Label::new(RPC_MESSAGES)) + .child( + Checkbox::new( + ix, + if row.rpc_trace_enabled { + Selection::Selected + } else { + Selection::Unselected + }, + ) + .on_click( + cx.listener_for( + &log_toolbar_view, + move |view, selection, cx| { + let enabled = matches!( + selection, + Selection::Selected + ); + view.toggle_logging_for_server( + row.server_id, + enabled, + cx, + ); + }, + ), + ), + ) + .on_mouse_down( + MouseButton::Left, + cx.listener_for(&log_view, move |view, _, cx| { + view.show_rpc_trace_for_server(row.server_id, cx) + }), + ) + .into_any_element() + } + }) } menu }) @@ -816,98 +862,6 @@ impl LspLogToolbarItemView { } cx.notify(); } - - fn show_logs_for_server(&mut self, id: LanguageServerId, cx: &mut ViewContext) { - if let Some(log_view) = &self.log_view { - log_view.update(cx, |view, cx| view.show_logs_for_server(id, cx)); - cx.notify(); - } - } - - fn show_rpc_trace_for_server(&mut self, id: LanguageServerId, cx: &mut ViewContext) { - if let Some(log_view) = &self.log_view { - log_view.update(cx, |view, cx| view.show_rpc_trace_for_server(id, cx)); - cx.notify(); - } - } - - fn render_language_server_menu_header(current_server: Option) -> Button { - Button::new( - "language_server_menu_header", - current_server - .and_then(|row| { - Some(Cow::Owned(format!( - "{} ({}) - {}", - row.server_name.0, - row.worktree_root_name, - if row.rpc_trace_selected { - RPC_MESSAGES - } else { - SERVER_LOGS - }, - ))) - }) - .unwrap_or_else(|| "No server selected".into()), - ) - } - - fn render_language_server_menu_item( - id: LanguageServerId, - name: LanguageServerName, - worktree_root_name: &str, - rpc_trace_enabled: bool, - _logs_selected: bool, - _rpc_trace_selected: bool, - cx: &mut ViewContext, - ) -> Div { - v_stack() - .size_full() - .child(Label::new(format!("{} ({})", name.0, worktree_root_name))) - .child( - div() - .child(Label::new(SERVER_LOGS)) - .cursor(CursorStyle::PointingHand) - .on_mouse_down( - MouseButton::Left, - cx.listener(move |view, _, cx| { - view.show_logs_for_server(id, cx); - }), - ), - ) - .child( - h_stack() - .size_full() - .child(Label::new(RPC_MESSAGES)) - .child( - Checkbox::new( - id.0, - if rpc_trace_enabled { - ui::Selection::Selected - } else { - ui::Selection::Unselected - }, - ) - .on_click(cx.listener( - move |this, selection, cx| { - let enabled = matches!(selection, ui::Selection::Selected); - this.toggle_logging_for_server(id, enabled, cx); - }, - )), - ) - .border_1() - .border_color(red()) - .cursor(CursorStyle::PointingHand) - .on_mouse_down( - MouseButton::Left, - cx.listener(move |view, _, cx| { - view.show_rpc_trace_for_server(id, cx); - }), - ), - ) - .border_1() - .border_color(red()) - .bg(red()) - } } pub enum Event { diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index 9b205cb28bddeaf2af016329fea045e206f0c65d..62efda19b50ad7c0861f5971cd6b30ee8f23c4bc 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -1,9 +1,9 @@ use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId}; use gpui::{ - actions, div, rems, uniform_list, AnyElement, AppContext, Div, EventEmitter, FocusHandle, - FocusableView, Hsla, InteractiveElement, IntoElement, Model, MouseButton, MouseDownEvent, - MouseMoveEvent, ParentElement, Pixels, Render, Styled, TextStyle, UniformListScrollHandle, - View, ViewContext, VisualContext, WeakView, WindowContext, + actions, canvas, div, rems, uniform_list, AnyElement, AppContext, AvailableSpace, Div, + EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model, + MouseButton, MouseDownEvent, MouseMoveEvent, ParentElement, Pixels, Render, Styled, TextStyle, + UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext, }; use language::{Buffer, OwnedSyntaxLayerInfo}; use settings::Settings; @@ -305,7 +305,7 @@ impl SyntaxTreeView { anonymous_node_style.color = color; } - let mut row = h_stack().size_full(); + let mut row = h_stack().bg(gpui::yellow()); if let Some(field_name) = cursor.field_name() { let mut field_style = style.clone(); if let Some(color) = property_color { @@ -332,7 +332,8 @@ impl SyntaxTreeView { Hsla::default() }) // todo!() does not work - .ml(rems(depth as f32 * 180.0)) + // .ml(rems(dbg!(depth) as f32 * 10.0)) + .pl(rems(dbg!(depth) as f32 * 10.0)) // .padding(gutter_padding + depth as f32 * 18.0) ; } @@ -341,7 +342,7 @@ impl SyntaxTreeView { impl Render for SyntaxTreeView { type Element = Div; - fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Div { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Self::Element { let settings = ThemeSettings::get_global(cx); let font = settings.buffer_font.clone(); let font_size = settings.buffer_font_size(cx); @@ -363,7 +364,7 @@ impl Render for SyntaxTreeView { self.hover_state_changed(cx); } - let mut rendered = div(); + let mut rendered = div().flex_1(); if let Some(layer) = self .editor @@ -417,7 +418,7 @@ impl Render for SyntaxTreeView { items }, ) - // todo!() does scroll either editor or the tree + .size_full() .track_scroll(self.list_scroll_handle.clone()) .on_mouse_move(cx.listener(move |tree_view, event: &MouseMoveEvent, cx| { tree_view.mouse_y = Some(event.position.y); @@ -431,7 +432,16 @@ impl Render for SyntaxTreeView { ) .text_bg(editor_colors.background); - rendered = rendered.child(list); + rendered = rendered.child( + canvas(move |bounds, cx| { + list.into_any_element().draw( + bounds.origin, + bounds.size.map(AvailableSpace::Definite), + cx, + ) + }) + .size_full(), + ); } rendered From 1474816a932bbb50018591059573e182847a4d5a Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 20 Dec 2023 12:18:26 +0200 Subject: [PATCH 197/644] Syntax tree panel style fixes --- crates/gpui2/src/elements/div.rs | 37 +++------ .../language_tools2/src/syntax_tree_view.rs | 80 +++++-------------- crates/ui2/src/components/context_menu.rs | 36 ++++++--- 3 files changed, 56 insertions(+), 97 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 24784d695c69983e69b94726a514f6890e5f5a30..55791a56a9306a721551ad9755a39c5eb959b293 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1427,16 +1427,7 @@ impl Interactivity { let line_height = cx.line_height(); let scroll_max = (content_size - bounds.size).max(&Size::default()); let interactive_bounds = interactive_bounds.clone(); - let id = self.element_id.clone(); cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { - if id == Some(ElementId::Name("SyntaxTreeView".into())) { - dbg!( - &overflow, - event.position, - &interactive_bounds, - interactive_bounds.visibly_contains(&event.position, cx) - ); - } if phase == DispatchPhase::Bubble && interactive_bounds.visibly_contains(&event.position, cx) { @@ -1450,15 +1441,9 @@ impl Interactivity { } if overflow.y == Overflow::Scroll { - if id == Some(ElementId::Name("SyntaxTreeView".into())) { - println!("prev scroll offset: {old_scroll_offset:?}, scroll_max: {scroll_max:?}, delta:{delta:?}"); - } - scroll_offset.y = - (scroll_offset.y + delta.y).clamp(-scroll_max.height, px(0.)); - if id == Some(ElementId::Name("SyntaxTreeView".into())) { - println!("new scroll offset: {scroll_offset:?}, scroll_max: {scroll_max:?}, delta:{delta:?}"); + scroll_offset.y = + (scroll_offset.y + delta.y).clamp(-scroll_max.height, px(0.)); } - } if *scroll_offset != old_scroll_offset { cx.notify(); @@ -1501,16 +1486,16 @@ impl Interactivity { } cx.with_z_index(style.z_index.unwrap_or(0), |cx| { - if style.background.as_ref().is_some_and(|fill| { - fill.color().is_some_and(|color| !color.is_transparent()) - }) { - cx.add_opaque_layer(bounds) - } + if style.background.as_ref().is_some_and(|fill| { + fill.color().is_some_and(|color| !color.is_transparent()) + }) { + cx.add_opaque_layer(bounds) + } - f(style, scroll_offset.unwrap_or_default(), cx) - }) - }, - ); + f(style, scroll_offset.unwrap_or_default(), cx) + }) + }, + ); if let Some(group) = self.group.as_ref() { GroupBounds::pop(group, cx); diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index 62efda19b50ad7c0861f5971cd6b30ee8f23c4bc..0fd33cb3cdd9e32976cf626d4f399632fbd1d6e8 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -2,7 +2,7 @@ use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId}; use gpui::{ actions, canvas, div, rems, uniform_list, AnyElement, AppContext, AvailableSpace, Div, EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model, - MouseButton, MouseDownEvent, MouseMoveEvent, ParentElement, Pixels, Render, Styled, TextStyle, + MouseButton, MouseDownEvent, MouseMoveEvent, ParentElement, Pixels, Render, Styled, UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext, }; use language::{Buffer, OwnedSyntaxLayerInfo}; @@ -10,7 +10,7 @@ use settings::Settings; use std::{mem, ops::Range}; use theme::{Theme, ThemeSettings}; use tree_sitter::{Node, TreeCursor}; -use ui::{h_stack, popover_menu, ButtonLike, ContextMenu, Label, PopoverMenu}; +use ui::{h_stack, popover_menu, ButtonLike, Color, ContextMenu, Label, LabelCommon, PopoverMenu}; use workspace::{ item::{Item, ItemHandle}, SplitDirection, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, @@ -279,63 +279,34 @@ impl SyntaxTreeView { cursor: &TreeCursor, depth: u32, selected: bool, - hovered: bool, - list_hovered: bool, - style: &TextStyle, editor_theme: &Theme, _cx: &AppContext, ) -> Div { let editor_colors = editor_theme.colors(); - let node = cursor.node(); - let mut range_style = style.clone(); - range_style.color = editor_colors.editor_line_number; - - let mut anonymous_node_style = style.clone(); - let string_color = editor_theme - .syntax() - .highlights - .iter() - .find_map(|(name, style)| (name == "string").then(|| style.color)?); - let property_color = editor_theme - .syntax() - .highlights - .iter() - .find_map(|(name, style)| (name == "property").then(|| style.color)?); - if let Some(color) = string_color { - anonymous_node_style.color = color; - } - - let mut row = h_stack().bg(gpui::yellow()); + let mut row = h_stack(); if let Some(field_name) = cursor.field_name() { - let mut field_style = style.clone(); - if let Some(color) = property_color { - field_style.color = color; - } - - row = row.children([Label::new(field_name), Label::new(": ")]); + row = row.children([Label::new(field_name).color(Color::Info), Label::new(": ")]); } + let node = cursor.node(); return row + .child(if node.is_named() { + Label::new(node.kind()).color(Color::Default) + } else { + Label::new(format!("\"{}\"", node.kind())).color(Color::Created) + }) .child( - if node.is_named() { - Label::new(node.kind()) - } else { - Label::new(format!("\"{}\"", node.kind())) - }, + div() + .child(Label::new(format_node_range(node)).color(Color::Muted)) + .pl_1(), ) - .child(Label::new(format_node_range(node))) .text_bg(if selected { editor_colors.element_selected - } else if hovered && list_hovered { - editor_colors.element_active } else { Hsla::default() }) - // todo!() does not work - // .ml(rems(dbg!(depth) as f32 * 10.0)) - .pl(rems(dbg!(depth) as f32 * 10.0)) - // .padding(gutter_padding + depth as f32 * 18.0) - ; + .pl(rems(depth as f32)) + .hover(|style| style.bg(editor_colors.element_active)); } } @@ -344,21 +315,11 @@ impl Render for SyntaxTreeView { fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Self::Element { let settings = ThemeSettings::get_global(cx); - let font = settings.buffer_font.clone(); - let font_size = settings.buffer_font_size(cx); - let editor_theme = settings.active_theme.clone(); let editor_colors = editor_theme.colors(); - let style = TextStyle { - color: editor_colors.text, - font_family: font.family, - font_features: font.features, - font_weight: font.weight, - font_style: font.style, - ..Default::default() - }; - - let line_height = cx.text_style().line_height_in_pixels(font_size); + let line_height = cx + .text_style() + .line_height_in_pixels(settings.buffer_font_size(cx)); if Some(line_height) != self.line_height { self.line_height = Some(line_height); self.hover_state_changed(cx); @@ -374,8 +335,6 @@ impl Render for SyntaxTreeView { { let layer = layer.clone(); let theme = editor_theme.clone(); - - let list_hovered = false; let list = uniform_list( cx.view().clone(), "SyntaxTreeView", @@ -401,9 +360,6 @@ impl Render for SyntaxTreeView { &cursor, depth, Some(descendant_ix) == this.selected_descendant_ix, - Some(descendant_ix) == this.hovered_descendant_ix, - list_hovered, - &style, &theme, cx, )); diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 4e3c03ad80a1ab1f66b84d69685a0d5260401fda..940d41a94c8976561c145ffe5aced81f5909b377 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -3,8 +3,8 @@ use crate::{ ListSeparator, ListSubHeader, }; use gpui::{ - px, Action, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, - IntoElement, Render, Subscription, View, VisualContext, + px, Action, AnyElement, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, + FocusableView, IntoElement, Render, Subscription, View, VisualContext, }; use menu::{SelectFirst, SelectLast, SelectNext, SelectPrev}; use std::{rc::Rc, time::Duration}; @@ -18,6 +18,9 @@ enum ContextMenuItem { handler: Rc, action: Option>, }, + CustomEntry { + entry_render: Box AnyElement>, + }, } pub struct ContextMenu { @@ -83,6 +86,16 @@ impl ContextMenu { self } + pub fn custom_entry( + mut self, + entry_render: impl Fn(&mut WindowContext) -> AnyElement + 'static, + ) -> Self { + self.items.push(ContextMenuItem::CustomEntry { + entry_render: Box::new(entry_render), + }); + self + } + pub fn action(mut self, label: impl Into, action: Box) -> Self { self.items.push(ContextMenuItem::Entry { label: label.into(), @@ -230,9 +243,9 @@ impl Render for ContextMenu { el }) .flex_none() - .child( - List::new().children(self.items.iter().enumerate().map( - |(ix, item)| match item { + .child(List::new().children(self.items.iter_mut().enumerate().map( + |(ix, item)| { + match item { ContextMenuItem::Separator => ListSeparator.into_any_element(), ContextMenuItem::Header(header) => { ListSubHeader::new(header.clone()).into_any_element() @@ -255,7 +268,7 @@ impl Render for ContextMenu { Label::new(label.clone()).into_any_element() }; - ListItem::new(label.clone()) + ListItem::new(ix) .inset(true) .selected(Some(ix) == self.selected_index) .on_click(move |_, cx| handler(cx)) @@ -271,9 +284,14 @@ impl Render for ContextMenu { ) .into_any_element() } - }, - )), - ), + ContextMenuItem::CustomEntry { entry_render } => ListItem::new(ix) + .inset(true) + .selected(Some(ix) == self.selected_index) + .child(entry_render(cx)) + .into_any_element(), + } + }, + ))), ) } } From fe40e3920bc1126bc5ad2186e09c0b407db6a20d Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 20 Dec 2023 17:02:03 +0200 Subject: [PATCH 198/644] Fix remaining z-index bugs Co-Authored-By: Antonio Scandurra --- crates/collab_ui2/src/collab_titlebar_item.rs | 1 - crates/gpui2/src/window.rs | 10 ++++++++++ crates/ui2/src/components/tab_bar.rs | 1 - crates/workspace2/src/toolbar.rs | 1 - 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index ae664859192e2bbb635d1f4552f604106bc61b54..24e510ae8d51175b7b28de32a2807c44927e4761 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -68,7 +68,6 @@ impl Render for CollabTitlebarItem { h_stack() .id("titlebar") - .z_index(160) // todo!("z-index") .justify_between() .w_full() .h(rems(1.75)) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 07be281f0aafede051b21ef9f4486fd3d8525246..986458ebf73d4492e0d5c457ab60b95bb5628dcc 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -2057,9 +2057,14 @@ pub trait BorrowWindow: BorrowMut + BorrowMut { size: self.window().viewport_size, }, }; + let new_stacking_order_id = + post_inc(&mut self.window_mut().next_frame.next_stacking_order_id); + let old_stacking_order = mem::take(&mut self.window_mut().next_frame.z_index_stack); + self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id; self.window_mut().next_frame.content_mask_stack.push(mask); let result = f(self); self.window_mut().next_frame.content_mask_stack.pop(); + self.window_mut().next_frame.z_index_stack = old_stacking_order; result } @@ -2068,9 +2073,14 @@ pub trait BorrowWindow: BorrowMut + BorrowMut { fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { let new_stacking_order_id = post_inc(&mut self.window_mut().next_frame.next_stacking_order_id); + let old_stacking_order_id = mem::replace( + &mut self.window_mut().next_frame.z_index_stack.id, + new_stacking_order_id, + ); self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id; self.window_mut().next_frame.z_index_stack.push(z_index); let result = f(self); + self.window_mut().next_frame.z_index_stack.id = old_stacking_order_id; self.window_mut().next_frame.z_index_stack.pop(); result } diff --git a/crates/ui2/src/components/tab_bar.rs b/crates/ui2/src/components/tab_bar.rs index d2e6e9518bdae89bd31506f1c1d8fad4660881fa..7cff2f51bd80f4dc38df6b9e2423d1627024ea33 100644 --- a/crates/ui2/src/components/tab_bar.rs +++ b/crates/ui2/src/components/tab_bar.rs @@ -96,7 +96,6 @@ impl RenderOnce for TabBar { div() .id(self.id) - .z_index(120) // todo!("z-index") .group("tab_bar") .flex() .flex_none() diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index 7436232b04e556ebe8ed648363908471512d1585..cd25582f36cbd397688a500e85c0e405865dae63 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -105,7 +105,6 @@ impl Render for Toolbar { v_stack() .p_1() .gap_2() - .z_index(80) // todo!("z-index") .border_b() .border_color(cx.theme().colors().border_variant) .bg(cx.theme().colors().toolbar_background) From 19d15681406ad2cbf7db855a42320c75eecfd5e9 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 20 Dec 2023 17:11:04 +0200 Subject: [PATCH 199/644] Lsp log selector fixes --- crates/gpui2/src/elements/uniform_list.rs | 4 - crates/language_tools2/src/lsp_log.rs | 104 ++++++++++-------- .../language_tools2/src/syntax_tree_view.rs | 22 +--- crates/ui2/src/components/context_menu.rs | 23 ++-- 4 files changed, 82 insertions(+), 71 deletions(-) diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 016f0160247e5931580a41d35f5052cf1f7df30d..82eac590977f7c01e53e33a5ca257a9c1a790030 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -127,7 +127,6 @@ impl Element for UniformList { .map(|s| s.item_size) .unwrap_or_else(|| self.measure_item(None, cx)); - let element_id = self.interactivity.element_id.clone(); let (layout_id, interactive) = self.interactivity .layout(state.map(|s| s.interactive), cx, |style, cx| { @@ -145,9 +144,6 @@ impl Element for UniformList { } }); - if element_id == Some(ElementId::Name("SyntaxTreeView".into())) { - dbg!(known_dimensions, available_space.height); - } let height = match available_space.height { AvailableSpace::Definite(height) => desired_height.min(height), AvailableSpace::MinContent | AvailableSpace::MaxContent => { diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 9a8ec9f71aef31430187e6f8e320373eef6aa337..20039d3908c7d8185df92441ea295a134acc78f4 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -520,6 +520,7 @@ impl LspLogView { self.editor_subscription = editor_subscription; cx.notify(); } + cx.focus(&self.focus_handle); } fn show_rpc_trace_for_server( @@ -560,6 +561,8 @@ impl LspLogView { self.editor_subscription = editor_subscription; cx.notify(); } + + cx.focus(&self.focus_handle); } fn toggle_rpc_trace_for_server( @@ -753,6 +756,7 @@ impl Render for LspLogToolbarItemView { let log_toolbar_view = log_toolbar_view.clone(); ContextMenu::build(cx, move |mut menu, cx| { for (ix, row) in menu_rows.into_iter().enumerate() { + let server_selected = Some(row.server_id) == current_server_id; menu = menu .header(format!( "{} ({})", @@ -761,52 +765,65 @@ impl Render for LspLogToolbarItemView { .entry( SERVER_LOGS, cx.handler_for(&log_view, move |view, cx| { - view.show_logs_for_server(row.server_id, cx) + view.show_logs_for_server(row.server_id, cx); }), - ) - .custom_entry({ - let log_view = log_view.clone(); - let log_toolbar_view = log_toolbar_view.clone(); - move |cx| { - h_stack() - .w_full() - .justify_between() - .child(Label::new(RPC_MESSAGES)) - .child( - Checkbox::new( - ix, - if row.rpc_trace_enabled { - Selection::Selected - } else { - Selection::Unselected + ); + if server_selected && row.logs_selected { + debug_assert_eq!( + Some(ix * 3 + 1), + menu.select_last(), + "Could not scroll to a just added LSP menu item" + ); + } + + menu = menu.custom_entry({ + let log_view = log_view.clone(); + let log_toolbar_view = log_toolbar_view.clone(); + move |cx| { + h_stack() + .w_full() + .justify_between() + .child(Label::new(RPC_MESSAGES)) + .child( + Checkbox::new( + ix, + if row.rpc_trace_enabled { + Selection::Selected + } else { + Selection::Unselected + }, + ) + .on_click( + cx.listener_for( + &log_toolbar_view, + move |view, selection, cx| { + let enabled = + matches!(selection, Selection::Selected); + view.toggle_logging_for_server( + row.server_id, + enabled, + cx, + ); }, - ) - .on_click( - cx.listener_for( - &log_toolbar_view, - move |view, selection, cx| { - let enabled = matches!( - selection, - Selection::Selected - ); - view.toggle_logging_for_server( - row.server_id, - enabled, - cx, - ); - }, - ), ), - ) - .on_mouse_down( - MouseButton::Left, - cx.listener_for(&log_view, move |view, _, cx| { - view.show_rpc_trace_for_server(row.server_id, cx) - }), - ) - .into_any_element() - } - }) + ), + ) + .on_mouse_down( + MouseButton::Left, + cx.listener_for(&log_view, move |view, _, cx| { + view.show_rpc_trace_for_server(row.server_id, cx); + }), + ) + .into_any_element() + } + }); + if server_selected && row.rpc_trace_selected { + debug_assert_eq!( + Some(ix * 3 + 2), + menu.select_last(), + "Could not scroll to a just added LSP menu item" + ); + } } menu }) @@ -858,6 +875,7 @@ impl LspLogToolbarItemView { log_view.show_logs_for_server(id, cx); cx.notify(); } + cx.focus(&log_view.focus_handle); }); } cx.notify(); diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index 0fd33cb3cdd9e32976cf626d4f399632fbd1d6e8..f0b03422cb25251faf6d5e0d6bfdcecb6aa810cd 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -8,7 +8,7 @@ use gpui::{ use language::{Buffer, OwnedSyntaxLayerInfo}; use settings::Settings; use std::{mem, ops::Range}; -use theme::{Theme, ThemeSettings}; +use theme::{ActiveTheme, ThemeSettings}; use tree_sitter::{Node, TreeCursor}; use ui::{h_stack, popover_menu, ButtonLike, Color, ContextMenu, Label, LabelCommon, PopoverMenu}; use workspace::{ @@ -275,14 +275,8 @@ impl SyntaxTreeView { Some(()) } - fn render_node( - cursor: &TreeCursor, - depth: u32, - selected: bool, - editor_theme: &Theme, - _cx: &AppContext, - ) -> Div { - let editor_colors = editor_theme.colors(); + fn render_node(cursor: &TreeCursor, depth: u32, selected: bool, cx: &AppContext) -> Div { + let colors = cx.theme().colors(); let mut row = h_stack(); if let Some(field_name) = cursor.field_name() { row = row.children([Label::new(field_name).color(Color::Info), Label::new(": ")]); @@ -301,12 +295,12 @@ impl SyntaxTreeView { .pl_1(), ) .text_bg(if selected { - editor_colors.element_selected + colors.element_selected } else { Hsla::default() }) .pl(rems(depth as f32)) - .hover(|style| style.bg(editor_colors.element_active)); + .hover(|style| style.bg(colors.element_hover)); } } @@ -315,8 +309,6 @@ impl Render for SyntaxTreeView { fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Self::Element { let settings = ThemeSettings::get_global(cx); - let editor_theme = settings.active_theme.clone(); - let editor_colors = editor_theme.colors(); let line_height = cx .text_style() .line_height_in_pixels(settings.buffer_font_size(cx)); @@ -334,7 +326,6 @@ impl Render for SyntaxTreeView { .and_then(|buffer| buffer.active_layer.as_ref()) { let layer = layer.clone(); - let theme = editor_theme.clone(); let list = uniform_list( cx.view().clone(), "SyntaxTreeView", @@ -360,7 +351,6 @@ impl Render for SyntaxTreeView { &cursor, depth, Some(descendant_ix) == this.selected_descendant_ix, - &theme, cx, )); descendant_ix += 1; @@ -386,7 +376,7 @@ impl Render for SyntaxTreeView { tree_view.handle_click(event.position.y, cx); }), ) - .text_bg(editor_colors.background); + .text_bg(cx.theme().colors().background); rendered = rendered.child( canvas(move |bounds, cx| { diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 940d41a94c8976561c145ffe5aced81f5909b377..1fda44e86d7f7529de4c3b014d12ce5982dd9e26 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -122,6 +122,7 @@ impl ContextMenu { { (handler)(cx) } + cx.emit(DismissEvent); } @@ -135,14 +136,20 @@ impl ContextMenu { cx.notify(); } - fn select_last(&mut self, _: &SelectLast, cx: &mut ViewContext) { + pub fn select_last(&mut self) -> Option { for (ix, item) in self.items.iter().enumerate().rev() { if item.is_selectable() { self.selected_index = Some(ix); - cx.notify(); - break; + return Some(ix); } } + None + } + + fn handle_select_last(&mut self, _: &SelectLast, cx: &mut ViewContext) { + if self.select_last().is_some() { + cx.notify(); + } } fn select_next(&mut self, _: &SelectNext, cx: &mut ViewContext) { @@ -169,7 +176,7 @@ impl ContextMenu { } } } else { - self.select_last(&Default::default(), cx); + self.handle_select_last(&Default::default(), cx); } } @@ -195,7 +202,7 @@ impl ContextMenu { .await; this.update(&mut cx, |this, cx| { cx.dispatch_action(action); - this.cancel(&Default::default(), cx) + this.cancel(&menu::Cancel, cx) }) }) .detach_and_log_err(cx); @@ -207,7 +214,7 @@ impl ContextMenu { impl ContextMenuItem { fn is_selectable(&self) -> bool { - matches!(self, Self::Entry { .. }) + matches!(self, Self::Entry { .. } | Self::CustomEntry { .. }) } } @@ -219,10 +226,10 @@ impl Render for ContextMenu { v_stack() .min_w(px(200.)) .track_focus(&self.focus_handle) - .on_mouse_down_out(cx.listener(|this, _, cx| this.cancel(&Default::default(), cx))) + .on_mouse_down_out(cx.listener(|this, _, cx| this.cancel(&menu::Cancel, cx))) .key_context("menu") .on_action(cx.listener(ContextMenu::select_first)) - .on_action(cx.listener(ContextMenu::select_last)) + .on_action(cx.listener(ContextMenu::handle_select_last)) .on_action(cx.listener(ContextMenu::select_next)) .on_action(cx.listener(ContextMenu::select_prev)) .on_action(cx.listener(ContextMenu::confirm)) From 331af82cb16dbb474cc92fff4d57cb867ee916bf Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 20 Dec 2023 18:22:39 +0200 Subject: [PATCH 200/644] Rework context menu's custom element API to handle clicks properly --- crates/language_tools2/src/lsp_log.rs | 86 ++++++++++---------- crates/ui2/src/components/context_menu.rs | 98 +++++++++++++---------- 2 files changed, 97 insertions(+), 87 deletions(-) diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 20039d3908c7d8185df92441ea295a134acc78f4..597c9c5b543fb5976c8019981216396b83739d9d 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -3,9 +3,8 @@ use editor::{Editor, EditorElement, EditorEvent, MoveToEnd}; use futures::{channel::mpsc, StreamExt}; use gpui::{ actions, div, AnchorCorner, AnyElement, AppContext, Context, Div, EventEmitter, FocusHandle, - FocusableView, InteractiveElement, IntoElement, Model, ModelContext, MouseButton, - ParentElement, Render, Styled, Subscription, View, ViewContext, VisualContext, WeakModel, - WindowContext, + FocusableView, IntoElement, Model, ModelContext, ParentElement, Render, Styled, Subscription, + View, ViewContext, VisualContext, WeakModel, WindowContext, }; use language::{LanguageServerId, LanguageServerName}; use lsp::IoKind; @@ -776,47 +775,48 @@ impl Render for LspLogToolbarItemView { ); } - menu = menu.custom_entry({ - let log_view = log_view.clone(); - let log_toolbar_view = log_toolbar_view.clone(); - move |cx| { - h_stack() - .w_full() - .justify_between() - .child(Label::new(RPC_MESSAGES)) - .child( - Checkbox::new( - ix, - if row.rpc_trace_enabled { - Selection::Selected - } else { - Selection::Unselected - }, - ) - .on_click( - cx.listener_for( - &log_toolbar_view, - move |view, selection, cx| { - let enabled = - matches!(selection, Selection::Selected); - view.toggle_logging_for_server( - row.server_id, - enabled, - cx, - ); - }, + menu = menu.custom_entry( + { + let log_toolbar_view = log_toolbar_view.clone(); + move |cx| { + h_stack() + .w_full() + .justify_between() + .child(Label::new(RPC_MESSAGES)) + .child( + div().z_index(120).child( + Checkbox::new( + ix, + if row.rpc_trace_enabled { + Selection::Selected + } else { + Selection::Unselected + }, + ) + .on_click(cx.listener_for( + &log_toolbar_view, + move |view, selection, cx| { + let enabled = matches!( + selection, + Selection::Selected + ); + view.toggle_logging_for_server( + row.server_id, + enabled, + cx, + ); + cx.stop_propagation(); + }, + )), ), - ), - ) - .on_mouse_down( - MouseButton::Left, - cx.listener_for(&log_view, move |view, _, cx| { - view.show_rpc_trace_for_server(row.server_id, cx); - }), - ) - .into_any_element() - } - }); + ) + .into_any_element() + } + }, + cx.handler_for(&log_view, move |view, cx| { + view.show_rpc_trace_for_server(row.server_id, cx); + }), + ); if server_selected && row.rpc_trace_selected { debug_assert_eq!( Some(ix * 3 + 2), diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 1fda44e86d7f7529de4c3b014d12ce5982dd9e26..97bb3865ef6dbefd95e4274fe77d37df630aee74 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -20,6 +20,7 @@ enum ContextMenuItem { }, CustomEntry { entry_render: Box AnyElement>, + handler: Rc, }, } @@ -89,9 +90,11 @@ impl ContextMenu { pub fn custom_entry( mut self, entry_render: impl Fn(&mut WindowContext) -> AnyElement + 'static, + handler: impl Fn(&mut WindowContext) + 'static, ) -> Self { self.items.push(ContextMenuItem::CustomEntry { entry_render: Box::new(entry_render), + handler: Rc::new(handler), }); self } @@ -117,10 +120,12 @@ impl ContextMenu { } pub fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext) { - if let Some(ContextMenuItem::Entry { handler, .. }) = - self.selected_index.and_then(|ix| self.items.get(ix)) - { - (handler)(cx) + match self.selected_index.and_then(|ix| self.items.get(ix)) { + Some( + ContextMenuItem::Entry { handler, .. } + | ContextMenuItem::CustomEntry { handler, .. }, + ) => (handler)(cx), + _ => {} } cx.emit(DismissEvent); @@ -251,51 +256,56 @@ impl Render for ContextMenu { }) .flex_none() .child(List::new().children(self.items.iter_mut().enumerate().map( - |(ix, item)| { - match item { - ContextMenuItem::Separator => ListSeparator.into_any_element(), - ContextMenuItem::Header(header) => { - ListSubHeader::new(header.clone()).into_any_element() - } - ContextMenuItem::Entry { - label, - handler, - icon, - action, - } => { - let handler = handler.clone(); - - let label_element = if let Some(icon) = icon { - h_stack() - .gap_1() - .child(Label::new(label.clone())) - .child(IconElement::new(*icon)) - .into_any_element() - } else { - Label::new(label.clone()).into_any_element() - }; + |(ix, item)| match item { + ContextMenuItem::Separator => ListSeparator.into_any_element(), + ContextMenuItem::Header(header) => { + ListSubHeader::new(header.clone()).into_any_element() + } + ContextMenuItem::Entry { + label, + handler, + icon, + action, + } => { + let handler = handler.clone(); - ListItem::new(ix) - .inset(true) - .selected(Some(ix) == self.selected_index) - .on_click(move |_, cx| handler(cx)) - .child( - h_stack() - .w_full() - .justify_between() - .child(label_element) - .children(action.as_ref().and_then(|action| { - KeyBinding::for_action(&**action, cx) - .map(|binding| div().ml_1().child(binding)) - })), - ) + let label_element = if let Some(icon) = icon { + h_stack() + .gap_1() + .child(Label::new(label.clone())) + .child(IconElement::new(*icon)) .into_any_element() - } - ContextMenuItem::CustomEntry { entry_render } => ListItem::new(ix) + } else { + Label::new(label.clone()).into_any_element() + }; + + ListItem::new(ix) + .inset(true) + .selected(Some(ix) == self.selected_index) + .on_click(move |_, cx| handler(cx)) + .child( + h_stack() + .w_full() + .justify_between() + .child(label_element) + .children(action.as_ref().and_then(|action| { + KeyBinding::for_action(&**action, cx) + .map(|binding| div().ml_1().child(binding)) + })), + ) + .into_any_element() + } + ContextMenuItem::CustomEntry { + entry_render, + handler, + } => { + let handler = handler.clone(); + ListItem::new(ix) .inset(true) .selected(Some(ix) == self.selected_index) + .on_click(move |_, cx| handler(cx)) .child(entry_render(cx)) - .into_any_element(), + .into_any_element() } }, ))), From 5145795f33ed5a127cbff792f464156201786b9b Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 11:27:28 -0500 Subject: [PATCH 201/644] Adjust styles for notification panel container --- crates/collab_ui2/src/notification_panel.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/collab_ui2/src/notification_panel.rs b/crates/collab_ui2/src/notification_panel.rs index 35288e810d645bf7ea2c158df071cc51fde4efc1..e2deced60f9aba7ecd8969395adb85357aac5105 100644 --- a/crates/collab_ui2/src/notification_panel.rs +++ b/crates/collab_ui2/src/notification_panel.rs @@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsStore}; use std::{sync::Arc, time::Duration}; use time::{OffsetDateTime, UtcOffset}; -use ui::{h_stack, v_stack, Avatar, Button, Clickable, Icon, IconButton, IconElement, Label}; +use ui::{h_stack, prelude::*, v_stack, Avatar, Button, Icon, IconButton, IconElement, Label}; use util::{ResultExt, TryFutureExt}; use workspace::{ dock::{DockPosition, Panel, PanelEvent}, @@ -545,16 +545,22 @@ impl NotificationPanel { impl Render for NotificationPanel { type Element = AnyElement; - fn render(&mut self, _: &mut ViewContext) -> AnyElement { + fn render(&mut self, cx: &mut ViewContext) -> AnyElement { if self.client.user_id().is_none() { self.render_sign_in_prompt() } else if self.notification_list.item_count() == 0 { self.render_empty_state() } else { v_stack() - .bg(gpui::red()) .child( h_stack() + .justify_between() + .px_2() + .py_1() + // Match the height of the tab bar so they line up. + .h(rems(ui::Tab::HEIGHT_IN_REMS)) + .border_b_1() + .border_color(cx.theme().colors().border) .child(Label::new("Notifications")) .child(IconElement::new(Icon::Envelope)), ) From fc923a2a98044cb31c8739b9e63092edd77500c7 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 20 Dec 2023 18:28:32 +0200 Subject: [PATCH 202/644] Close syntax tree view menu on click too --- crates/language_tools2/src/syntax_tree_view.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index f0b03422cb25251faf6d5e0d6bfdcecb6aa810cd..dcdcb612b781e6d93e92650c111f9ea9e1ac9d1f 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -480,6 +480,7 @@ impl SyntaxTreeToolbarItemView { buffer_state.active_layer = Some(layer.to_owned()); view.selected_descendant_ix = None; cx.notify(); + view.focus_handle.focus(cx); Some(()) }) } From 5840750b3d854575e9503a321dbeac5252ab633c Mon Sep 17 00:00:00 2001 From: Julia Date: Wed, 20 Dec 2023 11:28:56 -0500 Subject: [PATCH 203/644] Avoid workspace use while leased --- crates/workspace2/src/pane.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index dcf4ed0811650ce85d961cee0fabd433f219c593..9d14c25fc73562becb5fc24b9ca4b81bc35548bd 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1452,15 +1452,15 @@ impl Pane { } fn update_status_bar(&mut self, cx: &mut ViewContext) { - let Ok(status_bar) = self - .workspace - .update(cx, |workspace, _| workspace.status_bar.clone()) - else { - return; - }; - + let workspace = self.workspace.clone(); let pane = cx.view().clone(); + cx.window_context().defer(move |cx| { + let Ok(status_bar) = workspace.update(cx, |workspace, _| workspace.status_bar.clone()) + else { + return; + }; + status_bar.update(cx, move |status_bar, cx| { status_bar.set_active_pane(&pane, cx); }); From 6e2346c53704f83431a58be09fb6d62e15c7578c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 20 Dec 2023 17:32:59 +0100 Subject: [PATCH 204/644] Prevent `ArenaRef` from being cloned --- crates/gpui2/src/arena.rs | 9 ----- crates/gpui2/src/key_dispatch.rs | 5 ++- crates/gpui2/src/window.rs | 57 +++++++++++++++++++++++--------- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index 5992baf06e1366bfa0aa0ddeb3a09c1c39b95f6a..ef66188a0ebcf7b6b4c4175bec2c7a571478f650 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -98,15 +98,6 @@ pub struct ArenaRef { valid: Rc>, } -impl Clone for ArenaRef { - fn clone(&self) -> Self { - Self { - ptr: self.ptr, - valid: self.valid.clone(), - } - } -} - impl ArenaRef { #[inline(always)] pub fn map(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaRef { diff --git a/crates/gpui2/src/key_dispatch.rs b/crates/gpui2/src/key_dispatch.rs index a9d717ea1acb6866ab75165bcc4c6daedd268899..03adf887b5aa9e4a0b1cb77cefc81c5adb2e0529 100644 --- a/crates/gpui2/src/key_dispatch.rs +++ b/crates/gpui2/src/key_dispatch.rs @@ -35,7 +35,6 @@ pub(crate) struct DispatchNode { type KeyListener = ArenaRef; -#[derive(Clone)] pub(crate) struct DispatchActionListener { pub(crate) action_type: TypeId, pub(crate) listener: ArenaRef, @@ -267,6 +266,10 @@ impl DispatchTree { &self.nodes[node_id.0] } + pub fn node_mut(&mut self, node_id: DispatchNodeId) -> &mut DispatchNode { + &mut self.nodes[node_id.0] + } + fn active_node(&mut self) -> &mut DispatchNode { let active_node_id = self.active_node_id(); &mut self.nodes[active_node_id.0] diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 07be281f0aafede051b21ef9f4486fd3d8525246..21eb04a44f6145def7b508412397db9037bc6e19 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1572,30 +1572,43 @@ impl<'a> WindowContext<'a> { self.propagate_event = true; for node_id in &dispatch_path { - let node = self.window.rendered_frame.dispatch_tree.node(*node_id); - + let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); if let Some(context) = node.context.clone() { context_stack.push(context); } - for key_listener in node.key_listeners.clone() { + let key_listeners = mem::take(&mut node.key_listeners); + for key_listener in &key_listeners { key_listener(event, DispatchPhase::Capture, self); if !self.propagate_event { - return; + break; } } + let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); + node.key_listeners = key_listeners; + + if !self.propagate_event { + return; + } } // Bubble phase for node_id in dispatch_path.iter().rev() { // Handle low level key events - let node = self.window.rendered_frame.dispatch_tree.node(*node_id); - for key_listener in node.key_listeners.clone() { + let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); + let key_listeners = mem::take(&mut node.key_listeners); + for key_listener in &key_listeners { key_listener(event, DispatchPhase::Bubble, self); if !self.propagate_event { - return; + break; } } + let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); + node.key_listeners = key_listeners; + + if !self.propagate_event { + return; + } // Match keystrokes let node = self.window.rendered_frame.dispatch_tree.node(*node_id); @@ -1639,38 +1652,52 @@ impl<'a> WindowContext<'a> { // Capture phase for node_id in &dispatch_path { - let node = self.window.rendered_frame.dispatch_tree.node(*node_id); + let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); + let action_listeners = mem::take(&mut node.action_listeners); for DispatchActionListener { action_type, listener, - } in node.action_listeners.clone() + } in &action_listeners { let any_action = action.as_any(); - if action_type == any_action.type_id() { + if *action_type == any_action.type_id() { listener(any_action, DispatchPhase::Capture, self); if !self.propagate_event { - return; + break; } } } + let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); + node.action_listeners = action_listeners; + + if !self.propagate_event { + return; + } } // Bubble phase for node_id in dispatch_path.iter().rev() { - let node = self.window.rendered_frame.dispatch_tree.node(*node_id); + let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); + let action_listeners = mem::take(&mut node.action_listeners); for DispatchActionListener { action_type, listener, - } in node.action_listeners.clone() + } in &action_listeners { let any_action = action.as_any(); - if action_type == any_action.type_id() { + if *action_type == any_action.type_id() { self.propagate_event = false; // Actions stop propagation by default during the bubble phase listener(any_action, DispatchPhase::Bubble, self); if !self.propagate_event { - return; + break; } } } + + let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); + node.action_listeners = action_listeners; + if !self.propagate_event { + return; + } } } From 3886b1993d22ae66a89f5c32d3139553fe159bca Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 11:41:51 -0500 Subject: [PATCH 205/644] Fix formatting breakage --- crates/collab_ui2/src/collab_panel.rs | 67 ++++++++++++++------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 35e2f8d7ed210dc3cfb2fbe59d1d399a3f2683b9..52149a481f99e814bb65aa59bc236053432a2cfb 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -1624,40 +1624,43 @@ impl CollabPanel { } fn render_signed_out(&mut self, cx: &mut ViewContext) -> Div { - v_stack() - .items_center() - .child(v_stack().gap_6().p_4() - .child( - Label::new("Work with your team in realtime with collaborative editing, voice, shared notes and more.") - ) - .child(v_stack().gap_2() + let collab_blurb = "Work with your team in realtime with collaborative editing, voice, shared notes and more."; + v_stack().items_center().child( + v_stack() + .gap_6() + .p_4() + .child(Label::new(collab_blurb)) .child( - Button::new("sign_in", "Sign in") - .icon_color(Color::Muted) - .icon(Icon::Github) - .icon_position(IconPosition::Start) - .style(ButtonStyle::Filled) - .full_width() - .on_click(cx.listener( - |this, _, cx| { - let client = this.client.clone(); - cx.spawn(|_, mut cx| async move { - client - .authenticate_and_connect(true, &cx) - .await - .notify_async_err(&mut cx); - }) - .detach() - }, - ))) - .child( - div().flex().w_full().items_center().child( - Label::new("Sign in to enable collaboration.") - .color(Color::Muted) - .size(LabelSize::Small) - )), - )) + v_stack() + .gap_2() + .child( + Button::new("sign_in", "Sign in") + .icon_color(Color::Muted) + .icon(Icon::Github) + .icon_position(IconPosition::Start) + .style(ButtonStyle::Filled) + .full_width() + .on_click(cx.listener(|this, _, cx| { + let client = this.client.clone(); + cx.spawn(|_, mut cx| async move { + client + .authenticate_and_connect(true, &cx) + .await + .notify_async_err(&mut cx); + }) + .detach() + })), + ) + .child( + div().flex().w_full().items_center().child( + Label::new("Sign in to enable collaboration.") + .color(Color::Muted) + .size(LabelSize::Small), + ), + ), + ), + ) } fn render_list_entry(&mut self, ix: usize, cx: &mut ViewContext) -> AnyElement { From 636c12ec3f140745152b4dbd92a4fcc7160636fb Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 11:45:18 -0500 Subject: [PATCH 206/644] Style signed-out and empty states for the notification panel --- crates/collab_ui2/src/notification_panel.rs | 111 ++++++++++++-------- 1 file changed, 65 insertions(+), 46 deletions(-) diff --git a/crates/collab_ui2/src/notification_panel.rs b/crates/collab_ui2/src/notification_panel.rs index e2deced60f9aba7ecd8969395adb85357aac5105..8a16261da4422751dcbc32687b6d8e748175418b 100644 --- a/crates/collab_ui2/src/notification_panel.rs +++ b/crates/collab_ui2/src/notification_panel.rs @@ -439,28 +439,6 @@ impl NotificationPanel { false } - fn render_sign_in_prompt(&self) -> AnyElement { - Button::new( - "sign_in_prompt_button", - "Sign in to view your notifications", - ) - .on_click({ - let client = self.client.clone(); - move |_, cx| { - let client = client.clone(); - cx.spawn(move |cx| async move { - client.authenticate_and_connect(true, &cx).log_err().await; - }) - .detach() - } - }) - .into_any_element() - } - - fn render_empty_state(&self) -> AnyElement { - Label::new("You have no notifications").into_any_element() - } - fn on_notification_event( &mut self, _: Model, @@ -543,31 +521,72 @@ impl NotificationPanel { } impl Render for NotificationPanel { - type Element = AnyElement; + type Element = Div; - fn render(&mut self, cx: &mut ViewContext) -> AnyElement { - if self.client.user_id().is_none() { - self.render_sign_in_prompt() - } else if self.notification_list.item_count() == 0 { - self.render_empty_state() - } else { - v_stack() - .child( - h_stack() - .justify_between() - .px_2() - .py_1() - // Match the height of the tab bar so they line up. - .h(rems(ui::Tab::HEIGHT_IN_REMS)) - .border_b_1() - .border_color(cx.theme().colors().border) - .child(Label::new("Notifications")) - .child(IconElement::new(Icon::Envelope)), - ) - .child(list(self.notification_list.clone()).size_full()) - .size_full() - .into_any_element() - } + fn render(&mut self, cx: &mut ViewContext) -> Div { + v_stack() + .size_full() + .child( + h_stack() + .justify_between() + .px_2() + .py_1() + // Match the height of the tab bar so they line up. + .h(rems(ui::Tab::HEIGHT_IN_REMS)) + .border_b_1() + .border_color(cx.theme().colors().border) + .child(Label::new("Notifications")) + .child(IconElement::new(Icon::Envelope)), + ) + .map(|this| { + if self.client.user_id().is_none() { + this.child( + v_stack() + .gap_2() + .p_4() + .child( + Button::new("sign_in_prompt_button", "Sign in") + .icon_color(Color::Muted) + .icon(Icon::Github) + .icon_position(IconPosition::Start) + .style(ButtonStyle::Filled) + .full_width() + .on_click({ + let client = self.client.clone(); + move |_, cx| { + let client = client.clone(); + cx.spawn(move |cx| async move { + client + .authenticate_and_connect(true, &cx) + .log_err() + .await; + }) + .detach() + } + }), + ) + .child( + div().flex().w_full().items_center().child( + Label::new("Sign in to view notifications.") + .color(Color::Muted) + .size(LabelSize::Small), + ), + ), + ) + } else if self.notification_list.item_count() == 0 { + this.child( + v_stack().p_4().child( + div().flex().w_full().items_center().child( + Label::new("You have no notifications.") + .color(Color::Muted) + .size(LabelSize::Small), + ), + ), + ) + } else { + this.child(list(self.notification_list.clone()).size_full()) + } + }) } } From 11140a1d348d4eb50a01b990f6bd11f1f10131bc Mon Sep 17 00:00:00 2001 From: Julia Date: Wed, 20 Dec 2023 12:15:13 -0500 Subject: [PATCH 207/644] Use ButtonLike rather than ad-hoc button Co-Authored-By: Marshall Bowers --- crates/diagnostics2/src/items.rs | 51 +++++++++++++++----------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/crates/diagnostics2/src/items.rs b/crates/diagnostics2/src/items.rs index 28bbe7aedc29c84578f5d01abd7d06febb51ac95..14ebe0c5166e07a641e6e94bec54025eaed6c0b7 100644 --- a/crates/diagnostics2/src/items.rs +++ b/crates/diagnostics2/src/items.rs @@ -1,16 +1,15 @@ use collections::HashSet; -use editor::{Editor, GoToDiagnostic}; +use editor::Editor; use gpui::{ - rems, Div, EventEmitter, InteractiveElement, IntoElement, ParentElement, Render, Stateful, - StatefulInteractiveElement, Styled, Subscription, View, ViewContext, WeakView, + rems, Div, EventEmitter, IntoElement, ParentElement, Render, Styled, Subscription, View, + ViewContext, WeakView, }; use language::Diagnostic; use lsp::LanguageServerId; -use theme::ActiveTheme; -use ui::{h_stack, Button, Clickable, Color, Icon, IconElement, Label, Tooltip}; +use ui::{h_stack, prelude::*, Button, ButtonLike, Color, Icon, IconElement, Label, Tooltip}; use workspace::{item::ItemHandle, StatusItemView, ToolbarItemEvent, Workspace}; -use crate::ProjectDiagnosticsEditor; +use crate::{Deploy, ProjectDiagnosticsEditor}; pub struct DiagnosticIndicator { summary: project::DiagnosticSummary, @@ -22,7 +21,7 @@ pub struct DiagnosticIndicator { } impl Render for DiagnosticIndicator { - type Element = Stateful
; + type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { let diagnostic_indicator = match (self.summary.error_count, self.summary.warning_count) { @@ -49,8 +48,11 @@ impl Render for DiagnosticIndicator { let message = diagnostic.message.split('\n').next().unwrap().to_string(); Some( Button::new("diagnostic_message", message) + .tooltip(|cx| { + Tooltip::for_action("Next Diagnostic", &editor::GoToDiagnostic, cx) + }) .on_click(cx.listener(|this, _, cx| { - this.go_to_next_diagnostic(&GoToDiagnostic, cx); + this.go_to_next_diagnostic(cx); })) .into_any_element(), ) @@ -59,25 +61,20 @@ impl Render for DiagnosticIndicator { }; h_stack() - .id("diagnostic-indicator") - .on_action(cx.listener(Self::go_to_next_diagnostic)) - .rounded_md() - .flex_none() .h(rems(1.375)) - .px_6() - .cursor_pointer() - .bg(cx.theme().colors().ghost_element_background) - .hover(|style| style.bg(cx.theme().colors().ghost_element_hover)) - .active(|style| style.bg(cx.theme().colors().ghost_element_active)) - .tooltip(|cx| Tooltip::text("Project Diagnostics", cx)) - .on_click(cx.listener(|this, _, cx| { - if let Some(workspace) = this.workspace.upgrade() { - workspace.update(cx, |workspace, cx| { - ProjectDiagnosticsEditor::deploy(workspace, &Default::default(), cx) - }) - } - })) - .child(diagnostic_indicator) + .gap_2() + .child( + ButtonLike::new("diagnostic-indicator") + .child(diagnostic_indicator) + .tooltip(|cx| Tooltip::for_action("Project Diagnostics", &Deploy, cx)) + .on_click(cx.listener(|this, _, cx| { + if let Some(workspace) = this.workspace.upgrade() { + workspace.update(cx, |workspace, cx| { + ProjectDiagnosticsEditor::deploy(workspace, &Default::default(), cx) + }) + } + })), + ) .children(status) } } @@ -120,7 +117,7 @@ impl DiagnosticIndicator { } } - fn go_to_next_diagnostic(&mut self, _: &GoToDiagnostic, cx: &mut ViewContext) { + fn go_to_next_diagnostic(&mut self, cx: &mut ViewContext) { if let Some(editor) = self.active_editor.as_ref().and_then(|e| e.upgrade()) { editor.update(cx, |editor, cx| { editor.go_to_diagnostic_impl(editor::Direction::Next, cx); From 8f677cc0c6f589ae279d9c8a6c04dcf6e00d51d9 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 20 Dec 2023 09:43:04 -0800 Subject: [PATCH 208/644] Assign draw order to surfaces using plane splitter --- crates/gpui2/src/scene.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index 811b2b6e30897f4fe23913e879608c02a26b98bd..e6b601b62f17cf087748f8ce4e672eab14b13fb8 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -104,6 +104,15 @@ impl SceneBuilder { ); } + for (ix, surface) in self.surfaces.iter().enumerate() { + let z = layer_z_values[surface.order as LayerId as usize]; + self.splitter.add( + surface + .bounds + .to_bsp_polygon(z, (PrimitiveKind::Surface, ix)), + ); + } + // Sort all polygons, then reassign the order field of each primitive to `draw_order` // We need primitives to be repr(C), hence the weird reuse of the order field for two different types. for (draw_order, polygon) in self From 9c4e8699bad5502325f2a4860b9ad65aab89e6eb Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 12:45:18 -0500 Subject: [PATCH 209/644] Remove unneeded wrapping element --- crates/collab_ui2/src/collab_panel.rs | 66 +++++++++++++-------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 52149a481f99e814bb65aa59bc236053432a2cfb..20edd9be56636259700bef95e9c83d1a74f017d2 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -1626,41 +1626,39 @@ impl CollabPanel { fn render_signed_out(&mut self, cx: &mut ViewContext) -> Div { let collab_blurb = "Work with your team in realtime with collaborative editing, voice, shared notes and more."; - v_stack().items_center().child( - v_stack() - .gap_6() - .p_4() - .child(Label::new(collab_blurb)) - .child( - v_stack() - .gap_2() - .child( - Button::new("sign_in", "Sign in") - .icon_color(Color::Muted) - .icon(Icon::Github) - .icon_position(IconPosition::Start) - .style(ButtonStyle::Filled) - .full_width() - .on_click(cx.listener(|this, _, cx| { - let client = this.client.clone(); - cx.spawn(|_, mut cx| async move { - client - .authenticate_and_connect(true, &cx) - .await - .notify_async_err(&mut cx); - }) - .detach() - })), - ) - .child( - div().flex().w_full().items_center().child( - Label::new("Sign in to enable collaboration.") - .color(Color::Muted) - .size(LabelSize::Small), - ), + v_stack() + .gap_6() + .p_4() + .child(Label::new(collab_blurb)) + .child( + v_stack() + .gap_2() + .child( + Button::new("sign_in", "Sign in") + .icon_color(Color::Muted) + .icon(Icon::Github) + .icon_position(IconPosition::Start) + .style(ButtonStyle::Filled) + .full_width() + .on_click(cx.listener(|this, _, cx| { + let client = this.client.clone(); + cx.spawn(|_, mut cx| async move { + client + .authenticate_and_connect(true, &cx) + .await + .notify_async_err(&mut cx); + }) + .detach() + })), + ) + .child( + div().flex().w_full().items_center().child( + Label::new("Sign in to enable collaboration.") + .color(Color::Muted) + .size(LabelSize::Small), ), - ), - ) + ), + ) } fn render_list_entry(&mut self, ix: usize, cx: &mut ViewContext) -> AnyElement { From dc047437c6718f22a02f72c756272d37d5d47c56 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 10:46:36 -0700 Subject: [PATCH 210/644] Don't consider any element hovered when actively dragging Co-Authored-By: Antonio --- crates/gpui2/src/elements/div.rs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index d5284c02a166911fbc536f152ef53586e2bbe54a..54c0884870f64079ef16d1215d20b1e099646c4a 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1311,6 +1311,7 @@ impl Interactivity { return; } let is_hovered = interactive_bounds.visibly_contains(&event.position, cx) + && !cx.has_active_drag() && has_mouse_down.borrow().is_none(); let mut was_hovered = was_hovered.borrow_mut(); @@ -1538,24 +1539,27 @@ impl Interactivity { if let Some(bounds) = bounds { let mouse_position = cx.mouse_position(); - if let Some(group_hover) = self.group_hover_style.as_ref() { - if let Some(group_bounds) = GroupBounds::get(&group_hover.group, cx) { - if group_bounds.contains(&mouse_position) + if !cx.has_active_drag() { + if let Some(group_hover) = self.group_hover_style.as_ref() { + if let Some(group_bounds) = GroupBounds::get(&group_hover.group, cx) { + if group_bounds.contains(&mouse_position) + && cx.was_top_layer(&mouse_position, cx.stacking_order()) + { + style.refine(&group_hover.style); + } + } + } + + if let Some(hover_style) = self.hover_style.as_ref() { + if bounds + .intersect(&cx.content_mask().bounds) + .contains(&mouse_position) && cx.was_top_layer(&mouse_position, cx.stacking_order()) { - style.refine(&group_hover.style); + style.refine(hover_style); } } } - if let Some(hover_style) = self.hover_style.as_ref() { - if bounds - .intersect(&cx.content_mask().bounds) - .contains(&mouse_position) - && cx.was_top_layer(&mouse_position, cx.stacking_order()) - { - style.refine(hover_style); - } - } if let Some(drag) = cx.active_drag.take() { for (state_type, group_drag_style) in &self.group_drag_over_styles { From 87f879bfa974c21742a96a89a89a2a7e488999b0 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 12:48:30 -0500 Subject: [PATCH 211/644] Add text wrapping to notifications --- crates/collab_ui2/src/notification_panel.rs | 129 +++++++++++--------- 1 file changed, 68 insertions(+), 61 deletions(-) diff --git a/crates/collab_ui2/src/notification_panel.rs b/crates/collab_ui2/src/notification_panel.rs index 8a16261da4422751dcbc32687b6d8e748175418b..e13d4bbe793e74959f032156ff4c34de84187361 100644 --- a/crates/collab_ui2/src/notification_panel.rs +++ b/crates/collab_ui2/src/notification_panel.rs @@ -6,11 +6,11 @@ use collections::HashMap; use db::kvp::KEY_VALUE_STORE; use futures::StreamExt; use gpui::{ - actions, div, list, px, serde_json, AnyElement, AppContext, AsyncWindowContext, CursorStyle, - DismissEvent, Div, Element, EventEmitter, FocusHandle, FocusableView, InteractiveElement, - IntoElement, ListAlignment, ListScrollEvent, ListState, Model, ParentElement, Render, Stateful, - StatefulInteractiveElement, Styled, Task, View, ViewContext, VisualContext, WeakView, - WindowContext, + actions, div, img, list, px, serde_json, AnyElement, AppContext, AsyncWindowContext, + CursorStyle, DismissEvent, Div, Element, EventEmitter, FocusHandle, FocusableView, + InteractiveElement, IntoElement, ListAlignment, ListScrollEvent, ListState, Model, + ParentElement, Render, Stateful, StatefulInteractiveElement, Styled, Task, View, ViewContext, + VisualContext, WeakView, WindowContext, }; use notifications::{NotificationEntry, NotificationEvent, NotificationStore}; use project::Fs; @@ -227,63 +227,10 @@ impl NotificationPanel { } Some( - div() + h_stack() .id(ix) - .child( - h_stack() - .children(actor.map(|actor| Avatar::new(actor.avatar_uri.clone()))) - .child( - v_stack().child(Label::new(text)).child( - h_stack() - .child(Label::new(format_timestamp( - timestamp, - now, - self.local_timezone, - ))) - .children(if let Some(is_accepted) = response { - Some(div().child(Label::new(if is_accepted { - "You accepted" - } else { - "You declined" - }))) - } else if needs_response { - Some( - h_stack() - .child(Button::new("decline", "Decline").on_click( - { - let notification = notification.clone(); - let view = cx.view().clone(); - move |_, cx| { - view.update(cx, |this, cx| { - this.respond_to_notification( - notification.clone(), - false, - cx, - ) - }); - } - }, - )) - .child(Button::new("accept", "Accept").on_click({ - let notification = notification.clone(); - let view = cx.view().clone(); - move |_, cx| { - view.update(cx, |this, cx| { - this.respond_to_notification( - notification.clone(), - true, - cx, - ) - }); - } - })), - ) - } else { - None - }), - ), - ), - ) + .size_full() + .gap_2() .when(can_navigate, |el| { el.cursor(CursorStyle::PointingHand).on_click({ let notification = notification.clone(); @@ -292,6 +239,66 @@ impl NotificationPanel { }) }) }) + .children( + actor.map(|actor| img(actor.avatar_uri.clone()).w_8().h_8().rounded_full()), + ) + .child( + v_stack() + .gap_1() + .size_full() + .child(Label::new(text.clone())) + .child( + h_stack() + .justify_between() + .child( + Label::new(format_timestamp( + timestamp, + now, + self.local_timezone, + )) + .color(Color::Muted), + ) + .children(if let Some(is_accepted) = response { + Some(div().child(Label::new(if is_accepted { + "You accepted" + } else { + "You declined" + }))) + } else if needs_response { + Some( + h_stack() + .child(Button::new("decline", "Decline").on_click({ + let notification = notification.clone(); + let view = cx.view().clone(); + move |_, cx| { + view.update(cx, |this, cx| { + this.respond_to_notification( + notification.clone(), + false, + cx, + ) + }); + } + })) + .child(Button::new("accept", "Accept").on_click({ + let notification = notification.clone(); + let view = cx.view().clone(); + move |_, cx| { + view.update(cx, |this, cx| { + this.respond_to_notification( + notification.clone(), + true, + cx, + ) + }); + } + })), + ) + } else { + None + }), + ), + ) .into_any(), ) } From 73b13b7dc65d7b0a3e1eb67a4ba054cf55644cc3 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 20 Dec 2023 13:00:01 -0500 Subject: [PATCH 212/644] v0.119.x dev --- Cargo.lock | 2 +- crates/zed/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3226037d51a40f06b24ed0ede79e2ee211c2ed43..c73484b16d9d32ec5c865ad480dd03e196b60de5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12012,7 +12012,7 @@ dependencies = [ [[package]] name = "zed" -version = "0.118.0" +version = "0.119.0" dependencies = [ "activity_indicator", "ai", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 0c115fb2850a07afc1d26b348c80d9816418c232..987208880be6beec91dc53ce2679c04aaa386f44 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Nathan Sobo "] description = "The fast, collaborative code editor." edition = "2021" name = "zed" -version = "0.118.0" +version = "0.119.0" publish = false [lib] From fffb30ac6d57e3974f2b12a6f97ea71dfe7da71b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 11:02:47 -0700 Subject: [PATCH 213/644] Add InteractiveElement::block_mouse which renders an "opaque" layer Co-Authored-By: Antonio Co-Authored-By: Max Brunsfeld --- crates/gpui2/src/elements/div.rs | 20 ++++++++++++++++---- crates/workspace2/src/dock.rs | 3 ++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 54c0884870f64079ef16d1215d20b1e099646c4a..0c67d1648e8500718afb1a86516734dbf91cd156 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -345,6 +345,10 @@ impl Interactivity { ); self.tooltip_builder = Some(Rc::new(build_tooltip)); } + + pub fn block_mouse(&mut self) { + self.block_mouse = true; + } } pub trait InteractiveElement: Sized { @@ -564,6 +568,11 @@ pub trait InteractiveElement: Sized { self.interactivity().on_drop(listener); self } + + fn block_mouse(mut self) -> Self { + self.interactivity().block_mouse(); + self + } } pub trait StatefulInteractiveElement: InteractiveElement { @@ -888,6 +897,7 @@ pub struct Interactivity { pub drag_listener: Option<(Box, DragListener)>, pub hover_listener: Option>, pub tooltip_builder: Option, + pub block_mouse: bool, #[cfg(debug_assertions)] pub location: Option>, @@ -1076,10 +1086,11 @@ impl Interactivity { }); } - if style - .background - .as_ref() - .is_some_and(|fill| fill.color().is_some_and(|color| !color.is_transparent())) + if self.block_mouse + || style + .background + .as_ref() + .is_some_and(|fill| fill.color().is_some_and(|color| !color.is_transparent())) { cx.add_opaque_layer(bounds) } @@ -1642,6 +1653,7 @@ impl Default for Interactivity { drag_listener: None, hover_listener: None, tooltip_builder: None, + block_mouse: false, #[cfg(debug_assertions)] location: None, diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index d0aba998b97895ae62359714f19522de6b2dadba..82f00da6f9b436d6f398dc5ebc553c9d2e7f2c87 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -499,7 +499,8 @@ impl Render for Dock { cx.stop_propagation(); } })) - .z_index(1); + .z_index(1) + .block_mouse(); const HANDLE_SIZE: Pixels = Pixels(6.); From b0b4610a73f014333935bc72e954e2bd706d7521 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 13:05:21 -0500 Subject: [PATCH 214/644] Fix positioning of right items --- crates/collab_ui2/src/notification_panel.rs | 31 ++++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/crates/collab_ui2/src/notification_panel.rs b/crates/collab_ui2/src/notification_panel.rs index e13d4bbe793e74959f032156ff4c34de84187361..f3df2fc1d39396d780e6b54170a7ad516aaea3e1 100644 --- a/crates/collab_ui2/src/notification_panel.rs +++ b/crates/collab_ui2/src/notification_panel.rs @@ -227,9 +227,13 @@ impl NotificationPanel { } Some( - h_stack() + div() .id(ix) + .flex() + .flex_row() .size_full() + .px_2() + .py_1() .gap_2() .when(can_navigate, |el| { el.cursor(CursorStyle::PointingHand).on_click({ @@ -239,9 +243,13 @@ impl NotificationPanel { }) }) }) - .children( - actor.map(|actor| img(actor.avatar_uri.clone()).w_8().h_8().rounded_full()), - ) + .children(actor.map(|actor| { + img(actor.avatar_uri.clone()) + .flex_none() + .w_8() + .h_8() + .rounded_full() + })) .child( v_stack() .gap_1() @@ -249,7 +257,6 @@ impl NotificationPanel { .child(Label::new(text.clone())) .child( h_stack() - .justify_between() .child( Label::new(format_timestamp( timestamp, @@ -259,14 +266,18 @@ impl NotificationPanel { .color(Color::Muted), ) .children(if let Some(is_accepted) = response { - Some(div().child(Label::new(if is_accepted { - "You accepted" - } else { - "You declined" - }))) + Some(div().flex().flex_grow().justify_end().child(Label::new( + if is_accepted { + "You accepted" + } else { + "You declined" + }, + ))) } else if needs_response { Some( h_stack() + .flex_grow() + .justify_end() .child(Button::new("decline", "Decline").on_click({ let notification = notification.clone(); let view = cx.view().clone(); From 4c0856e09679cea31e9cc8d5a5f05fe97e82d7f9 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 20 Dec 2023 13:15:44 -0500 Subject: [PATCH 215/644] collab 0.32.0 --- Cargo.lock | 2 +- crates/collab/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c73484b16d9d32ec5c865ad480dd03e196b60de5..af4d5317e8380e1e8b6afba2d20ff0234f28bfa2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1753,7 +1753,7 @@ dependencies = [ [[package]] name = "collab" -version = "0.31.0" +version = "0.32.0" dependencies = [ "anyhow", "async-trait", diff --git a/crates/collab/Cargo.toml b/crates/collab/Cargo.toml index fd5c183d2af600fd7ea385072bfc1bf8fae19557..7bab81c4ed5e8b5b70a7170840d6d1d77fcaa7cc 100644 --- a/crates/collab/Cargo.toml +++ b/crates/collab/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Nathan Sobo "] default-run = "collab" edition = "2021" name = "collab" -version = "0.31.0" +version = "0.32.0" publish = false [[bin]] From da34dd49bbb648d8e696098e80ed9f2d39b5c58f Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 13:25:17 -0500 Subject: [PATCH 216/644] Fix text wrapping issues with `overflow_hidden` This seems to influence sizing calculations in ways I don't fully understand. --- crates/collab_ui2/src/notification_panel.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/collab_ui2/src/notification_panel.rs b/crates/collab_ui2/src/notification_panel.rs index f3df2fc1d39396d780e6b54170a7ad516aaea3e1..20951b34dbc34fbc007badbe6226c0f6f80bdfad 100644 --- a/crates/collab_ui2/src/notification_panel.rs +++ b/crates/collab_ui2/src/notification_panel.rs @@ -254,6 +254,7 @@ impl NotificationPanel { v_stack() .gap_1() .size_full() + .overflow_hidden() .child(Label::new(text.clone())) .child( h_stack() From 15f16f08d986613802678eece12f2bcec35d6865 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 11:43:45 -0700 Subject: [PATCH 217/644] Move application of content mask and z-index into Interactivity::paint This allows the content mask to correctly apply to bounds used in event handlers, which prevents content under opaque borders from being hovered in overflow hidden containers. Co-Authored-By: Antonio Co-Authored-By: Max Brunsfeld --- crates/gpui2/src/elements/div.rs | 1005 +++++++++++---------- crates/gpui2/src/elements/uniform_list.rs | 90 +- crates/gpui2/src/style.rs | 139 +-- crates/workspace2/src/dock.rs | 1 + 4 files changed, 637 insertions(+), 598 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 0c67d1648e8500718afb1a86516734dbf91cd156..e51c8b2a2eab75ff33eaab746eddbfb250ef12d6 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -826,17 +826,11 @@ impl Element for Div { content_size, &mut element_state.interactive_state, cx, - |style, scroll_offset, cx| { - style.paint(bounds, cx, |cx| { - cx.with_text_style(style.text_style().cloned(), |cx| { - cx.with_content_mask(style.overflow_mask(bounds), |cx| { - cx.with_element_offset(scroll_offset, |cx| { - for child in &mut self.children { - child.paint(cx); - } - }) - }) - }) + |_style, scroll_offset, cx| { + cx.with_element_offset(scroll_offset, |cx| { + for child in &mut self.children { + child.paint(cx); + } }) }, ); @@ -965,7 +959,7 @@ impl Interactivity { content_size: Size, element_state: &mut InteractiveElementState, cx: &mut WindowContext, - f: impl FnOnce(Style, Point, &mut WindowContext), + f: impl FnOnce(&Style, Point, &mut WindowContext), ) { let style = self.compute_style(Some(bounds), element_state, cx); @@ -975,552 +969,571 @@ impl Interactivity { let z_index = style.z_index.unwrap_or(0); cx.with_z_index(z_index, |cx| { - #[cfg(debug_assertions)] - if self.element_id.is_some() - && (style.debug || style.debug_below || cx.has_global::()) - && bounds.contains(&cx.mouse_position()) - { - const FONT_SIZE: crate::Pixels = crate::Pixels(10.); - let element_id = format!("{:?}", self.element_id.as_ref().unwrap()); - let str_len = element_id.len(); - - let render_debug_text = |cx: &mut WindowContext| { - if let Some(text) = cx - .text_system() - .shape_text( - &element_id, - FONT_SIZE, - &[cx.text_style().to_run(str_len)], - None, - ) - .ok() - .map(|mut text| text.pop()) - .flatten() - { - text.paint(bounds.origin, FONT_SIZE, cx).ok(); - - let text_bounds = crate::Bounds { - origin: bounds.origin, - size: text.size(FONT_SIZE), - }; - if self.location.is_some() - && text_bounds.contains(&cx.mouse_position()) - && cx.modifiers().command + style.paint(bounds, cx, |cx| { + cx.with_text_style(style.text_style().cloned(), |cx| { + cx.with_content_mask(style.overflow_mask(bounds, cx.rem_size()), |cx| { + #[cfg(debug_assertions)] + if self.element_id.is_some() + && (style.debug + || style.debug_below + || cx.has_global::()) + && bounds.contains(&cx.mouse_position()) { - let command_held = cx.modifiers().command; - cx.on_key_event({ - let text_bounds = text_bounds.clone(); - move |e: &crate::ModifiersChangedEvent, _phase, cx| { - if e.modifiers.command != command_held + const FONT_SIZE: crate::Pixels = crate::Pixels(10.); + let element_id = format!("{:?}", self.element_id.as_ref().unwrap()); + let str_len = element_id.len(); + + let render_debug_text = |cx: &mut WindowContext| { + if let Some(text) = cx + .text_system() + .shape_text( + &element_id, + FONT_SIZE, + &[cx.text_style().to_run(str_len)], + None, + ) + .ok() + .map(|mut text| text.pop()) + .flatten() + { + text.paint(bounds.origin, FONT_SIZE, cx).ok(); + + let text_bounds = crate::Bounds { + origin: bounds.origin, + size: text.size(FONT_SIZE), + }; + if self.location.is_some() && text_bounds.contains(&cx.mouse_position()) + && cx.modifiers().command { - cx.notify(); - } - } - }); - - let hovered = bounds.contains(&cx.mouse_position()); - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - if phase == DispatchPhase::Capture { - if bounds.contains(&event.position) != hovered { - cx.notify(); - } - } - }); - - cx.on_mouse_event({ - let location = self.location.clone().unwrap(); - let text_bounds = text_bounds.clone(); - move |e: &crate::MouseDownEvent, phase, cx| { - if text_bounds.contains(&e.position) && phase.capture() { - cx.stop_propagation(); - let Ok(dir) = std::env::current_dir() else { - return; - }; - - eprintln!( - "This element is created at:\n{}:{}:{}", - location.file(), - location.line(), - location.column() + let command_held = cx.modifiers().command; + cx.on_key_event({ + let text_bounds = text_bounds.clone(); + move |e: &crate::ModifiersChangedEvent, _phase, cx| { + if e.modifiers.command != command_held + && text_bounds.contains(&cx.mouse_position()) + { + cx.notify(); + } + } + }); + + let hovered = bounds.contains(&cx.mouse_position()); + cx.on_mouse_event( + move |event: &MouseMoveEvent, phase, cx| { + if phase == DispatchPhase::Capture { + if bounds.contains(&event.position) != hovered { + cx.notify(); + } + } + }, ); - std::process::Command::new("zed") - .arg(format!( - "{}/{}:{}:{}", - dir.to_string_lossy(), - location.file(), - location.line(), - location.column() - )) - .spawn() - .ok(); + cx.on_mouse_event({ + let location = self.location.clone().unwrap(); + let text_bounds = text_bounds.clone(); + move |e: &crate::MouseDownEvent, phase, cx| { + if text_bounds.contains(&e.position) + && phase.capture() + { + cx.stop_propagation(); + let Ok(dir) = std::env::current_dir() else { + return; + }; + + eprintln!( + "This element is created at:\n{}:{}:{}", + location.file(), + location.line(), + location.column() + ); + + std::process::Command::new("zed") + .arg(format!( + "{}/{}:{}:{}", + dir.to_string_lossy(), + location.file(), + location.line(), + location.column() + )) + .spawn() + .ok(); + } + } + }); + cx.paint_quad(crate::outline( + crate::Bounds { + origin: bounds.origin + + crate::point( + crate::px(0.), + FONT_SIZE - px(2.), + ), + size: crate::Size { + width: text_bounds.size.width, + height: crate::px(1.), + }, + }, + crate::red(), + )) } } + }; + + cx.with_z_index(1, |cx| { + cx.with_text_style( + Some(crate::TextStyleRefinement { + color: Some(crate::red()), + line_height: Some(FONT_SIZE.into()), + background_color: Some(crate::white()), + ..Default::default() + }), + render_debug_text, + ) }); - cx.paint_quad(crate::outline( - crate::Bounds { - origin: bounds.origin - + crate::point(crate::px(0.), FONT_SIZE - px(2.)), - size: crate::Size { - width: text_bounds.size.width, - height: crate::px(1.), - }, - }, - crate::red(), - )) } - } - }; - - cx.with_z_index(1, |cx| { - cx.with_text_style( - Some(crate::TextStyleRefinement { - color: Some(crate::red()), - line_height: Some(FONT_SIZE.into()), - background_color: Some(crate::white()), - ..Default::default() - }), - render_debug_text, - ) - }); - } - if self.block_mouse - || style - .background - .as_ref() - .is_some_and(|fill| fill.color().is_some_and(|color| !color.is_transparent())) - { - cx.add_opaque_layer(bounds) - } - - let interactive_bounds = InteractiveBounds { - bounds: bounds.intersect(&cx.content_mask().bounds), - stacking_order: cx.stacking_order().clone(), - }; - - if let Some(mouse_cursor) = style.mouse_cursor { - let mouse_position = &cx.mouse_position(); - let hovered = interactive_bounds.visibly_contains(mouse_position, cx); - if hovered { - cx.set_cursor_style(mouse_cursor); - } - } - - // If this element can be focused, register a mouse down listener - // that will automatically transfer focus when hitting the element. - // This behavior can be suppressed by using `cx.prevent_default()`. - if let Some(focus_handle) = element_state.focus_handle.clone() { - cx.on_mouse_event({ - let interactive_bounds = interactive_bounds.clone(); - move |event: &MouseDownEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && !cx.default_prevented() - && interactive_bounds.visibly_contains(&event.position, cx) + if self.block_mouse + || style.background.as_ref().is_some_and(|fill| { + fill.color().is_some_and(|color| !color.is_transparent()) + }) { - cx.focus(&focus_handle); - // If there is a parent that is also focusable, prevent it - // from transferring focus because we already did so. - cx.prevent_default(); + cx.add_opaque_layer(bounds) } - } - }); - } - for listener in self.mouse_down_listeners.drain(..) { - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| { - listener(event, &interactive_bounds, phase, cx); - }) - } + let interactive_bounds = InteractiveBounds { + bounds: bounds.intersect(&cx.content_mask().bounds), + stacking_order: cx.stacking_order().clone(), + }; - for listener in self.mouse_up_listeners.drain(..) { - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { - listener(event, &interactive_bounds, phase, cx); - }) - } + if let Some(mouse_cursor) = style.mouse_cursor { + let mouse_position = &cx.mouse_position(); + let hovered = interactive_bounds.visibly_contains(mouse_position, cx); + if hovered { + cx.set_cursor_style(mouse_cursor); + } + } - for listener in self.mouse_move_listeners.drain(..) { - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - listener(event, &interactive_bounds, phase, cx); - }) - } + // If this element can be focused, register a mouse down listener + // that will automatically transfer focus when hitting the element. + // This behavior can be suppressed by using `cx.prevent_default()`. + if let Some(focus_handle) = element_state.focus_handle.clone() { + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + move |event: &MouseDownEvent, phase, cx| { + if phase == DispatchPhase::Bubble + && !cx.default_prevented() + && interactive_bounds.visibly_contains(&event.position, cx) + { + cx.focus(&focus_handle); + // If there is a parent that is also focusable, prevent it + // from transferring focus because we already did so. + cx.prevent_default(); + } + } + }); + } - for listener in self.scroll_wheel_listeners.drain(..) { - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { - listener(event, &interactive_bounds, phase, cx); - }) - } + for listener in self.mouse_down_listeners.drain(..) { + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| { + listener(event, &interactive_bounds, phase, cx); + }) + } - let hover_group_bounds = self - .group_hover_style - .as_ref() - .and_then(|group_hover| GroupBounds::get(&group_hover.group, cx)); - - if let Some(group_bounds) = hover_group_bounds { - let hovered = group_bounds.contains(&cx.mouse_position()); - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - if phase == DispatchPhase::Capture { - if group_bounds.contains(&event.position) != hovered { - cx.notify(); + for listener in self.mouse_up_listeners.drain(..) { + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| { + listener(event, &interactive_bounds, phase, cx); + }) + } + + for listener in self.mouse_move_listeners.drain(..) { + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + listener(event, &interactive_bounds, phase, cx); + }) } - } - }); - } - if self.hover_style.is_some() - || self.base_style.mouse_cursor.is_some() - || cx.active_drag.is_some() && !self.drag_over_styles.is_empty() - { - let bounds = bounds.intersect(&cx.content_mask().bounds); - let hovered = bounds.contains(&cx.mouse_position()); - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - if phase == DispatchPhase::Capture { - if bounds.contains(&event.position) != hovered { - cx.notify(); + for listener in self.scroll_wheel_listeners.drain(..) { + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { + listener(event, &interactive_bounds, phase, cx); + }) } - } - }); - } - let mut drag_listener = mem::take(&mut self.drag_listener); - let drop_listeners = mem::take(&mut self.drop_listeners); - let click_listeners = mem::take(&mut self.click_listeners); - - if !drop_listeners.is_empty() { - cx.on_mouse_event({ - let interactive_bounds = interactive_bounds.clone(); - move |event: &MouseUpEvent, phase, cx| { - if let Some(drag) = &cx.active_drag { - if phase == DispatchPhase::Bubble - && interactive_bounds.drag_target_contains(&event.position, cx) - { - let drag_state_type = drag.value.as_ref().type_id(); - for (drop_state_type, listener) in &drop_listeners { - if *drop_state_type == drag_state_type { - let drag = cx - .active_drag - .take() - .expect("checked for type drag state type above"); - - listener(drag.value.as_ref(), cx); + let hover_group_bounds = self + .group_hover_style + .as_ref() + .and_then(|group_hover| GroupBounds::get(&group_hover.group, cx)); + + if let Some(group_bounds) = hover_group_bounds { + let hovered = group_bounds.contains(&cx.mouse_position()); + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + if phase == DispatchPhase::Capture { + if group_bounds.contains(&event.position) != hovered { cx.notify(); - cx.stop_propagation(); } } - } + }); } - } - }); - } - if !click_listeners.is_empty() || drag_listener.is_some() { - let pending_mouse_down = element_state - .pending_mouse_down - .get_or_insert_with(Default::default) - .clone(); - - let clicked_state = element_state - .clicked_state - .get_or_insert_with(Default::default) - .clone(); - - cx.on_mouse_event({ - let interactive_bounds = interactive_bounds.clone(); - let pending_mouse_down = pending_mouse_down.clone(); - move |event: &MouseDownEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && event.button == MouseButton::Left - && interactive_bounds.visibly_contains(&event.position, cx) + if self.hover_style.is_some() + || self.base_style.mouse_cursor.is_some() + || cx.active_drag.is_some() && !self.drag_over_styles.is_empty() { - *pending_mouse_down.borrow_mut() = Some(event.clone()); - cx.notify(); + let bounds = bounds.intersect(&cx.content_mask().bounds); + let hovered = bounds.contains(&cx.mouse_position()); + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + if phase == DispatchPhase::Capture { + if bounds.contains(&event.position) != hovered { + cx.notify(); + } + } + }); } - } - }); - cx.on_mouse_event({ - let pending_mouse_down = pending_mouse_down.clone(); - move |event: &MouseMoveEvent, phase, cx| { - if phase == DispatchPhase::Capture { - return; - } + let mut drag_listener = mem::take(&mut self.drag_listener); + let drop_listeners = mem::take(&mut self.drop_listeners); + let click_listeners = mem::take(&mut self.click_listeners); - let mut pending_mouse_down = pending_mouse_down.borrow_mut(); - if let Some(mouse_down) = pending_mouse_down.clone() { - if !cx.has_active_drag() - && (event.position - mouse_down.position).magnitude() - > DRAG_THRESHOLD - { - if let Some((drag_value, drag_listener)) = drag_listener.take() { - *clicked_state.borrow_mut() = ElementClickedState::default(); - let cursor_offset = event.position - bounds.origin; - let drag = (drag_listener)(drag_value.as_ref(), cx); - cx.active_drag = Some(AnyDrag { - view: drag, - value: drag_value, - cursor_offset, - }); - pending_mouse_down.take(); - cx.notify(); - cx.stop_propagation(); + if !drop_listeners.is_empty() { + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + move |event: &MouseUpEvent, phase, cx| { + if let Some(drag) = &cx.active_drag { + if phase == DispatchPhase::Bubble + && interactive_bounds + .drag_target_contains(&event.position, cx) + { + let drag_state_type = drag.value.as_ref().type_id(); + for (drop_state_type, listener) in &drop_listeners { + if *drop_state_type == drag_state_type { + let drag = cx.active_drag.take().expect( + "checked for type drag state type above", + ); + + listener(drag.value.as_ref(), cx); + cx.notify(); + cx.stop_propagation(); + } + } + } + } } - } + }); } - } - }); - cx.on_mouse_event({ - let interactive_bounds = interactive_bounds.clone(); - let mut captured_mouse_down = None; - move |event: &MouseUpEvent, phase, cx| match phase { - // Clear the pending mouse down during the capture phase, - // so that it happens even if another event handler stops - // propagation. - DispatchPhase::Capture => { - let mut pending_mouse_down = pending_mouse_down.borrow_mut(); - if pending_mouse_down.is_some() { - captured_mouse_down = pending_mouse_down.take(); - cx.notify(); - } - } - // Fire click handlers during the bubble phase. - DispatchPhase::Bubble => { - if let Some(mouse_down) = captured_mouse_down.take() { - if interactive_bounds.visibly_contains(&event.position, cx) { - let mouse_click = ClickEvent { - down: mouse_down, - up: event.clone(), - }; - for listener in &click_listeners { - listener(&mouse_click, cx); + if !click_listeners.is_empty() || drag_listener.is_some() { + let pending_mouse_down = element_state + .pending_mouse_down + .get_or_insert_with(Default::default) + .clone(); + + let clicked_state = element_state + .clicked_state + .get_or_insert_with(Default::default) + .clone(); + + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + let pending_mouse_down = pending_mouse_down.clone(); + move |event: &MouseDownEvent, phase, cx| { + if phase == DispatchPhase::Bubble + && event.button == MouseButton::Left + && interactive_bounds.visibly_contains(&event.position, cx) + { + *pending_mouse_down.borrow_mut() = Some(event.clone()); + cx.notify(); } } - } + }); + + cx.on_mouse_event({ + let pending_mouse_down = pending_mouse_down.clone(); + move |event: &MouseMoveEvent, phase, cx| { + if phase == DispatchPhase::Capture { + return; + } + + let mut pending_mouse_down = pending_mouse_down.borrow_mut(); + if let Some(mouse_down) = pending_mouse_down.clone() { + if !cx.has_active_drag() + && (event.position - mouse_down.position).magnitude() + > DRAG_THRESHOLD + { + if let Some((drag_value, drag_listener)) = + drag_listener.take() + { + *clicked_state.borrow_mut() = + ElementClickedState::default(); + let cursor_offset = event.position - bounds.origin; + let drag = (drag_listener)(drag_value.as_ref(), cx); + cx.active_drag = Some(AnyDrag { + view: drag, + value: drag_value, + cursor_offset, + }); + pending_mouse_down.take(); + cx.notify(); + cx.stop_propagation(); + } + } + } + } + }); + + cx.on_mouse_event({ + let interactive_bounds = interactive_bounds.clone(); + let mut captured_mouse_down = None; + move |event: &MouseUpEvent, phase, cx| match phase { + // Clear the pending mouse down during the capture phase, + // so that it happens even if another event handler stops + // propagation. + DispatchPhase::Capture => { + let mut pending_mouse_down = + pending_mouse_down.borrow_mut(); + if pending_mouse_down.is_some() { + captured_mouse_down = pending_mouse_down.take(); + cx.notify(); + } + } + // Fire click handlers during the bubble phase. + DispatchPhase::Bubble => { + if let Some(mouse_down) = captured_mouse_down.take() { + if interactive_bounds + .visibly_contains(&event.position, cx) + { + let mouse_click = ClickEvent { + down: mouse_down, + up: event.clone(), + }; + for listener in &click_listeners { + listener(&mouse_click, cx); + } + } + } + } + } + }); } - } - }); - } - if let Some(hover_listener) = self.hover_listener.take() { - let was_hovered = element_state - .hover_state - .get_or_insert_with(Default::default) - .clone(); - let has_mouse_down = element_state - .pending_mouse_down - .get_or_insert_with(Default::default) - .clone(); - let interactive_bounds = interactive_bounds.clone(); - - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - if phase != DispatchPhase::Bubble { - return; - } - let is_hovered = interactive_bounds.visibly_contains(&event.position, cx) - && !cx.has_active_drag() - && has_mouse_down.borrow().is_none(); - let mut was_hovered = was_hovered.borrow_mut(); + if let Some(hover_listener) = self.hover_listener.take() { + let was_hovered = element_state + .hover_state + .get_or_insert_with(Default::default) + .clone(); + let has_mouse_down = element_state + .pending_mouse_down + .get_or_insert_with(Default::default) + .clone(); + let interactive_bounds = interactive_bounds.clone(); + + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + if phase != DispatchPhase::Bubble { + return; + } + let is_hovered = interactive_bounds + .visibly_contains(&event.position, cx) + && !cx.has_active_drag() + && has_mouse_down.borrow().is_none(); + let mut was_hovered = was_hovered.borrow_mut(); - if is_hovered != was_hovered.clone() { - *was_hovered = is_hovered; - drop(was_hovered); + if is_hovered != was_hovered.clone() { + *was_hovered = is_hovered; + drop(was_hovered); - hover_listener(&is_hovered, cx); - } - }); - } + hover_listener(&is_hovered, cx); + } + }); + } - if let Some(tooltip_builder) = self.tooltip_builder.take() { - let active_tooltip = element_state - .active_tooltip - .get_or_insert_with(Default::default) - .clone(); - let pending_mouse_down = element_state - .pending_mouse_down - .get_or_insert_with(Default::default) - .clone(); - let interactive_bounds = interactive_bounds.clone(); - - cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { - let is_hovered = interactive_bounds.visibly_contains(&event.position, cx) - && pending_mouse_down.borrow().is_none(); - if !is_hovered { - active_tooltip.borrow_mut().take(); - return; - } + if let Some(tooltip_builder) = self.tooltip_builder.take() { + let active_tooltip = element_state + .active_tooltip + .get_or_insert_with(Default::default) + .clone(); + let pending_mouse_down = element_state + .pending_mouse_down + .get_or_insert_with(Default::default) + .clone(); + let interactive_bounds = interactive_bounds.clone(); - if phase != DispatchPhase::Bubble { - return; - } + cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| { + let is_hovered = interactive_bounds + .visibly_contains(&event.position, cx) + && pending_mouse_down.borrow().is_none(); + if !is_hovered { + active_tooltip.borrow_mut().take(); + return; + } - if active_tooltip.borrow().is_none() { - let task = cx.spawn({ - let active_tooltip = active_tooltip.clone(); - let tooltip_builder = tooltip_builder.clone(); + if phase != DispatchPhase::Bubble { + return; + } - move |mut cx| async move { - cx.background_executor().timer(TOOLTIP_DELAY).await; - cx.update(|_, cx| { + if active_tooltip.borrow().is_none() { + let task = cx.spawn({ + let active_tooltip = active_tooltip.clone(); + let tooltip_builder = tooltip_builder.clone(); + + move |mut cx| async move { + cx.background_executor().timer(TOOLTIP_DELAY).await; + cx.update(|_, cx| { + active_tooltip.borrow_mut().replace( + ActiveTooltip { + tooltip: Some(AnyTooltip { + view: tooltip_builder(cx), + cursor_offset: cx.mouse_position(), + }), + _task: None, + }, + ); + cx.notify(); + }) + .ok(); + } + }); active_tooltip.borrow_mut().replace(ActiveTooltip { - tooltip: Some(AnyTooltip { - view: tooltip_builder(cx), - cursor_offset: cx.mouse_position(), - }), - _task: None, + tooltip: None, + _task: Some(task), }); - cx.notify(); - }) - .ok(); - } - }); - active_tooltip.borrow_mut().replace(ActiveTooltip { - tooltip: None, - _task: Some(task), - }); - } - }); + } + }); - let active_tooltip = element_state - .active_tooltip - .get_or_insert_with(Default::default) - .clone(); - cx.on_mouse_event(move |_: &MouseDownEvent, _, _| { - active_tooltip.borrow_mut().take(); - }); + let active_tooltip = element_state + .active_tooltip + .get_or_insert_with(Default::default) + .clone(); + cx.on_mouse_event(move |_: &MouseDownEvent, _, _| { + active_tooltip.borrow_mut().take(); + }); - if let Some(active_tooltip) = element_state - .active_tooltip - .get_or_insert_with(Default::default) - .borrow() - .as_ref() - { - if active_tooltip.tooltip.is_some() { - cx.active_tooltip = active_tooltip.tooltip.clone() - } - } - } + if let Some(active_tooltip) = element_state + .active_tooltip + .get_or_insert_with(Default::default) + .borrow() + .as_ref() + { + if active_tooltip.tooltip.is_some() { + cx.active_tooltip = active_tooltip.tooltip.clone() + } + } + } - let clicked_state = element_state - .clicked_state - .get_or_insert_with(Default::default) - .clone(); - if clicked_state.borrow().is_clicked() { - cx.on_mouse_event(move |_: &MouseUpEvent, phase, cx| { - if phase == DispatchPhase::Capture { - *clicked_state.borrow_mut() = ElementClickedState::default(); - cx.notify(); - } - }); - } else { - let active_group_bounds = self - .group_active_style - .as_ref() - .and_then(|group_active| GroupBounds::get(&group_active.group, cx)); - let interactive_bounds = interactive_bounds.clone(); - cx.on_mouse_event(move |down: &MouseDownEvent, phase, cx| { - if phase == DispatchPhase::Bubble && !cx.default_prevented() { - let group = active_group_bounds - .map_or(false, |bounds| bounds.contains(&down.position)); - let element = interactive_bounds.visibly_contains(&down.position, cx); - if group || element { - *clicked_state.borrow_mut() = ElementClickedState { group, element }; - cx.notify(); + let clicked_state = element_state + .clicked_state + .get_or_insert_with(Default::default) + .clone(); + if clicked_state.borrow().is_clicked() { + cx.on_mouse_event(move |_: &MouseUpEvent, phase, cx| { + if phase == DispatchPhase::Capture { + *clicked_state.borrow_mut() = ElementClickedState::default(); + cx.notify(); + } + }); + } else { + let active_group_bounds = self + .group_active_style + .as_ref() + .and_then(|group_active| GroupBounds::get(&group_active.group, cx)); + let interactive_bounds = interactive_bounds.clone(); + cx.on_mouse_event(move |down: &MouseDownEvent, phase, cx| { + if phase == DispatchPhase::Bubble && !cx.default_prevented() { + let group = active_group_bounds + .map_or(false, |bounds| bounds.contains(&down.position)); + let element = + interactive_bounds.visibly_contains(&down.position, cx); + if group || element { + *clicked_state.borrow_mut() = + ElementClickedState { group, element }; + cx.notify(); + } + } + }); } - } - }); - } - let overflow = style.overflow; - if overflow.x == Overflow::Scroll || overflow.y == Overflow::Scroll { - if let Some(scroll_handle) = &self.scroll_handle { - scroll_handle.0.borrow_mut().overflow = overflow; - } + let overflow = style.overflow; + if overflow.x == Overflow::Scroll || overflow.y == Overflow::Scroll { + if let Some(scroll_handle) = &self.scroll_handle { + scroll_handle.0.borrow_mut().overflow = overflow; + } - let scroll_offset = element_state - .scroll_offset - .get_or_insert_with(Rc::default) - .clone(); - let line_height = cx.line_height(); - let scroll_max = (content_size - bounds.size).max(&Size::default()); - let interactive_bounds = interactive_bounds.clone(); - - cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { - if phase == DispatchPhase::Bubble - && interactive_bounds.visibly_contains(&event.position, cx) - { - let mut scroll_offset = scroll_offset.borrow_mut(); - let old_scroll_offset = *scroll_offset; - let delta = event.delta.pixel_delta(line_height); + let scroll_offset = element_state + .scroll_offset + .get_or_insert_with(Rc::default) + .clone(); + let line_height = cx.line_height(); + let scroll_max = (content_size - bounds.size).max(&Size::default()); + let interactive_bounds = interactive_bounds.clone(); + + cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { + if phase == DispatchPhase::Bubble + && interactive_bounds.visibly_contains(&event.position, cx) + { + let mut scroll_offset = scroll_offset.borrow_mut(); + let old_scroll_offset = *scroll_offset; + let delta = event.delta.pixel_delta(line_height); + + if overflow.x == Overflow::Scroll { + scroll_offset.x = (scroll_offset.x + delta.x) + .clamp(-scroll_max.width, px(0.)); + } - if overflow.x == Overflow::Scroll { - scroll_offset.x = - (scroll_offset.x + delta.x).clamp(-scroll_max.width, px(0.)); - } + if overflow.y == Overflow::Scroll { + scroll_offset.y = (scroll_offset.y + delta.y) + .clamp(-scroll_max.height, px(0.)); + } - if overflow.y == Overflow::Scroll { - scroll_offset.y = - (scroll_offset.y + delta.y).clamp(-scroll_max.height, px(0.)); + if *scroll_offset != old_scroll_offset { + cx.notify(); + cx.stop_propagation(); + } + } + }); } - if *scroll_offset != old_scroll_offset { - cx.notify(); - cx.stop_propagation(); + if let Some(group) = self.group.clone() { + GroupBounds::push(group, bounds, cx); } - } - }); - } - if let Some(group) = self.group.clone() { - GroupBounds::push(group, bounds, cx); - } + let scroll_offset = element_state + .scroll_offset + .as_ref() + .map(|scroll_offset| *scroll_offset.borrow()); + + let key_down_listeners = mem::take(&mut self.key_down_listeners); + let key_up_listeners = mem::take(&mut self.key_up_listeners); + let action_listeners = mem::take(&mut self.action_listeners); + cx.with_key_dispatch( + self.key_context.clone(), + element_state.focus_handle.clone(), + |_, cx| { + for listener in key_down_listeners { + cx.on_key_event(move |event: &KeyDownEvent, phase, cx| { + listener(event, phase, cx); + }) + } - let scroll_offset = element_state - .scroll_offset - .as_ref() - .map(|scroll_offset| *scroll_offset.borrow()); - - let key_down_listeners = mem::take(&mut self.key_down_listeners); - let key_up_listeners = mem::take(&mut self.key_up_listeners); - let action_listeners = mem::take(&mut self.action_listeners); - cx.with_key_dispatch( - self.key_context.clone(), - element_state.focus_handle.clone(), - |_, cx| { - for listener in key_down_listeners { - cx.on_key_event(move |event: &KeyDownEvent, phase, cx| { - listener(event, phase, cx); - }) - } + for listener in key_up_listeners { + cx.on_key_event(move |event: &KeyUpEvent, phase, cx| { + listener(event, phase, cx); + }) + } - for listener in key_up_listeners { - cx.on_key_event(move |event: &KeyUpEvent, phase, cx| { - listener(event, phase, cx); - }) - } + for (action_type, listener) in action_listeners { + cx.on_action(action_type, listener) + } - for (action_type, listener) in action_listeners { - cx.on_action(action_type, listener) - } + f(&style, scroll_offset.unwrap_or_default(), cx) + }, + ); - cx.with_z_index(style.z_index.unwrap_or(0), |cx| { - if style.background.as_ref().is_some_and(|fill| { - fill.color().is_some_and(|color| !color.is_transparent()) - }) { - cx.add_opaque_layer(bounds) + if let Some(group) = self.group.as_ref() { + GroupBounds::pop(group, cx); } - f(style, scroll_offset.unwrap_or_default(), cx) - }) - }, - ); - - if let Some(group) = self.group.as_ref() { - GroupBounds::pop(group, cx); - } + }); + }); + }); }); } diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 7fba7ef47777553ae6e5e36ab8e20f5e01869360..53d8a3cb95f9d72592c7ea33ac5a87476499b51d 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -200,54 +200,52 @@ impl Element for UniformList { bounds.lower_right() - point(border.right + padding.right, border.bottom), ); - style.paint(bounds, cx, |cx| { - if self.item_count > 0 { - let content_height = - item_height * self.item_count + padding.top + padding.bottom; - let min_scroll_offset = padded_bounds.size.height - content_height; - let is_scrolled = scroll_offset.y != px(0.); - - if is_scrolled && scroll_offset.y < min_scroll_offset { - shared_scroll_offset.borrow_mut().y = min_scroll_offset; - scroll_offset.y = min_scroll_offset; - } - - if let Some(scroll_handle) = self.scroll_handle.clone() { - scroll_handle.0.borrow_mut().replace(ScrollHandleState { - item_height, - list_height: padded_bounds.size.height, - scroll_offset: shared_scroll_offset, - }); - } - - let first_visible_element_ix = - (-(scroll_offset.y + padding.top) / item_height).floor() as usize; - let last_visible_element_ix = - ((-scroll_offset.y + padded_bounds.size.height) / item_height).ceil() - as usize; - let visible_range = first_visible_element_ix - ..cmp::min(last_visible_element_ix, self.item_count); - - let mut items = (self.render_items)(visible_range.clone(), cx); - cx.with_z_index(1, |cx| { - let content_mask = ContentMask { bounds }; - cx.with_content_mask(Some(content_mask), |cx| { - for (item, ix) in items.iter_mut().zip(visible_range) { - let item_origin = padded_bounds.origin - + point( - px(0.), - item_height * ix + scroll_offset.y + padding.top, - ); - let available_space = size( - AvailableSpace::Definite(padded_bounds.size.width), - AvailableSpace::Definite(item_height), - ); - item.draw(item_origin, available_space, cx); - } - }); + if self.item_count > 0 { + let content_height = + item_height * self.item_count + padding.top + padding.bottom; + let min_scroll_offset = padded_bounds.size.height - content_height; + let is_scrolled = scroll_offset.y != px(0.); + + if is_scrolled && scroll_offset.y < min_scroll_offset { + shared_scroll_offset.borrow_mut().y = min_scroll_offset; + scroll_offset.y = min_scroll_offset; + } + + if let Some(scroll_handle) = self.scroll_handle.clone() { + scroll_handle.0.borrow_mut().replace(ScrollHandleState { + item_height, + list_height: padded_bounds.size.height, + scroll_offset: shared_scroll_offset, }); } - }); + + let first_visible_element_ix = + (-(scroll_offset.y + padding.top) / item_height).floor() as usize; + let last_visible_element_ix = ((-scroll_offset.y + padded_bounds.size.height) + / item_height) + .ceil() as usize; + let visible_range = first_visible_element_ix + ..cmp::min(last_visible_element_ix, self.item_count); + + let mut items = (self.render_items)(visible_range.clone(), cx); + cx.with_z_index(1, |cx| { + let content_mask = ContentMask { bounds }; + cx.with_content_mask(Some(content_mask), |cx| { + for (item, ix) in items.iter_mut().zip(visible_range) { + let item_origin = padded_bounds.origin + + point( + px(0.), + item_height * ix + scroll_offset.y + padding.top, + ); + let available_space = size( + AvailableSpace::Definite(padded_bounds.size.width), + AvailableSpace::Definite(item_height), + ); + item.draw(item_origin, available_space, cx); + } + }); + }); + } }, ) } diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index f777e2d8cf2b950fb1770810d38e18b383745229..89527c9d5a7faa410630d0eb7118ce9d9009cdca 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -258,16 +258,30 @@ impl Style { } } - pub fn overflow_mask(&self, bounds: Bounds) -> Option> { + pub fn overflow_mask( + &self, + bounds: Bounds, + rem_size: Pixels, + ) -> Option> { match self.overflow { Point { x: Overflow::Visible, y: Overflow::Visible, } => None, _ => { - let current_mask = bounds; - let min = current_mask.origin; - let max = current_mask.lower_right(); + let mut min = bounds.origin; + let mut max = bounds.lower_right(); + + if self + .border_color + .map_or(false, |color| !color.is_transparent()) + { + min.x += self.border_widths.left.to_pixels(rem_size); + max.x -= self.border_widths.right.to_pixels(rem_size); + min.y += self.border_widths.top.to_pixels(rem_size); + max.y -= self.border_widths.bottom.to_pixels(rem_size); + } + let bounds = match ( self.overflow.x == Overflow::Visible, self.overflow.y == Overflow::Visible, @@ -285,61 +299,62 @@ impl Style { point(bounds.lower_right().x, max.y), ), // both hidden - (false, false) => bounds, + (false, false) => Bounds::from_corners(min, max), }; + Some(ContentMask { bounds }) } } } - pub fn apply_text_style(&self, cx: &mut C, f: F) -> R - where - C: BorrowAppContext, - F: FnOnce(&mut C) -> R, - { - if self.text.is_some() { - cx.with_text_style(Some(self.text.clone()), f) - } else { - f(cx) - } - } - - /// Apply overflow to content mask - pub fn apply_overflow(&self, bounds: Bounds, cx: &mut C, f: F) -> R - where - C: BorrowWindow, - F: FnOnce(&mut C) -> R, - { - let current_mask = cx.content_mask(); - - let min = current_mask.bounds.origin; - let max = current_mask.bounds.lower_right(); - - let mask_bounds = match ( - self.overflow.x == Overflow::Visible, - self.overflow.y == Overflow::Visible, - ) { - // x and y both visible - (true, true) => return f(cx), - // x visible, y hidden - (true, false) => Bounds::from_corners( - point(min.x, bounds.origin.y), - point(max.x, bounds.lower_right().y), - ), - // x hidden, y visible - (false, true) => Bounds::from_corners( - point(bounds.origin.x, min.y), - point(bounds.lower_right().x, max.y), - ), - // both hidden - (false, false) => bounds, - }; - let mask = ContentMask { - bounds: mask_bounds, - }; - - cx.with_content_mask(Some(mask), f) - } + // pub fn apply_text_style(&self, cx: &mut C, f: F) -> R + // where + // C: BorrowAppContext, + // F: FnOnce(&mut C) -> R, + // { + // if self.text.is_some() { + // cx.with_text_style(Some(self.text.clone()), f) + // } else { + // f(cx) + // } + // } + + // /// Apply overflow to content mask + // pub fn apply_overflow(&self, bounds: Bounds, cx: &mut C, f: F) -> R + // where + // C: BorrowWindow, + // F: FnOnce(&mut C) -> R, + // { + // let current_mask = cx.content_mask(); + + // let min = current_mask.bounds.origin; + // let max = current_mask.bounds.lower_right(); + + // let mask_bounds = match ( + // self.overflow.x == Overflow::Visible, + // self.overflow.y == Overflow::Visible, + // ) { + // // x and y both visible + // (true, true) => return f(cx), + // // x visible, y hidden + // (true, false) => Bounds::from_corners( + // point(min.x, bounds.origin.y), + // point(max.x, bounds.lower_right().y), + // ), + // // x hidden, y visible + // (false, true) => Bounds::from_corners( + // point(bounds.origin.x, min.y), + // point(bounds.lower_right().x, max.y), + // ), + // // both hidden + // (false, false) => bounds, + // }; + // let mask = ContentMask { + // bounds: mask_bounds, + // }; + + // cx.with_content_mask(Some(mask), f) + // } /// Paints the background of an element styled with this style. pub fn paint( @@ -369,14 +384,14 @@ impl Style { }); let background_color = self.background.as_ref().and_then(Fill::color); - if background_color.is_some() || self.is_border_visible() { + if background_color.is_some() { cx.with_z_index(1, |cx| { cx.paint_quad(quad( bounds, self.corner_radii.to_pixels(bounds.size, rem_size), background_color.unwrap_or_default(), - self.border_widths.to_pixels(rem_size), - self.border_color.unwrap_or_default(), + Edges::default(), + Hsla::transparent_black(), )); }); } @@ -385,6 +400,18 @@ impl Style { continuation(cx); }); + if self.is_border_visible() { + cx.with_z_index(3, |cx| { + cx.paint_quad(quad( + bounds, + self.corner_radii.to_pixels(bounds.size, rem_size), + Hsla::transparent_black(), + self.border_widths.to_pixels(rem_size), + self.border_color.unwrap_or_default(), + )); + }); + } + #[cfg(debug_assertions)] if self.debug_below { cx.remove_global::(); diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 82f00da6f9b436d6f398dc5ebc553c9d2e7f2c87..e59d7ee49492e8361223d6d3ccf8457913cf965b 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -537,6 +537,7 @@ impl Render for Dock { div() .flex() .border_color(cx.theme().colors().border) + .overflow_hidden() .map(|this| match self.position().axis() { Axis::Horizontal => this.w(px(size)).h_full().flex_row(), Axis::Vertical => this.h(px(size)).w_full().flex_col(), From 26fb67b3e4ab900fcf328d1b459a2d69ac8f578b Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 20 Dec 2023 20:38:37 +0100 Subject: [PATCH 218/644] chore: Remove 'db' dependency from recent_projects2 (#3740) It was pulling in gpui1 into zed2 build. Release Notes: - N/A --- Cargo.lock | 1 - crates/recent_projects2/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af4d5317e8380e1e8b6afba2d20ff0234f28bfa2..bd0a86d16128c219047e2ea3b47548534192d1a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7481,7 +7481,6 @@ dependencies = [ name = "recent_projects2" version = "0.1.0" dependencies = [ - "db", "editor2", "futures 0.3.28", "fuzzy2", diff --git a/crates/recent_projects2/Cargo.toml b/crates/recent_projects2/Cargo.toml index 3d10c147e0ae69ed257d3787618496c904fe823a..46854ab4e8b9787a237d38644cd776732d8202f5 100644 --- a/crates/recent_projects2/Cargo.toml +++ b/crates/recent_projects2/Cargo.toml @@ -9,7 +9,6 @@ path = "src/recent_projects.rs" doctest = false [dependencies] -db = { path = "../db" } editor = { package = "editor2", path = "../editor2" } fuzzy = { package = "fuzzy2", path = "../fuzzy2" } gpui = { package = "gpui2", path = "../gpui2" } From 9acb5825e66f694406a52f3757faa6d203998dff Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 13:00:52 -0700 Subject: [PATCH 219/644] Compute the query editor placeholder text with a focus handle So we're not beholden to the current focus. --- crates/editor2/src/editor.rs | 7 +++++-- crates/editor2/src/element.rs | 3 ++- crates/search2/src/buffer_search.rs | 5 +++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 58f8e857a9a167219b5e1cdeec5a2bbb1b5b62f9..aa627db2a3baa08764f8d8569c65a9cee638ffed 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -2003,8 +2003,11 @@ impl Editor { placeholder_text: impl Into>, cx: &mut ViewContext, ) { - self.placeholder_text = Some(placeholder_text.into()); - cx.notify(); + let placeholder_text = Some(placeholder_text.into()); + if self.placeholder_text != placeholder_text { + self.placeholder_text = placeholder_text; + cx.notify(); + } } pub fn set_cursor_shape(&mut self, cursor_shape: CursorShape, cx: &mut ViewContext) { diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 8031bc5db60923b2470f723035c4df801cdd164e..9dab9d00aec20e6b4763d56713ec8514174efa1e 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -1722,11 +1722,12 @@ impl EditorElement { return Vec::new(); } - // When the editor is empty and unfocused, then show the placeholder. + // Show the placeholder when the editor is empty if snapshot.is_empty() { let font_size = self.style.text.font_size.to_pixels(cx.rem_size()); let placeholder_color = cx.theme().styles.colors.text_placeholder; let placeholder_text = snapshot.placeholder_text(); + let placeholder_lines = placeholder_text .as_ref() .map_or("", AsRef::as_ref) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index ebaf111e6061c9b9ca032774c9fd1c85f31b552f..f84db72c13f224e7fdcb56f7b78a7f6d193f6370 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -113,8 +113,9 @@ impl Render for BufferSearchBar { } let supported_options = self.supported_options(); + let query_focus_handle = self.query_editor.focus_handle(cx); let previous_query_keystrokes = cx - .bindings_for_action(&PreviousHistoryQuery {}) + .bindings_for_action_in(&PreviousHistoryQuery {}, &query_focus_handle) .into_iter() .next() .map(|binding| { @@ -125,7 +126,7 @@ impl Render for BufferSearchBar { .collect::>() }); let next_query_keystrokes = cx - .bindings_for_action(&NextHistoryQuery {}) + .bindings_for_action_in(&NextHistoryQuery {}, &query_focus_handle) .into_iter() .next() .map(|binding| { From 9a06b7e77d1e795c4e0b505ec8b7412574154f7f Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 15:59:01 -0500 Subject: [PATCH 220/644] Style incoming call notifications --- .../incoming_call_notification.rs | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/crates/collab_ui2/src/notifications/incoming_call_notification.rs b/crates/collab_ui2/src/notifications/incoming_call_notification.rs index 53ff51d1cd8bd641cd46b90a508616968fa4de80..d5bdf4ff446887cd69cfe96676aec6964b9e0c24 100644 --- a/crates/collab_ui2/src/notifications/incoming_call_notification.rs +++ b/crates/collab_ui2/src/notifications/incoming_call_notification.rs @@ -2,12 +2,14 @@ use crate::notification_window_options; use call::{ActiveCall, IncomingCall}; use futures::StreamExt; use gpui::{ - div, px, red, AppContext, Div, Element, ParentElement, Render, RenderOnce, Styled, ViewContext, + img, px, AppContext, Div, ParentElement, Render, RenderOnce, Styled, ViewContext, VisualContext as _, WindowHandle, }; +use settings::Settings; use std::sync::{Arc, Weak}; +use theme::ThemeSettings; use ui::prelude::*; -use ui::{h_stack, v_stack, Avatar, Button, Label}; +use ui::{h_stack, v_stack, Button, Label}; use util::ResultExt; use workspace::AppState; @@ -112,36 +114,52 @@ impl IncomingCallNotification { state: Arc::new(IncomingCallNotificationState::new(call, app_state)), } } - fn render_caller(&self, cx: &mut ViewContext) -> impl Element { - h_stack() - .child(Avatar::new(self.state.call.calling_user.avatar_uri.clone())) - .child( - v_stack() - .child(Label::new(format!( - "{} is sharing a project in Zed", - self.state.call.calling_user.github_login - ))) - .child(self.render_buttons(cx)), - ) - } - - fn render_buttons(&self, cx: &mut ViewContext) -> impl Element { - h_stack() - .child(Button::new("accept", "Accept").render(cx).on_click({ - let state = self.state.clone(); - move |_, cx| state.respond(true, cx) - })) - .child(Button::new("decline", "Decline").render(cx).on_click({ - let state = self.state.clone(); - move |_, cx| state.respond(false, cx) - })) - } } impl Render for IncomingCallNotification { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - div().bg(red()).flex_none().child(self.render_caller(cx)) + // TODO: Is there a better place for us to initialize the font? + let (ui_font, ui_font_size) = { + let theme_settings = ThemeSettings::get_global(cx); + ( + theme_settings.ui_font.family.clone(), + theme_settings.ui_font_size.clone(), + ) + }; + + cx.set_rem_size(ui_font_size); + + h_stack() + .font(ui_font) + .text_ui() + .justify_between() + .size_full() + .overflow_hidden() + .elevation_3(cx) + .p_2() + .gap_2() + .child( + img(self.state.call.calling_user.avatar_uri.clone()) + .w_12() + .h_12() + .rounded_full(), + ) + .child(v_stack().overflow_hidden().child(Label::new(format!( + "{} is sharing a project in Zed", + self.state.call.calling_user.github_login + )))) + .child( + v_stack() + .child(Button::new("accept", "Accept").render(cx).on_click({ + let state = self.state.clone(); + move |_, cx| state.respond(true, cx) + })) + .child(Button::new("decline", "Decline").render(cx).on_click({ + let state = self.state.clone(); + move |_, cx| state.respond(false, cx) + })), + ) } } From 7b51f738267a0245d6a96b9c5f9f89f852fbc837 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 16:06:59 -0500 Subject: [PATCH 221/644] Tighten up project share notifications --- .../project_shared_notification.rs | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/crates/collab_ui2/src/notifications/project_shared_notification.rs b/crates/collab_ui2/src/notifications/project_shared_notification.rs index 2dc0dee6f47e8a9dfc4dcf9fef957cc75147a3d2..707e961423472ddb8b032a253bb20ff66f2adbaa 100644 --- a/crates/collab_ui2/src/notifications/project_shared_notification.rs +++ b/crates/collab_ui2/src/notifications/project_shared_notification.rs @@ -23,7 +23,7 @@ pub fn init(app_state: &Arc, cx: &mut AppContext) { } => { let window_size = Size { width: px(400.), - height: px(96.), + height: px(72.), }; for screen in cx.displays() { @@ -139,35 +139,33 @@ impl Render for ProjectSharedNotification { .text_ui() .justify_between() .size_full() + .overflow_hidden() .elevation_3(cx) .p_2() .gap_2() .child( - h_stack() - .gap_2() - .child( - img(self.owner.avatar_uri.clone()) - .w_16() - .h_16() - .rounded_full(), - ) - .child( - v_stack() - .child(Label::new(self.owner.github_login.clone())) - .child(Label::new(format!( - "is sharing a project in Zed{}", - if self.worktree_root_names.is_empty() { - "" - } else { - ":" - } - ))) - .children(if self.worktree_root_names.is_empty() { - None - } else { - Some(Label::new(self.worktree_root_names.join(", "))) - }), - ), + img(self.owner.avatar_uri.clone()) + .w_12() + .h_12() + .rounded_full(), + ) + .child( + v_stack() + .overflow_hidden() + .child(Label::new(self.owner.github_login.clone())) + .child(Label::new(format!( + "is sharing a project in Zed{}", + if self.worktree_root_names.is_empty() { + "" + } else { + ":" + } + ))) + .children(if self.worktree_root_names.is_empty() { + None + } else { + Some(Label::new(self.worktree_root_names.join(", "))) + }), ) .child( v_stack() From d499cccebb02257d43eef8345d283370fb3d549d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 14:47:56 -0700 Subject: [PATCH 222/644] Only compute placeholder text once --- crates/editor2/src/editor.rs | 4 ++ crates/search2/src/buffer_search.rs | 97 +++++++++++++---------------- 2 files changed, 48 insertions(+), 53 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index aa627db2a3baa08764f8d8569c65a9cee638ffed..cb607a7e6c16a23b6294907ce1715e3ad9e75513 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -1998,6 +1998,10 @@ impl Editor { self.collaboration_hub = Some(hub); } + pub fn placeholder_text(&self) -> Option<&str> { + self.placeholder_text.as_deref() + } + pub fn set_placeholder_text( &mut self, placeholder_text: impl Into>, diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index f84db72c13f224e7fdcb56f7b78a7f6d193f6370..5b4113aee2eef1a9e7b602e74f0479e23df4bdf4 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -102,66 +102,57 @@ impl EventEmitter for BufferSearchBar {} impl EventEmitter for BufferSearchBar {} impl Render for BufferSearchBar { type Element = Div; + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - // let query_container_style = if self.query_contains_error { - // theme.search.invalid_editor - // } else { - // theme.search.editor.input.container - // }; if self.dismissed { return div(); } + let supported_options = self.supported_options(); - let query_focus_handle = self.query_editor.focus_handle(cx); - let previous_query_keystrokes = cx - .bindings_for_action_in(&PreviousHistoryQuery {}, &query_focus_handle) - .into_iter() - .next() - .map(|binding| { - binding - .keystrokes() - .iter() - .map(|k| k.to_string()) - .collect::>() - }); - let next_query_keystrokes = cx - .bindings_for_action_in(&NextHistoryQuery {}, &query_focus_handle) - .into_iter() - .next() - .map(|binding| { - binding - .keystrokes() - .iter() - .map(|k| k.to_string()) - .collect::>() - }); - let new_placeholder_text = match (previous_query_keystrokes, next_query_keystrokes) { - (Some(previous_query_keystrokes), Some(next_query_keystrokes)) => { - format!( - "Search ({}/{} for previous/next query)", - previous_query_keystrokes.join(" "), - next_query_keystrokes.join(" ") - ) - } - (None, Some(next_query_keystrokes)) => { - format!( - "Search ({} for next query)", - next_query_keystrokes.join(" ") - ) - } - (Some(previous_query_keystrokes), None) => { - format!( - "Search ({} for previous query)", - previous_query_keystrokes.join(" ") - ) + if self.query_editor.read(cx).placeholder_text().is_none() { + let query_focus_handle = self.query_editor.focus_handle(cx); + let up_keystrokes = cx + .bindings_for_action_in(&PreviousHistoryQuery {}, &query_focus_handle) + .into_iter() + .next() + .map(|binding| { + binding + .keystrokes() + .iter() + .map(|k| k.to_string()) + .collect::>() + }); + let down_keystrokes = cx + .bindings_for_action_in(&NextHistoryQuery {}, &query_focus_handle) + .into_iter() + .next() + .map(|binding| { + binding + .keystrokes() + .iter() + .map(|k| k.to_string()) + .collect::>() + }); + + let placeholder_text = + up_keystrokes + .zip(down_keystrokes) + .map(|(up_keystrokes, down_keystrokes)| { + Arc::from(format!( + "Search ({}/{} for previous/next query)", + up_keystrokes.join(" "), + down_keystrokes.join(" ") + )) + }); + + if let Some(placeholder_text) = placeholder_text { + self.query_editor.update(cx, |editor, cx| { + editor.set_placeholder_text(placeholder_text, cx); + }); } - (None, None) => String::new(), - }; - let new_placeholder_text = Arc::from(new_placeholder_text); - self.query_editor.update(cx, |editor, cx| { - editor.set_placeholder_text(new_placeholder_text, cx); - }); + } + self.replacement_editor.update(cx, |editor, cx| { editor.set_placeholder_text("Replace with...", cx); }); From 53b608378c23fbdc2ba3baf79a180c1fe91aeb18 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 17:02:15 -0500 Subject: [PATCH 223/644] Don't apply the gap when we don't have any items in the first row --- crates/workspace2/src/toolbar.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index cd25582f36cbd397688a500e85c0e405865dae63..4431e1b3ff39d7e595611cfb230dcb6a770f1d05 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -102,16 +102,19 @@ impl Render for Toolbar { let secondary_item = self.secondary_items().next().map(|item| item.to_any()); + let has_left_items = self.left_items().count() > 0; + let has_right_items = self.right_items().count() > 0; + v_stack() .p_1() - .gap_2() + .when(has_left_items || has_right_items, |this| this.gap_2()) .border_b() .border_color(cx.theme().colors().border_variant) .bg(cx.theme().colors().toolbar_background) .child( h_stack() .justify_between() - .when(self.left_items().count() > 0, |this| { + .when(has_left_items, |this| { this.child( h_stack() .flex_1() @@ -119,7 +122,7 @@ impl Render for Toolbar { .children(self.left_items().map(|item| item.to_any())), ) }) - .when(self.right_items().count() > 0, |this| { + .when(has_right_items, |this| { this.child( h_stack() .flex_1() From b9bc74abe55915a8e05308b07e3dcf27a244fc07 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 17:03:44 -0500 Subject: [PATCH 224/644] Increase toolbar padding --- crates/workspace2/src/toolbar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index 4431e1b3ff39d7e595611cfb230dcb6a770f1d05..f8bca157c37275a617c30bb68b15346767a3f974 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -106,7 +106,7 @@ impl Render for Toolbar { let has_right_items = self.right_items().count() > 0; v_stack() - .p_1() + .p_2() .when(has_left_items || has_right_items, |this| this.gap_2()) .border_b() .border_color(cx.theme().colors().border_variant) From b493d8f6c0b84e90af061eabe0b825072b18b0b6 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 17:10:27 -0500 Subject: [PATCH 225/644] Improve spacing of items in buffer search bar --- crates/search2/src/buffer_search.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index ebaf111e6061c9b9ca032774c9fd1c85f31b552f..51557320f78b6c95c2d321706970068a555206f2 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -214,6 +214,8 @@ impl Render for BufferSearchBar { } h_stack() + .w_full() + .gap_2() .key_context(key_context) .on_action(cx.listener(Self::previous_history_query)) .on_action(cx.listener(Self::next_history_query)) @@ -239,7 +241,6 @@ impl Render for BufferSearchBar { .when(self.supported_options().word, |this| { this.on_action(cx.listener(Self::toggle_whole_word)) }) - .w_full() .child( h_stack() .flex_1() @@ -268,6 +269,7 @@ impl Render for BufferSearchBar { ) .child( h_stack() + .gap_2() .flex_none() .child( h_stack() From 8a8b498ee114cded149172515dc1e2e13f2bfed2 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 17:25:38 -0500 Subject: [PATCH 226/644] Style replace input --- crates/search2/src/buffer_search.rs | 61 +++++++++++++++++------------ 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index 51557320f78b6c95c2d321706970068a555206f2..dcf9c4c6f2220cddac91706f27b303d5cfb206da 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -189,22 +189,6 @@ impl Render for BufferSearchBar { Some(ui::Label::new(message)) }); let should_show_replace_input = self.replace_enabled && supported_options.replacement; - let replace_all = should_show_replace_input.then(|| { - super::render_replace_button( - ReplaceAll, - ui::Icon::ReplaceAll, - "Replace all", - cx.listener(|this, _, cx| this.replace_all(&ReplaceAll, cx)), - ) - }); - let replace_next = should_show_replace_input.then(|| { - super::render_replace_button( - ReplaceNext, - ui::Icon::ReplaceNext, - "Replace next", - cx.listener(|this, _, cx| this.replace_next(&ReplaceNext, cx)), - ) - }); let in_replace = self.replacement_editor.focus_handle(cx).is_focused(cx); let mut key_context = KeyContext::default(); @@ -290,16 +274,47 @@ impl Render for BufferSearchBar { .gap_0p5() .flex_1() .when(self.replace_enabled, |this| { - this.child(self.replacement_editor.clone()) - .children(replace_next) - .children(replace_all) + this.child( + h_stack() + .flex_1() + // We're giving this a fixed height to match the height of the search input, + // which has an icon inside that is increasing its height. + .h_8() + .px_2() + .py_1() + .gap_2() + .border_1() + .border_color(cx.theme().colors().border) + .rounded_lg() + .child(self.render_text_input(&self.replacement_editor, cx)), + ) + .when(should_show_replace_input, |this| { + this.child(super::render_replace_button( + ReplaceNext, + ui::Icon::ReplaceNext, + "Replace next", + cx.listener(|this, _, cx| this.replace_next(&ReplaceNext, cx)), + )) + .child(super::render_replace_button( + ReplaceAll, + ui::Icon::ReplaceAll, + "Replace all", + cx.listener(|this, _, cx| this.replace_all(&ReplaceAll, cx)), + )) + }) }), ) .child( h_stack() .gap_0p5() .flex_none() - .child(self.render_action_button()) + .child( + IconButton::new("select-all", ui::Icon::SelectAll) + .on_click(|_, cx| cx.dispatch_action(SelectAllMatches.boxed_clone())) + .tooltip(|cx| { + Tooltip::for_action("Select all matches", &SelectAllMatches, cx) + }), + ) .children(match_count) .child(render_nav_button( ui::Icon::ChevronLeft, @@ -627,12 +642,6 @@ impl BufferSearchBar { self.update_matches(cx) } - fn render_action_button(&self) -> impl IntoElement { - IconButton::new("select-all", ui::Icon::SelectAll) - .on_click(|_, cx| cx.dispatch_action(SelectAllMatches.boxed_clone())) - .tooltip(|cx| Tooltip::for_action("Select all matches", &SelectAllMatches, cx)) - } - fn render_search_option_button( &self, option: SearchOptions, From 2ac472e0e068770109c37917bf9d6368345a8325 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 17:31:36 -0500 Subject: [PATCH 227/644] Inline buttons --- crates/search2/src/buffer_search.rs | 32 ++++++++++++++++++----------- crates/search2/src/search.rs | 19 ----------------- 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index dcf9c4c6f2220cddac91706f27b303d5cfb206da..ec70b3721996a9d8f483ebf7708019b7f94a1f91 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -289,18 +289,26 @@ impl Render for BufferSearchBar { .child(self.render_text_input(&self.replacement_editor, cx)), ) .when(should_show_replace_input, |this| { - this.child(super::render_replace_button( - ReplaceNext, - ui::Icon::ReplaceNext, - "Replace next", - cx.listener(|this, _, cx| this.replace_next(&ReplaceNext, cx)), - )) - .child(super::render_replace_button( - ReplaceAll, - ui::Icon::ReplaceAll, - "Replace all", - cx.listener(|this, _, cx| this.replace_all(&ReplaceAll, cx)), - )) + this.child( + IconButton::new("search-replace-next", ui::Icon::ReplaceNext) + .tooltip(move |cx| { + Tooltip::for_action("Replace next", &ReplaceNext, cx) + }) + .on_click(cx.listener(|this, _, cx| { + this.replace_next(&ReplaceNext, cx) + })), + ) + .child( + IconButton::new("search-replace-all", ui::Icon::ReplaceAll) + .tooltip(move |cx| { + Tooltip::for_action("Replace all", &ReplaceAll, cx) + }) + .on_click( + cx.listener(|this, _, cx| { + this.replace_all(&ReplaceAll, cx) + }), + ), + ) }) }), ) diff --git a/crates/search2/src/search.rs b/crates/search2/src/search.rs index 18fcc258f44497c8863f9000201238cebc1520ab..1d496a10b03e3ab6789d467d75d034f26a755134 100644 --- a/crates/search2/src/search.rs +++ b/crates/search2/src/search.rs @@ -5,10 +5,6 @@ pub use mode::SearchMode; use project::search::SearchQuery; use ui::{prelude::*, Tooltip}; use ui::{ButtonStyle, Icon, IconButton}; -//pub use project_search::{ProjectSearchBar, ProjectSearchView}; -// use theme::components::{ -// action_button::Button, svg::Svg, ComponentExt, IconButtonStyle, ToggleIconButtonStyle, -// }; pub mod buffer_search; mod history; @@ -121,18 +117,3 @@ fn toggle_replace_button( .when(active, |button| button.style(ButtonStyle::Filled)) .tooltip(|cx| Tooltip::for_action("Toggle replace", &ToggleReplace, cx)) } - -fn render_replace_button( - action: impl Action + 'static + Send + Sync, - icon: Icon, - tooltip: &'static str, - on_click: impl Fn(&gpui::ClickEvent, &mut WindowContext) + 'static, -) -> impl IntoElement { - let id: SharedString = format!("search-replace-{}", action.name()).into(); - IconButton::new(id, icon) - .tooltip({ - let action = action.boxed_clone(); - move |cx| Tooltip::for_action(tooltip, &*action, cx) - }) - .on_click(on_click) -} From e5e8e8882f162a125bfa15acaf41c10162fc1c21 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 17:34:08 -0500 Subject: [PATCH 228/644] Inline toggle replace button --- crates/search2/src/buffer_search.rs | 18 ++++++++++++++---- crates/search2/src/search.rs | 14 +------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index ec70b3721996a9d8f483ebf7708019b7f94a1f91..06e1b625bc4baaa79264467ac10c1a0a23465e63 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -261,12 +261,22 @@ impl Render for BufferSearchBar { .child(search_button_for_mode(SearchMode::Regex)), ) .when(supported_options.replacement, |this| { - this.child(super::toggle_replace_button( - self.replace_enabled, - cx.listener(|this, _: &ClickEvent, cx| { + this.child( + IconButton::new( + "buffer-search-bar-toggle-replace-button", + Icon::Replace, + ) + .style(ButtonStyle::Subtle) + .when(self.replace_enabled, |button| { + button.style(ButtonStyle::Filled) + }) + .on_click(cx.listener(|this, _: &ClickEvent, cx| { this.toggle_replace(&ToggleReplace, cx); + })) + .tooltip(|cx| { + Tooltip::for_action("Toggle replace", &ToggleReplace, cx) }), - )) + ) }), ) .child( diff --git a/crates/search2/src/search.rs b/crates/search2/src/search.rs index 1d496a10b03e3ab6789d467d75d034f26a755134..a5bd299e874603a9c2be6147f0c5e5a9d74ad8d9 100644 --- a/crates/search2/src/search.rs +++ b/crates/search2/src/search.rs @@ -4,7 +4,7 @@ use gpui::{actions, Action, AppContext, IntoElement}; pub use mode::SearchMode; use project::search::SearchQuery; use ui::{prelude::*, Tooltip}; -use ui::{ButtonStyle, Icon, IconButton}; +use ui::{ButtonStyle, IconButton}; pub mod buffer_search; mod history; @@ -105,15 +105,3 @@ impl SearchOptions { }) } } - -fn toggle_replace_button( - active: bool, - action: impl Fn(&gpui::ClickEvent, &mut WindowContext) + 'static, -) -> impl IntoElement { - // todo: add toggle_replace button - IconButton::new("buffer-search-bar-toggle-replace-button", Icon::Replace) - .on_click(action) - .style(ButtonStyle::Subtle) - .when(active, |button| button.style(ButtonStyle::Filled)) - .tooltip(|cx| Tooltip::for_action("Toggle replace", &ToggleReplace, cx)) -} From 72c8beae30c6d4277b46de2dd0a30068ac137a68 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 21 Dec 2023 00:45:23 +0200 Subject: [PATCH 229/644] Restore "reveal in project panel" and "search in directory" context menu actions --- Cargo.lock | 1 + crates/project_panel2/Cargo.toml | 1 + crates/project_panel2/src/project_panel.rs | 103 ++------------------- crates/search2/src/project_search.rs | 1 + crates/search2/src/search.rs | 1 + 5 files changed, 14 insertions(+), 93 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd0a86d16128c219047e2ea3b47548534192d1a2..cddd744a9f8ffa5b6a7f02dfe49066a0ba0e6e58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7057,6 +7057,7 @@ dependencies = [ "pretty_assertions", "project2", "schemars", + "search2", "serde", "serde_derive", "serde_json", diff --git a/crates/project_panel2/Cargo.toml b/crates/project_panel2/Cargo.toml index 48abfbe1def3493c46e0ddbb21ad077232a41a70..d3ef1eb825ccb45aa2818eb862f1584d6230de56 100644 --- a/crates/project_panel2/Cargo.toml +++ b/crates/project_panel2/Cargo.toml @@ -15,6 +15,7 @@ editor = { path = "../editor2", package = "editor2" } gpui = { path = "../gpui2", package = "gpui2" } menu = { path = "../menu2", package = "menu2" } project = { path = "../project2", package = "project2" } +search = { package = "search2", path = "../search2" } settings = { path = "../settings2", package = "settings2" } theme = { path = "../theme2", package = "theme2" } ui = { path = "../ui2", package = "ui2" } diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index d8b5c1551f4ef33495e7d84b168a702182479017..07a6e4be5ef0d8d545a4c971beeaf3183a6ad4b7 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -55,7 +55,7 @@ pub struct ProjectPanel { filename_editor: View, clipboard_entry: Option, _dragged_entry_destination: Option>, - _workspace: WeakView, + workspace: WeakView, width: Option, pending_serialization: Task>, } @@ -152,10 +152,6 @@ pub enum Event { entry_id: ProjectEntryId, }, Focus, - NewSearchInDirectory { - dir_entry: Entry, - }, - ActivatePanel, } #[derive(Serialize, Deserialize)] @@ -190,10 +186,10 @@ impl ProjectPanel { } project::Event::RevealInProjectPanel(entry_id) => { this.reveal_entry(project, *entry_id, false, cx); - cx.emit(Event::ActivatePanel); + cx.emit(PanelEvent::Activate); } project::Event::ActivateProjectPanel => { - cx.emit(Event::ActivatePanel); + cx.emit(PanelEvent::Activate); } project::Event::WorktreeRemoved(id) => { this.expanded_dir_ids.remove(id); @@ -244,7 +240,7 @@ impl ProjectPanel { filename_editor, clipboard_entry: None, _dragged_entry_destination: None, - _workspace: workspace.weak_handle(), + workspace: workspace.weak_handle(), width: None, pending_serialization: Task::ready(None), }; @@ -1004,9 +1000,12 @@ impl ProjectPanel { ) { if let Some((_, entry)) = self.selected_entry(cx) { if entry.is_dir() { - cx.emit(Event::NewSearchInDirectory { - dir_entry: entry.clone(), - }); + let entry = entry.clone(); + self.workspace + .update(cx, |workspace, cx| { + search::ProjectSearchView::new_search_in_directory(workspace, &entry, cx); + }) + .ok(); } } } @@ -1666,7 +1665,6 @@ mod tests { use std::{ collections::HashSet, path::{Path, PathBuf}, - sync::atomic::{self, AtomicUsize}, }; use workspace::AppState; @@ -2705,87 +2703,6 @@ mod tests { ); } - #[gpui::test] - async fn test_new_search_in_directory_trigger(cx: &mut gpui::TestAppContext) { - init_test_with_editor(cx); - - let fs = FakeFs::new(cx.executor().clone()); - fs.insert_tree( - "/src", - json!({ - "test": { - "first.rs": "// First Rust file", - "second.rs": "// Second Rust file", - "third.rs": "// Third Rust file", - } - }), - ) - .await; - - let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await; - let workspace = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); - let cx = &mut VisualTestContext::from_window(*workspace, cx); - let panel = workspace - .update(cx, |workspace, cx| ProjectPanel::new(workspace, cx)) - .unwrap(); - - let new_search_events_count = Arc::new(AtomicUsize::new(0)); - let _subscription = panel.update(cx, |_, cx| { - let subcription_count = Arc::clone(&new_search_events_count); - let view = cx.view().clone(); - cx.subscribe(&view, move |_, _, event, _| { - if matches!(event, Event::NewSearchInDirectory { .. }) { - subcription_count.fetch_add(1, atomic::Ordering::SeqCst); - } - }) - }); - - toggle_expand_dir(&panel, "src/test", cx); - select_path(&panel, "src/test/first.rs", cx); - panel.update(cx, |panel, cx| panel.confirm(&Confirm, cx)); - cx.executor().run_until_parked(); - assert_eq!( - visible_entries_as_strings(&panel, 0..10, cx), - &[ - "v src", - " v test", - " first.rs <== selected", - " second.rs", - " third.rs" - ] - ); - panel.update(cx, |panel, cx| { - panel.new_search_in_directory(&NewSearchInDirectory, cx) - }); - assert_eq!( - new_search_events_count.load(atomic::Ordering::SeqCst), - 0, - "Should not trigger new search in directory when called on a file" - ); - - select_path(&panel, "src/test", cx); - panel.update(cx, |panel, cx| panel.confirm(&Confirm, cx)); - cx.executor().run_until_parked(); - assert_eq!( - visible_entries_as_strings(&panel, 0..10, cx), - &[ - "v src", - " v test <== selected", - " first.rs", - " second.rs", - " third.rs" - ] - ); - panel.update(cx, |panel, cx| { - panel.new_search_in_directory(&NewSearchInDirectory, cx) - }); - assert_eq!( - new_search_events_count.load(atomic::Ordering::SeqCst), - 1, - "Should trigger new search in directory when called on a directory" - ); - } - #[gpui::test] async fn test_collapse_all_entries(cx: &mut gpui::TestAppContext) { init_test_with_editor(cx); diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index af8ac418347a9b5f9e06888dd3bac3e8c4b8a143..3e245ed72d4a9e8523b281ef79ee58387b2ad5bd 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -918,6 +918,7 @@ impl ProjectSearchView { }) .unwrap_or(Task::ready(Ok(false))) } + pub fn new_search_in_directory( workspace: &mut Workspace, dir_entry: &Entry, diff --git a/crates/search2/src/search.rs b/crates/search2/src/search.rs index a5bd299e874603a9c2be6147f0c5e5a9d74ad8d9..f0301a5bcc7a637c17d47c59f5102f352ac3840c 100644 --- a/crates/search2/src/search.rs +++ b/crates/search2/src/search.rs @@ -3,6 +3,7 @@ pub use buffer_search::BufferSearchBar; use gpui::{actions, Action, AppContext, IntoElement}; pub use mode::SearchMode; use project::search::SearchQuery; +pub use project_search::ProjectSearchView; use ui::{prelude::*, Tooltip}; use ui::{ButtonStyle, IconButton}; From 2cd7d2db469ff38be0b374b06c065bd5322c3d22 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 21 Dec 2023 01:18:00 +0200 Subject: [PATCH 230/644] Remove nightly from zed1 and use proper namespaces for nightly in zed2 manifest --- crates/zed/Cargo.toml | 8 -------- crates/zed2/Cargo.toml | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 987208880be6beec91dc53ce2679c04aaa386f44..53a5c1cdde56848aab4d69b54e5b118c563a77dc 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -171,14 +171,6 @@ osx_minimum_system_version = "10.15.7" osx_info_plist_exts = ["resources/info/*"] osx_url_schemes = ["zed-dev"] -[package.metadata.bundle-nightly] -icon = ["resources/app-icon-nightly@2x.png", "resources/app-icon-nightly.png"] -identifier = "dev.zed.Zed-Nightly" -name = "Zed Nightly" -osx_minimum_system_version = "10.15.7" -osx_info_plist_exts = ["resources/info/*"] -osx_url_schemes = ["zed-nightly"] - [package.metadata.bundle-preview] icon = ["resources/app-icon-preview@2x.png", "resources/app-icon-preview.png"] identifier = "dev.zed.Zed-Preview" diff --git a/crates/zed2/Cargo.toml b/crates/zed2/Cargo.toml index 8cc333348462e327d8bf9eded5ef3d72de46f382..3da22401e0a8c3284934556ab68adca58b6a51e0 100644 --- a/crates/zed2/Cargo.toml +++ b/crates/zed2/Cargo.toml @@ -169,11 +169,11 @@ osx_url_schemes = ["zed-dev"] [package.metadata.bundle-nightly] icon = ["resources/app-icon-nightly@2x.png", "resources/app-icon-nightly.png"] -identifier = "dev.zed.Zed-Dev" +identifier = "dev.zed.Zed-Nightly" name = "Zed Nightly" osx_minimum_system_version = "10.15.7" osx_info_plist_exts = ["resources/info/*"] -osx_url_schemes = ["zed-dev"] +osx_url_schemes = ["zed-nightly"] [package.metadata.bundle-preview] icon = ["resources/app-icon-preview@2x.png", "resources/app-icon-preview.png"] From 443b1dd3458a97d93a71c9ae89a60a0cb539f2b6 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 18:23:21 -0500 Subject: [PATCH 231/644] Add `ToggleButton` component --- crates/storybook2/src/story_selector.rs | 2 + crates/ui2/src/components/button.rs | 2 + .../ui2/src/components/button/button_like.rs | 20 ++- .../src/components/button/toggle_button.rs | 128 ++++++++++++++++++ crates/ui2/src/components/stories.rs | 2 + .../src/components/stories/toggle_button.rs | 89 ++++++++++++ 6 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 crates/ui2/src/components/button/toggle_button.rs create mode 100644 crates/ui2/src/components/stories/toggle_button.rs diff --git a/crates/storybook2/src/story_selector.rs b/crates/storybook2/src/story_selector.rs index bd87e1fde9d60b9f9f54b4a02314491340665da1..82dffd42fdf4b75916202bdff02dd0fa36cfa961 100644 --- a/crates/storybook2/src/story_selector.rs +++ b/crates/storybook2/src/story_selector.rs @@ -31,6 +31,7 @@ pub enum ComponentStory { Scroll, Tab, TabBar, + ToggleButton, Text, ViewportUnits, ZIndex, @@ -62,6 +63,7 @@ impl ComponentStory { Self::Text => TextStory::view(cx).into(), Self::Tab => cx.build_view(|_| ui::TabStory).into(), Self::TabBar => cx.build_view(|_| ui::TabBarStory).into(), + Self::ToggleButton => cx.build_view(|_| ui::ToggleButtonStory).into(), Self::ViewportUnits => cx.build_view(|_| crate::stories::ViewportUnitsStory).into(), Self::ZIndex => cx.build_view(|_| ZIndexStory).into(), Self::Picker => PickerStory::new(cx).into(), diff --git a/crates/ui2/src/components/button.rs b/crates/ui2/src/components/button.rs index 25e88201f47417860b85ffc6267408ea47b1c052..71aaf7780ccc93e11dbbb3f15975ea054917a320 100644 --- a/crates/ui2/src/components/button.rs +++ b/crates/ui2/src/components/button.rs @@ -2,7 +2,9 @@ mod button; pub(self) mod button_icon; mod button_like; mod icon_button; +mod toggle_button; pub use button::*; pub use button_like::*; pub use icon_button::*; +pub use toggle_button::*; diff --git a/crates/ui2/src/components/button/button_like.rs b/crates/ui2/src/components/button/button_like.rs index 19fa2b48a4c4768473df078c161873a55d488498..b25ac1d1ecf64dab50af7c4c3ca8e1d188968e7c 100644 --- a/crates/ui2/src/components/button/button_like.rs +++ b/crates/ui2/src/components/button/button_like.rs @@ -59,6 +59,13 @@ pub enum ButtonStyle { Transparent, } +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] +pub(crate) enum ButtonLikeRounding { + All, + Left, + Right, +} + #[derive(Debug, Clone)] pub(crate) struct ButtonLikeStyles { pub background: Hsla, @@ -256,6 +263,7 @@ pub struct ButtonLike { pub(super) selected: bool, pub(super) width: Option, size: ButtonSize, + rounding: Option, tooltip: Option AnyView>>, on_click: Option>, children: SmallVec<[AnyElement; 2]>, @@ -271,11 +279,17 @@ impl ButtonLike { selected: false, width: None, size: ButtonSize::Default, + rounding: Some(ButtonLikeRounding::All), tooltip: None, children: SmallVec::new(), on_click: None, } } + + pub(crate) fn rounding(mut self, rounding: impl Into>) -> Self { + self.rounding = rounding.into(); + self + } } impl Disableable for ButtonLike { @@ -356,7 +370,11 @@ impl RenderOnce for ButtonLike { .flex_none() .h(self.size.height()) .when_some(self.width, |this, width| this.w(width).justify_center()) - .rounded_md() + .when_some(self.rounding, |this, rounding| match rounding { + ButtonLikeRounding::All => this.rounded_md(), + ButtonLikeRounding::Left => this.rounded_l_md(), + ButtonLikeRounding::Right => this.rounded_r_md(), + }) .gap_1() .map(|this| match self.size { ButtonSize::Default | ButtonSize::Compact => this.px_1(), diff --git a/crates/ui2/src/components/button/toggle_button.rs b/crates/ui2/src/components/button/toggle_button.rs new file mode 100644 index 0000000000000000000000000000000000000000..39a517111b9a1958afac86979f4adbbdd18c25bf --- /dev/null +++ b/crates/ui2/src/components/button/toggle_button.rs @@ -0,0 +1,128 @@ +use gpui::{AnyView, ClickEvent}; + +use crate::{prelude::*, ButtonLike, ButtonLikeRounding}; + +/// The position of a [`ToggleButton`] within a group of buttons. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum ToggleButtonPosition { + /// The toggle button is first in the group. + First, + + /// The toggle button is in the middle of the group (i.e., it is not the first or last toggle button). + Middle, + + /// The toggle button is last in the group. + Last, +} + +#[derive(IntoElement)] +pub struct ToggleButton { + base: ButtonLike, + position_in_group: Option, + label: SharedString, + label_color: Option, +} + +impl ToggleButton { + pub fn new(id: impl Into, label: impl Into) -> Self { + Self { + base: ButtonLike::new(id), + position_in_group: None, + label: label.into(), + label_color: None, + } + } + + pub fn color(mut self, label_color: impl Into>) -> Self { + self.label_color = label_color.into(); + self + } + + pub fn position_in_group(mut self, position: ToggleButtonPosition) -> Self { + self.position_in_group = Some(position); + self + } + + pub fn first(self) -> Self { + self.position_in_group(ToggleButtonPosition::First) + } + + pub fn middle(self) -> Self { + self.position_in_group(ToggleButtonPosition::Middle) + } + + pub fn last(self) -> Self { + self.position_in_group(ToggleButtonPosition::Last) + } +} + +impl Selectable for ToggleButton { + fn selected(mut self, selected: bool) -> Self { + self.base = self.base.selected(selected); + self + } +} + +impl Disableable for ToggleButton { + fn disabled(mut self, disabled: bool) -> Self { + self.base = self.base.disabled(disabled); + self + } +} + +impl Clickable for ToggleButton { + fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut WindowContext) + 'static) -> Self { + self.base = self.base.on_click(handler); + self + } +} + +impl ButtonCommon for ToggleButton { + fn id(&self) -> &ElementId { + self.base.id() + } + + fn style(mut self, style: ButtonStyle) -> Self { + self.base = self.base.style(style); + self + } + + fn size(mut self, size: ButtonSize) -> Self { + self.base = self.base.size(size); + self + } + + fn tooltip(mut self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self { + self.base = self.base.tooltip(tooltip); + self + } +} + +impl RenderOnce for ToggleButton { + type Rendered = ButtonLike; + + fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + let is_disabled = self.base.disabled; + let is_selected = self.base.selected; + + let label_color = if is_disabled { + Color::Disabled + } else if is_selected { + Color::Selected + } else { + self.label_color.unwrap_or_default() + }; + + self.base + .when_some(self.position_in_group, |this, position| match position { + ToggleButtonPosition::First => this.rounding(ButtonLikeRounding::Left), + ToggleButtonPosition::Middle => this.rounding(None), + ToggleButtonPosition::Last => this.rounding(ButtonLikeRounding::Right), + }) + .child( + Label::new(self.label) + .color(label_color) + .line_height_style(LineHeightStyle::UILabel), + ) + } +} diff --git a/crates/ui2/src/components/stories.rs b/crates/ui2/src/components/stories.rs index f02787a1db6f9233985cac41de47f877b878917a..f321a7525fb00efc2e9851d77aa1780df68c3311 100644 --- a/crates/ui2/src/components/stories.rs +++ b/crates/ui2/src/components/stories.rs @@ -12,6 +12,7 @@ mod list_header; mod list_item; mod tab; mod tab_bar; +mod toggle_button; pub use avatar::*; pub use button::*; @@ -27,3 +28,4 @@ pub use list_header::*; pub use list_item::*; pub use tab::*; pub use tab_bar::*; +pub use toggle_button::*; diff --git a/crates/ui2/src/components/stories/toggle_button.rs b/crates/ui2/src/components/stories/toggle_button.rs new file mode 100644 index 0000000000000000000000000000000000000000..6fe741ada3b8059aa0d946025e4abdddeb443335 --- /dev/null +++ b/crates/ui2/src/components/stories/toggle_button.rs @@ -0,0 +1,89 @@ +use gpui::{Component, Render}; +use story::{StoryContainer, StoryItem, StorySection}; + +use crate::{prelude::*, ToggleButton}; + +pub struct ToggleButtonStory; + +impl Render for ToggleButtonStory { + type Element = Component; + + fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + StoryContainer::new( + "Toggle Button", + "crates/ui2/src/components/stories/toggle_button.rs", + ) + .child( + StorySection::new().child( + StoryItem::new( + "Default", + ToggleButton::new("default_toggle_button", "Hello"), + ) + .description("Displays a toggle button.") + .usage(""), + ), + ) + .child( + StorySection::new().child( + StoryItem::new( + "Toggle button group", + h_stack() + .child( + ToggleButton::new(1, "Apple") + .style(ButtonStyle::Filled) + .first(), + ) + .child( + ToggleButton::new(2, "Banana") + .style(ButtonStyle::Filled) + .middle(), + ) + .child( + ToggleButton::new(3, "Cherry") + .style(ButtonStyle::Filled) + .middle(), + ) + .child( + ToggleButton::new(4, "Dragonfruit") + .style(ButtonStyle::Filled) + .last(), + ), + ) + .description("Displays a group of toggle buttons.") + .usage(""), + ), + ) + .child( + StorySection::new().child( + StoryItem::new( + "Toggle button group with selection", + h_stack() + .child( + ToggleButton::new(1, "Apple") + .style(ButtonStyle::Filled) + .first(), + ) + .child( + ToggleButton::new(2, "Banana") + .style(ButtonStyle::Filled) + .selected(true) + .middle(), + ) + .child( + ToggleButton::new(3, "Cherry") + .style(ButtonStyle::Filled) + .middle(), + ) + .child( + ToggleButton::new(4, "Dragonfruit") + .style(ButtonStyle::Filled) + .last(), + ), + ) + .description("Displays a group of toggle buttons.") + .usage(""), + ), + ) + .into_element() + } +} From 93c8bee7476b7813e24537d4501b998aa60b3061 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 18:32:12 -0500 Subject: [PATCH 232/644] Use `ToggleButton`s for search mode in buffer search --- crates/search2/src/buffer_search.rs | 43 +++++++++++++++++++++++------ crates/search2/src/search_bar.rs | 20 +------------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index 06e1b625bc4baaa79264467ac10c1a0a23465e63..f4f350893a484185759e8011266923d1b2eac83d 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -1,7 +1,7 @@ use crate::{ history::SearchHistory, mode::{next_mode, SearchMode}, - search_bar::{render_nav_button, render_search_mode_button}, + search_bar::render_nav_button, ActivateRegexMode, ActivateTextMode, CycleMode, NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext, SearchOptions, SelectAllMatches, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleReplace, ToggleWholeWord, @@ -21,7 +21,7 @@ use settings::Settings; use std::{any::Any, sync::Arc}; use theme::ThemeSettings; -use ui::{h_stack, prelude::*, Icon, IconButton, IconElement, Tooltip}; +use ui::{h_stack, prelude::*, Icon, IconButton, IconElement, ToggleButton, Tooltip}; use util::ResultExt; use workspace::{ item::ItemHandle, @@ -165,11 +165,6 @@ impl Render for BufferSearchBar { editor.set_placeholder_text("Replace with...", cx); }); - let search_button_for_mode = |mode| { - let is_active = self.current_mode == mode; - - render_search_mode_button(mode, is_active) - }; let match_count = self .active_searchable_item .as_ref() @@ -257,8 +252,38 @@ impl Render for BufferSearchBar { .flex_none() .child( h_stack() - .child(search_button_for_mode(SearchMode::Text)) - .child(search_button_for_mode(SearchMode::Regex)), + .child( + ToggleButton::new("search-mode-text", SearchMode::Text.label()) + .style(ButtonStyle::Filled) + .selected(self.current_mode == SearchMode::Text) + .on_click(cx.listener(move |_, _event, cx| { + cx.dispatch_action(SearchMode::Text.action()) + })) + .tooltip(|cx| { + Tooltip::for_action( + SearchMode::Text.tooltip(), + &*SearchMode::Text.action(), + cx, + ) + }) + .first(), + ) + .child( + ToggleButton::new("search-mode-regex", SearchMode::Regex.label()) + .style(ButtonStyle::Filled) + .selected(self.current_mode == SearchMode::Regex) + .on_click(cx.listener(move |_, _event, cx| { + cx.dispatch_action(SearchMode::Regex.action()) + })) + .tooltip(|cx| { + Tooltip::for_action( + SearchMode::Regex.tooltip(), + &*SearchMode::Regex.action(), + cx, + ) + }) + .last(), + ), ) .when(supported_options.replacement, |this| { this.child( diff --git a/crates/search2/src/search_bar.rs b/crates/search2/src/search_bar.rs index dcc46ac228b702f2f81f1ab99baaf3d44631ab2f..628be3112ecc06e9d00e8d33361e8f17fa6efd54 100644 --- a/crates/search2/src/search_bar.rs +++ b/crates/search2/src/search_bar.rs @@ -1,8 +1,6 @@ use gpui::{Action, IntoElement}; +use ui::IconButton; use ui::{prelude::*, Tooltip}; -use ui::{Button, IconButton}; - -use crate::mode::SearchMode; pub(super) fn render_nav_button( icon: ui::Icon, @@ -18,19 +16,3 @@ pub(super) fn render_nav_button( .tooltip(move |cx| Tooltip::for_action(tooltip, action, cx)) .disabled(!active) } - -pub(crate) fn render_search_mode_button(mode: SearchMode, is_active: bool) -> Button { - Button::new(mode.label(), mode.label()) - .selected(is_active) - .on_click({ - let action = mode.action(); - move |_, cx| { - cx.dispatch_action(action.boxed_clone()); - } - }) - .tooltip({ - let action = mode.action(); - let tooltip_text = mode.tooltip(); - move |cx| Tooltip::for_action(tooltip_text.clone(), &*action, cx) - }) -} From 11807bb82db910e6ac0f09246b4c14b991845fe4 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 20 Dec 2023 18:47:22 -0500 Subject: [PATCH 233/644] Add large variant for buttons --- crates/search2/src/buffer_search.rs | 2 ++ crates/ui2/src/components/button/button_like.rs | 3 +++ crates/ui2/src/components/stories/toggle_button.rs | 8 ++++++++ 3 files changed, 13 insertions(+) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index f4f350893a484185759e8011266923d1b2eac83d..eae741afde5ff114198c9ff10a4969d9e81fae88 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -255,6 +255,7 @@ impl Render for BufferSearchBar { .child( ToggleButton::new("search-mode-text", SearchMode::Text.label()) .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .selected(self.current_mode == SearchMode::Text) .on_click(cx.listener(move |_, _event, cx| { cx.dispatch_action(SearchMode::Text.action()) @@ -271,6 +272,7 @@ impl Render for BufferSearchBar { .child( ToggleButton::new("search-mode-regex", SearchMode::Regex.label()) .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .selected(self.current_mode == SearchMode::Regex) .on_click(cx.listener(move |_, _event, cx| { cx.dispatch_action(SearchMode::Regex.action()) diff --git a/crates/ui2/src/components/button/button_like.rs b/crates/ui2/src/components/button/button_like.rs index b25ac1d1ecf64dab50af7c4c3ca8e1d188968e7c..44e18e850d8496c7994c84abaedf8ef650602229 100644 --- a/crates/ui2/src/components/button/button_like.rs +++ b/crates/ui2/src/components/button/button_like.rs @@ -233,6 +233,7 @@ impl ButtonStyle { /// that are consistently sized with buttons. #[derive(Default, PartialEq, Clone, Copy)] pub enum ButtonSize { + Large, #[default] Default, Compact, @@ -242,6 +243,7 @@ pub enum ButtonSize { impl ButtonSize { fn height(self) -> Rems { match self { + ButtonSize::Large => rems(32. / 16.), ButtonSize::Default => rems(22. / 16.), ButtonSize::Compact => rems(18. / 16.), ButtonSize::None => rems(16. / 16.), @@ -377,6 +379,7 @@ impl RenderOnce for ButtonLike { }) .gap_1() .map(|this| match self.size { + ButtonSize::Large => this.px_2(), ButtonSize::Default | ButtonSize::Compact => this.px_1(), ButtonSize::None => this, }) diff --git a/crates/ui2/src/components/stories/toggle_button.rs b/crates/ui2/src/components/stories/toggle_button.rs index 6fe741ada3b8059aa0d946025e4abdddeb443335..0a4ea5f83eb968a94aaf97ad611a0a561d6cbc63 100644 --- a/crates/ui2/src/components/stories/toggle_button.rs +++ b/crates/ui2/src/components/stories/toggle_button.rs @@ -31,21 +31,25 @@ impl Render for ToggleButtonStory { .child( ToggleButton::new(1, "Apple") .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .first(), ) .child( ToggleButton::new(2, "Banana") .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .middle(), ) .child( ToggleButton::new(3, "Cherry") .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .middle(), ) .child( ToggleButton::new(4, "Dragonfruit") .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .last(), ), ) @@ -61,22 +65,26 @@ impl Render for ToggleButtonStory { .child( ToggleButton::new(1, "Apple") .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .first(), ) .child( ToggleButton::new(2, "Banana") .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .selected(true) .middle(), ) .child( ToggleButton::new(3, "Cherry") .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .middle(), ) .child( ToggleButton::new(4, "Dragonfruit") .style(ButtonStyle::Filled) + .size(ButtonSize::Large) .last(), ), ) From 5e7c74c7b6c809df7acdea14fadcd0d2bf354619 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 20 Dec 2023 16:01:52 -0800 Subject: [PATCH 234/644] Ensure that on_release callbacks are called even if view outlives its window --- crates/go_to_line2/src/go_to_line.rs | 28 ++++++++++++++++------------ crates/gpui2/src/window.rs | 8 ++++++-- crates/vim2/src/editor_events.rs | 6 +++--- crates/workspace2/src/workspace2.rs | 2 +- crates/zed2/src/open_listener.rs | 2 +- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/crates/go_to_line2/src/go_to_line.rs b/crates/go_to_line2/src/go_to_line.rs index d6b464cf0ec3a690c8587b367f88552a4e629930..02fcd4771623494bd502b65ca81f900a06d34266 100644 --- a/crates/go_to_line2/src/go_to_line.rs +++ b/crates/go_to_line2/src/go_to_line.rs @@ -1,8 +1,8 @@ use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Editor}; use gpui::{ - actions, div, prelude::*, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, - FocusableView, Render, SharedString, Styled, Subscription, View, ViewContext, VisualContext, - WindowContext, + actions, div, prelude::*, AnyWindowHandle, AppContext, DismissEvent, Div, EventEmitter, + FocusHandle, FocusableView, Render, SharedString, Styled, Subscription, View, ViewContext, + VisualContext, }; use text::{Bias, Point}; use theme::ActiveTheme; @@ -74,15 +74,19 @@ impl GoToLine { } } - fn release(&mut self, cx: &mut WindowContext) { - let scroll_position = self.prev_scroll_position.take(); - self.active_editor.update(cx, |editor, cx| { - editor.highlight_rows(None); - if let Some(scroll_position) = scroll_position { - editor.set_scroll_position(scroll_position, cx); - } - cx.notify(); - }) + fn release(&mut self, window: AnyWindowHandle, cx: &mut AppContext) { + window + .update(cx, |_, cx| { + let scroll_position = self.prev_scroll_position.take(); + self.active_editor.update(cx, |editor, cx| { + editor.highlight_rows(None); + if let Some(scroll_position) = scroll_position { + editor.set_scroll_position(scroll_position, cx); + } + cx.notify(); + }) + }) + .ok(); } fn on_line_editor_event( diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 8546e094d41f63f2ecd6725c178ba495ae74017d..9e8347c783ca62121efc581b24b2e40c0209d228 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -2422,16 +2422,20 @@ impl<'a, V: 'static> ViewContext<'a, V> { subscription } + /// Register a callback to be invoked when the view is released. + /// + /// The callback receives a handle to the view's window. This handle may be + /// invalid, if the window was closed before the view was released. pub fn on_release( &mut self, - on_release: impl FnOnce(&mut V, &mut WindowContext) + 'static, + on_release: impl FnOnce(&mut V, AnyWindowHandle, &mut AppContext) + 'static, ) -> Subscription { let window_handle = self.window.handle; let (subscription, activate) = self.app.release_listeners.insert( self.view.model.entity_id, Box::new(move |this, cx| { let this = this.downcast_mut().expect("invalid entity type"); - let _ = window_handle.update(cx, |_, cx| on_release(this, cx)); + on_release(this, window_handle, cx) }), ); activate(); diff --git a/crates/vim2/src/editor_events.rs b/crates/vim2/src/editor_events.rs index 0e2a1451fe06f145fc305f04f039eb0b62d17dcc..70f486f298cf42d92b919480936d0626a6fbc54b 100644 --- a/crates/vim2/src/editor_events.rs +++ b/crates/vim2/src/editor_events.rs @@ -13,7 +13,7 @@ pub fn init(cx: &mut AppContext) { .detach(); let id = cx.view().entity_id(); - cx.on_release(move |_, cx| released(id, cx)).detach(); + cx.on_release(move |_, _, cx| released(id, cx)).detach(); }) .detach(); } @@ -51,8 +51,8 @@ fn blurred(editor: View, cx: &mut WindowContext) { }); } -fn released(entity_id: EntityId, cx: &mut WindowContext) { - Vim::update(cx, |vim, _| { +fn released(entity_id: EntityId, cx: &mut AppContext) { + cx.update_global(|vim: &mut Vim, _| { if vim .active_editor .as_ref() diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 797e95088d89970f5759efee28b14e5237325f3b..c8712205cb62735cc5f39b534cd34962b6666829 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -642,7 +642,7 @@ impl Workspace { this.serialize_workspace(cx); cx.notify(); }), - cx.on_release(|this, cx| { + cx.on_release(|this, _, cx| { this.app_state.workspace_store.update(cx, |store, _| { store.workspaces.remove(&this.window_self); }) diff --git a/crates/zed2/src/open_listener.rs b/crates/zed2/src/open_listener.rs index 4c961a2b317b6d0a2e5399fa0be3e7b1b219311f..b45254f7174c600f27ff552fef8ae7c2a2be7446 100644 --- a/crates/zed2/src/open_listener.rs +++ b/crates/zed2/src/open_listener.rs @@ -253,7 +253,7 @@ pub async fn handle_cli_connection( let (done_tx, done_rx) = oneshot::channel(); let _subscription = workspace.update(&mut cx, |workspace, cx| { - cx.on_release(move |_, _| { + cx.on_release(move |_, _, _| { let _ = done_tx.send(()); }) }); From 42bdc11112346aced8d596b91bb5bdc8f335da44 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 20 Dec 2023 16:08:58 -0800 Subject: [PATCH 235/644] Prune dead workspaces from WorkspaceStore on read Also, remove unnecessary window handle from Workspace. --- crates/workspace2/src/workspace2.rs | 33 +++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index c8712205cb62735cc5f39b534cd34962b6666829..2bc0d403101841c03c0315902c919da7659184b9 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -430,7 +430,6 @@ pub enum Event { } pub struct Workspace { - window_self: WindowHandle, weak_self: WeakView, workspace_actions: Vec) -> Div>>, zoomed: Option, @@ -642,9 +641,10 @@ impl Workspace { this.serialize_workspace(cx); cx.notify(); }), - cx.on_release(|this, _, cx| { + cx.on_release(|this, window, cx| { this.app_state.workspace_store.update(cx, |store, _| { - store.workspaces.remove(&this.window_self); + let window = window.downcast::().unwrap(); + debug_assert!(store.workspaces.remove(&window)); }) }), ]; @@ -665,7 +665,6 @@ impl Workspace { // }); }); Workspace { - window_self: window_handle, weak_self: weak_handle.clone(), zoomed: None, zoomed_position: None, @@ -3708,7 +3707,7 @@ impl WorkspaceStore { let active_project = ActiveCall::global(cx).read(cx).location().cloned(); let mut response = proto::FollowResponse::default(); - for workspace in &this.workspaces { + this.workspaces.retain(|workspace| { workspace .update(cx, |workspace, cx| { let handler_response = workspace.handle_follow(follower.project_id, cx); @@ -3726,8 +3725,8 @@ impl WorkspaceStore { } } }) - .ok(); - } + .is_ok() + }); if let Err(ix) = this.followers.binary_search(&follower) { this.followers.insert(ix, follower); @@ -3765,15 +3764,17 @@ impl WorkspaceStore { let update = envelope.payload; this.update(&mut cx, |this, cx| { - for workspace in &this.workspaces { - workspace.update(cx, |workspace, cx| { - let project_id = workspace.project.read(cx).remote_id(); - if update.project_id != project_id && update.project_id.is_some() { - return; - } - workspace.handle_update_followers(leader_id, update.clone(), cx); - })?; - } + this.workspaces.retain(|workspace| { + workspace + .update(cx, |workspace, cx| { + let project_id = workspace.project.read(cx).remote_id(); + if update.project_id != project_id && update.project_id.is_some() { + return; + } + workspace.handle_update_followers(leader_id, update.clone(), cx); + }) + .is_ok() + }); Ok(()) })? } From 2f56fe9129e98520ee9ffbc79c38f0d01ae4ca4d Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 21 Dec 2023 02:21:27 +0200 Subject: [PATCH 236/644] For file finder queries, search in all gitignored worktree entries --- crates/file_finder/src/file_finder.rs | 131 ++++++++++++++++++++++--- crates/file_finder2/src/file_finder.rs | 120 +++++++++++++++++++--- 2 files changed, 229 insertions(+), 22 deletions(-) diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 156b062df85f2c1fed4aa30fda7e41aa507297a4..cd64e8c4fbc9aa034043bb12bcbb71203b06e117 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -324,15 +324,10 @@ impl FileFinderDelegate { let include_root_name = worktrees.len() > 1; let candidate_sets = worktrees .into_iter() - .map(|worktree| { - let worktree = worktree.read(cx); - PathMatchCandidateSet { - snapshot: worktree.snapshot(), - include_ignored: worktree - .root_entry() - .map_or(false, |entry| entry.is_ignored), - include_root_name, - } + .map(|worktree| PathMatchCandidateSet { + snapshot: worktree.read(cx).snapshot(), + include_ignored: true, + include_root_name, }) .collect::>(); @@ -1058,7 +1053,7 @@ mod tests { } #[gpui::test] - async fn test_ignored_files(cx: &mut TestAppContext) { + async fn test_ignored_root(cx: &mut TestAppContext) { let app_state = init_test(cx); app_state .fs @@ -1115,7 +1110,105 @@ mod tests { f.delegate_mut().spawn_search(test_path_like("hi"), cx) }) .await; - finder.read_with(cx, |f, _| assert_eq!(f.delegate().matches.len(), 7)); + finder.update(cx, |f, _| { + assert_eq!( + collect_search_results(f), + vec![ + PathBuf::from("ignored-root/happiness"), + PathBuf::from("ignored-root/height"), + PathBuf::from("ignored-root/hi"), + PathBuf::from("ignored-root/hiccup"), + PathBuf::from("tracked-root/happiness"), + PathBuf::from("tracked-root/height"), + PathBuf::from("tracked-root/hi"), + PathBuf::from("tracked-root/hiccup"), + ], + "All files in all roots (including gitignored) should be searched" + ) + }); + } + + #[gpui::test] + async fn test_ignored_files(cx: &mut TestAppContext) { + let app_state = init_test(cx); + app_state + .fs + .as_fake() + .insert_tree( + "/root", + json!({ + ".git": {}, + ".gitignore": "ignored_a\n.env\n", + "a": { + "banana_env": "11", + "bandana_env": "12", + }, + "ignored_a": { + "ignored_banana_env": "21", + "ignored_bandana_env": "22", + "ignored_nested": { + "ignored_nested_banana_env": "31", + "ignored_nested_bandana_env": "32", + }, + }, + ".env": "something", + }), + ) + .await; + + let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; + let window = cx.add_window(|cx| Workspace::test_new(project, cx)); + let workspace = window.root(cx); + cx.dispatch_action(window.into(), Toggle); + + let finder = cx.read(|cx| workspace.read(cx).modal::().unwrap()); + + finder + .update(cx, |finder, cx| { + finder.delegate_mut().update_matches("env".to_string(), cx) + }) + .await; + finder.update(cx, |f, _| { + assert_eq!( + collect_search_results(f), + vec![ + PathBuf::from(".env"), + PathBuf::from("a/banana_env"), + PathBuf::from("a/bandana_env"), + ], + "Root gitignored files and all non-gitignored files should be searched" + ) + }); + + let _ = workspace + .update(cx, |workspace, cx| { + workspace.open_abs_path( + PathBuf::from("/root/ignored_a/ignored_banana_env"), + true, + cx, + ) + }) + .await + .unwrap(); + cx.foreground().run_until_parked(); + finder + .update(cx, |finder, cx| { + finder.delegate_mut().update_matches("env".to_string(), cx) + }) + .await; + finder.update(cx, |f, _| { + assert_eq!( + collect_search_results(f), + vec![ + PathBuf::from(".env"), + PathBuf::from("a/banana_env"), + PathBuf::from("a/bandana_env"), + PathBuf::from("ignored_a/ignored_banana_env"), + PathBuf::from("ignored_a/ignored_bandana_env"), + ], + "Root gitignored dir got listed and its entries got into worktree, but all gitignored dirs below it were not listed. Old entries + new listed gitignored entries should be searched" + ) + }); } #[gpui::test] @@ -2192,4 +2285,20 @@ mod tests { absolute: None, } } + + fn collect_search_results(picker: &Picker) -> Vec { + let matches = &picker.delegate().matches; + assert!( + matches.history.is_empty(), + "Should have no history matches, but got: {:?}", + matches.history + ); + let mut results = matches + .search + .iter() + .map(|path_match| Path::new(path_match.path_prefix.as_ref()).join(&path_match.path)) + .collect::>(); + results.sort(); + results + } } diff --git a/crates/file_finder2/src/file_finder.rs b/crates/file_finder2/src/file_finder.rs index a9619530c674bee9fc05a93853d9c140469a63ab..8faba99cb23a9bedffed5ab0c0f3a8147870b25a 100644 --- a/crates/file_finder2/src/file_finder.rs +++ b/crates/file_finder2/src/file_finder.rs @@ -354,15 +354,10 @@ impl FileFinderDelegate { let include_root_name = worktrees.len() > 1; let candidate_sets = worktrees .into_iter() - .map(|worktree| { - let worktree = worktree.read(cx); - PathMatchCandidateSet { - snapshot: worktree.snapshot(), - include_ignored: worktree - .root_entry() - .map_or(false, |entry| entry.is_ignored), - include_root_name, - } + .map(|worktree| PathMatchCandidateSet { + snapshot: worktree.read(cx).snapshot(), + include_ignored: true, + include_root_name, }) .collect::>(); @@ -1038,7 +1033,7 @@ mod tests { } #[gpui::test] - async fn test_ignored_files(cx: &mut TestAppContext) { + async fn test_ignored_root(cx: &mut TestAppContext) { let app_state = init_test(cx); app_state .fs @@ -1081,7 +1076,94 @@ mod tests { picker.delegate.spawn_search(test_path_like("hi"), cx) }) .await; - picker.update(cx, |picker, _| assert_eq!(picker.delegate.matches.len(), 7)); + picker.update(cx, |picker, _| { + assert_eq!( + collect_search_results(picker), + vec![ + PathBuf::from("ignored-root/happiness"), + PathBuf::from("ignored-root/height"), + PathBuf::from("ignored-root/hi"), + PathBuf::from("ignored-root/hiccup"), + PathBuf::from("tracked-root/happiness"), + PathBuf::from("tracked-root/height"), + PathBuf::from("tracked-root/hi"), + PathBuf::from("tracked-root/hiccup"), + ], + "All files in all roots (including gitignored) should be searched" + ) + }); + } + + #[gpui::test] + async fn test_ignored_files(cx: &mut TestAppContext) { + let app_state = init_test(cx); + app_state + .fs + .as_fake() + .insert_tree( + "/root", + json!({ + ".git": {}, + ".gitignore": "ignored_a\n.env\n", + "a": { + "banana_env": "11", + "bandana_env": "12", + }, + "ignored_a": { + "ignored_banana_env": "21", + "ignored_bandana_env": "22", + "ignored_nested": { + "ignored_nested_banana_env": "31", + "ignored_nested_bandana_env": "32", + }, + }, + ".env": "something", + }), + ) + .await; + + let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await; + + let (picker, workspace, cx) = build_find_picker(project, cx); + + cx.simulate_input("env"); + picker.update(cx, |picker, _| { + assert_eq!( + collect_search_results(picker), + vec![ + PathBuf::from(".env"), + PathBuf::from("a/banana_env"), + PathBuf::from("a/bandana_env"), + ], + "Root gitignored files and all non-gitignored files should be searched" + ) + }); + + let _ = workspace + .update(cx, |workspace, cx| { + workspace.open_abs_path( + PathBuf::from("/root/ignored_a/ignored_banana_env"), + true, + cx, + ) + }) + .await + .unwrap(); + cx.run_until_parked(); + cx.simulate_input("env"); + picker.update(cx, |picker, _| { + assert_eq!( + collect_search_results(picker), + vec![ + PathBuf::from(".env"), + PathBuf::from("a/banana_env"), + PathBuf::from("a/bandana_env"), + PathBuf::from("ignored_a/ignored_banana_env"), + PathBuf::from("ignored_a/ignored_bandana_env"), + ], + "Root gitignored dir got listed and its entries got into worktree, but all gitignored dirs below it were not listed. Old entries + new listed gitignored entries should be searched" + ) + }); } #[gpui::test] @@ -1846,4 +1928,20 @@ mod tests { .clone() }) } + + fn collect_search_results(picker: &Picker) -> Vec { + let matches = &picker.delegate.matches; + assert!( + matches.history.is_empty(), + "Should have no history matches, but got: {:?}", + matches.history + ); + let mut results = matches + .search + .iter() + .map(|path_match| Path::new(path_match.path_prefix.as_ref()).join(&path_match.path)) + .collect::>(); + results.sort(); + results + } } From 24970c1da9d19af78bd5dbdac9d873959770d06d Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 20 Dec 2023 16:33:10 -0800 Subject: [PATCH 237/644] Fix view handle leaks in ListState callbacks --- crates/collab_ui2/src/chat_panel.rs | 10 +++++++--- crates/collab_ui2/src/collab_panel.rs | 9 ++++++--- crates/collab_ui2/src/notification_panel.rs | 12 ++++++------ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/crates/collab_ui2/src/chat_panel.rs b/crates/collab_ui2/src/chat_panel.rs index f3f2a37171b32c5be5c610725951b199b1a28525..27eb4ca17a919b41135c3fb381a2f405e91b7802 100644 --- a/crates/collab_ui2/src/chat_panel.rs +++ b/crates/collab_ui2/src/chat_panel.rs @@ -92,11 +92,15 @@ impl ChatPanel { let workspace_handle = workspace.weak_handle(); - cx.build_view(|cx| { - let view: View = cx.view().clone(); + cx.build_view(|cx: &mut ViewContext| { + let view = cx.view().downgrade(); let message_list = ListState::new(0, gpui::ListAlignment::Bottom, px(1000.), move |ix, cx| { - view.update(cx, |view, cx| view.render_message(ix, cx)) + if let Some(view) = view.upgrade() { + view.update(cx, |view, cx| view.render_message(ix, cx)) + } else { + div().into_any() + } }); message_list.set_scroll_handler(cx.listener(|this, event: &ListScrollEvent, cx| { diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 35e2f8d7ed210dc3cfb2fbe59d1d399a3f2683b9..b19d0ba2ebeb500c379d4ab3df09f8dc7fb6a7e0 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -178,8 +178,6 @@ enum ListEntry { impl CollabPanel { pub fn new(workspace: &mut Workspace, cx: &mut ViewContext) -> View { cx.build_view(|cx| { - let view = cx.view().clone(); - let filter_editor = cx.build_view(|cx| { let mut editor = Editor::single_line(cx); editor.set_placeholder_text("Filter...", cx); @@ -219,9 +217,14 @@ impl CollabPanel { }) .detach(); + let view = cx.view().downgrade(); let list_state = ListState::new(0, gpui::ListAlignment::Top, px(1000.), move |ix, cx| { - view.update(cx, |view, cx| view.render_list_entry(ix, cx)) + if let Some(view) = view.upgrade() { + view.update(cx, |view, cx| view.render_list_entry(ix, cx)) + } else { + div().into_any() + } }); let mut this = Self { diff --git a/crates/collab_ui2/src/notification_panel.rs b/crates/collab_ui2/src/notification_panel.rs index 35288e810d645bf7ea2c158df071cc51fde4efc1..30c3439121541b4597642c1ed5a3e932f9c558d8 100644 --- a/crates/collab_ui2/src/notification_panel.rs +++ b/crates/collab_ui2/src/notification_panel.rs @@ -88,8 +88,6 @@ impl NotificationPanel { let workspace_handle = workspace.weak_handle(); cx.build_view(|cx: &mut ViewContext| { - let view = cx.view().clone(); - let mut status = client.status(); cx.spawn(|this, mut cx| async move { while let Some(_) = status.next().await { @@ -105,12 +103,14 @@ impl NotificationPanel { }) .detach(); + let view = cx.view().downgrade(); let notification_list = ListState::new(0, ListAlignment::Top, px(1000.), move |ix, cx| { - view.update(cx, |this, cx| { - this.render_notification(ix, cx) - .unwrap_or_else(|| div().into_any()) - }) + view.upgrade() + .and_then(|view| { + view.update(cx, |this, cx| this.render_notification(ix, cx)) + }) + .unwrap_or_else(|| div().into_any()) }); notification_list.set_scroll_handler(cx.listener( |this, event: &ListScrollEvent, cx| { From c56e7cd1241c61a6280e070cfa516d04d5007cae Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 19:53:57 -0700 Subject: [PATCH 238/644] Remove unused import --- crates/gpui2/src/style.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index 89527c9d5a7faa410630d0eb7118ce9d9009cdca..3e9593b0fd6635a1b9b2ce867e6fc465a47d80de 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -1,10 +1,10 @@ use std::{iter, mem, ops::Range}; use crate::{ - black, phi, point, quad, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds, - ContentMask, Corners, CornersRefinement, CursorStyle, DefiniteLength, Edges, EdgesRefinement, - Font, FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rgba, - SharedString, Size, SizeRefinement, Styled, TextRun, WindowContext, + black, phi, point, quad, rems, AbsoluteLength, BorrowWindow, Bounds, ContentMask, Corners, + CornersRefinement, CursorStyle, DefiniteLength, Edges, EdgesRefinement, Font, FontFeatures, + FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rgba, SharedString, Size, + SizeRefinement, Styled, TextRun, WindowContext, }; use collections::HashSet; use refineable::{Cascade, Refineable}; From 5747c9b7a1a856710ea9c5319bf73c6e98514c4c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 19:52:08 -0700 Subject: [PATCH 239/644] Clear pending keystrokes when an action is dispatched --- crates/gpui2/src/key_dispatch.rs | 2 ++ crates/gpui2/src/keymap/matcher.rs | 5 ----- crates/gpui2/src/window.rs | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/crates/gpui2/src/key_dispatch.rs b/crates/gpui2/src/key_dispatch.rs index 03adf887b5aa9e4a0b1cb77cefc81c5adb2e0529..3201e00bc6b6ebd6bbbbf9ff28dc01ff14246447 100644 --- a/crates/gpui2/src/key_dispatch.rs +++ b/crates/gpui2/src/key_dispatch.rs @@ -103,6 +103,8 @@ impl DispatchTree { .keystroke_matchers .remove_entry(self.context_stack.as_slice()) { + dbg!("preserve matcher", matcher.has_pending_keystrokes()); + self.keystroke_matchers.insert(context_stack, matcher); } } diff --git a/crates/gpui2/src/keymap/matcher.rs b/crates/gpui2/src/keymap/matcher.rs index 7d4e408e93deaf69df76a48d72c2c0eaeefe9bb6..9d74975c5635415ea3cf08dc8007f735fca981c3 100644 --- a/crates/gpui2/src/keymap/matcher.rs +++ b/crates/gpui2/src/keymap/matcher.rs @@ -19,11 +19,6 @@ impl KeystrokeMatcher { } } - // todo!("replace with a function that calls an FnMut for every binding matching the action") - // pub fn bindings_for_action(&self, action_id: TypeId) -> impl Iterator { - // self.keymap.lock().bindings_for_action(action_id) - // } - pub fn clear_pending(&mut self) { self.pending_keystrokes.clear(); } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 9e8347c783ca62121efc581b24b2e40c0209d228..49fb60efe406341ead1edbc18a45ed696ce3dba2 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -572,6 +572,17 @@ impl<'a> WindowContext<'a> { }); } + pub(crate) fn clear_pending_keystrokes(&mut self) { + self.window + .rendered_frame + .dispatch_tree + .clear_pending_keystrokes(); + self.window + .next_frame + .dispatch_tree + .clear_pending_keystrokes(); + } + /// Schedules the given function to be run at the end of the current effect cycle, allowing entities /// that are currently on the stack to be returned to the app. pub fn defer(&mut self, f: impl FnOnce(&mut WindowContext) + 'static) { @@ -1626,6 +1637,10 @@ impl<'a> WindowContext<'a> { } } + if !actions.is_empty() { + self.clear_pending_keystrokes(); + } + for action in actions { self.dispatch_action_on_node(node_id, action.boxed_clone()); if !self.propagate_event { From 036636ee808775fd96e8daca4222b72d17b34e9e Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Wed, 20 Dec 2023 23:54:50 -0500 Subject: [PATCH 240/644] Fix layout issues with feedback modal The feedback modal still needs a styling update --- crates/feedback2/src/feedback_modal.rs | 99 ++++++++++++-------------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/crates/feedback2/src/feedback_modal.rs b/crates/feedback2/src/feedback_modal.rs index 22904f3a0a2c14857e13bde40c2049e1a0982988..165a0a332cdf49b1419c94e0aaf389feeef60761 100644 --- a/crates/feedback2/src/feedback_modal.rs +++ b/crates/feedback2/src/feedback_modal.rs @@ -447,66 +447,61 @@ impl Render for FeedbackModal { .child(self.feedback_editor.clone()), ) .child( - div() + h_stack() + .bg(cx.theme().colors().editor_background) + .p_2() + .border() + .rounded_md() + .border_color(if self.valid_email_address() { + cx.theme().colors().border + } else { + red() + }) + .child(self.email_address_editor.clone()), + ) + .child( + h_stack() + .justify_between() + .gap_1() .child( - h_stack() - .bg(cx.theme().colors().editor_background) - .p_2() - .border() - .rounded_md() - .border_color(if self.valid_email_address() { - cx.theme().colors().border - } else { - red() - }) - .child(self.email_address_editor.clone()), + Button::new("community_repository", "Community Repository") + .style(ButtonStyle::Transparent) + .icon(Icon::ExternalLink) + .icon_position(IconPosition::End) + .icon_size(IconSize::Small) + .on_click(open_community_repo), ) .child( h_stack() - .justify_between() .gap_1() .child( - Button::new("community_repo", "Community Repo") - .style(ButtonStyle::Transparent) - .icon(Icon::ExternalLink) - .icon_position(IconPosition::End) - .icon_size(IconSize::Small) - .on_click(open_community_repo), + Button::new("cancel_feedback", "Cancel") + .style(ButtonStyle::Subtle) + .color(Color::Muted) + .on_click(cx.listener(move |_, _, cx| { + cx.spawn(|this, mut cx| async move { + this.update(&mut cx, |_, cx| cx.emit(DismissEvent)) + .ok(); + }) + .detach(); + })), ) .child( - h_stack() - .gap_1() - .child( - Button::new("cancel_feedback", "Cancel") - .style(ButtonStyle::Subtle) - .color(Color::Muted) - .on_click(cx.listener(move |_, _, cx| { - cx.spawn(|this, mut cx| async move { - this.update(&mut cx, |_, cx| { - cx.emit(DismissEvent) - }) - .ok(); - }) - .detach(); - })), - ) - .child( - Button::new("submit_feedback", submit_button_text) - .color(Color::Accent) - .style(ButtonStyle::Filled) - .on_click(cx.listener(|this, _, cx| { - this.submit(cx).detach(); - })) - .tooltip(move |cx| { - Tooltip::with_meta( - "Submit feedback to the Zed team.", - None, - provide_an_email_address, - cx, - ) - }) - .when(!self.can_submit(), |this| this.disabled(true)), - ), + Button::new("submit_feedback", submit_button_text) + .color(Color::Accent) + .style(ButtonStyle::Filled) + .on_click(cx.listener(|this, _, cx| { + this.submit(cx).detach(); + })) + .tooltip(move |cx| { + Tooltip::with_meta( + "Submit feedback to the Zed team.", + None, + provide_an_email_address, + cx, + ) + }) + .when(!self.can_submit(), |this| this.disabled(true)), ), ), ) From 73682daf38c023646b1fec6cffad9412661f059c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 09:41:48 +0100 Subject: [PATCH 241/644] Provide mut access to allocated arena struct via non-cloneable ArenaBox This commit also allows turning an `ArenaBox` into an `ArenaRef` when non-mutable access is required, which makes `ArenaRef: Clone`. This fixes a bug that prevented the command palette from reading all the available actions while the `command_palette::Toggle` action was being dispatched. --- crates/gpui2/src/arena.rs | 42 ++++++++++++--- crates/gpui2/src/element.rs | 4 +- crates/gpui2/src/key_dispatch.rs | 5 +- crates/gpui2/src/window.rs | 92 ++++++++++++-------------------- 4 files changed, 70 insertions(+), 73 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index ef66188a0ebcf7b6b4c4175bec2c7a571478f650..bb493a6d06487a5b07f7a2afbedc36d85fa9f715 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -52,7 +52,7 @@ impl Arena { } #[inline(always)] - pub fn alloc(&mut self, f: impl FnOnce() -> T) -> ArenaRef { + pub fn alloc(&mut self, f: impl FnOnce() -> T) -> ArenaBox { #[inline(always)] unsafe fn inner_writer(ptr: *mut T, f: F) where @@ -70,7 +70,7 @@ impl Arena { let next_offset = self.offset.add(layout.size()); assert!(next_offset <= self.end); - let result = ArenaRef { + let result = ArenaBox { ptr: self.offset.cast(), valid: self.valid.clone(), }; @@ -93,15 +93,15 @@ impl Drop for Arena { } } -pub struct ArenaRef { +pub struct ArenaBox { ptr: *mut T, valid: Rc>, } -impl ArenaRef { +impl ArenaBox { #[inline(always)] - pub fn map(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaRef { - ArenaRef { + pub fn map(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaBox { + ArenaBox { ptr: f(&mut self), valid: self.valid, } @@ -115,7 +115,7 @@ impl ArenaRef { } } -impl Deref for ArenaRef { +impl Deref for ArenaBox { type Target = T; #[inline(always)] @@ -125,7 +125,7 @@ impl Deref for ArenaRef { } } -impl DerefMut for ArenaRef { +impl DerefMut for ArenaBox { #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { self.validate(); @@ -133,6 +133,32 @@ impl DerefMut for ArenaRef { } } +pub struct ArenaRef(ArenaBox); + +impl From> for ArenaRef { + fn from(value: ArenaBox) -> Self { + ArenaRef(value) + } +} + +impl Clone for ArenaRef { + fn clone(&self) -> Self { + Self(ArenaBox { + ptr: self.0.ptr, + valid: self.0.valid.clone(), + }) + } +} + +impl Deref for ArenaRef { + type Target = T; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + self.0.deref() + } +} + #[cfg(test)] mod tests { use std::{cell::Cell, rc::Rc}; diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index d0ed50a3d54780130a0894b77c35493b0278e344..4201123a10110f540258b8afc462aeab63b3fb1a 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -1,5 +1,5 @@ use crate::{ - ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, Size, + ArenaBox, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, Size, ViewContext, WindowContext, ELEMENT_ARENA, }; use derive_more::{Deref, DerefMut}; @@ -405,7 +405,7 @@ where } } -pub struct AnyElement(ArenaRef); +pub struct AnyElement(ArenaBox); impl AnyElement { pub fn new(element: E) -> Self diff --git a/crates/gpui2/src/key_dispatch.rs b/crates/gpui2/src/key_dispatch.rs index 3201e00bc6b6ebd6bbbbf9ff28dc01ff14246447..cc6376e68d4c47e4476dd9ef2ae08a300f43727c 100644 --- a/crates/gpui2/src/key_dispatch.rs +++ b/crates/gpui2/src/key_dispatch.rs @@ -35,6 +35,7 @@ pub(crate) struct DispatchNode { type KeyListener = ArenaRef; +#[derive(Clone)] pub(crate) struct DispatchActionListener { pub(crate) action_type: TypeId, pub(crate) listener: ArenaRef, @@ -268,10 +269,6 @@ impl DispatchTree { &self.nodes[node_id.0] } - pub fn node_mut(&mut self, node_id: DispatchNodeId) -> &mut DispatchNode { - &mut self.nodes[node_id.0] - } - fn active_node(&mut self) -> &mut DispatchNode { let active_node_id = self.active_node_id(); &mut self.nodes[active_node_id.0] diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 49fb60efe406341ead1edbc18a45ed696ce3dba2..e57984fa0d0fe2ee577a162608159cc72ea0f848 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1,17 +1,15 @@ use crate::{ - arena::{Arena, ArenaRef}, - key_dispatch::DispatchActionListener, - px, size, transparent_black, Action, AnyDrag, AnyView, AppContext, AsyncWindowContext, - AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle, DevicePixels, DispatchNodeId, - DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter, FileDropEvent, Flatten, - FontId, GlobalElementId, GlyphId, Hsla, ImageData, InputEvent, IsZero, KeyBinding, KeyContext, - KeyDownEvent, KeystrokeEvent, LayoutId, Model, ModelContext, Modifiers, MonochromeSprite, - MouseButton, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, - PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, - RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, Scene, SceneBuilder, - Shadow, SharedString, Size, Style, SubscriberSet, Subscription, Surface, TaffyLayoutEngine, - Task, Underline, UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, - SUBPIXEL_VARIANTS, + px, size, transparent_black, Action, AnyDrag, AnyView, AppContext, Arena, ArenaBox, ArenaRef, + AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle, + DevicePixels, DispatchActionListener, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, + Entity, EntityId, EventEmitter, FileDropEvent, Flatten, FontId, GlobalElementId, GlyphId, Hsla, + ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent, LayoutId, + Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent, + Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, + PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, + RenderSvgParams, ScaledPixels, Scene, SceneBuilder, Shadow, SharedString, Size, Style, + SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, + VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS, }; use anyhow::{anyhow, Context as _, Result}; use collections::FxHashMap; @@ -96,7 +94,7 @@ impl DispatchPhase { } type AnyObserver = Box bool + 'static>; -type AnyMouseListener = ArenaRef; +type AnyMouseListener = ArenaBox; type AnyWindowFocusListener = Box bool + 'static>; struct FocusEvent { @@ -906,7 +904,10 @@ impl<'a> WindowContext<'a> { } }) .map(|handler| handler as _); - self.window.next_frame.dispatch_tree.on_key_event(listener); + self.window + .next_frame + .dispatch_tree + .on_key_event(ArenaRef::from(listener)); } /// Register an action listener on the window for the next frame. The type of action @@ -928,7 +929,7 @@ impl<'a> WindowContext<'a> { self.window .next_frame .dispatch_tree - .on_action(action_type, listener); + .on_action(action_type, ArenaRef::from(listener)); } pub fn is_action_available(&self, action: &dyn Action) -> bool { @@ -1339,7 +1340,7 @@ impl<'a> WindowContext<'a> { cx.window .next_frame .dispatch_tree - .on_action(*action_type, listener) + .on_action(*action_type, ArenaRef::from(listener)) } } @@ -1583,43 +1584,30 @@ impl<'a> WindowContext<'a> { self.propagate_event = true; for node_id in &dispatch_path { - let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); + let node = self.window.rendered_frame.dispatch_tree.node(*node_id); + if let Some(context) = node.context.clone() { context_stack.push(context); } - let key_listeners = mem::take(&mut node.key_listeners); - for key_listener in &key_listeners { + for key_listener in node.key_listeners.clone() { key_listener(event, DispatchPhase::Capture, self); if !self.propagate_event { - break; + return; } } - let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); - node.key_listeners = key_listeners; - - if !self.propagate_event { - return; - } } // Bubble phase for node_id in dispatch_path.iter().rev() { // Handle low level key events - let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); - let key_listeners = mem::take(&mut node.key_listeners); - for key_listener in &key_listeners { + let node = self.window.rendered_frame.dispatch_tree.node(*node_id); + for key_listener in node.key_listeners.clone() { key_listener(event, DispatchPhase::Bubble, self); if !self.propagate_event { - break; + return; } } - let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); - node.key_listeners = key_listeners; - - if !self.propagate_event { - return; - } // Match keystrokes let node = self.window.rendered_frame.dispatch_tree.node(*node_id); @@ -1667,52 +1655,38 @@ impl<'a> WindowContext<'a> { // Capture phase for node_id in &dispatch_path { - let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); - let action_listeners = mem::take(&mut node.action_listeners); + let node = self.window.rendered_frame.dispatch_tree.node(*node_id); for DispatchActionListener { action_type, listener, - } in &action_listeners + } in node.action_listeners.clone() { let any_action = action.as_any(); - if *action_type == any_action.type_id() { + if action_type == any_action.type_id() { listener(any_action, DispatchPhase::Capture, self); if !self.propagate_event { - break; + return; } } } - let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); - node.action_listeners = action_listeners; - - if !self.propagate_event { - return; - } } // Bubble phase for node_id in dispatch_path.iter().rev() { - let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); - let action_listeners = mem::take(&mut node.action_listeners); + let node = self.window.rendered_frame.dispatch_tree.node(*node_id); for DispatchActionListener { action_type, listener, - } in &action_listeners + } in node.action_listeners.clone() { let any_action = action.as_any(); - if *action_type == any_action.type_id() { + if action_type == any_action.type_id() { self.propagate_event = false; // Actions stop propagation by default during the bubble phase listener(any_action, DispatchPhase::Bubble, self); if !self.propagate_event { - break; + return; } } } - - let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id); - node.action_listeners = action_listeners; - if !self.propagate_event { - return; - } } } From c7933a6ad8d5c1ca8dd296e82ed39747bc74c95b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 09:44:54 +0100 Subject: [PATCH 242/644] Remove stray dbg --- crates/gpui2/src/key_dispatch.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/gpui2/src/key_dispatch.rs b/crates/gpui2/src/key_dispatch.rs index cc6376e68d4c47e4476dd9ef2ae08a300f43727c..a9d717ea1acb6866ab75165bcc4c6daedd268899 100644 --- a/crates/gpui2/src/key_dispatch.rs +++ b/crates/gpui2/src/key_dispatch.rs @@ -104,8 +104,6 @@ impl DispatchTree { .keystroke_matchers .remove_entry(self.context_stack.as_slice()) { - dbg!("preserve matcher", matcher.has_pending_keystrokes()); - self.keystroke_matchers.insert(context_stack, matcher); } } From b38a09526c5d7953daf3f7b9ad03481424bdb3ac Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 10:03:15 +0100 Subject: [PATCH 243/644] Fix stale scroll position in tab bar --- crates/gpui2/src/elements/div.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 74b414bb03ac98b5bfcd7617521ef5122171155b..7bda5966f59ee38fc8578328ca1ab9e69025ef62 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1467,6 +1467,14 @@ impl Interactivity { .clone(); let line_height = cx.line_height(); let scroll_max = (content_size - bounds.size).max(&Size::default()); + // Clamp scroll offset in case scroll max is smaller now (e.g., if children + // were removed or the bounds became larger). + { + let mut scroll_offset = scroll_offset.borrow_mut(); + scroll_offset.x = scroll_offset.x.clamp(-scroll_max.width, px(0.)); + scroll_offset.y = scroll_offset.x.clamp(-scroll_max.height, px(0.)); + } + let interactive_bounds = interactive_bounds.clone(); cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| { if phase == DispatchPhase::Bubble From b14c07ca54d40ec9184bdcdebe3223109cdeb09b Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 21 Dec 2023 14:27:13 +0200 Subject: [PATCH 244/644] Fix Zed cli actions: opening notes and joining calls --- crates/workspace2/src/workspace2.rs | 18 +++++- crates/zed2/src/main.rs | 97 +++++++++++++++++++++-------- 2 files changed, 87 insertions(+), 28 deletions(-) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 2bc0d403101841c03c0315902c919da7659184b9..b4508b9ddadee9fb47f345cbfe81286a58603b71 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -4023,7 +4023,23 @@ pub fn join_channel( }) } -pub fn activate_any_workspace_window(cx: &mut AsyncAppContext) -> Option { +pub async fn get_any_active_workspace( + app_state: Arc, + mut cx: AsyncAppContext, +) -> anyhow::Result> { + // find an existing workspace to focus and show call controls + let active_window = activate_any_workspace_window(&mut cx); + if active_window.is_none() { + cx.update(|cx| Workspace::new_local(vec![], app_state.clone(), None, cx))? + .await?; + } + activate_any_workspace_window(&mut cx) + .context("could not open zed")? + .downcast::() + .context("could not open zed workspace window") +} + +fn activate_any_workspace_window(cx: &mut AsyncAppContext) -> Option { cx.update(|cx| { for window in cx.windows() { let is_workspace = window.downcast::().is_some(); diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index f4d9aa2510f4739659f4749fd877d9ea8de76c98..93643648b8c78b13556d97e6de2f491b99642a67 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -9,6 +9,7 @@ use backtrace::Backtrace; use chrono::Utc; use cli::FORCE_CLI_MODE_ENV_VAR_NAME; use client::{Client, UserStore}; +use collab_ui::channel_view::ChannelView; use db::kvp::KEY_VALUE_STORE; use editor::Editor; use fs::RealFs; @@ -274,22 +275,36 @@ fn main() { cx.spawn(move |cx| handle_cli_connection(connection, app_state, cx)) .detach(); } - Ok(Some(OpenRequest::JoinChannel { channel_id: _ })) => { + Ok(Some(OpenRequest::JoinChannel { channel_id })) => { triggered_authentication = true; let app_state = app_state.clone(); let client = client.clone(); - cx.spawn(|mut cx| async move { + cx.spawn(|cx| async move { // ignore errors here, we'll show a generic "not signed in" let _ = authenticate(client, &cx).await; - //todo!() - // cx.update(|cx| workspace::join_channel(channel_id, app_state, None, cx)) - // .await + cx.update(|cx| workspace::join_channel(channel_id, app_state, None, cx))? + .await?; anyhow::Ok(()) }) - .detach_and_log_err(cx) + .detach_and_log_err(cx); } - Ok(Some(OpenRequest::OpenChannelNotes { channel_id: _ })) => { - todo!() + Ok(Some(OpenRequest::OpenChannelNotes { channel_id })) => { + triggered_authentication = true; + let app_state = app_state.clone(); + let client = client.clone(); + cx.spawn(|mut cx| async move { + // ignore errors here, we'll show a generic "not signed in" + let _ = authenticate(client, &cx).await; + let workspace_window = + workspace::get_any_active_workspace(app_state, cx.clone()).await?; + let _ = workspace_window + .update(&mut cx, |_, cx| { + ChannelView::open(channel_id, cx.view().clone(), cx) + })? + .await?; + anyhow::Ok(()) + }) + .detach_and_log_err(cx); } Ok(None) | Err(_) => cx .spawn({ @@ -300,25 +315,53 @@ fn main() { } let app_state = app_state.clone(); - cx.spawn(|cx| async move { - while let Some(request) = open_rx.next().await { - match request { - OpenRequest::Paths { paths } => { - cx.update(|cx| open_paths_and_log_errs(&paths, &app_state, cx)) - .ok(); - } - OpenRequest::CliConnection { connection } => { - let app_state = app_state.clone(); - cx.spawn(move |cx| { - handle_cli_connection(connection, app_state.clone(), cx) - }) - .detach(); - } - OpenRequest::JoinChannel { channel_id: _ } => { - todo!() - } - OpenRequest::OpenChannelNotes { channel_id: _ } => { - todo!() + let closure_client = client.clone(); + cx.spawn(move |mut cx| { + let client = closure_client.clone(); + async move { + while let Some(request) = open_rx.next().await { + match request { + OpenRequest::Paths { paths } => { + cx.update(|cx| open_paths_and_log_errs(&paths, &app_state, cx)) + .ok(); + } + OpenRequest::CliConnection { connection } => { + let app_state = app_state.clone(); + cx.spawn(move |cx| { + handle_cli_connection(connection, app_state.clone(), cx) + }) + .detach(); + } + OpenRequest::JoinChannel { channel_id } => { + let app_state = app_state.clone(); + cx.update(|mut cx| { + cx.spawn(|cx| async move { + cx.update(|cx| { + workspace::join_channel(channel_id, app_state, None, cx) + })? + .await?; + anyhow::Ok(()) + }) + .detach_and_log_err(&mut cx); + }) + .log_err(); + } + OpenRequest::OpenChannelNotes { channel_id } => { + let app_state = app_state.clone(); + let open_notes_task = cx.spawn(|mut cx| async move { + let workspace_window = + workspace::get_any_active_workspace(app_state, cx.clone()) + .await?; + let _ = workspace_window + .update(&mut cx, |_, cx| { + ChannelView::open(channel_id, cx.view().clone(), cx) + })? + .await?; + anyhow::Ok(()) + }); + cx.update(|cx| open_notes_task.detach_and_log_err(cx)) + .log_err(); + } } } } From b0ee7b2fb99a331ab9c1d4a15b231f4064be5692 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 14:28:06 +0100 Subject: [PATCH 245/644] Fix clicking on "+" button not working when a tab was underneath We were mistakenly pushing an opaque layer without intersecting it with the content mask. Also, we were pushing two opaque layers for the same div unnecessarily. --- crates/gpui2/src/elements/div.rs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 7bda5966f59ee38fc8578328ca1ab9e69025ef62..e6fc58e872dbb5c054bfb0bd11a98f3713586a01 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1092,19 +1092,19 @@ impl Interactivity { }); } + let interactive_bounds = InteractiveBounds { + bounds: bounds.intersect(&cx.content_mask().bounds), + stacking_order: cx.stacking_order().clone(), + }; + if self.block_mouse || style.background.as_ref().is_some_and(|fill| { fill.color().is_some_and(|color| !color.is_transparent()) }) { - cx.add_opaque_layer(bounds) + cx.add_opaque_layer(interactive_bounds.bounds); } - let interactive_bounds = InteractiveBounds { - bounds: bounds.intersect(&cx.content_mask().bounds), - stacking_order: cx.stacking_order().clone(), - }; - if !cx.has_active_drag() { if let Some(mouse_cursor) = style.mouse_cursor { let mouse_position = &cx.mouse_position(); @@ -1534,15 +1534,7 @@ impl Interactivity { cx.on_action(action_type, listener) } - cx.with_z_index(style.z_index.unwrap_or(0), |cx| { - if style.background.as_ref().is_some_and(|fill| { - fill.color().is_some_and(|color| !color.is_transparent()) - }) { - cx.add_opaque_layer(bounds) - } - - f(&style, scroll_offset.unwrap_or_default(), cx) - }) + f(&style, scroll_offset.unwrap_or_default(), cx) }, ); From 73b527ec8fae4a33fd9dd1439f492246bd71237d Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Thu, 21 Dec 2023 09:04:54 -0500 Subject: [PATCH 246/644] Store email address on modal close --- crates/feedback2/src/feedback_modal.rs | 40 +++++++++++++++----------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/crates/feedback2/src/feedback_modal.rs b/crates/feedback2/src/feedback_modal.rs index 165a0a332cdf49b1419c94e0aaf389feeef60761..d22d5d908b1855abf8776f12c7699096c53f9c3d 100644 --- a/crates/feedback2/src/feedback_modal.rs +++ b/crates/feedback2/src/feedback_modal.rs @@ -87,6 +87,8 @@ impl EventEmitter for FeedbackModal {} impl ModalView for FeedbackModal { fn on_before_dismiss(&mut self, cx: &mut ViewContext) -> bool { + self.update_email_in_store(cx); + if self.dismiss_modal { return true; } @@ -214,21 +216,6 @@ impl FeedbackModal { cx.spawn(|this, mut cx| async move { let answer = answer.await.ok(); if answer == Some(0) { - match email.clone() { - Some(email) => { - KEY_VALUE_STORE - .write_kvp(DATABASE_KEY_NAME.to_string(), email) - .await - .ok(); - } - None => { - KEY_VALUE_STORE - .delete_kvp(DATABASE_KEY_NAME.to_string()) - .await - .ok(); - } - }; - this.update(&mut cx, |this, cx| { this.submission_state = Some(SubmissionState::CannotSubmit { reason: CannotSubmitReason::AwaitingSubmission, @@ -351,6 +338,28 @@ impl FeedbackModal { } } + fn update_email_in_store(&self, cx: &mut ViewContext) { + let email = self.email_address_editor.read(cx).text_option(cx); + + cx.spawn(|_, _| async move { + match email { + Some(email) => { + KEY_VALUE_STORE + .write_kvp(DATABASE_KEY_NAME.to_string(), email) + .await + .ok(); + } + None => { + KEY_VALUE_STORE + .delete_kvp(DATABASE_KEY_NAME.to_string()) + .await + .ok(); + } + } + }) + .detach(); + } + fn valid_email_address(&self) -> bool { !self.in_invalid_state(InvalidStateFlags::EmailAddress) } @@ -508,7 +517,6 @@ impl Render for FeedbackModal { } } -// TODO: Maybe store email address whenever the modal is closed, versus just on submit, so users can remove it if they want without submitting // TODO: Testing of various button states, dismissal prompts, etc. // #[cfg(test)] From e2a447420078fa194f772dbc031d57e297cd3d40 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 15:22:49 +0100 Subject: [PATCH 247/644] Allow scrolling saved conversations --- crates/assistant2/src/assistant_panel.rs | 45 +++++++++++++++--------- crates/gpui2/src/element.rs | 11 ++++++ 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 7b15619758679b5e9246780813de63f0f1371261..2c1493cdfe93fdd5b392acd91390079bae9e378e 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -29,12 +29,12 @@ use editor::{ use fs::Fs; use futures::StreamExt; use gpui::{ - div, point, relative, rems, uniform_list, Action, AnyElement, AppContext, AsyncWindowContext, - ClipboardItem, Context, Div, EventEmitter, FocusHandle, Focusable, FocusableView, FontStyle, - FontWeight, HighlightStyle, InteractiveElement, IntoElement, Model, ModelContext, - ParentElement, Pixels, PromptLevel, Render, SharedString, StatefulInteractiveElement, Styled, - Subscription, Task, TextStyle, UniformListScrollHandle, View, ViewContext, VisualContext, - WeakModel, WeakView, WhiteSpace, WindowContext, + canvas, div, point, relative, rems, uniform_list, Action, AnyElement, AppContext, + AsyncWindowContext, AvailableSpace, ClipboardItem, Context, Div, EventEmitter, FocusHandle, + Focusable, FocusableView, FontStyle, FontWeight, HighlightStyle, InteractiveElement, + IntoElement, Model, ModelContext, ParentElement, Pixels, PromptLevel, Render, SharedString, + StatefulInteractiveElement, Styled, Subscription, Task, TextStyle, UniformListScrollHandle, + View, ViewContext, VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext, }; use language::{language_settings::SoftWrap, Buffer, LanguageRegistry, ToOffset as _}; use project::Project; @@ -1184,17 +1184,28 @@ impl Render for AssistantPanel { .child(if let Some(editor) = self.active_editor() { editor.clone().into_any_element() } else { - uniform_list( - cx.view().clone(), - "saved_conversations", - self.saved_conversations.len(), - |this, range, cx| { - range - .map(|ix| this.render_saved_conversation(ix, cx)) - .collect() - }, - ) - .track_scroll(self.saved_conversations_scroll_handle.clone()) + let view = cx.view().clone(); + let scroll_handle = self.saved_conversations_scroll_handle.clone(); + let conversation_count = self.saved_conversations.len(); + canvas(move |bounds, cx| { + uniform_list( + view, + "saved_conversations", + conversation_count, + |this, range, cx| { + range + .map(|ix| this.render_saved_conversation(ix, cx)) + .collect() + }, + ) + .track_scroll(scroll_handle) + .draw( + bounds.origin, + bounds.size, + cx, + ); + }) + .size_full() .into_any_element() }), ) diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index 4201123a10110f540258b8afc462aeab63b3fb1a..3901db73e05c6148b813dc3937dd42843b7bc6b7 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -23,6 +23,17 @@ pub trait IntoElement: Sized { self.into_element().into_any() } + fn draw(self, origin: Point, available_space: Size, cx: &mut WindowContext) + where + T: Clone + Default + Debug + Into, + { + let element = DrawableElement { + element: Some(self.into_element()), + phase: ElementDrawPhase::Start, + }; + DrawableElement::draw(element, origin, available_space.map(Into::into), cx); + } + fn draw_and_update_state( self, origin: Point, From 176a022b10ac6c9e4ca6237a6c44e73de4044a88 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 15:23:16 +0100 Subject: [PATCH 248/644] Correctly clamp scroll offset vertically --- crates/gpui2/src/elements/div.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index e6fc58e872dbb5c054bfb0bd11a98f3713586a01..90af9e130e79a375cd339e03880790c8cc1acdd6 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1472,7 +1472,7 @@ impl Interactivity { { let mut scroll_offset = scroll_offset.borrow_mut(); scroll_offset.x = scroll_offset.x.clamp(-scroll_max.width, px(0.)); - scroll_offset.y = scroll_offset.x.clamp(-scroll_max.height, px(0.)); + scroll_offset.y = scroll_offset.y.clamp(-scroll_max.height, px(0.)); } let interactive_bounds = interactive_bounds.clone(); From 5e4557ed1634807e9ae8199a80d059ac00c42f75 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 15:26:41 +0100 Subject: [PATCH 249/644] Fix warnings --- crates/assistant2/src/assistant_panel.rs | 6 +++--- crates/terminal_view2/src/terminal_element.rs | 18 ++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 2c1493cdfe93fdd5b392acd91390079bae9e378e..85d3f6f74083afe982ce7bc377426dcb08b45d05 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -30,9 +30,9 @@ use fs::Fs; use futures::StreamExt; use gpui::{ canvas, div, point, relative, rems, uniform_list, Action, AnyElement, AppContext, - AsyncWindowContext, AvailableSpace, ClipboardItem, Context, Div, EventEmitter, FocusHandle, - Focusable, FocusableView, FontStyle, FontWeight, HighlightStyle, InteractiveElement, - IntoElement, Model, ModelContext, ParentElement, Pixels, PromptLevel, Render, SharedString, + AsyncWindowContext, ClipboardItem, Context, Div, EventEmitter, FocusHandle, Focusable, + FocusableView, FontStyle, FontWeight, HighlightStyle, InteractiveElement, IntoElement, Model, + ModelContext, ParentElement, Pixels, PromptLevel, Render, SharedString, StatefulInteractiveElement, Styled, Subscription, Task, TextStyle, UniformListScrollHandle, View, ViewContext, VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext, }; diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index f30c1cf1bc186f3d9f121739f6a00bdf59fb0c75..3b7b32dd6f609a2dc22668805cfa8adeda27bae0 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -1,11 +1,11 @@ use editor::{Cursor, HighlightedRange, HighlightedRangeLine}; use gpui::{ - black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace, - BorrowWindow, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, - FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, - Interactivity, IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, - Pixels, PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, - Styled, TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, + black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, BorrowWindow, + Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, FontStyle, + FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, Interactivity, + IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels, + PlatformInputHandler, Point, Rgba, ShapedLine, StatefulInteractiveElement, Styled, TextRun, + TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, }; use itertools::Itertools; use language::CursorShape; @@ -854,10 +854,8 @@ impl Element for TerminalElement { }); } - if let Some(mut element) = layout.hyperlink_tooltip.take() { - let width: AvailableSpace = bounds.size.width.into(); - let height: AvailableSpace = bounds.size.height.into(); - element.draw(origin, Size { width, height }, cx) + if let Some(element) = layout.hyperlink_tooltip.take() { + element.draw(origin, bounds.size, cx) } }); } From 01947ed730056b3bfa89c3c5e3850838417f7a06 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 15:32:05 +0100 Subject: [PATCH 250/644] Use existing AnyElement::draw --- crates/assistant2/src/assistant_panel.rs | 9 +++++---- crates/gpui2/src/element.rs | 11 ----------- crates/terminal_view2/src/terminal_element.rs | 16 ++++++++-------- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 85d3f6f74083afe982ce7bc377426dcb08b45d05..d50fdccd6f5f6dbd2e65e515cbab60a2633f89fb 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -30,9 +30,9 @@ use fs::Fs; use futures::StreamExt; use gpui::{ canvas, div, point, relative, rems, uniform_list, Action, AnyElement, AppContext, - AsyncWindowContext, ClipboardItem, Context, Div, EventEmitter, FocusHandle, Focusable, - FocusableView, FontStyle, FontWeight, HighlightStyle, InteractiveElement, IntoElement, Model, - ModelContext, ParentElement, Pixels, PromptLevel, Render, SharedString, + AsyncWindowContext, AvailableSpace, ClipboardItem, Context, Div, EventEmitter, FocusHandle, + Focusable, FocusableView, FontStyle, FontWeight, HighlightStyle, InteractiveElement, + IntoElement, Model, ModelContext, ParentElement, Pixels, PromptLevel, Render, SharedString, StatefulInteractiveElement, Styled, Subscription, Task, TextStyle, UniformListScrollHandle, View, ViewContext, VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext, }; @@ -1199,9 +1199,10 @@ impl Render for AssistantPanel { }, ) .track_scroll(scroll_handle) + .into_any_element() .draw( bounds.origin, - bounds.size, + bounds.size.map(AvailableSpace::Definite), cx, ); }) diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index 3901db73e05c6148b813dc3937dd42843b7bc6b7..4201123a10110f540258b8afc462aeab63b3fb1a 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -23,17 +23,6 @@ pub trait IntoElement: Sized { self.into_element().into_any() } - fn draw(self, origin: Point, available_space: Size, cx: &mut WindowContext) - where - T: Clone + Default + Debug + Into, - { - let element = DrawableElement { - element: Some(self.into_element()), - phase: ElementDrawPhase::Start, - }; - DrawableElement::draw(element, origin, available_space.map(Into::into), cx); - } - fn draw_and_update_state( self, origin: Point, diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index 3b7b32dd6f609a2dc22668805cfa8adeda27bae0..ec1e1736c31a3ab24911c83f46d2edf734a2b2eb 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -1,11 +1,11 @@ use editor::{Cursor, HighlightedRange, HighlightedRangeLine}; use gpui::{ - black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, BorrowWindow, - Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, FontStyle, - FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, Interactivity, - IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels, - PlatformInputHandler, Point, Rgba, ShapedLine, StatefulInteractiveElement, Styled, TextRun, - TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, + black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace, + BorrowWindow, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, + FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, + Interactivity, IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, + Pixels, PlatformInputHandler, Point, Rgba, ShapedLine, StatefulInteractiveElement, Styled, + TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, }; use itertools::Itertools; use language::CursorShape; @@ -854,8 +854,8 @@ impl Element for TerminalElement { }); } - if let Some(element) = layout.hyperlink_tooltip.take() { - element.draw(origin, bounds.size, cx) + if let Some(mut element) = layout.hyperlink_tooltip.take() { + element.draw(origin, bounds.size.map(AvailableSpace::Definite), cx) } }); } From 7a9c4057a7f2eb67e55439f74635f6c9d063674b Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 10:56:52 -0500 Subject: [PATCH 251/644] Increase inline assistant editor's line height (#3757) This PR increases the line height for the inline assistant editor. This fixes an issue where descenders were being clipped. Release Notes: - N/A --- crates/assistant2/src/assistant_panel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index d50fdccd6f5f6dbd2e65e515cbab60a2633f89fb..84576c5262783e66a79be96eb24e142dbd83597c 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -3066,7 +3066,7 @@ impl InlineAssistant { font_size: rems(0.875).into(), font_weight: FontWeight::NORMAL, font_style: FontStyle::Normal, - line_height: relative(1.).into(), + line_height: relative(1.3).into(), background_color: None, underline: None, white_space: WhiteSpace::Normal, From 67f76468f1299bbf79b7ef54646302cd75f0fc22 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 16:58:36 +0100 Subject: [PATCH 252/644] Replace `BspSplitter` with brute-force sorting of primitives --- Cargo.lock | 12 ---- crates/gpui2/Cargo.toml | 1 - crates/gpui2/src/scene.rs | 125 +++++++------------------------------- 3 files changed, 23 insertions(+), 115 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cddd744a9f8ffa5b6a7f02dfe49066a0ba0e6e58..8b749a4f5537a2c775e85ff66f285f462ebb36e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4060,7 +4060,6 @@ dependencies = [ "parking", "parking_lot 0.11.2", "pathfinder_geometry", - "plane-split", "png", "postage", "rand 0.8.5", @@ -6656,17 +6655,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "plane-split" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f7d82649829ecdef8e258790b0587acf0a8403f0ce963473d8e918acc1643" -dependencies = [ - "euclid", - "log", - "smallvec", -] - [[package]] name = "plist" version = "1.5.0" diff --git a/crates/gpui2/Cargo.toml b/crates/gpui2/Cargo.toml index afb5d3ea0ce7080830bbcb1eb86aad62b8f7432c..bf0ac955a5ec20d8a9ca6d0c0bac0bc5e7c95542 100644 --- a/crates/gpui2/Cargo.toml +++ b/crates/gpui2/Cargo.toml @@ -56,7 +56,6 @@ uuid = { version = "1.1.2", features = ["v4"] } waker-fn = "1.1.0" slotmap = "1.0.6" schemars.workspace = true -plane-split = "0.18.0" bitflags = "2.4.0" [dev-dependencies] diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index e6b601b62f17cf087748f8ce4e672eab14b13fb8..b26d73d7f6b6083af42b9a74496fc924be833a80 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -3,8 +3,6 @@ use crate::{ ScaledPixels, StackingOrder, }; use collections::BTreeMap; -use etagere::euclid::{Point3D, Vector3D}; -use plane_split::{BspSplitter, Polygon as BspPolygon}; use std::{fmt::Debug, iter::Peekable, mem, slice}; // Exported to metal @@ -19,7 +17,6 @@ pub type DrawOrder = u32; pub(crate) struct SceneBuilder { last_order: Option<(StackingOrder, LayerId)>, layers_by_order: BTreeMap, - splitter: BspSplitter<(PrimitiveKind, usize)>, shadows: Vec, quads: Vec, paths: Vec>, @@ -34,7 +31,6 @@ impl Default for SceneBuilder { SceneBuilder { last_order: None, layers_by_order: BTreeMap::new(), - splitter: BspSplitter::new(), shadows: Vec::new(), quads: Vec::new(), paths: Vec::new(), @@ -49,102 +45,47 @@ impl Default for SceneBuilder { impl SceneBuilder { pub fn build(&mut self) -> Scene { // Map each layer id to a float between 0. and 1., with 1. closer to the viewer. - let mut layer_z_values = vec![0.; self.layers_by_order.len()]; + let mut orders = vec![0; self.layers_by_order.len()]; for (ix, layer_id) in self.layers_by_order.values().enumerate() { - layer_z_values[*layer_id as usize] = ix as f32 / self.layers_by_order.len() as f32; + orders[*layer_id as usize] = ix as u32; } self.layers_by_order.clear(); self.last_order = None; - // Add all primitives to the BSP splitter to determine draw order - self.splitter.reset(); - - for (ix, shadow) in self.shadows.iter().enumerate() { - let z = layer_z_values[shadow.order as LayerId as usize]; - self.splitter - .add(shadow.bounds.to_bsp_polygon(z, (PrimitiveKind::Shadow, ix))); - } - - for (ix, quad) in self.quads.iter().enumerate() { - let z = layer_z_values[quad.order as LayerId as usize]; - self.splitter - .add(quad.bounds.to_bsp_polygon(z, (PrimitiveKind::Quad, ix))); + for shadow in &mut self.shadows { + shadow.order = orders[shadow.order as usize]; } + self.shadows.sort_by_key(|shadow| shadow.order); - for (ix, path) in self.paths.iter().enumerate() { - let z = layer_z_values[path.order as LayerId as usize]; - self.splitter - .add(path.bounds.to_bsp_polygon(z, (PrimitiveKind::Path, ix))); + for quad in &mut self.quads { + quad.order = orders[quad.order as usize]; } + self.quads.sort_by_key(|quad| quad.order); - for (ix, underline) in self.underlines.iter().enumerate() { - let z = layer_z_values[underline.order as LayerId as usize]; - self.splitter.add( - underline - .bounds - .to_bsp_polygon(z, (PrimitiveKind::Underline, ix)), - ); + for path in &mut self.paths { + path.order = orders[path.order as usize]; } + self.paths.sort_by_key(|path| path.order); - for (ix, monochrome_sprite) in self.monochrome_sprites.iter().enumerate() { - let z = layer_z_values[monochrome_sprite.order as LayerId as usize]; - self.splitter.add( - monochrome_sprite - .bounds - .to_bsp_polygon(z, (PrimitiveKind::MonochromeSprite, ix)), - ); + for underline in &mut self.underlines { + underline.order = orders[underline.order as usize]; } + self.underlines.sort_by_key(|underline| underline.order); - for (ix, polychrome_sprite) in self.polychrome_sprites.iter().enumerate() { - let z = layer_z_values[polychrome_sprite.order as LayerId as usize]; - self.splitter.add( - polychrome_sprite - .bounds - .to_bsp_polygon(z, (PrimitiveKind::PolychromeSprite, ix)), - ); + for monochrome_sprite in &mut self.monochrome_sprites { + monochrome_sprite.order = orders[monochrome_sprite.order as usize]; } + self.monochrome_sprites.sort_by_key(|sprite| sprite.order); - for (ix, surface) in self.surfaces.iter().enumerate() { - let z = layer_z_values[surface.order as LayerId as usize]; - self.splitter.add( - surface - .bounds - .to_bsp_polygon(z, (PrimitiveKind::Surface, ix)), - ); + for polychrome_sprite in &mut self.polychrome_sprites { + polychrome_sprite.order = orders[polychrome_sprite.order as usize]; } + self.polychrome_sprites.sort_by_key(|sprite| sprite.order); - // Sort all polygons, then reassign the order field of each primitive to `draw_order` - // We need primitives to be repr(C), hence the weird reuse of the order field for two different types. - for (draw_order, polygon) in self - .splitter - .sort(Vector3D::new(0., 0., 1.)) - .iter() - .enumerate() - { - match polygon.anchor { - (PrimitiveKind::Shadow, ix) => self.shadows[ix].order = draw_order as DrawOrder, - (PrimitiveKind::Quad, ix) => self.quads[ix].order = draw_order as DrawOrder, - (PrimitiveKind::Path, ix) => self.paths[ix].order = draw_order as DrawOrder, - (PrimitiveKind::Underline, ix) => { - self.underlines[ix].order = draw_order as DrawOrder - } - (PrimitiveKind::MonochromeSprite, ix) => { - self.monochrome_sprites[ix].order = draw_order as DrawOrder - } - (PrimitiveKind::PolychromeSprite, ix) => { - self.polychrome_sprites[ix].order = draw_order as DrawOrder - } - (PrimitiveKind::Surface, ix) => self.surfaces[ix].order = draw_order as DrawOrder, - } + for surface in &mut self.surfaces { + surface.order = orders[surface.order as usize]; } - - self.shadows.sort_unstable(); - self.quads.sort_unstable(); - self.paths.sort_unstable(); - self.underlines.sort_unstable(); - self.monochrome_sprites.sort_unstable(); - self.polychrome_sprites.sort_unstable(); - self.surfaces.sort_unstable(); + self.surfaces.sort_by_key(|surface| surface.order); Scene { shadows: mem::take(&mut self.shadows), @@ -845,23 +786,3 @@ impl PathVertex { #[derive(Copy, Clone, Debug)] pub struct AtlasId(pub(crate) usize); - -impl Bounds { - fn to_bsp_polygon(&self, z: f32, anchor: A) -> BspPolygon { - let upper_left = self.origin; - let upper_right = self.upper_right(); - let lower_right = self.lower_right(); - let lower_left = self.lower_left(); - - BspPolygon::from_points( - [ - Point3D::new(upper_left.x.into(), upper_left.y.into(), z as f64), - Point3D::new(upper_right.x.into(), upper_right.y.into(), z as f64), - Point3D::new(lower_right.x.into(), lower_right.y.into(), z as f64), - Point3D::new(lower_left.x.into(), lower_left.y.into(), z as f64), - ], - anchor, - ) - .expect("Polygon should not be empty") - } -} From c03c0d50d5f26bacba46dab50f3977cc5db4f98d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 17:54:13 +0100 Subject: [PATCH 253/644] Use smaller quads to draw borders Co-Authored-By: Nathan Sobo --- crates/gpui2/src/geometry.rs | 21 +++++++++++++ crates/gpui2/src/style.rs | 60 +++++++++++++++++++++++++++++++++--- crates/gpui2/src/window.rs | 1 + 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/crates/gpui2/src/geometry.rs b/crates/gpui2/src/geometry.rs index f58435d7b9a2e9b3fa48062d2e28ed21502c1ca1..6b4d9ae807b581eff4fe38baf913843e43bd8c83 100644 --- a/crates/gpui2/src/geometry.rs +++ b/crates/gpui2/src/geometry.rs @@ -1590,6 +1590,15 @@ impl Edges { left: self.left.scale(factor), } } + + /// Returns the maximum value of any edge. + /// + /// # Returns + /// + /// The maximum `Pixels` value among all four edges. + pub fn max(&self) -> Pixels { + self.top.max(self.right).max(self.bottom).max(self.left) + } } impl Into> for f32 { @@ -1740,6 +1749,18 @@ impl Corners { bottom_left: self.bottom_left.scale(factor), } } + + /// Returns the maximum value of any corner. + /// + /// # Returns + /// + /// The maximum `Pixels` value among all four corners. + pub fn max(&self) -> Pixels { + self.top_left + .max(self.top_right) + .max(self.bottom_right) + .max(self.bottom_left) + } } impl Corners { diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index 3e9593b0fd6635a1b9b2ce867e6fc465a47d80de..de54da79b3d0eb1e7489962143dbbc7d0dc0809f 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -402,13 +402,65 @@ impl Style { if self.is_border_visible() { cx.with_z_index(3, |cx| { - cx.paint_quad(quad( + let corner_radii = self.corner_radii.to_pixels(bounds.size, rem_size); + let border_widths = self.border_widths.to_pixels(rem_size); + let max_border_width = border_widths.max(); + let max_corner_radius = corner_radii.max(); + + let top_bounds = Bounds::from_corners( + bounds.origin, + bounds.upper_right() + + point(Pixels::ZERO, max_border_width.max(max_corner_radius)), + ); + let bottom_bounds = Bounds::from_corners( + bounds.lower_left() + - point(Pixels::ZERO, max_border_width.max(max_corner_radius)), + bounds.lower_right(), + ); + let left_bounds = Bounds::from_corners( + top_bounds.lower_left(), + bottom_bounds.origin + point(max_border_width, Pixels::ZERO), + ); + let right_bounds = Bounds::from_corners( + top_bounds.lower_right() - point(max_border_width, Pixels::ZERO), + bottom_bounds.upper_right(), + ); + + let quad = quad( bounds, - self.corner_radii.to_pixels(bounds.size, rem_size), + corner_radii, Hsla::transparent_black(), - self.border_widths.to_pixels(rem_size), + border_widths, self.border_color.unwrap_or_default(), - )); + ); + + cx.with_content_mask(Some(ContentMask { bounds: top_bounds }), |cx| { + cx.paint_quad(quad.clone()); + }); + cx.with_content_mask( + Some(ContentMask { + bounds: right_bounds, + }), + |cx| { + cx.paint_quad(quad.clone()); + }, + ); + cx.with_content_mask( + Some(ContentMask { + bounds: bottom_bounds, + }), + |cx| { + cx.paint_quad(quad.clone()); + }, + ); + cx.with_content_mask( + Some(ContentMask { + bounds: left_bounds, + }), + |cx| { + cx.paint_quad(quad); + }, + ); }); } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index e57984fa0d0fe2ee577a162608159cc72ea0f848..c20e2f7b94a3337e05b1fa755fdb624d93396213 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -3074,6 +3074,7 @@ impl From<(&'static str, u64)> for ElementId { } /// A rectangle, to be rendered on the screen by GPUI at the given position and size. +#[derive(Clone)] pub struct PaintQuad { bounds: Bounds, corner_radii: Corners, From 53a4b711dd79b7e7a5e79a13c509605962428e16 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 17:55:26 +0100 Subject: [PATCH 254/644] Delete stray comment --- crates/gpui2/src/scene.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index b26d73d7f6b6083af42b9a74496fc924be833a80..cb62ce314f8147455768a359717c4168d88b7edb 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -44,7 +44,6 @@ impl Default for SceneBuilder { impl SceneBuilder { pub fn build(&mut self) -> Scene { - // Map each layer id to a float between 0. and 1., with 1. closer to the viewer. let mut orders = vec![0; self.layers_by_order.len()]; for (ix, layer_id) in self.layers_by_order.values().enumerate() { orders[*layer_id as usize] = ix as u32; From 824b68788fbd99b454ff18c7aeb53d50bb40f2e2 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 12:15:11 -0500 Subject: [PATCH 255/644] Improve chat panel styling (#3758) This PR improves the chat panel styling, especially with regards to the spacing. Release Notes: - N/A --- crates/collab_ui2/src/chat_panel.rs | 172 ++++++++++++++------------- crates/ui2/src/components/tab_bar.rs | 44 +++---- 2 files changed, 116 insertions(+), 100 deletions(-) diff --git a/crates/collab_ui2/src/chat_panel.rs b/crates/collab_ui2/src/chat_panel.rs index 27eb4ca17a919b41135c3fb381a2f405e91b7802..108d53b07231ec795e983f8d6bcb681f67153984 100644 --- a/crates/collab_ui2/src/chat_panel.rs +++ b/crates/collab_ui2/src/chat_panel.rs @@ -21,7 +21,7 @@ use settings::{Settings, SettingsStore}; use std::sync::Arc; use theme::ActiveTheme as _; use time::{OffsetDateTime, UtcOffset}; -use ui::{prelude::*, Avatar, Button, Icon, IconButton, Label, Tooltip}; +use ui::{prelude::*, Avatar, Button, Icon, IconButton, Label, TabBar, Tooltip}; use util::{ResultExt, TryFutureExt}; use workspace::{ dock::{DockPosition, Panel, PanelEvent}, @@ -97,7 +97,9 @@ impl ChatPanel { let message_list = ListState::new(0, gpui::ListAlignment::Bottom, px(1000.), move |ix, cx| { if let Some(view) = view.upgrade() { - view.update(cx, |view, cx| view.render_message(ix, cx)) + view.update(cx, |view, cx| { + view.render_message(ix, cx).into_any_element() + }) } else { div().into_any() } @@ -263,37 +265,41 @@ impl ChatPanel { .full() .on_action(cx.listener(Self::send)) .child( - h_stack() - .w_full() - .h_7() - .justify_between() - .z_index(1) - .bg(cx.theme().colors().background) - .child(Label::new( - self.active_chat - .as_ref() - .and_then(|c| Some(format!("#{}", c.0.read(cx).channel(cx)?.name))) - .unwrap_or_default(), - )) - .child( - h_stack() - .child( - IconButton::new("notes", Icon::File) - .on_click(cx.listener(Self::open_notes)) - .tooltip(|cx| Tooltip::text("Open notes", cx)), - ) - .child( - IconButton::new("call", Icon::AudioOn) - .on_click(cx.listener(Self::join_call)) - .tooltip(|cx| Tooltip::text("Join call", cx)), - ), - ), - ) - .child( - div() - .flex_grow() - .child(self.render_active_channel_messages(cx)), + h_stack().z_index(1).child( + TabBar::new("chat_header") + .child( + h_stack() + .w_full() + .h(rems(ui::Tab::HEIGHT_IN_REMS)) + .px_2() + .child(Label::new( + self.active_chat + .as_ref() + .and_then(|c| { + Some(format!("#{}", c.0.read(cx).channel(cx)?.name)) + }) + .unwrap_or_default(), + )), + ) + .end_child( + IconButton::new("notes", Icon::File) + .on_click(cx.listener(Self::open_notes)) + .tooltip(|cx| Tooltip::text("Open notes", cx)), + ) + .end_child( + IconButton::new("call", Icon::AudioOn) + .on_click(cx.listener(Self::join_call)) + .tooltip(|cx| Tooltip::text("Join call", cx)), + ), + ), ) + .child(div().flex_grow().px_2().py_1().map(|this| { + if self.active_chat.is_some() { + this.child(list(self.message_list.clone()).full()) + } else { + this + } + })) .child( div() .z_index(1) @@ -304,39 +310,42 @@ impl ChatPanel { .into_any() } - fn render_active_channel_messages(&self, _cx: &mut ViewContext) -> AnyElement { - if self.active_chat.is_some() { - list(self.message_list.clone()).full().into_any_element() - } else { - div().into_any_element() - } - } - - fn render_message(&mut self, ix: usize, cx: &mut ViewContext) -> AnyElement { + fn render_message(&mut self, ix: usize, cx: &mut ViewContext) -> impl IntoElement { let active_chat = &self.active_chat.as_ref().unwrap().0; - let (message, is_continuation, is_admin) = active_chat.update(cx, |active_chat, cx| { - let is_admin = self - .channel_store - .read(cx) - .is_channel_admin(active_chat.channel_id); - - let last_message = active_chat.message(ix.saturating_sub(1)); - let this_message = active_chat.message(ix).clone(); - let is_continuation = last_message.id != this_message.id - && this_message.sender.id == last_message.sender.id; - - if let ChannelMessageId::Saved(id) = this_message.id { - if this_message - .mentions - .iter() - .any(|(_, user_id)| Some(*user_id) == self.client.user_id()) - { - active_chat.acknowledge_message(id); + let (message, is_continuation_from_previous, is_continuation_to_next, is_admin) = + active_chat.update(cx, |active_chat, cx| { + let is_admin = self + .channel_store + .read(cx) + .is_channel_admin(active_chat.channel_id); + + let last_message = active_chat.message(ix.saturating_sub(1)); + let this_message = active_chat.message(ix).clone(); + let next_message = + active_chat.message(ix.saturating_add(1).min(active_chat.message_count() - 1)); + + let is_continuation_from_previous = last_message.id != this_message.id + && last_message.sender.id == this_message.sender.id; + let is_continuation_to_next = this_message.id != next_message.id + && this_message.sender.id == next_message.sender.id; + + if let ChannelMessageId::Saved(id) = this_message.id { + if this_message + .mentions + .iter() + .any(|(_, user_id)| Some(*user_id) == self.client.user_id()) + { + active_chat.acknowledge_message(id); + } } - } - (this_message, is_continuation, is_admin) - }); + ( + this_message, + is_continuation_from_previous, + is_continuation_to_next, + is_admin, + ) + }); let _is_pending = message.is_pending(); let text = self.markdown_data.entry(message.id).or_insert_with(|| { @@ -359,27 +368,31 @@ impl ChatPanel { ChannelMessageId::Pending(id) => ("pending-message", id).into(), }; - let mut result = v_stack() + v_stack() .w_full() .id(element_id) .relative() + .overflow_hidden() .group("") - .mb_1(); - - if !is_continuation { - result = result.child( - h_stack() - .child(Avatar::new(message.sender.avatar_uri.clone())) - .child(Label::new(message.sender.github_login.clone())) - .child(Label::new(format_timestamp( - message.timestamp, - now, - self.local_timezone, - ))), - ); - } - - result + .when(!is_continuation_from_previous, |this| { + this.child( + h_stack() + .gap_2() + .child(Avatar::new(message.sender.avatar_uri.clone())) + .child(Label::new(message.sender.github_login.clone())) + .child( + Label::new(format_timestamp( + message.timestamp, + now, + self.local_timezone, + )) + .color(Color::Muted), + ), + ) + }) + .when(!is_continuation_to_next, |this| + // HACK: This should really be a margin, but margins seem to get collapsed. + this.pb_2()) .child(text.element("body".into(), cx)) .child( div() @@ -396,7 +409,6 @@ impl ChatPanel { ) })), ) - .into_any() } fn render_markdown_with_mentions( diff --git a/crates/ui2/src/components/tab_bar.rs b/crates/ui2/src/components/tab_bar.rs index 7cff2f51bd80f4dc38df6b9e2423d1627024ea33..c0d9953196dae47733d687e5f91e4b125dd2bcf8 100644 --- a/crates/ui2/src/components/tab_bar.rs +++ b/crates/ui2/src/components/tab_bar.rs @@ -102,16 +102,18 @@ impl RenderOnce for TabBar { .w_full() .h(rems(HEIGHT_IN_REMS)) .bg(cx.theme().colors().tab_bar_background) - .child( - h_stack() - .flex_none() - .gap_1() - .px_1() - .border_b() - .border_r() - .border_color(cx.theme().colors().border) - .children(self.start_children), - ) + .when(!self.start_children.is_empty(), |this| { + this.child( + h_stack() + .flex_none() + .gap_1() + .px_1() + .border_b() + .border_r() + .border_color(cx.theme().colors().border) + .children(self.start_children), + ) + }) .child( div() .relative() @@ -140,15 +142,17 @@ impl RenderOnce for TabBar { .children(self.children), ), ) - .child( - h_stack() - .flex_none() - .gap_1() - .px_1() - .border_b() - .border_l() - .border_color(cx.theme().colors().border) - .children(self.end_children), - ) + .when(!self.end_children.is_empty(), |this| { + this.child( + h_stack() + .flex_none() + .gap_1() + .px_1() + .border_b() + .border_l() + .border_color(cx.theme().colors().border) + .children(self.end_children), + ) + }) } } From 38a8aa2d047a3d69f702e4cd6a936788225bb91f Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Thu, 21 Dec 2023 12:15:27 -0500 Subject: [PATCH 256/644] Bump tree-sitter-nu rev id --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cddd744a9f8ffa5b6a7f02dfe49066a0ba0e6e58..82cc00bf9e65188980161fce3567cf70cbadd406 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10510,7 +10510,7 @@ dependencies = [ [[package]] name = "tree-sitter-nu" version = "0.0.1" -source = "git+https://github.com/nushell/tree-sitter-nu?rev=786689b0562b9799ce53e824cb45a1a2a04dc673#786689b0562b9799ce53e824cb45a1a2a04dc673" +source = "git+https://github.com/nushell/tree-sitter-nu?rev=a0b80b2e21e5e39571252dc799e19eb89f1fc912#a0b80b2e21e5e39571252dc799e19eb89f1fc912" dependencies = [ "cc", "tree-sitter", diff --git a/Cargo.toml b/Cargo.toml index 42432a8a2a0f6fa3d713769f7b7c14f962d02520..e8299d6ce3639be0ca07bd50a86d59077006c075 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -207,7 +207,7 @@ tree-sitter-racket = { git = "https://github.com/zed-industries/tree-sitter-rack tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "f545a41f57502e1b5ddf2a6668896c1b0620f930"} tree-sitter-lua = "0.0.14" tree-sitter-nix = { git = "https://github.com/nix-community/tree-sitter-nix", rev = "66e3e9ce9180ae08fc57372061006ef83f0abde7" } -tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "786689b0562b9799ce53e824cb45a1a2a04dc673"} +tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "a0b80b2e21e5e39571252dc799e19eb89f1fc912"} tree-sitter-vue = {git = "https://github.com/zed-industries/tree-sitter-vue", rev = "6608d9d60c386f19d80af7d8132322fa11199c42"} tree-sitter-uiua = {git = "https://github.com/shnarazk/tree-sitter-uiua", rev = "9260f11be5900beda4ee6d1a24ab8ddfaf5a19b2"} From 31e47f9b525f316fb862684df42e952eb6a91e84 Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 21 Dec 2023 12:56:30 -0500 Subject: [PATCH 257/644] Prevent panic dragging tab into terminal panel --- crates/workspace2/src/pane.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 4d20699528e453718b5afdc142cb7e87047c9fb9..7b9ac4ab13652ec2e9377027086aebdfc206cd14 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1754,6 +1754,10 @@ impl Pane { } fn handle_drag_move(&mut self, event: &DragMoveEvent, cx: &mut ViewContext) { + if !self.can_split { + return; + } + let edge_width = cx.rem_size() * 8; let cursor = event.event.position; let direction = if cursor.x < event.bounds.left() + edge_width { @@ -1767,9 +1771,9 @@ impl Pane { } else { None }; + if direction != self.drag_split_direction { self.drag_split_direction = direction; - cx.notify(); } } From 9efe5a30aab08aded81b45addea299123e77dc41 Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 21 Dec 2023 13:08:48 -0500 Subject: [PATCH 258/644] Fix pane drag target not appearing over terminal element --- crates/workspace2/src/pane.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 7b9ac4ab13652ec2e9377027086aebdfc206cd14..d0b47a2d1e5aadc49395f6ccf5a76f25c5a5aa86 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1938,6 +1938,7 @@ impl Render for Pane { .child( // drag target div() + .z_index(1) .invisible() .absolute() .bg(theme::color_alpha( From 7cfea09019bf9ec6088b5964b3b4da1ee897d182 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 19:40:03 +0100 Subject: [PATCH 259/644] Revert "Optimize order rendering and border drawing" --- Cargo.lock | 12 ++++ crates/gpui2/Cargo.toml | 1 + crates/gpui2/src/geometry.rs | 21 ------ crates/gpui2/src/scene.rs | 126 ++++++++++++++++++++++++++++------- crates/gpui2/src/style.rs | 60 ++--------------- crates/gpui2/src/window.rs | 1 - 6 files changed, 120 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e591ae58fe49b454d7cc09724032918de7a73a7..82cc00bf9e65188980161fce3567cf70cbadd406 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4060,6 +4060,7 @@ dependencies = [ "parking", "parking_lot 0.11.2", "pathfinder_geometry", + "plane-split", "png", "postage", "rand 0.8.5", @@ -6655,6 +6656,17 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "plane-split" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f7d82649829ecdef8e258790b0587acf0a8403f0ce963473d8e918acc1643" +dependencies = [ + "euclid", + "log", + "smallvec", +] + [[package]] name = "plist" version = "1.5.0" diff --git a/crates/gpui2/Cargo.toml b/crates/gpui2/Cargo.toml index bf0ac955a5ec20d8a9ca6d0c0bac0bc5e7c95542..afb5d3ea0ce7080830bbcb1eb86aad62b8f7432c 100644 --- a/crates/gpui2/Cargo.toml +++ b/crates/gpui2/Cargo.toml @@ -56,6 +56,7 @@ uuid = { version = "1.1.2", features = ["v4"] } waker-fn = "1.1.0" slotmap = "1.0.6" schemars.workspace = true +plane-split = "0.18.0" bitflags = "2.4.0" [dev-dependencies] diff --git a/crates/gpui2/src/geometry.rs b/crates/gpui2/src/geometry.rs index 6b4d9ae807b581eff4fe38baf913843e43bd8c83..f58435d7b9a2e9b3fa48062d2e28ed21502c1ca1 100644 --- a/crates/gpui2/src/geometry.rs +++ b/crates/gpui2/src/geometry.rs @@ -1590,15 +1590,6 @@ impl Edges { left: self.left.scale(factor), } } - - /// Returns the maximum value of any edge. - /// - /// # Returns - /// - /// The maximum `Pixels` value among all four edges. - pub fn max(&self) -> Pixels { - self.top.max(self.right).max(self.bottom).max(self.left) - } } impl Into> for f32 { @@ -1749,18 +1740,6 @@ impl Corners { bottom_left: self.bottom_left.scale(factor), } } - - /// Returns the maximum value of any corner. - /// - /// # Returns - /// - /// The maximum `Pixels` value among all four corners. - pub fn max(&self) -> Pixels { - self.top_left - .max(self.top_right) - .max(self.bottom_right) - .max(self.bottom_left) - } } impl Corners { diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index cb62ce314f8147455768a359717c4168d88b7edb..e6b601b62f17cf087748f8ce4e672eab14b13fb8 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -3,6 +3,8 @@ use crate::{ ScaledPixels, StackingOrder, }; use collections::BTreeMap; +use etagere::euclid::{Point3D, Vector3D}; +use plane_split::{BspSplitter, Polygon as BspPolygon}; use std::{fmt::Debug, iter::Peekable, mem, slice}; // Exported to metal @@ -17,6 +19,7 @@ pub type DrawOrder = u32; pub(crate) struct SceneBuilder { last_order: Option<(StackingOrder, LayerId)>, layers_by_order: BTreeMap, + splitter: BspSplitter<(PrimitiveKind, usize)>, shadows: Vec, quads: Vec, paths: Vec>, @@ -31,6 +34,7 @@ impl Default for SceneBuilder { SceneBuilder { last_order: None, layers_by_order: BTreeMap::new(), + splitter: BspSplitter::new(), shadows: Vec::new(), quads: Vec::new(), paths: Vec::new(), @@ -44,47 +48,103 @@ impl Default for SceneBuilder { impl SceneBuilder { pub fn build(&mut self) -> Scene { - let mut orders = vec![0; self.layers_by_order.len()]; + // Map each layer id to a float between 0. and 1., with 1. closer to the viewer. + let mut layer_z_values = vec![0.; self.layers_by_order.len()]; for (ix, layer_id) in self.layers_by_order.values().enumerate() { - orders[*layer_id as usize] = ix as u32; + layer_z_values[*layer_id as usize] = ix as f32 / self.layers_by_order.len() as f32; } self.layers_by_order.clear(); self.last_order = None; - for shadow in &mut self.shadows { - shadow.order = orders[shadow.order as usize]; + // Add all primitives to the BSP splitter to determine draw order + self.splitter.reset(); + + for (ix, shadow) in self.shadows.iter().enumerate() { + let z = layer_z_values[shadow.order as LayerId as usize]; + self.splitter + .add(shadow.bounds.to_bsp_polygon(z, (PrimitiveKind::Shadow, ix))); + } + + for (ix, quad) in self.quads.iter().enumerate() { + let z = layer_z_values[quad.order as LayerId as usize]; + self.splitter + .add(quad.bounds.to_bsp_polygon(z, (PrimitiveKind::Quad, ix))); } - self.shadows.sort_by_key(|shadow| shadow.order); - for quad in &mut self.quads { - quad.order = orders[quad.order as usize]; + for (ix, path) in self.paths.iter().enumerate() { + let z = layer_z_values[path.order as LayerId as usize]; + self.splitter + .add(path.bounds.to_bsp_polygon(z, (PrimitiveKind::Path, ix))); } - self.quads.sort_by_key(|quad| quad.order); - for path in &mut self.paths { - path.order = orders[path.order as usize]; + for (ix, underline) in self.underlines.iter().enumerate() { + let z = layer_z_values[underline.order as LayerId as usize]; + self.splitter.add( + underline + .bounds + .to_bsp_polygon(z, (PrimitiveKind::Underline, ix)), + ); } - self.paths.sort_by_key(|path| path.order); - for underline in &mut self.underlines { - underline.order = orders[underline.order as usize]; + for (ix, monochrome_sprite) in self.monochrome_sprites.iter().enumerate() { + let z = layer_z_values[monochrome_sprite.order as LayerId as usize]; + self.splitter.add( + monochrome_sprite + .bounds + .to_bsp_polygon(z, (PrimitiveKind::MonochromeSprite, ix)), + ); } - self.underlines.sort_by_key(|underline| underline.order); - for monochrome_sprite in &mut self.monochrome_sprites { - monochrome_sprite.order = orders[monochrome_sprite.order as usize]; + for (ix, polychrome_sprite) in self.polychrome_sprites.iter().enumerate() { + let z = layer_z_values[polychrome_sprite.order as LayerId as usize]; + self.splitter.add( + polychrome_sprite + .bounds + .to_bsp_polygon(z, (PrimitiveKind::PolychromeSprite, ix)), + ); } - self.monochrome_sprites.sort_by_key(|sprite| sprite.order); - for polychrome_sprite in &mut self.polychrome_sprites { - polychrome_sprite.order = orders[polychrome_sprite.order as usize]; + for (ix, surface) in self.surfaces.iter().enumerate() { + let z = layer_z_values[surface.order as LayerId as usize]; + self.splitter.add( + surface + .bounds + .to_bsp_polygon(z, (PrimitiveKind::Surface, ix)), + ); } - self.polychrome_sprites.sort_by_key(|sprite| sprite.order); - for surface in &mut self.surfaces { - surface.order = orders[surface.order as usize]; + // Sort all polygons, then reassign the order field of each primitive to `draw_order` + // We need primitives to be repr(C), hence the weird reuse of the order field for two different types. + for (draw_order, polygon) in self + .splitter + .sort(Vector3D::new(0., 0., 1.)) + .iter() + .enumerate() + { + match polygon.anchor { + (PrimitiveKind::Shadow, ix) => self.shadows[ix].order = draw_order as DrawOrder, + (PrimitiveKind::Quad, ix) => self.quads[ix].order = draw_order as DrawOrder, + (PrimitiveKind::Path, ix) => self.paths[ix].order = draw_order as DrawOrder, + (PrimitiveKind::Underline, ix) => { + self.underlines[ix].order = draw_order as DrawOrder + } + (PrimitiveKind::MonochromeSprite, ix) => { + self.monochrome_sprites[ix].order = draw_order as DrawOrder + } + (PrimitiveKind::PolychromeSprite, ix) => { + self.polychrome_sprites[ix].order = draw_order as DrawOrder + } + (PrimitiveKind::Surface, ix) => self.surfaces[ix].order = draw_order as DrawOrder, + } } - self.surfaces.sort_by_key(|surface| surface.order); + + self.shadows.sort_unstable(); + self.quads.sort_unstable(); + self.paths.sort_unstable(); + self.underlines.sort_unstable(); + self.monochrome_sprites.sort_unstable(); + self.polychrome_sprites.sort_unstable(); + self.surfaces.sort_unstable(); Scene { shadows: mem::take(&mut self.shadows), @@ -785,3 +845,23 @@ impl PathVertex { #[derive(Copy, Clone, Debug)] pub struct AtlasId(pub(crate) usize); + +impl Bounds { + fn to_bsp_polygon(&self, z: f32, anchor: A) -> BspPolygon { + let upper_left = self.origin; + let upper_right = self.upper_right(); + let lower_right = self.lower_right(); + let lower_left = self.lower_left(); + + BspPolygon::from_points( + [ + Point3D::new(upper_left.x.into(), upper_left.y.into(), z as f64), + Point3D::new(upper_right.x.into(), upper_right.y.into(), z as f64), + Point3D::new(lower_right.x.into(), lower_right.y.into(), z as f64), + Point3D::new(lower_left.x.into(), lower_left.y.into(), z as f64), + ], + anchor, + ) + .expect("Polygon should not be empty") + } +} diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index de54da79b3d0eb1e7489962143dbbc7d0dc0809f..3e9593b0fd6635a1b9b2ce867e6fc465a47d80de 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -402,65 +402,13 @@ impl Style { if self.is_border_visible() { cx.with_z_index(3, |cx| { - let corner_radii = self.corner_radii.to_pixels(bounds.size, rem_size); - let border_widths = self.border_widths.to_pixels(rem_size); - let max_border_width = border_widths.max(); - let max_corner_radius = corner_radii.max(); - - let top_bounds = Bounds::from_corners( - bounds.origin, - bounds.upper_right() - + point(Pixels::ZERO, max_border_width.max(max_corner_radius)), - ); - let bottom_bounds = Bounds::from_corners( - bounds.lower_left() - - point(Pixels::ZERO, max_border_width.max(max_corner_radius)), - bounds.lower_right(), - ); - let left_bounds = Bounds::from_corners( - top_bounds.lower_left(), - bottom_bounds.origin + point(max_border_width, Pixels::ZERO), - ); - let right_bounds = Bounds::from_corners( - top_bounds.lower_right() - point(max_border_width, Pixels::ZERO), - bottom_bounds.upper_right(), - ); - - let quad = quad( + cx.paint_quad(quad( bounds, - corner_radii, + self.corner_radii.to_pixels(bounds.size, rem_size), Hsla::transparent_black(), - border_widths, + self.border_widths.to_pixels(rem_size), self.border_color.unwrap_or_default(), - ); - - cx.with_content_mask(Some(ContentMask { bounds: top_bounds }), |cx| { - cx.paint_quad(quad.clone()); - }); - cx.with_content_mask( - Some(ContentMask { - bounds: right_bounds, - }), - |cx| { - cx.paint_quad(quad.clone()); - }, - ); - cx.with_content_mask( - Some(ContentMask { - bounds: bottom_bounds, - }), - |cx| { - cx.paint_quad(quad.clone()); - }, - ); - cx.with_content_mask( - Some(ContentMask { - bounds: left_bounds, - }), - |cx| { - cx.paint_quad(quad); - }, - ); + )); }); } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index c20e2f7b94a3337e05b1fa755fdb624d93396213..e57984fa0d0fe2ee577a162608159cc72ea0f848 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -3074,7 +3074,6 @@ impl From<(&'static str, u64)> for ElementId { } /// A rectangle, to be rendered on the screen by GPUI at the given position and size. -#[derive(Clone)] pub struct PaintQuad { bounds: Bounds, corner_radii: Corners, From dabc98690cdc1f47793ce3dfa680fd074139b6f8 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 15:48:37 -0500 Subject: [PATCH 260/644] Use small labels for title bar buttons (#3763) This PR adjusts the sizing of the labels in the buttons in the title bar to use the small label size. This should bring them more in line with how things looked in Zed1. Release Notes: - N/A --- crates/collab_ui2/src/collab_titlebar_item.rs | 2 ++ crates/ui2/src/components/button/button.rs | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 24e510ae8d51175b7b28de32a2807c44927e4761..8e542e413e8bce8e07f0bd77fba0c90855f3ccde 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -334,6 +334,7 @@ impl CollabTitlebarItem { .trigger( Button::new("project_name_trigger", name) .style(ButtonStyle::Subtle) + .label_size(LabelSize::Small) .tooltip(move |cx| Tooltip::text("Recent Projects", cx)) .on_click(cx.listener(|this, _, cx| { this.toggle_project_menu(&ToggleProjectMenu, cx); @@ -368,6 +369,7 @@ impl CollabTitlebarItem { Button::new("project_branch_trigger", branch_name) .color(Color::Muted) .style(ButtonStyle::Subtle) + .label_size(LabelSize::Small) .tooltip(move |cx| { Tooltip::with_meta( "Recent Branches", diff --git a/crates/ui2/src/components/button/button.rs b/crates/ui2/src/components/button/button.rs index 014a2f536278e6064769a5605eb43dafd01a4ee0..406cd1f420be8b6ff2e2a81e92f47fd8fa0748b1 100644 --- a/crates/ui2/src/components/button/button.rs +++ b/crates/ui2/src/components/button/button.rs @@ -12,6 +12,7 @@ pub struct Button { base: ButtonLike, label: SharedString, label_color: Option, + label_size: Option, selected_label: Option, icon: Option, icon_position: Option, @@ -26,6 +27,7 @@ impl Button { base: ButtonLike::new(id), label: label.into(), label_color: None, + label_size: None, selected_label: None, icon: None, icon_position: None, @@ -40,6 +42,11 @@ impl Button { self } + pub fn label_size(mut self, label_size: impl Into>) -> Self { + self.label_size = label_size.into(); + self + } + pub fn selected_label>(mut self, label: impl Into>) -> Self { self.selected_label = label.into().map(Into::into); self @@ -164,6 +171,7 @@ impl RenderOnce for Button { .child( Label::new(label) .color(label_color) + .size(self.label_size.unwrap_or_default()) .line_height_style(LineHeightStyle::UILabel), ) .when(!self.icon_position.is_some(), |this| { From a773a3cb9234ae7a4ce03c704dafe2e7c855cfa9 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 16:07:55 -0500 Subject: [PATCH 261/644] Increase horizontal padding for inset `ListItem`s --- crates/ui2/src/components/list/list_item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ui2/src/components/list/list_item.rs b/crates/ui2/src/components/list/list_item.rs index bdb5c2b854f2cfb7a04cbd70334d81a4daab98c4..797a6faba58025a013bdd5af60bb520ba675a841 100644 --- a/crates/ui2/src/components/list/list_item.rs +++ b/crates/ui2/src/components/list/list_item.rs @@ -134,7 +134,7 @@ impl RenderOnce for ListItem { // When an item is inset draw the indent spacing outside of the item .when(self.inset, |this| { this.ml(self.indent_level as f32 * self.indent_step_size) - .px_1() + .px_2() }) .when(!self.inset, |this| { this From dc09dbc98c2d27886146cdb1ab328d6f55031441 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 16:17:04 -0500 Subject: [PATCH 262/644] Use a `ListItem` as the empty state for `Picker`s --- crates/picker2/src/picker2.rs | 27 ++++++--------------- crates/ui2/src/components/list/list_item.rs | 11 ++++++++- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 8a75996f482c2c692adf95eed1015ef783d8ee1f..3cc9f8a1ade1046cad82780760ef02252a827874 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -1,11 +1,11 @@ use editor::Editor; use gpui::{ - div, prelude::*, rems, uniform_list, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, + div, prelude::*, uniform_list, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Length, MouseButton, MouseDownEvent, Render, Task, UniformListScrollHandle, View, ViewContext, WindowContext, }; use std::{cmp, sync::Arc}; -use ui::{prelude::*, v_stack, Color, Divider, Label}; +use ui::{prelude::*, v_stack, Color, Divider, Label, ListItem}; use workspace::ModalView; pub struct Picker { @@ -229,21 +229,10 @@ impl Render for Picker { .px_3() .child(self.editor.clone()); - let empty_state = div().p_1().child( - h_stack() - // TODO: This number matches the height of the uniform list items. - // Align these two with a less magic number. - .h(rems(1.4375)) - .px_2() - .child(Label::new("No matches").color(Color::Muted)), - ); - div() .key_context("Picker") .size_full() - .when_some(self.width, |el, width| { - el.w(width) - }) + .when_some(self.width, |el, width| el.w(width)) .overflow_hidden() // This is a bit of a hack to remove the modal styling when we're rendering the `Picker` // as a part of a modal rather than the entire modal. @@ -257,9 +246,7 @@ impl Render for Picker { .on_action(cx.listener(Self::cancel)) .on_action(cx.listener(Self::confirm)) .on_action(cx.listener(Self::secondary_confirm)) - .child( - picker_editor - ) + .child(picker_editor) .child(Divider::horizontal()) .when(self.delegate.match_count() > 0, |el| { el.child( @@ -272,7 +259,6 @@ impl Render for Picker { self.delegate.match_count(), { let selected_index = self.delegate.selected_index(); - move |picker, visible_range, cx| { visible_range .map(|ix| { @@ -305,7 +291,10 @@ impl Render for Picker { }) .when(self.delegate.match_count() == 0, |el| { el.child( - empty_state + ListItem::new("empty_state") + .inset(true) + .disabled(true) + .child(Label::new("No matches").color(Color::Muted)), ) }) } diff --git a/crates/ui2/src/components/list/list_item.rs b/crates/ui2/src/components/list/list_item.rs index 797a6faba58025a013bdd5af60bb520ba675a841..ca161b12f4790e6f9bee18a52b4dcb594e3deeca 100644 --- a/crates/ui2/src/components/list/list_item.rs +++ b/crates/ui2/src/components/list/list_item.rs @@ -8,6 +8,7 @@ use crate::{prelude::*, Disclosure}; #[derive(IntoElement)] pub struct ListItem { id: ElementId, + disabled: bool, selected: bool, indent_level: usize, indent_step_size: Pixels, @@ -32,6 +33,7 @@ impl ListItem { pub fn new(id: impl Into) -> Self { Self { id: id.into(), + disabled: false, selected: false, indent_level: 0, indent_step_size: px(12.), @@ -110,6 +112,13 @@ impl ListItem { } } +impl Disableable for ListItem { + fn disabled(mut self, disabled: bool) -> Self { + self.disabled = disabled; + self + } +} + impl Selectable for ListItem { fn selected(mut self, selected: bool) -> Self { self.selected = selected; @@ -157,7 +166,7 @@ impl RenderOnce for ListItem { .gap_1() .px_2() .group("list_item") - .when(self.inset, |this| { + .when(self.inset && !self.disabled, |this| { this // TODO: Add focus state // .when(self.state == InteractionState::Focused, |this| { From 71a222abcb597e7b306aecb771e250f7587b5406 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 16:33:41 -0500 Subject: [PATCH 263/644] Use sparse spacing for `ListItem`s in `Picker`s --- .../src/collab_panel/channel_modal.rs | 3 +- .../src/collab_panel/contact_finder.rs | 3 +- .../command_palette2/src/command_palette.rs | 34 +++++++++++-------- crates/file_finder2/src/file_finder.rs | 21 +++++++----- .../src/language_selector.rs | 3 +- crates/outline2/src/outline.rs | 18 ++++++---- crates/picker2/src/picker2.rs | 3 +- .../project_symbols2/src/project_symbols.rs | 28 ++++++++------- .../recent_projects2/src/recent_projects.rs | 20 ++++++----- crates/storybook2/src/stories/picker.rs | 3 +- crates/theme_selector2/src/theme_selector.rs | 3 +- crates/ui2/src/components/list/list_item.rs | 18 ++++++++++ crates/vcs_menu2/src/lib.rs | 9 +++-- crates/welcome2/src/base_keymap_picker.rs | 5 +-- 14 files changed, 110 insertions(+), 61 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel/channel_modal.rs b/crates/collab_ui2/src/collab_panel/channel_modal.rs index f844c609cac074d6457613b81b654a8e0b1c5d3c..f373dbad1fbc2dbdbe6f022bac806c6cf2f22bf0 100644 --- a/crates/collab_ui2/src/collab_panel/channel_modal.rs +++ b/crates/collab_ui2/src/collab_panel/channel_modal.rs @@ -11,7 +11,7 @@ use gpui::{ }; use picker::{Picker, PickerDelegate}; use std::sync::Arc; -use ui::{prelude::*, Avatar, Checkbox, ContextMenu, ListItem}; +use ui::{prelude::*, Avatar, Checkbox, ContextMenu, ListItem, ListItemSpacing}; use util::TryFutureExt; use workspace::ModalView; @@ -366,6 +366,7 @@ impl PickerDelegate for ChannelModalDelegate { Some( ListItem::new(ix) .inset(true) + .spacing(ListItemSpacing::Sparse) .selected(selected) .start_slot(Avatar::new(user.avatar_uri.clone())) .child(Label::new(user.github_login.clone())) diff --git a/crates/collab_ui2/src/collab_panel/contact_finder.rs b/crates/collab_ui2/src/collab_panel/contact_finder.rs index 31d836279b6a17d4b119dcad0d562d66388f30ac..a38d22c096b0caffc5f6f3ba520ba79ecc2a8924 100644 --- a/crates/collab_ui2/src/collab_panel/contact_finder.rs +++ b/crates/collab_ui2/src/collab_panel/contact_finder.rs @@ -6,7 +6,7 @@ use gpui::{ use picker::{Picker, PickerDelegate}; use std::sync::Arc; use theme::ActiveTheme as _; -use ui::{prelude::*, Avatar, ListItem}; +use ui::{prelude::*, Avatar, ListItem, ListItemSpacing}; use util::{ResultExt as _, TryFutureExt}; use workspace::ModalView; @@ -153,6 +153,7 @@ impl PickerDelegate for ContactFinderDelegate { Some( ListItem::new(ix) .inset(true) + .spacing(ListItemSpacing::Sparse) .selected(selected) .start_slot(Avatar::new(user.avatar_uri.clone())) .child(Label::new(user.github_login.clone())) diff --git a/crates/command_palette2/src/command_palette.rs b/crates/command_palette2/src/command_palette.rs index 04efe1df53ae200273dc6d35e9231b55304571c2..05891bc0f199a83c2eb911179d042c259a46702a 100644 --- a/crates/command_palette2/src/command_palette.rs +++ b/crates/command_palette2/src/command_palette.rs @@ -11,7 +11,7 @@ use gpui::{ }; use picker::{Picker, PickerDelegate}; -use ui::{h_stack, prelude::*, v_stack, HighlightedLabel, KeyBinding, ListItem}; +use ui::{h_stack, prelude::*, v_stack, HighlightedLabel, KeyBinding, ListItem, ListItemSpacing}; use util::{ channel::{parse_zed_link, ReleaseChannel, RELEASE_CHANNEL}, ResultExt, @@ -308,20 +308,24 @@ impl PickerDelegate for CommandPaletteDelegate { let r#match = self.matches.get(ix)?; let command = self.commands.get(r#match.candidate_id)?; Some( - ListItem::new(ix).inset(true).selected(selected).child( - h_stack() - .w_full() - .justify_between() - .child(HighlightedLabel::new( - command.name.clone(), - r#match.positions.clone(), - )) - .children(KeyBinding::for_action_in( - &*command.action, - &self.previous_focus_handle, - cx, - )), - ), + ListItem::new(ix) + .inset(true) + .spacing(ListItemSpacing::Sparse) + .selected(selected) + .child( + h_stack() + .w_full() + .justify_between() + .child(HighlightedLabel::new( + command.name.clone(), + r#match.positions.clone(), + )) + .children(KeyBinding::for_action_in( + &*command.action, + &self.previous_focus_handle, + cx, + )), + ), ) } } diff --git a/crates/file_finder2/src/file_finder.rs b/crates/file_finder2/src/file_finder.rs index 8faba99cb23a9bedffed5ab0c0f3a8147870b25a..369128a753754f3e53de84f2701fc74a947f9f1a 100644 --- a/crates/file_finder2/src/file_finder.rs +++ b/crates/file_finder2/src/file_finder.rs @@ -15,7 +15,7 @@ use std::{ }, }; use text::Point; -use ui::{prelude::*, HighlightedLabel, ListItem}; +use ui::{prelude::*, HighlightedLabel, ListItem, ListItemSpacing}; use util::{paths::PathLikeWithPosition, post_inc, ResultExt}; use workspace::{ModalView, Workspace}; @@ -714,13 +714,18 @@ impl PickerDelegate for FileFinderDelegate { self.labels_for_match(path_match, cx, ix); Some( - ListItem::new(ix).inset(true).selected(selected).child( - v_stack() - .child(HighlightedLabel::new(file_name, file_name_positions)) - .child( - HighlightedLabel::new(full_path, full_path_positions).color(Color::Muted), - ), - ), + ListItem::new(ix) + .spacing(ListItemSpacing::Sparse) + .inset(true) + .selected(selected) + .child( + v_stack() + .child(HighlightedLabel::new(file_name, file_name_positions)) + .child( + HighlightedLabel::new(full_path, full_path_positions) + .color(Color::Muted), + ), + ), ) } } diff --git a/crates/language_selector2/src/language_selector.rs b/crates/language_selector2/src/language_selector.rs index 8b28eab11d165cf7f7a893d39232b0ee76d830e2..3da8649c6e006fcc56a0255ef96babf76121b881 100644 --- a/crates/language_selector2/src/language_selector.rs +++ b/crates/language_selector2/src/language_selector.rs @@ -12,7 +12,7 @@ use language::{Buffer, LanguageRegistry}; use picker::{Picker, PickerDelegate}; use project::Project; use std::sync::Arc; -use ui::{prelude::*, HighlightedLabel, ListItem}; +use ui::{prelude::*, HighlightedLabel, ListItem, ListItemSpacing}; use util::ResultExt; use workspace::{ModalView, Workspace}; @@ -226,6 +226,7 @@ impl PickerDelegate for LanguageSelectorDelegate { Some( ListItem::new(ix) .inset(true) + .spacing(ListItemSpacing::Sparse) .selected(selected) .child(HighlightedLabel::new(label, mat.positions.clone())), ) diff --git a/crates/outline2/src/outline.rs b/crates/outline2/src/outline.rs index f3d1f327da7b587f48a5175ea3ebea3112d3bfb5..ba67f33b25de382bdf0b4c30ec8bbf7d635c44b3 100644 --- a/crates/outline2/src/outline.rs +++ b/crates/outline2/src/outline.rs @@ -18,7 +18,7 @@ use std::{ }; use theme::{color_alpha, ActiveTheme, ThemeSettings}; -use ui::{prelude::*, ListItem}; +use ui::{prelude::*, ListItem, ListItemSpacing}; use util::ResultExt; use workspace::ModalView; @@ -296,12 +296,16 @@ impl PickerDelegate for OutlineViewDelegate { StyledText::new(outline_item.text.clone()).with_highlights(&text_style, highlights); Some( - ListItem::new(ix).inset(true).selected(selected).child( - div() - .text_ui() - .pl(rems(outline_item.depth as f32)) - .child(styled_text), - ), + ListItem::new(ix) + .inset(true) + .spacing(ListItemSpacing::Sparse) + .selected(selected) + .child( + div() + .text_ui() + .pl(rems(outline_item.depth as f32)) + .child(styled_text), + ), ) } } diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 3cc9f8a1ade1046cad82780760ef02252a827874..d37638293ce16ce75b7d7fd52961f7aba5a1d6b0 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -5,7 +5,7 @@ use gpui::{ View, ViewContext, WindowContext, }; use std::{cmp, sync::Arc}; -use ui::{prelude::*, v_stack, Color, Divider, Label, ListItem}; +use ui::{prelude::*, v_stack, Color, Divider, Label, ListItem, ListItemSpacing}; use workspace::ModalView; pub struct Picker { @@ -293,6 +293,7 @@ impl Render for Picker { el.child( ListItem::new("empty_state") .inset(true) + .spacing(ListItemSpacing::Sparse) .disabled(true) .child(Label::new("No matches").color(Color::Muted)), ) diff --git a/crates/project_symbols2/src/project_symbols.rs b/crates/project_symbols2/src/project_symbols.rs index da67fc888f43deed6e470940a8deaaaf22030b16..d9bdd41b6e4d1915f8962cce89e7e68534ecb8f0 100644 --- a/crates/project_symbols2/src/project_symbols.rs +++ b/crates/project_symbols2/src/project_symbols.rs @@ -11,7 +11,7 @@ use std::{borrow::Cow, cmp::Reverse, sync::Arc}; use theme::ActiveTheme; use util::ResultExt; use workspace::{ - ui::{v_stack, Color, Label, LabelCommon, LabelLike, ListItem, Selectable}, + ui::{v_stack, Color, Label, LabelCommon, LabelLike, ListItem, ListItemSpacing, Selectable}, Workspace, }; @@ -237,17 +237,21 @@ impl PickerDelegate for ProjectSymbolsDelegate { ); Some( - ListItem::new(ix).inset(true).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)), - ), + 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)), + ), ) } } diff --git a/crates/recent_projects2/src/recent_projects.rs b/crates/recent_projects2/src/recent_projects.rs index 13790a5b23ee47ff4cb343fab2fbe26b70cb16d0..1a38a5c2004044085dbfaed394255e7dd87c1a19 100644 --- a/crates/recent_projects2/src/recent_projects.rs +++ b/crates/recent_projects2/src/recent_projects.rs @@ -10,7 +10,7 @@ use highlighted_workspace_location::HighlightedWorkspaceLocation; use ordered_float::OrderedFloat; use picker::{Picker, PickerDelegate}; use std::sync::Arc; -use ui::{prelude::*, ListItem}; +use ui::{prelude::*, ListItem, ListItemSpacing}; use util::paths::PathExt; use workspace::{ notifications::simple_message_notification::MessageNotification, ModalView, Workspace, @@ -251,13 +251,17 @@ impl PickerDelegate for RecentProjectsDelegate { ); Some( - ListItem::new(ix).inset(true).selected(selected).child( - v_stack() - .child(highlighted_location.names) - .when(self.render_paths, |this| { - this.children(highlighted_location.paths) - }), - ), + ListItem::new(ix) + .inset(true) + .spacing(ListItemSpacing::Sparse) + .selected(selected) + .child( + v_stack() + .child(highlighted_location.names) + .when(self.render_paths, |this| { + this.children(highlighted_location.paths) + }), + ), ) } } diff --git a/crates/storybook2/src/stories/picker.rs b/crates/storybook2/src/stories/picker.rs index 75aa7aed055c16e2303dc1b76870ba60c2aa7ab0..edaaaa70bd1e8522785ded0c0771963505dbe2fd 100644 --- a/crates/storybook2/src/stories/picker.rs +++ b/crates/storybook2/src/stories/picker.rs @@ -4,7 +4,7 @@ use gpui::{ }; use picker::{Picker, PickerDelegate}; use std::sync::Arc; -use ui::prelude::*; +use ui::{prelude::*, ListItemSpacing}; use ui::{Label, ListItem}; pub struct PickerStory { @@ -62,6 +62,7 @@ impl PickerDelegate for Delegate { Some( ListItem::new(ix) .inset(true) + .spacing(ListItemSpacing::Sparse) .selected(selected) .child(Label::new(candidate)), ) diff --git a/crates/theme_selector2/src/theme_selector.rs b/crates/theme_selector2/src/theme_selector.rs index e0cdc455557ed948d3f69aba1fa74809579cc794..ae067ce87cfe037f8b75f0ca2f8edabfdb2f3bf7 100644 --- a/crates/theme_selector2/src/theme_selector.rs +++ b/crates/theme_selector2/src/theme_selector.rs @@ -9,7 +9,7 @@ use picker::{Picker, PickerDelegate}; use settings::{update_settings_file, SettingsStore}; use std::sync::Arc; use theme::{Theme, ThemeMeta, ThemeRegistry, ThemeSettings}; -use ui::{prelude::*, v_stack, ListItem}; +use ui::{prelude::*, v_stack, ListItem, ListItemSpacing}; use util::ResultExt; use workspace::{ui::HighlightedLabel, ModalView, Workspace}; @@ -276,6 +276,7 @@ impl PickerDelegate for ThemeSelectorDelegate { Some( ListItem::new(ix) .inset(true) + .spacing(ListItemSpacing::Sparse) .selected(selected) .child(HighlightedLabel::new( theme_match.string.clone(), diff --git a/crates/ui2/src/components/list/list_item.rs b/crates/ui2/src/components/list/list_item.rs index ca161b12f4790e6f9bee18a52b4dcb594e3deeca..6295e2940d3a086d77b4d1aadec98b8c44f1d765 100644 --- a/crates/ui2/src/components/list/list_item.rs +++ b/crates/ui2/src/components/list/list_item.rs @@ -5,11 +5,19 @@ use smallvec::SmallVec; use crate::{prelude::*, Disclosure}; +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)] +pub enum ListItemSpacing { + #[default] + Dense, + Sparse, +} + #[derive(IntoElement)] pub struct ListItem { id: ElementId, disabled: bool, selected: bool, + spacing: ListItemSpacing, indent_level: usize, indent_step_size: Pixels, /// A slot for content that appears before the children, like an icon or avatar. @@ -35,6 +43,7 @@ impl ListItem { id: id.into(), disabled: false, selected: false, + spacing: ListItemSpacing::Dense, indent_level: 0, indent_step_size: px(12.), start_slot: None, @@ -50,6 +59,11 @@ impl ListItem { } } + pub fn spacing(mut self, spacing: ListItemSpacing) -> Self { + self.spacing = spacing; + self + } + pub fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut WindowContext) + 'static) -> Self { self.on_click = Some(Box::new(handler)); self @@ -165,6 +179,10 @@ impl RenderOnce for ListItem { .relative() .gap_1() .px_2() + .map(|this| match self.spacing { + ListItemSpacing::Dense => this, + ListItemSpacing::Sparse => this.py_1(), + }) .group("list_item") .when(self.inset && !self.disabled, |this| { this diff --git a/crates/vcs_menu2/src/lib.rs b/crates/vcs_menu2/src/lib.rs index 1483a2e81e8c6fe6470ed1b264cc4ff2a18a2a06..cece283d4ee3025ea1afe0071da43839774db3b3 100644 --- a/crates/vcs_menu2/src/lib.rs +++ b/crates/vcs_menu2/src/lib.rs @@ -8,7 +8,7 @@ use gpui::{ }; use picker::{Picker, PickerDelegate}; use std::sync::Arc; -use ui::{v_stack, HighlightedLabel, ListItem, Selectable}; +use ui::{v_stack, HighlightedLabel, ListItem, ListItemSpacing, Selectable}; use util::ResultExt; use workspace::{ModalView, Toast, Workspace}; @@ -134,6 +134,7 @@ impl BranchListDelegate { impl PickerDelegate for BranchListDelegate { type ListItem = ListItem; + fn placeholder_text(&self) -> Arc { "Select branch...".into() } @@ -281,8 +282,10 @@ impl PickerDelegate for BranchListDelegate { .collect(); Some( ListItem::new(SharedString::from(format!("vcs-menu-{ix}"))) - .start_slot(HighlightedLabel::new(shortened_branch_name, highlights)) - .selected(selected), + .inset(true) + .spacing(ListItemSpacing::Sparse) + .selected(selected) + .start_slot(HighlightedLabel::new(shortened_branch_name, highlights)), ) } // fn render_header( diff --git a/crates/welcome2/src/base_keymap_picker.rs b/crates/welcome2/src/base_keymap_picker.rs index 7f799c633949dc3481c496c827909dceef658889..9655d7e13516e8ec14708bcb27142aed9f5a3e14 100644 --- a/crates/welcome2/src/base_keymap_picker.rs +++ b/crates/welcome2/src/base_keymap_picker.rs @@ -8,7 +8,7 @@ use picker::{Picker, PickerDelegate}; use project::Fs; use settings::{update_settings_file, Settings}; use std::sync::Arc; -use ui::{prelude::*, ListItem}; +use ui::{prelude::*, ListItem, ListItemSpacing}; use util::ResultExt; use workspace::{ui::HighlightedLabel, ModalView, Workspace}; @@ -198,8 +198,9 @@ impl PickerDelegate for BaseKeymapSelectorDelegate { Some( ListItem::new(ix) - .selected(selected) .inset(true) + .spacing(ListItemSpacing::Sparse) + .selected(selected) .child(HighlightedLabel::new( keymap_match.string.clone(), keymap_match.positions.clone(), From e2c36633ea2898ea3b5856194329c98edaf7e1fc Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 17:03:57 -0500 Subject: [PATCH 264/644] Align `Picker` editor with entries (#3765) This PR re-aligns the `Picker` editor with the entries after the changes in #3764. Release Notes: - N/A --- crates/picker2/src/picker2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index d37638293ce16ce75b7d7fd52961f7aba5a1d6b0..42b1d7433f01e23c9cce7b488fa972f59691f560 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -226,7 +226,7 @@ impl Render for Picker { .overflow_hidden() .flex_none() .h_9() - .px_3() + .px_4() .child(self.editor.clone()); div() From 3d1e52297eef39d164e4d838088095179070a8b4 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 17:42:54 -0500 Subject: [PATCH 265/644] Scale down status bar items (#3766) This PR scales down the sizes of items in the status bar. This brings us more in line with Zed1. Release Notes: - N/A --- .../src/activity_indicator.rs | 4 +- crates/copilot_button2/src/copilot_button.rs | 4 +- crates/diagnostics2/src/items.rs | 45 ++++++++++++++----- crates/editor2/src/items.rs | 2 +- .../feedback2/src/deploy_feedback_button.rs | 1 + .../src/active_buffer_language.rs | 3 +- crates/vim2/src/mode_indicator.rs | 6 +-- crates/workspace2/src/dock.rs | 1 + 8 files changed, 48 insertions(+), 18 deletions(-) diff --git a/crates/activity_indicator2/src/activity_indicator.rs b/crates/activity_indicator2/src/activity_indicator.rs index f83517e0618316a5407f5ab6a9bc3cabc653033a..2b7846cd8d96a9c9014c0e4ab05595df4757509e 100644 --- a/crates/activity_indicator2/src/activity_indicator.rs +++ b/crates/activity_indicator2/src/activity_indicator.rs @@ -10,7 +10,7 @@ use language::{LanguageRegistry, LanguageServerBinaryStatus}; use project::{LanguageServerProgress, Project}; use smallvec::SmallVec; use std::{cmp::Reverse, fmt::Write, sync::Arc}; -use ui::{h_stack, Label}; +use ui::prelude::*; use util::ResultExt; use workspace::{item::ItemHandle, StatusItemView, Workspace}; @@ -324,7 +324,7 @@ impl Render for ActivityIndicator { result .children(content.icon.map(|icon| svg().path(icon))) - .child(Label::new(SharedString::from(content.message))) + .child(Label::new(SharedString::from(content.message)).size(LabelSize::Small)) } } diff --git a/crates/copilot_button2/src/copilot_button.rs b/crates/copilot_button2/src/copilot_button.rs index dc6f8085339de18f40bd1c4262bc3b9e0d8c9a67..705bdc1bec52f99690287efb8cc351337148a8db 100644 --- a/crates/copilot_button2/src/copilot_button.rs +++ b/crates/copilot_button2/src/copilot_button.rs @@ -18,7 +18,8 @@ use workspace::{ create_and_open_local_file, item::ItemHandle, ui::{ - popover_menu, ButtonCommon, Clickable, ContextMenu, Icon, IconButton, PopoverMenu, Tooltip, + popover_menu, ButtonCommon, Clickable, ContextMenu, Icon, IconButton, IconSize, + PopoverMenu, Tooltip, }, StatusItemView, Toast, Workspace, }; @@ -69,6 +70,7 @@ impl Render for CopilotButton { if let Status::Error(e) = status { return div().child( IconButton::new("copilot-error", icon) + .icon_size(IconSize::Small) .on_click(cx.listener(move |this, _, cx| { if let Some(workspace) = cx.window_handle().downcast::() { workspace.update(cx, |workspace, cx| { diff --git a/crates/diagnostics2/src/items.rs b/crates/diagnostics2/src/items.rs index 14ebe0c5166e07a641e6e94bec54025eaed6c0b7..cc598ba90ca741e3b4024512544a81d0655d281c 100644 --- a/crates/diagnostics2/src/items.rs +++ b/crates/diagnostics2/src/items.rs @@ -25,29 +25,54 @@ impl Render for DiagnosticIndicator { fn render(&mut self, cx: &mut ViewContext) -> Self::Element { let diagnostic_indicator = match (self.summary.error_count, self.summary.warning_count) { - (0, 0) => h_stack().child(IconElement::new(Icon::Check).color(Color::Success)), + (0, 0) => h_stack().child( + IconElement::new(Icon::Check) + .size(IconSize::Small) + .color(Color::Success), + ), (0, warning_count) => h_stack() .gap_1() - .child(IconElement::new(Icon::ExclamationTriangle).color(Color::Warning)) - .child(Label::new(warning_count.to_string())), + .child( + IconElement::new(Icon::ExclamationTriangle) + .size(IconSize::Small) + .color(Color::Warning), + ) + .child(Label::new(warning_count.to_string()).size(LabelSize::Small)), (error_count, 0) => h_stack() .gap_1() - .child(IconElement::new(Icon::XCircle).color(Color::Error)) - .child(Label::new(error_count.to_string())), + .child( + IconElement::new(Icon::XCircle) + .size(IconSize::Small) + .color(Color::Error), + ) + .child(Label::new(error_count.to_string()).size(LabelSize::Small)), (error_count, warning_count) => h_stack() .gap_1() - .child(IconElement::new(Icon::XCircle).color(Color::Error)) - .child(Label::new(error_count.to_string())) - .child(IconElement::new(Icon::ExclamationTriangle).color(Color::Warning)) - .child(Label::new(warning_count.to_string())), + .child( + IconElement::new(Icon::XCircle) + .size(IconSize::Small) + .color(Color::Error), + ) + .child(Label::new(error_count.to_string()).size(LabelSize::Small)) + .child( + IconElement::new(Icon::ExclamationTriangle) + .size(IconSize::Small) + .color(Color::Warning), + ) + .child(Label::new(warning_count.to_string()).size(LabelSize::Small)), }; let status = if !self.in_progress_checks.is_empty() { - Some(Label::new("Checking…").into_any_element()) + Some( + Label::new("Checking…") + .size(LabelSize::Small) + .into_any_element(), + ) } else if let Some(diagnostic) = &self.current_diagnostic { let message = diagnostic.message.split('\n').next().unwrap().to_string(); Some( Button::new("diagnostic_message", message) + .label_size(LabelSize::Small) .tooltip(|cx| { Tooltip::for_action("Next Diagnostic", &editor::GoToDiagnostic, cx) }) diff --git a/crates/editor2/src/items.rs b/crates/editor2/src/items.rs index fc8f7dfbbfb5cefe7f6d91b1d4dfdc6adbc3a3d8..e0374d3d7307ce0972a94d66993e0b9df05750a0 100644 --- a/crates/editor2/src/items.rs +++ b/crates/editor2/src/items.rs @@ -1200,7 +1200,7 @@ impl Render for CursorPosition { write!(text, " ({} selected)", self.selected_count).unwrap(); } - el.child(Label::new(text)) + el.child(Label::new(text).size(LabelSize::Small)) }) } } diff --git a/crates/feedback2/src/deploy_feedback_button.rs b/crates/feedback2/src/deploy_feedback_button.rs index 3b28c64dc3a57c51937f636c1693ea779aa1bf0d..926a5d791e0550dd27c354a5cc6db3530518f189 100644 --- a/crates/feedback2/src/deploy_feedback_button.rs +++ b/crates/feedback2/src/deploy_feedback_button.rs @@ -31,6 +31,7 @@ impl Render for DeployFeedbackButton { .is_some(); IconButton::new("give-feedback", Icon::Envelope) .style(ui::ButtonStyle::Subtle) + .icon_size(IconSize::Small) .selected(is_open) .tooltip(|cx| Tooltip::text("Share Feedback", cx)) .on_click(|_, cx| { diff --git a/crates/language_selector2/src/active_buffer_language.rs b/crates/language_selector2/src/active_buffer_language.rs index 4034cb04297e5ce6ab0db036a776a0edc111ebae..48224198a2e13a1651102a7e26253b0a7b6568bb 100644 --- a/crates/language_selector2/src/active_buffer_language.rs +++ b/crates/language_selector2/src/active_buffer_language.rs @@ -3,7 +3,7 @@ use gpui::{ div, Div, IntoElement, ParentElement, Render, Subscription, View, ViewContext, WeakView, }; use std::sync::Arc; -use ui::{Button, ButtonCommon, Clickable, Tooltip}; +use ui::{Button, ButtonCommon, Clickable, LabelSize, Tooltip}; use workspace::{item::ItemHandle, StatusItemView, Workspace}; use crate::LanguageSelector; @@ -50,6 +50,7 @@ impl Render for ActiveBufferLanguage { el.child( Button::new("change-language", active_language_text) + .label_size(LabelSize::Small) .on_click(cx.listener(|this, _, cx| { if let Some(workspace) = this.workspace.upgrade() { workspace.update(cx, |workspace, cx| { diff --git a/crates/vim2/src/mode_indicator.rs b/crates/vim2/src/mode_indicator.rs index 8c831ba797243a219b0cdf0730acb3caf4d0e0d4..f3b16e68ae0bdd2d6f933bf9909e96d8f9608374 100644 --- a/crates/vim2/src/mode_indicator.rs +++ b/crates/vim2/src/mode_indicator.rs @@ -1,6 +1,6 @@ -use gpui::{div, AnyElement, Element, IntoElement, Render, Subscription, ViewContext}; +use gpui::{div, AnyElement, Element, Render, Subscription, ViewContext}; use settings::SettingsStore; -use workspace::{item::ItemHandle, ui::Label, StatusItemView}; +use workspace::{item::ItemHandle, ui::prelude::*, StatusItemView}; use crate::{state::Mode, Vim}; @@ -61,7 +61,7 @@ impl Render for ModeIndicator { Mode::VisualLine => "-- VISUAL LINE --", Mode::VisualBlock => "-- VISUAL BLOCK --", }; - Label::new(text).into_any_element() + Label::new(text).size(LabelSize::Small).into_any_element() } } diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index e59d7ee49492e8361223d6d3ccf8457913cf965b..6f17d77fef8ead496a164b4aeaee0e150fdb9533 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -637,6 +637,7 @@ impl Render for PanelButtons { .attach(menu_attach) .trigger( IconButton::new(name, icon) + .icon_size(IconSize::Small) .selected(is_active_button) .on_click({ let action = action.boxed_clone(); From f3fda8018f37afae08121b8ce28b195cf52a75b9 Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 21 Dec 2023 17:52:29 -0500 Subject: [PATCH 266/644] Prevent drag-dropping non-terminal item into terminal pane --- crates/gpui2/src/elements/div.rs | 74 +++++++++++++++------ crates/terminal_view2/src/terminal_panel.rs | 9 +++ crates/workspace2/src/pane.rs | 17 ++++- crates/workspace2/src/workspace2.rs | 2 + 4 files changed, 79 insertions(+), 23 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 90af9e130e79a375cd339e03880790c8cc1acdd6..7c74eb1039f6277c99c562392b26ad925d4d6e5a 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -297,6 +297,10 @@ impl Interactivity { )); } + pub fn can_drop(&mut self, predicate: impl Fn(&dyn Any, &mut WindowContext) -> bool + 'static) { + self.can_drop_predicate = Some(Box::new(predicate)); + } + pub fn on_click(&mut self, listener: impl Fn(&ClickEvent, &mut WindowContext) + 'static) where Self: Sized, @@ -569,6 +573,14 @@ pub trait InteractiveElement: Sized { self } + fn can_drop( + mut self, + predicate: impl Fn(&dyn Any, &mut WindowContext) -> bool + 'static, + ) -> Self { + self.interactivity().can_drop(predicate); + self + } + fn block_mouse(mut self) -> Self { self.interactivity().block_mouse(); self @@ -699,6 +711,8 @@ pub type DragListener = Box AnyView + 's type DropListener = Box; +type CanDropPredicate = Box bool + 'static>; + pub type TooltipBuilder = Rc AnyView + 'static>; pub type KeyDownListener = Box; @@ -887,6 +901,7 @@ pub struct Interactivity { pub key_up_listeners: Vec, pub action_listeners: Vec<(TypeId, ActionListener)>, pub drop_listeners: Vec<(TypeId, DropListener)>, + pub can_drop_predicate: Option, pub click_listeners: Vec, pub drag_listener: Option<(Box, DragListener)>, pub hover_listener: Option>, @@ -1198,6 +1213,7 @@ impl Interactivity { let mut drag_listener = mem::take(&mut self.drag_listener); let drop_listeners = mem::take(&mut self.drop_listeners); let click_listeners = mem::take(&mut self.click_listeners); + let can_drop_predicate = mem::take(&mut self.can_drop_predicate); if !drop_listeners.is_empty() { cx.on_mouse_event({ @@ -1215,9 +1231,17 @@ impl Interactivity { "checked for type drag state type above", ); - listener(drag.value.as_ref(), cx); - cx.notify(); - cx.stop_propagation(); + let mut can_drop = true; + if let Some(predicate) = &can_drop_predicate { + can_drop = + predicate(drag.value.as_ref(), cx); + } + + if can_drop { + listener(drag.value.as_ref(), cx); + cx.notify(); + cx.stop_propagation(); + } } } } @@ -1596,27 +1620,36 @@ impl Interactivity { } if let Some(drag) = cx.active_drag.take() { - for (state_type, group_drag_style) in &self.group_drag_over_styles { - if let Some(group_bounds) = GroupBounds::get(&group_drag_style.group, cx) { - if *state_type == drag.value.as_ref().type_id() - && group_bounds.contains(&mouse_position) + let mut can_drop = true; + if let Some(can_drop_predicate) = &self.can_drop_predicate { + can_drop = can_drop_predicate(drag.value.as_ref(), cx); + } + + if can_drop { + for (state_type, group_drag_style) in &self.group_drag_over_styles { + if let Some(group_bounds) = + GroupBounds::get(&group_drag_style.group, cx) { - style.refine(&group_drag_style.style); + if *state_type == drag.value.as_ref().type_id() + && group_bounds.contains(&mouse_position) + { + style.refine(&group_drag_style.style); + } } } - } - for (state_type, drag_over_style) in &self.drag_over_styles { - if *state_type == drag.value.as_ref().type_id() - && bounds - .intersect(&cx.content_mask().bounds) - .contains(&mouse_position) - && cx.was_top_layer_under_active_drag( - &mouse_position, - cx.stacking_order(), - ) - { - style.refine(drag_over_style); + for (state_type, drag_over_style) in &self.drag_over_styles { + if *state_type == drag.value.as_ref().type_id() + && bounds + .intersect(&cx.content_mask().bounds) + .contains(&mouse_position) + && cx.was_top_layer_under_active_drag( + &mouse_position, + cx.stacking_order(), + ) + { + style.refine(drag_over_style); + } } } @@ -1672,6 +1705,7 @@ impl Default for Interactivity { key_up_listeners: Vec::new(), action_listeners: Vec::new(), drop_listeners: Vec::new(), + can_drop_predicate: None, click_listeners: Vec::new(), drag_listener: None, hover_listener: None, diff --git a/crates/terminal_view2/src/terminal_panel.rs b/crates/terminal_view2/src/terminal_panel.rs index fa266ceb6cf3fceb76d1db0f693778b6659c539c..245add3eeb9b3cad48f38a3c443597330ffc8328 100644 --- a/crates/terminal_view2/src/terminal_panel.rs +++ b/crates/terminal_view2/src/terminal_panel.rs @@ -58,6 +58,15 @@ impl TerminalPanel { workspace.weak_handle(), workspace.project().clone(), Default::default(), + Some(Arc::new(|a, cx| { + if let Some(tab) = a.downcast_ref::() { + if let Some(item) = tab.pane.read(cx).item_for_index(tab.ix) { + return item.downcast::().is_some(); + } + } + + false + })), cx, ); pane.set_can_split(false, cx); diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index d0b47a2d1e5aadc49395f6ccf5a76f25c5a5aa86..66bbe85087f91e8abf90a1f91c7700683edfb479 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -181,7 +181,7 @@ pub struct Pane { workspace: WeakView, project: Model, drag_split_direction: Option, - // can_drop: Rc, &WindowContext) -> bool>, + can_drop_predicate: Option bool>>, can_split: bool, // render_tab_bar_buttons: Rc) -> AnyElement>, _subscriptions: Vec, @@ -229,7 +229,7 @@ pub struct NavigationEntry { } #[derive(Clone)] -struct DraggedTab { +pub struct DraggedTab { pub pane: View, pub ix: usize, pub item_id: EntityId, @@ -325,6 +325,7 @@ impl Pane { workspace: WeakView, project: Model, next_timestamp: Arc, + can_drop_predicate: Option bool + 'static>>, cx: &mut ViewContext, ) -> Self { // todo!("context menu") @@ -371,7 +372,7 @@ impl Pane { // tab_context_menu: cx.build_view(|_| ContextMenu::new(pane_view_id, cx)), workspace, project, - // can_drop: Rc::new(|_, _| true), + can_drop_predicate, can_split: true, // render_tab_bar_buttons: Rc::new(move |pane, cx| { // Flex::row() @@ -746,6 +747,10 @@ impl Pane { .position(|i| i.item_id() == item.item_id()) } + pub fn item_for_index(&self, ix: usize) -> Option<&dyn ItemHandle> { + self.items.get(ix).map(|i| i.as_ref()) + } + pub fn toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext) { if self.zoomed { cx.emit(Event::ZoomOut); @@ -1530,6 +1535,9 @@ impl Pane { ) .drag_over::(|tab| tab.bg(cx.theme().colors().drop_target_background)) .drag_over::(|tab| tab.bg(cx.theme().colors().drop_target_background)) + .when_some(self.can_drop_predicate.clone(), |this, p| { + this.can_drop(move |a, cx| p(a, cx)) + }) .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { this.drag_split_direction = None; this.handle_tab_drop(dragged_tab, ix, cx) @@ -1947,6 +1955,9 @@ impl Render for Pane { )) .group_drag_over::("", |style| style.visible()) .group_drag_over::("", |style| style.visible()) + .when_some(self.can_drop_predicate.clone(), |this, p| { + this.can_drop(move |a, cx| p(a, cx)) + }) .on_drop(cx.listener(move |this, dragged_tab, cx| { this.handle_tab_drop(dragged_tab, this.active_item_index(), cx) })) diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index b4508b9ddadee9fb47f345cbfe81286a58603b71..c1695891f6abf986012948dc5f4364aebdd6e68c 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -542,6 +542,7 @@ impl Workspace { weak_handle.clone(), project.clone(), pane_history_timestamp.clone(), + None, cx, ) }); @@ -1724,6 +1725,7 @@ impl Workspace { self.weak_handle(), self.project.clone(), self.pane_history_timestamp.clone(), + None, cx, ) }); From 5307b75b2f81a105922b4f271ea34d8f969193a8 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 22:29:30 -0500 Subject: [PATCH 267/644] Add more left padding to title bar (#3768) This PR adds more left padding to the title bar to achieve the same positioning of the title bar items that we have in Zed1. Release Notes: - N/A --- crates/collab_ui2/src/collab_titlebar_item.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 8e542e413e8bce8e07f0bd77fba0c90855f3ccde..e4a6ff089a17efd8ab8abd36e0e8ade954cfb30a 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -74,14 +74,13 @@ impl Render for CollabTitlebarItem { // Set a non-scaling min-height here to ensure the titlebar is // always at least the height of the traffic lights. .min_h(px(32.)) - .pl_2() .map(|this| { if matches!(cx.window_bounds(), WindowBounds::Fullscreen) { this.pl_2() } else { // Use pixels here instead of a rem-based size because the macOS traffic // lights are a static size, and don't scale with the rest of the UI. - this.pl(px(72.)) + this.pl(px(80.)) } }) .bg(cx.theme().colors().title_bar_background) From 4fb12cb348e9c2f35d51ce4c73b329b148dc6f03 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 22:36:15 -0500 Subject: [PATCH 268/644] Add vertical padding to the picker entry list (#3769) This PR adds vertical padding to the list of picker entries. This prevents us from ending up with entries squished against the edges of the picker. Release Notes: - N/A --- crates/picker2/src/picker2.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 42b1d7433f01e23c9cce7b488fa972f59691f560..8dcc8b96983bc71178a7b63b5109ea7ac92ab352 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -252,6 +252,7 @@ impl Render for Picker { el.child( v_stack() .flex_grow() + .py_2() .child( uniform_list( cx.view().clone(), From 94e22ae515191cdadcd13fa933182dd5a17fbb1a Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 22:36:40 -0500 Subject: [PATCH 269/644] Fix typo in "Noctis Hibernus" theme name (#3770) This PR fixes a typo in the name of the "Noctis Hibernus" theme. Release Notes: - N/A --- assets/themes/src/vscode/noctis/family.json | 2 +- crates/theme2/src/themes/noctis.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/themes/src/vscode/noctis/family.json b/assets/themes/src/vscode/noctis/family.json index 525cb160f52e48ba839e6d1d51b81b50abad40cb..623be89c9019c45d325d16e139437c501ece67c8 100644 --- a/assets/themes/src/vscode/noctis/family.json +++ b/assets/themes/src/vscode/noctis/family.json @@ -13,7 +13,7 @@ "appearance": "dark" }, { - "name": "Noctus Hibernus", + "name": "Noctis Hibernus", "file_name": "hibernus.json", "appearance": "light" }, diff --git a/crates/theme2/src/themes/noctis.rs b/crates/theme2/src/themes/noctis.rs index ca1601df99ad16592300cbee25c0bc6da303a621..55aea3d24c04ff59f23be080f4b0a3436f9020fa 100644 --- a/crates/theme2/src/themes/noctis.rs +++ b/crates/theme2/src/themes/noctis.rs @@ -577,7 +577,7 @@ pub fn noctis() -> UserThemeFamily { }, }, UserTheme { - name: "Noctus Hibernus".into(), + name: "Noctis Hibernus".into(), appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { From 80143b2571d664b01e031f6d4a353c959cd0ddc0 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 22:45:29 -0500 Subject: [PATCH 270/644] =?UTF-8?q?Fix=20names=20for=20Ros=C3=A9=20Pine=20?= =?UTF-8?q?themes=20(#3771)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR fixes the names of the Rosé Pine themes. We want to keep the Unicode "é" in the theme name, both because this is the actual name of the theme, and also to maintain parity with Zed1. Release Notes: - N/A --- Cargo.lock | 7 +++++++ assets/themes/src/vscode/rose-pine/family.json | 8 ++++---- crates/theme2/src/themes/rose_pine.rs | 8 ++++---- crates/theme_importer/Cargo.toml | 1 + crates/theme_importer/src/main.rs | 3 ++- crates/theme_importer/src/vscode/converter.rs | 2 +- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82cc00bf9e65188980161fce3567cf70cbadd406..f8d8c1cc0d16f1175a4c52a271ad6fa615b76743 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -306,6 +306,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "any_ascii" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea50b14b7a4b9343f8c627a7a53c52076482bd4bdad0a24fd3ec533ed616cc2c" + [[package]] name = "anyhow" version = "1.0.75" @@ -9836,6 +9842,7 @@ dependencies = [ name = "theme_importer" version = "0.1.0" dependencies = [ + "any_ascii", "anyhow", "clap 4.4.4", "convert_case 0.6.0", diff --git a/assets/themes/src/vscode/rose-pine/family.json b/assets/themes/src/vscode/rose-pine/family.json index 3f7b149db8bf0e9e949214e526a755aaa0f60830..517b20c6529edaec43f90da8a91a02474c882428 100644 --- a/assets/themes/src/vscode/rose-pine/family.json +++ b/assets/themes/src/vscode/rose-pine/family.json @@ -1,19 +1,19 @@ { - "name": "Rose Pine", + "name": "Rosé Pine", "author": "Rosé Pine", "themes": [ { - "name": "Rose Pine", + "name": "Rosé Pine", "file_name": "rose-pine.json", "appearance": "dark" }, { - "name": "Rose Pine Moon", + "name": "Rosé Pine Moon", "file_name": "rose-pine-moon.json", "appearance": "dark" }, { - "name": "Rose Pine Dawn", + "name": "Rosé Pine Dawn", "file_name": "rose-pine-dawn.json", "appearance": "light" } diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index 828838530f4650cce4e468437927748784d3f997..a24c7ef80d5a530cff0e335f537f554506f3856e 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -11,11 +11,11 @@ use crate::{ pub fn rose_pine() -> UserThemeFamily { UserThemeFamily { - name: "Rose Pine".into(), + name: "Rosé Pine".into(), author: "Rosé Pine".into(), themes: vec![ UserTheme { - name: "Rose Pine".into(), + name: "Rosé Pine".into(), appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { @@ -278,7 +278,7 @@ pub fn rose_pine() -> UserThemeFamily { }, }, UserTheme { - name: "Rose Pine Moon".into(), + name: "Rosé Pine Moon".into(), appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { @@ -541,7 +541,7 @@ pub fn rose_pine() -> UserThemeFamily { }, }, UserTheme { - name: "Rose Pine Dawn".into(), + name: "Rosé Pine Dawn".into(), appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { diff --git a/crates/theme_importer/Cargo.toml b/crates/theme_importer/Cargo.toml index 4b8641faa47eefce6438fdca04a5a3cda80232bd..23a53053cecd76a151fd29152f86c1a73a15ac67 100644 --- a/crates/theme_importer/Cargo.toml +++ b/crates/theme_importer/Cargo.toml @@ -7,6 +7,7 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +any_ascii = "0.3.2" anyhow.workspace = true clap = { version = "4.4", features = ["derive"] } convert_case = "0.6.0" diff --git a/crates/theme_importer/src/main.rs b/crates/theme_importer/src/main.rs index a02b1ca1149529d66298c8fc637389d1c2cebeb3..01ab1915718b45a5ff988a438ee9adf65e96301e 100644 --- a/crates/theme_importer/src/main.rs +++ b/crates/theme_importer/src/main.rs @@ -9,6 +9,7 @@ use std::path::PathBuf; use std::process::Command; use std::str::FromStr; +use any_ascii::any_ascii; use anyhow::{anyhow, Context, Result}; use clap::Parser; use convert_case::{Case, Casing}; @@ -187,7 +188,7 @@ fn main() -> Result<()> { let mut theme_modules = Vec::new(); for theme_family in theme_families { - let theme_family_slug = theme_family.name.to_string().to_case(Case::Snake); + let theme_family_slug = any_ascii(&theme_family.name).to_case(Case::Snake); let mut output_file = File::create(themes_output_path.join(format!("{theme_family_slug}.rs")))?; diff --git a/crates/theme_importer/src/vscode/converter.rs b/crates/theme_importer/src/vscode/converter.rs index 8ade4937311f25c93604e70122161a06771e2304..41534d0d0e29553ef4568bd03193f020afa2dc94 100644 --- a/crates/theme_importer/src/vscode/converter.rs +++ b/crates/theme_importer/src/vscode/converter.rs @@ -56,7 +56,7 @@ impl VsCodeThemeConverter { let syntax_theme = self.convert_syntax_theme()?; Ok(UserTheme { - name: self.theme_metadata.name.into(), + name: self.theme_metadata.name, appearance, styles: UserThemeStylesRefinement { colors: theme_colors_refinements, From cd9156886f60908e01702834b27bf74630a27110 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 23:22:22 -0500 Subject: [PATCH 271/644] Increase the indent step size for the collab panel (#3772) This PR increases the indent step size for the collab panel. This gives the channel list a clearer hierarchy for nested channels, as well as help align the disclosures with the parent channel's icon. Release Notes: - N/A --- crates/collab_ui2/src/collab_panel.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 7d01c080e89d124f0ca2ffd4d8a273ada7f30f32..b5b7a726d3490464dc13df60c707f68222075def 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2120,6 +2120,7 @@ impl CollabPanel { ListItem::new(channel_id as usize) // Add one level of depth for the disclosure arrow. .indent_level(depth + 1) + .indent_step_size(px(20.)) .selected(is_selected || is_active) .toggle(disclosed) .on_toggle( @@ -2190,6 +2191,7 @@ impl CollabPanel { .inset(false) // Add one level of depth for the disclosure arrow. .indent_level(depth + 1) + .indent_step_size(px(20.)) .start_slot( IconElement::new(Icon::Hash) .size(IconSize::Small) From 248458cef51cb86320ff429d9b40ce089e7a0da7 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 23:35:50 -0500 Subject: [PATCH 272/644] Indent contacts in collab panel (#3773) This PR indents contacts in the collab panel. Release Notes: - N/A --- crates/collab_ui2/src/collab_panel.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index b5b7a726d3490464dc13df60c707f68222075def..ad11877fd3065f33fc558078eed541aa1f3602c3 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -1871,6 +1871,8 @@ impl CollabPanel { let github_login = SharedString::from(contact.user.github_login.clone()); let item = ListItem::new(github_login.clone()) + .indent_level(1) + .indent_step_size(px(20.)) .selected(is_selected) .on_click(cx.listener(move |this, _, cx| this.call(user_id, cx))) .child( @@ -1968,6 +1970,8 @@ impl CollabPanel { }; ListItem::new(github_login.clone()) + .indent_level(1) + .indent_step_size(px(20.)) .selected(is_selected) .child( h_stack() From 2659b2744a010721604298f00aa8e97bd8175a6f Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Dec 2023 23:41:24 -0500 Subject: [PATCH 273/644] Add vertical padding to the picker empty state (#3774) This PR adds vertical padding to the picker's empty state. This matches the styles added in #3769. Release Notes: - N/A --- crates/picker2/src/picker2.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 8dcc8b96983bc71178a7b63b5109ea7ac92ab352..aa88d70dc44e84ee0eb25dc37f250af5a007e6c0 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -292,11 +292,13 @@ impl Render for Picker { }) .when(self.delegate.match_count() == 0, |el| { el.child( - ListItem::new("empty_state") - .inset(true) - .spacing(ListItemSpacing::Sparse) - .disabled(true) - .child(Label::new("No matches").color(Color::Muted)), + v_stack().flex_grow().py_2().child( + ListItem::new("empty_state") + .inset(true) + .spacing(ListItemSpacing::Sparse) + .disabled(true) + .child(Label::new("No matches").color(Color::Muted)), + ), ) }) } From 48ad53baddbff58b0b706c67acbd7664a2b3462b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Dec 2023 19:52:15 +0100 Subject: [PATCH 274/644] Revert "Revert "Optimize order rendering and border drawing"" --- Cargo.lock | 12 ---- crates/gpui2/Cargo.toml | 1 - crates/gpui2/src/geometry.rs | 21 ++++++ crates/gpui2/src/scene.rs | 126 +++++++---------------------------- crates/gpui2/src/style.rs | 60 +++++++++++++++-- crates/gpui2/src/window.rs | 1 + 6 files changed, 101 insertions(+), 120 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8d8c1cc0d16f1175a4c52a271ad6fa615b76743..1bcbd3be387341da6da2e0c2ae041a5edead8ba1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4066,7 +4066,6 @@ dependencies = [ "parking", "parking_lot 0.11.2", "pathfinder_geometry", - "plane-split", "png", "postage", "rand 0.8.5", @@ -6662,17 +6661,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "plane-split" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f7d82649829ecdef8e258790b0587acf0a8403f0ce963473d8e918acc1643" -dependencies = [ - "euclid", - "log", - "smallvec", -] - [[package]] name = "plist" version = "1.5.0" diff --git a/crates/gpui2/Cargo.toml b/crates/gpui2/Cargo.toml index afb5d3ea0ce7080830bbcb1eb86aad62b8f7432c..bf0ac955a5ec20d8a9ca6d0c0bac0bc5e7c95542 100644 --- a/crates/gpui2/Cargo.toml +++ b/crates/gpui2/Cargo.toml @@ -56,7 +56,6 @@ uuid = { version = "1.1.2", features = ["v4"] } waker-fn = "1.1.0" slotmap = "1.0.6" schemars.workspace = true -plane-split = "0.18.0" bitflags = "2.4.0" [dev-dependencies] diff --git a/crates/gpui2/src/geometry.rs b/crates/gpui2/src/geometry.rs index f58435d7b9a2e9b3fa48062d2e28ed21502c1ca1..6b4d9ae807b581eff4fe38baf913843e43bd8c83 100644 --- a/crates/gpui2/src/geometry.rs +++ b/crates/gpui2/src/geometry.rs @@ -1590,6 +1590,15 @@ impl Edges { left: self.left.scale(factor), } } + + /// Returns the maximum value of any edge. + /// + /// # Returns + /// + /// The maximum `Pixels` value among all four edges. + pub fn max(&self) -> Pixels { + self.top.max(self.right).max(self.bottom).max(self.left) + } } impl Into> for f32 { @@ -1740,6 +1749,18 @@ impl Corners { bottom_left: self.bottom_left.scale(factor), } } + + /// Returns the maximum value of any corner. + /// + /// # Returns + /// + /// The maximum `Pixels` value among all four corners. + pub fn max(&self) -> Pixels { + self.top_left + .max(self.top_right) + .max(self.bottom_right) + .max(self.bottom_left) + } } impl Corners { diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index e6b601b62f17cf087748f8ce4e672eab14b13fb8..cb62ce314f8147455768a359717c4168d88b7edb 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -3,8 +3,6 @@ use crate::{ ScaledPixels, StackingOrder, }; use collections::BTreeMap; -use etagere::euclid::{Point3D, Vector3D}; -use plane_split::{BspSplitter, Polygon as BspPolygon}; use std::{fmt::Debug, iter::Peekable, mem, slice}; // Exported to metal @@ -19,7 +17,6 @@ pub type DrawOrder = u32; pub(crate) struct SceneBuilder { last_order: Option<(StackingOrder, LayerId)>, layers_by_order: BTreeMap, - splitter: BspSplitter<(PrimitiveKind, usize)>, shadows: Vec, quads: Vec, paths: Vec>, @@ -34,7 +31,6 @@ impl Default for SceneBuilder { SceneBuilder { last_order: None, layers_by_order: BTreeMap::new(), - splitter: BspSplitter::new(), shadows: Vec::new(), quads: Vec::new(), paths: Vec::new(), @@ -48,103 +44,47 @@ impl Default for SceneBuilder { impl SceneBuilder { pub fn build(&mut self) -> Scene { - // Map each layer id to a float between 0. and 1., with 1. closer to the viewer. - let mut layer_z_values = vec![0.; self.layers_by_order.len()]; + let mut orders = vec![0; self.layers_by_order.len()]; for (ix, layer_id) in self.layers_by_order.values().enumerate() { - layer_z_values[*layer_id as usize] = ix as f32 / self.layers_by_order.len() as f32; + orders[*layer_id as usize] = ix as u32; } self.layers_by_order.clear(); self.last_order = None; - // Add all primitives to the BSP splitter to determine draw order - self.splitter.reset(); - - for (ix, shadow) in self.shadows.iter().enumerate() { - let z = layer_z_values[shadow.order as LayerId as usize]; - self.splitter - .add(shadow.bounds.to_bsp_polygon(z, (PrimitiveKind::Shadow, ix))); - } - - for (ix, quad) in self.quads.iter().enumerate() { - let z = layer_z_values[quad.order as LayerId as usize]; - self.splitter - .add(quad.bounds.to_bsp_polygon(z, (PrimitiveKind::Quad, ix))); + for shadow in &mut self.shadows { + shadow.order = orders[shadow.order as usize]; } + self.shadows.sort_by_key(|shadow| shadow.order); - for (ix, path) in self.paths.iter().enumerate() { - let z = layer_z_values[path.order as LayerId as usize]; - self.splitter - .add(path.bounds.to_bsp_polygon(z, (PrimitiveKind::Path, ix))); + for quad in &mut self.quads { + quad.order = orders[quad.order as usize]; } + self.quads.sort_by_key(|quad| quad.order); - for (ix, underline) in self.underlines.iter().enumerate() { - let z = layer_z_values[underline.order as LayerId as usize]; - self.splitter.add( - underline - .bounds - .to_bsp_polygon(z, (PrimitiveKind::Underline, ix)), - ); + for path in &mut self.paths { + path.order = orders[path.order as usize]; } + self.paths.sort_by_key(|path| path.order); - for (ix, monochrome_sprite) in self.monochrome_sprites.iter().enumerate() { - let z = layer_z_values[monochrome_sprite.order as LayerId as usize]; - self.splitter.add( - monochrome_sprite - .bounds - .to_bsp_polygon(z, (PrimitiveKind::MonochromeSprite, ix)), - ); + for underline in &mut self.underlines { + underline.order = orders[underline.order as usize]; } + self.underlines.sort_by_key(|underline| underline.order); - for (ix, polychrome_sprite) in self.polychrome_sprites.iter().enumerate() { - let z = layer_z_values[polychrome_sprite.order as LayerId as usize]; - self.splitter.add( - polychrome_sprite - .bounds - .to_bsp_polygon(z, (PrimitiveKind::PolychromeSprite, ix)), - ); + for monochrome_sprite in &mut self.monochrome_sprites { + monochrome_sprite.order = orders[monochrome_sprite.order as usize]; } + self.monochrome_sprites.sort_by_key(|sprite| sprite.order); - for (ix, surface) in self.surfaces.iter().enumerate() { - let z = layer_z_values[surface.order as LayerId as usize]; - self.splitter.add( - surface - .bounds - .to_bsp_polygon(z, (PrimitiveKind::Surface, ix)), - ); + for polychrome_sprite in &mut self.polychrome_sprites { + polychrome_sprite.order = orders[polychrome_sprite.order as usize]; } + self.polychrome_sprites.sort_by_key(|sprite| sprite.order); - // Sort all polygons, then reassign the order field of each primitive to `draw_order` - // We need primitives to be repr(C), hence the weird reuse of the order field for two different types. - for (draw_order, polygon) in self - .splitter - .sort(Vector3D::new(0., 0., 1.)) - .iter() - .enumerate() - { - match polygon.anchor { - (PrimitiveKind::Shadow, ix) => self.shadows[ix].order = draw_order as DrawOrder, - (PrimitiveKind::Quad, ix) => self.quads[ix].order = draw_order as DrawOrder, - (PrimitiveKind::Path, ix) => self.paths[ix].order = draw_order as DrawOrder, - (PrimitiveKind::Underline, ix) => { - self.underlines[ix].order = draw_order as DrawOrder - } - (PrimitiveKind::MonochromeSprite, ix) => { - self.monochrome_sprites[ix].order = draw_order as DrawOrder - } - (PrimitiveKind::PolychromeSprite, ix) => { - self.polychrome_sprites[ix].order = draw_order as DrawOrder - } - (PrimitiveKind::Surface, ix) => self.surfaces[ix].order = draw_order as DrawOrder, - } + for surface in &mut self.surfaces { + surface.order = orders[surface.order as usize]; } - - self.shadows.sort_unstable(); - self.quads.sort_unstable(); - self.paths.sort_unstable(); - self.underlines.sort_unstable(); - self.monochrome_sprites.sort_unstable(); - self.polychrome_sprites.sort_unstable(); - self.surfaces.sort_unstable(); + self.surfaces.sort_by_key(|surface| surface.order); Scene { shadows: mem::take(&mut self.shadows), @@ -845,23 +785,3 @@ impl PathVertex { #[derive(Copy, Clone, Debug)] pub struct AtlasId(pub(crate) usize); - -impl Bounds { - fn to_bsp_polygon(&self, z: f32, anchor: A) -> BspPolygon { - let upper_left = self.origin; - let upper_right = self.upper_right(); - let lower_right = self.lower_right(); - let lower_left = self.lower_left(); - - BspPolygon::from_points( - [ - Point3D::new(upper_left.x.into(), upper_left.y.into(), z as f64), - Point3D::new(upper_right.x.into(), upper_right.y.into(), z as f64), - Point3D::new(lower_right.x.into(), lower_right.y.into(), z as f64), - Point3D::new(lower_left.x.into(), lower_left.y.into(), z as f64), - ], - anchor, - ) - .expect("Polygon should not be empty") - } -} diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index 3e9593b0fd6635a1b9b2ce867e6fc465a47d80de..de54da79b3d0eb1e7489962143dbbc7d0dc0809f 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -402,13 +402,65 @@ impl Style { if self.is_border_visible() { cx.with_z_index(3, |cx| { - cx.paint_quad(quad( + let corner_radii = self.corner_radii.to_pixels(bounds.size, rem_size); + let border_widths = self.border_widths.to_pixels(rem_size); + let max_border_width = border_widths.max(); + let max_corner_radius = corner_radii.max(); + + let top_bounds = Bounds::from_corners( + bounds.origin, + bounds.upper_right() + + point(Pixels::ZERO, max_border_width.max(max_corner_radius)), + ); + let bottom_bounds = Bounds::from_corners( + bounds.lower_left() + - point(Pixels::ZERO, max_border_width.max(max_corner_radius)), + bounds.lower_right(), + ); + let left_bounds = Bounds::from_corners( + top_bounds.lower_left(), + bottom_bounds.origin + point(max_border_width, Pixels::ZERO), + ); + let right_bounds = Bounds::from_corners( + top_bounds.lower_right() - point(max_border_width, Pixels::ZERO), + bottom_bounds.upper_right(), + ); + + let quad = quad( bounds, - self.corner_radii.to_pixels(bounds.size, rem_size), + corner_radii, Hsla::transparent_black(), - self.border_widths.to_pixels(rem_size), + border_widths, self.border_color.unwrap_or_default(), - )); + ); + + cx.with_content_mask(Some(ContentMask { bounds: top_bounds }), |cx| { + cx.paint_quad(quad.clone()); + }); + cx.with_content_mask( + Some(ContentMask { + bounds: right_bounds, + }), + |cx| { + cx.paint_quad(quad.clone()); + }, + ); + cx.with_content_mask( + Some(ContentMask { + bounds: bottom_bounds, + }), + |cx| { + cx.paint_quad(quad.clone()); + }, + ); + cx.with_content_mask( + Some(ContentMask { + bounds: left_bounds, + }), + |cx| { + cx.paint_quad(quad); + }, + ); }); } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index e57984fa0d0fe2ee577a162608159cc72ea0f848..c20e2f7b94a3337e05b1fa755fdb624d93396213 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -3074,6 +3074,7 @@ impl From<(&'static str, u64)> for ElementId { } /// A rectangle, to be rendered on the screen by GPUI at the given position and size. +#[derive(Clone)] pub struct PaintQuad { bounds: Bounds, corner_radii: Corners, From 2a516ec1e0d05976a396968e4020f7ee5077a81b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 09:24:01 +0100 Subject: [PATCH 275/644] Honor `PrimitiveKind` ordering when `order` is the same This was a bug in the previous implementation that was being masked by how we were using BSP. --- crates/gpui2/src/scene.rs | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index cb62ce314f8147455768a359717c4168d88b7edb..687943a7b18fafcb52170ea93b628f4c58cafcbf 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -269,10 +269,11 @@ impl<'a> Iterator for BatchIterator<'a> { match batch_kind { PrimitiveKind::Shadow => { let shadows_start = self.shadows_start; - let mut shadows_end = shadows_start; + let mut shadows_end = shadows_start + 1; + self.shadows_iter.next(); while self .shadows_iter - .next_if(|shadow| shadow.order <= max_order) + .next_if(|shadow| shadow.order < max_order) .is_some() { shadows_end += 1; @@ -284,10 +285,11 @@ impl<'a> Iterator for BatchIterator<'a> { } PrimitiveKind::Quad => { let quads_start = self.quads_start; - let mut quads_end = quads_start; + let mut quads_end = quads_start + 1; + self.quads_iter.next(); while self .quads_iter - .next_if(|quad| quad.order <= max_order) + .next_if(|quad| quad.order < max_order) .is_some() { quads_end += 1; @@ -297,10 +299,11 @@ impl<'a> Iterator for BatchIterator<'a> { } PrimitiveKind::Path => { let paths_start = self.paths_start; - let mut paths_end = paths_start; + let mut paths_end = paths_start + 1; + self.paths_iter.next(); while self .paths_iter - .next_if(|path| path.order <= max_order) + .next_if(|path| path.order < max_order) .is_some() { paths_end += 1; @@ -310,10 +313,11 @@ impl<'a> Iterator for BatchIterator<'a> { } PrimitiveKind::Underline => { let underlines_start = self.underlines_start; - let mut underlines_end = underlines_start; + let mut underlines_end = underlines_start + 1; + self.underlines_iter.next(); while self .underlines_iter - .next_if(|underline| underline.order <= max_order) + .next_if(|underline| underline.order < max_order) .is_some() { underlines_end += 1; @@ -326,11 +330,12 @@ impl<'a> Iterator for BatchIterator<'a> { PrimitiveKind::MonochromeSprite => { let texture_id = self.monochrome_sprites_iter.peek().unwrap().tile.texture_id; let sprites_start = self.monochrome_sprites_start; - let mut sprites_end = sprites_start; + let mut sprites_end = sprites_start + 1; + self.monochrome_sprites_iter.next(); while self .monochrome_sprites_iter .next_if(|sprite| { - sprite.order <= max_order && sprite.tile.texture_id == texture_id + sprite.order < max_order && sprite.tile.texture_id == texture_id }) .is_some() { @@ -345,11 +350,12 @@ impl<'a> Iterator for BatchIterator<'a> { PrimitiveKind::PolychromeSprite => { let texture_id = self.polychrome_sprites_iter.peek().unwrap().tile.texture_id; let sprites_start = self.polychrome_sprites_start; - let mut sprites_end = self.polychrome_sprites_start; + let mut sprites_end = self.polychrome_sprites_start + 1; + self.polychrome_sprites_iter.next(); while self .polychrome_sprites_iter .next_if(|sprite| { - sprite.order <= max_order && sprite.tile.texture_id == texture_id + sprite.order < max_order && sprite.tile.texture_id == texture_id }) .is_some() { @@ -363,10 +369,11 @@ impl<'a> Iterator for BatchIterator<'a> { } PrimitiveKind::Surface => { let surfaces_start = self.surfaces_start; - let mut surfaces_end = surfaces_start; + let mut surfaces_end = surfaces_start + 1; + self.surfaces_iter.next(); while self .surfaces_iter - .next_if(|surface| surface.order <= max_order) + .next_if(|surface| surface.order < max_order) .is_some() { surfaces_end += 1; From 01ce2044917825e6656825cf87573e788af3b339 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 09:29:56 +0100 Subject: [PATCH 276/644] Avoid painting a background quad if it is fully transparent --- crates/gpui2/src/style.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index de54da79b3d0eb1e7489962143dbbc7d0dc0809f..c281818c0f0bad1107d49a8b1895762c910e8af7 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -384,7 +384,7 @@ impl Style { }); let background_color = self.background.as_ref().and_then(Fill::color); - if background_color.is_some() { + if background_color.map_or(false, |color| !color.is_transparent()) { cx.with_z_index(1, |cx| { cx.paint_quad(quad( bounds, From 6c4670287d7bc4c671d81b19b5c88a9e8346a17a Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 22 Dec 2023 10:45:51 +0200 Subject: [PATCH 277/644] Highlight termina on external files drag and drop --- crates/terminal_view2/src/terminal_element.rs | 21 +++++++------------ crates/terminal_view2/src/terminal_panel.rs | 14 +++++-------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index ec1e1736c31a3ab24911c83f46d2edf734a2b2eb..eb7348b9357cfe2c2c44c3405ceb2665318a7a7a 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -4,8 +4,9 @@ use gpui::{ BorrowWindow, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, Interactivity, IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, - Pixels, PlatformInputHandler, Point, Rgba, ShapedLine, StatefulInteractiveElement, Styled, - TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, + Pixels, PlatformInputHandler, Point, Rgba, ShapedLine, StatefulInteractiveElement, + StyleRefinement, Styled, TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, + WindowContext, }; use itertools::Itertools; use language::CursorShape; @@ -24,7 +25,7 @@ use terminal::{ use theme::{ActiveTheme, Theme, ThemeSettings}; use ui::Tooltip; -use std::mem; +use std::{any::TypeId, mem}; use std::{fmt::Debug, ops::RangeInclusive}; ///The information generated during layout that is necessary for painting @@ -689,6 +690,10 @@ impl TerminalElement { } }); + self.interactivity.drag_over_styles.push(( + TypeId::of::(), + StyleRefinement::default().bg(cx.theme().colors().drop_target_background), + )); self.interactivity.on_drop::({ let focus = focus.clone(); let terminal = terminal.clone(); @@ -787,8 +792,6 @@ impl Element for TerminalElement { ) { let mut layout = self.compute_layout(bounds, cx); - let theme = cx.theme(); - cx.paint_quad(fill(bounds, layout.background_color)); let origin = bounds.origin + Point::new(layout.gutter, px(0.)); @@ -801,16 +804,8 @@ impl Element for TerminalElement { .map(|cursor| cursor.bounding_rect(origin)), }; - let terminal_focus_handle = self.focus.clone(); - let terminal_handle = self.terminal.clone(); self.register_mouse_listeners(origin, layout.mode, bounds, cx); - // todo!(change this to work in terms of on_drag_move or some such) - // .drag_over::(|style| { - // // todo!() why does not it work? z-index of elements? - // style.bg(cx.theme().colors().ghost_element_hover) - // }) - let mut interactivity = mem::take(&mut self.interactivity); interactivity.paint(bounds, bounds.size, state, cx, |_, _, cx| { cx.handle_input(&self.focus, terminal_input_handler); diff --git a/crates/terminal_view2/src/terminal_panel.rs b/crates/terminal_view2/src/terminal_panel.rs index 245add3eeb9b3cad48f38a3c443597330ffc8328..3c7b2a2e0e9d1e1d8f7a37311e4923c996da5e8b 100644 --- a/crates/terminal_view2/src/terminal_panel.rs +++ b/crates/terminal_view2/src/terminal_panel.rs @@ -4,8 +4,8 @@ use crate::TerminalView; use db::kvp::KEY_VALUE_STORE; use gpui::{ actions, div, serde_json, AppContext, AsyncWindowContext, Div, Entity, EventEmitter, - FocusHandle, FocusableView, ParentElement, Render, Styled, Subscription, Task, View, - ViewContext, VisualContext, WeakView, WindowContext, + ExternalPaths, FocusHandle, FocusableView, ParentElement, Render, Styled, Subscription, Task, + View, ViewContext, VisualContext, WeakView, WindowContext, }; use project::Fs; use serde::{Deserialize, Serialize}; @@ -64,6 +64,9 @@ impl TerminalPanel { return item.downcast::().is_some(); } } + if a.downcast_ref::().is_some() { + return true; + } false })), @@ -72,13 +75,6 @@ impl TerminalPanel { pane.set_can_split(false, cx); pane.set_can_navigate(false, cx); // todo!() - // pane.on_can_drop(move |drag_and_drop, cx| { - // drag_and_drop - // .currently_dragged::(window) - // .map_or(false, |(_, item)| { - // item.handle.act_as::(cx).is_some() - // }) - // }); // pane.set_render_tab_bar_buttons(cx, move |pane, cx| { // let this = weak_self.clone(); // Flex::row() From 3de72f83666ea787e0c32ddc84732467bc65d252 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 10:23:27 +0100 Subject: [PATCH 278/644] Fix context menu in tab bar --- crates/collab_ui2/src/collab_panel.rs | 11 +++ .../src/collab_panel/channel_modal.rs | 6 +- crates/copilot_button2/src/copilot_button.rs | 10 ++- crates/language_tools2/src/lsp_log.rs | 1 + .../language_tools2/src/syntax_tree_view.rs | 1 + crates/project_panel2/src/project_panel.rs | 1 + crates/ui2/src/components/context_menu.rs | 13 +++- .../src/components/stories/context_menu.rs | 11 +-- crates/workspace2/src/dock.rs | 2 +- crates/workspace2/src/pane.rs | 74 +++++++++++++++---- 10 files changed, 100 insertions(+), 30 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index ad11877fd3065f33fc558078eed541aa1f3602c3..3f0115e3fc8a1b40bb578f534ed518aa7b2fc3ae 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -993,6 +993,7 @@ impl CollabPanel { }; context_menu = context_menu.entry( expand_action_name, + None, cx.handler_for(&this, move |this, cx| { this.toggle_channel_collapsed(channel_id, cx) }), @@ -1002,18 +1003,21 @@ impl CollabPanel { context_menu = context_menu .entry( "Open Notes", + None, cx.handler_for(&this, move |this, cx| { this.open_channel_notes(channel_id, cx) }), ) .entry( "Open Chat", + None, cx.handler_for(&this, move |this, cx| { this.join_channel_chat(channel_id, cx) }), ) .entry( "Copy Channel Link", + None, cx.handler_for(&this, move |this, cx| { this.copy_channel_link(channel_id, cx) }), @@ -1024,14 +1028,17 @@ impl CollabPanel { .separator() .entry( "New Subchannel", + None, cx.handler_for(&this, move |this, cx| this.new_subchannel(channel_id, cx)), ) .entry( "Rename", + None, cx.handler_for(&this, move |this, cx| this.rename_channel(channel_id, cx)), ) .entry( "Move this channel", + None, cx.handler_for(&this, move |this, cx| { this.start_move_channel(channel_id, cx) }), @@ -1040,6 +1047,7 @@ impl CollabPanel { if let Some(channel_name) = clipboard_channel_name { context_menu = context_menu.separator().entry( format!("Move '#{}' here", channel_name), + None, cx.handler_for(&this, move |this, cx| { this.move_channel_on_clipboard(channel_id, cx) }), @@ -1050,14 +1058,17 @@ impl CollabPanel { .separator() .entry( "Invite Members", + None, cx.handler_for(&this, move |this, cx| this.invite_members(channel_id, cx)), ) .entry( "Manage Members", + None, cx.handler_for(&this, move |this, cx| this.manage_members(channel_id, cx)), ) .entry( "Delete", + None, cx.handler_for(&this, move |this, cx| this.remove_channel(channel_id, cx)), ); } diff --git a/crates/collab_ui2/src/collab_panel/channel_modal.rs b/crates/collab_ui2/src/collab_panel/channel_modal.rs index f373dbad1fbc2dbdbe6f022bac806c6cf2f22bf0..d68aa32e9b339159062d36a08cf402c610c7d781 100644 --- a/crates/collab_ui2/src/collab_panel/channel_modal.rs +++ b/crates/collab_ui2/src/collab_panel/channel_modal.rs @@ -532,7 +532,7 @@ impl ChannelModalDelegate { let user_id = user.id; let picker = cx.view().clone(); let context_menu = ContextMenu::build(cx, |mut menu, _cx| { - menu = menu.entry("Remove Member", { + menu = menu.entry("Remove Member", None, { let picker = picker.clone(); move |cx| { picker.update(cx, |picker, cx| { @@ -544,7 +544,7 @@ impl ChannelModalDelegate { let picker = picker.clone(); match role { ChannelRole::Admin => { - menu = menu.entry("Revoke Admin", move |cx| { + menu = menu.entry("Revoke Admin", None, move |cx| { picker.update(cx, |picker, cx| { picker .delegate @@ -553,7 +553,7 @@ impl ChannelModalDelegate { }); } ChannelRole::Member => { - menu = menu.entry("Make Admin", move |cx| { + menu = menu.entry("Make Admin", None, move |cx| { picker.update(cx, |picker, cx| { picker .delegate diff --git a/crates/copilot_button2/src/copilot_button.rs b/crates/copilot_button2/src/copilot_button.rs index 705bdc1bec52f99690287efb8cc351337148a8db..7cd2b09db80d3ef4627cbad23f253bc766c77c4b 100644 --- a/crates/copilot_button2/src/copilot_button.rs +++ b/crates/copilot_button2/src/copilot_button.rs @@ -133,8 +133,11 @@ impl CopilotButton { pub fn build_copilot_start_menu(&mut self, cx: &mut ViewContext) -> View { let fs = self.fs.clone(); ContextMenu::build(cx, |menu, cx| { - menu.entry("Sign In", initiate_sign_in) - .entry("Disable Copilot", move |cx| hide_copilot(fs.clone(), cx)) + menu.entry("Sign In", None, initiate_sign_in).entry( + "Disable Copilot", + None, + move |cx| hide_copilot(fs.clone(), cx), + ) }) } @@ -154,6 +157,7 @@ impl CopilotButton { if language_enabled { "Hide" } else { "Show" }, language.name() ), + None, move |cx| toggle_copilot_for_language(language.clone(), fs.clone(), cx), ); } @@ -169,6 +173,7 @@ impl CopilotButton { "{} Suggestions for This Path", if path_enabled { "Hide" } else { "Show" } ), + None, move |cx| { if let Some(workspace) = cx.window_handle().downcast::() { if let Ok(workspace) = workspace.root_view(cx) { @@ -194,6 +199,7 @@ impl CopilotButton { } else { "Show Suggestions for All Files" }, + None, move |cx| toggle_copilot_globally(fs.clone(), cx), ) .separator() diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 597c9c5b543fb5976c8019981216396b83739d9d..973cd9c355713a30b03b79bc28802991db81f4da 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -763,6 +763,7 @@ impl Render for LspLogToolbarItemView { )) .entry( SERVER_LOGS, + None, cx.handler_for(&log_view, move |view, cx| { view.show_logs_for_server(row.server_id, cx); }), diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index dcdcb612b781e6d93e92650c111f9ea9e1ac9d1f..c9a621f967155097a97fc9017ed6b17ccba1f7ec 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -459,6 +459,7 @@ impl SyntaxTreeToolbarItemView { layer.language.name(), format_node_range(layer.node()) ), + None, cx.handler_for(&view, move |view, cx| { view.select_layer(layer_ix, cx); }), diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index 07a6e4be5ef0d8d545a4c971beeaf3183a6ad4b7..7f6ae63ee1c4a85590cebe4e22011f29d04aa819 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -400,6 +400,7 @@ impl ProjectPanel { if is_root { menu = menu.entry( "Remove from Project", + None, cx.handler_for(&this, move |this, cx| { this.project.update(cx, |project, cx| { project.remove_worktree(worktree_id, cx) diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 97bb3865ef6dbefd95e4274fe77d37df630aee74..85021698330f0f0c09529cdc6e7d80b49901a5a4 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -76,13 +76,14 @@ impl ContextMenu { pub fn entry( mut self, label: impl Into, + action: Option>, handler: impl Fn(&mut WindowContext) + 'static, ) -> Self { self.items.push(ContextMenuItem::Entry { label: label.into(), handler: Rc::new(handler), icon: None, - action: None, + action, }); self } @@ -282,7 +283,10 @@ impl Render for ContextMenu { ListItem::new(ix) .inset(true) .selected(Some(ix) == self.selected_index) - .on_click(move |_, cx| handler(cx)) + .on_click(cx.listener(move |_, _, cx| { + handler(cx); + cx.emit(DismissEvent); + })) .child( h_stack() .w_full() @@ -303,7 +307,10 @@ impl Render for ContextMenu { ListItem::new(ix) .inset(true) .selected(Some(ix) == self.selected_index) - .on_click(move |_, cx| handler(cx)) + .on_click(cx.listener(move |_, _, cx| { + handler(cx); + cx.emit(DismissEvent); + })) .child(entry_render(cx)) .into_any_element() } diff --git a/crates/ui2/src/components/stories/context_menu.rs b/crates/ui2/src/components/stories/context_menu.rs index cae5939f2aa7f12f148adf75f0255a660f7e6f95..68d5f7bd33e3daf61a18e038a3a3b519e6309069 100644 --- a/crates/ui2/src/components/stories/context_menu.rs +++ b/crates/ui2/src/components/stories/context_menu.rs @@ -1,4 +1,4 @@ -use gpui::{actions, Action, AnchorCorner, Div, Render, View}; +use gpui::{actions, AnchorCorner, Div, Render, View}; use story::Story; use crate::prelude::*; @@ -10,12 +10,9 @@ fn build_menu(cx: &mut WindowContext, header: impl Into) -> View, mut save_intent: SaveIntent, - should_close: impl 'static + Fn(EntityId) -> bool, + should_close: impl Fn(EntityId) -> bool, ) -> Task> { // Find the items to close. let mut items_to_close = Vec::new(); @@ -1571,28 +1571,74 @@ impl Pane { } }; + let pane = cx.view().clone(); right_click_menu(ix).trigger(tab).menu(move |cx| { - ContextMenu::build(cx, |menu, _| { + let pane = pane.clone(); + ContextMenu::build(cx, move |menu, cx| { let menu = menu - .action("Close", CloseActiveItem { save_intent: None }.boxed_clone()) - .action("Close Others", CloseInactiveItems.boxed_clone()) + .entry( + "Close", + Some(Box::new(CloseActiveItem { save_intent: None })), + cx.handler_for(&pane, move |pane, cx| { + pane.close_item_by_id(item_id, SaveIntent::Close, cx) + .detach_and_log_err(cx); + }), + ) + .entry( + "Close Others", + Some(Box::new(CloseInactiveItems)), + cx.handler_for(&pane, move |pane, cx| { + pane.close_items(cx, SaveIntent::Close, |id| id != item_id) + .detach_and_log_err(cx); + }), + ) .separator() - .action("Close Left", CloseItemsToTheLeft.boxed_clone()) - .action("Close Right", CloseItemsToTheRight.boxed_clone()) + .entry( + "Close Left", + Some(Box::new(CloseItemsToTheLeft)), + cx.handler_for(&pane, move |pane, cx| { + pane.close_items_to_the_left_by_id(item_id, cx) + .detach_and_log_err(cx); + }), + ) + .entry( + "Close Right", + Some(Box::new(CloseItemsToTheRight)), + cx.handler_for(&pane, move |pane, cx| { + pane.close_items_to_the_right_by_id(item_id, cx) + .detach_and_log_err(cx); + }), + ) .separator() - .action("Close Clean", CloseCleanItems.boxed_clone()) - .action( + .entry( + "Close Clean", + Some(Box::new(CloseCleanItems)), + cx.handler_for(&pane, move |pane, cx| { + pane.close_clean_items(&CloseCleanItems, cx) + .map(|task| task.detach_and_log_err(cx)); + }), + ) + .entry( "Close All", - CloseAllItems { save_intent: None }.boxed_clone(), + Some(Box::new(CloseAllItems { save_intent: None })), + cx.handler_for(&pane, |pane, cx| { + pane.close_all_items(&CloseAllItems { save_intent: None }, cx) + .map(|task| task.detach_and_log_err(cx)); + }), ); if let Some(entry) = single_entry_to_resolve { - menu.separator().action( + let entry_id = entry.to_proto(); + menu.separator().entry( "Reveal In Project Panel", - RevealInProjectPanel { - entry_id: entry.to_proto(), - } - .boxed_clone(), + Some(Box::new(RevealInProjectPanel { entry_id })), + cx.handler_for(&pane, move |pane, cx| { + pane.project.update(cx, |_, cx| { + cx.emit(project::Event::RevealInProjectPanel( + ProjectEntryId::from_proto(entry_id), + )) + }); + }), ) } else { menu From 41ff37d56e9161ed2946b6cfe5d9758edc2ae8be Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 22 Dec 2023 01:27:22 -0500 Subject: [PATCH 279/644] Slow down sampling metric collection rate --- crates/client/src/telemetry.rs | 7 ++++--- crates/client2/src/telemetry.rs | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs index a3e7449cf8a4be5a25b4f7eaaa4f3d2379d70d68..6d70de6138ce26028c3ff5576283e19abef8f2e0 100644 --- a/crates/client/src/telemetry.rs +++ b/crates/client/src/telemetry.rs @@ -187,10 +187,11 @@ impl Telemetry { // Avoiding calling `refresh_all()`, just update what we need system.refresh_specifics(refresh_kind); + // Waiting some amount of time before the first query is important to get a reasonable value + // https://docs.rs/sysinfo/0.29.10/sysinfo/trait.ProcessExt.html#tymethod.cpu_usage + const DURATION_BETWEEN_SYSTEM_EVENTS: Duration = Duration::from_secs(4 * 60); + loop { - // Waiting some amount of time before the first query is important to get a reasonable value - // https://docs.rs/sysinfo/0.29.10/sysinfo/trait.ProcessExt.html#tymethod.cpu_usage - const DURATION_BETWEEN_SYSTEM_EVENTS: Duration = Duration::from_secs(60); smol::Timer::after(DURATION_BETWEEN_SYSTEM_EVENTS).await; system.refresh_specifics(refresh_kind); diff --git a/crates/client2/src/telemetry.rs b/crates/client2/src/telemetry.rs index b303e68183d3a263f11ed0759410a43264c7c564..71c4c33491e99bbb8361f5acbbacd0a59881a409 100644 --- a/crates/client2/src/telemetry.rs +++ b/crates/client2/src/telemetry.rs @@ -205,10 +205,11 @@ impl Telemetry { // Avoiding calling `refresh_all()`, just update what we need system.refresh_specifics(refresh_kind); + // Waiting some amount of time before the first query is important to get a reasonable value + // https://docs.rs/sysinfo/0.29.10/sysinfo/trait.ProcessExt.html#tymethod.cpu_usage + const DURATION_BETWEEN_SYSTEM_EVENTS: Duration = Duration::from_secs(4 * 60); + loop { - // Waiting some amount of time before the first query is important to get a reasonable value - // https://docs.rs/sysinfo/0.29.10/sysinfo/trait.ProcessExt.html#tymethod.cpu_usage - const DURATION_BETWEEN_SYSTEM_EVENTS: Duration = Duration::from_secs(60); smol::Timer::after(DURATION_BETWEEN_SYSTEM_EVENTS).await; system.refresh_specifics(refresh_kind); From fce31b7ddfde208ea79f730d2cf5003983a37dfa Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 22 Dec 2023 10:50:33 +0200 Subject: [PATCH 280/644] Remove the warnings from element.rs --- crates/editor2/src/element.rs | 107 +++++++++++++++------------------- 1 file changed, 47 insertions(+), 60 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 9dab9d00aec20e6b4763d56713ec8514174efa1e..d97883bebab24713d96c32e9df5017bfc3cbbfe2 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -493,8 +493,8 @@ impl EditorElement { event: &MouseMoveEvent, position_map: &PositionMap, text_bounds: Bounds, - gutter_bounds: Bounds, - stacking_order: &StackingOrder, + _gutter_bounds: Bounds, + _stacking_order: &StackingOrder, cx: &mut ViewContext, ) { if !editor.has_pending_selection() { @@ -738,7 +738,7 @@ impl EditorElement { cx.with_z_index(1, |cx| { for (ix, fold_indicator) in layout.fold_indicators.drain(..).enumerate() { - if let Some(mut fold_indicator) = fold_indicator { + if let Some(fold_indicator) = fold_indicator { let mut fold_indicator = fold_indicator.into_any_element(); let available_space = size( AvailableSpace::MinContent, @@ -867,7 +867,6 @@ impl EditorElement { layout: &mut LayoutState, cx: &mut WindowContext, ) { - let scroll_position = layout.position_map.snapshot.scroll_position(); let start_row = layout.visible_display_row_range.start; let content_origin = text_bounds.origin + point(layout.gutter_margin, Pixels::ZERO); let line_end_overshoot = 0.15 * layout.position_map.line_height; @@ -1411,7 +1410,7 @@ impl EditorElement { if self.editor.read(cx).scroll_manager.is_dragging_scrollbar() { cx.on_mouse_event({ let editor = self.editor.clone(); - move |event: &MouseUpEvent, phase, cx| { + move |_: &MouseUpEvent, phase, cx| { if phase == DispatchPhase::Capture { return; } @@ -1767,11 +1766,7 @@ impl EditorElement { } } - fn compute_layout( - &mut self, - mut bounds: Bounds, - cx: &mut WindowContext, - ) -> LayoutState { + fn compute_layout(&mut self, bounds: Bounds, cx: &mut WindowContext) -> LayoutState { self.editor.update(cx, |editor, cx| { let snapshot = editor.snapshot(cx); let style = self.style.clone(); @@ -1811,22 +1806,23 @@ impl EditorElement { let text_width = bounds.size.width - gutter_width; let overscroll = size(em_width, px(0.)); - let snapshot = { - editor.set_visible_line_count((bounds.size.height / line_height).into(), cx); - - let editor_width = text_width - gutter_margin - overscroll.width - em_width; - let wrap_width = match editor.soft_wrap_mode(cx) { - SoftWrap::None => (MAX_LINE_LEN / 2) as f32 * em_advance, - SoftWrap::EditorWidth => editor_width, - SoftWrap::Column(column) => editor_width.min(column as f32 * em_advance), - }; - - if editor.set_wrap_width(Some(wrap_width), cx) { - editor.snapshot(cx) - } else { - snapshot - } - }; + // todo!() + // let snapshot = { + // editor.set_visible_line_count((bounds.size.height / line_height).into(), cx); + + // let editor_width = text_width - gutter_margin - overscroll.width - em_width; + // let wrap_width = match editor.soft_wrap_mode(cx) { + // SoftWrap::None => (MAX_LINE_LEN / 2) as f32 * em_advance, + // SoftWrap::EditorWidth => editor_width, + // SoftWrap::Column(column) => editor_width.min(column as f32 * em_advance), + // }; + + // if editor.set_wrap_width(Some(wrap_width), cx) { + // editor.snapshot(cx) + // } else { + // snapshot + // } + // }; let wrap_guides = editor .wrap_guides(cx) @@ -1834,7 +1830,6 @@ impl EditorElement { .map(|(guide, active)| (self.column_pixels(*guide, cx), *active)) .collect::>(); - let scroll_height = Pixels::from(snapshot.max_point().row() + 1) * line_height; let gutter_size = size(gutter_width, bounds.size.height); let text_size = size(text_width, bounds.size.height); @@ -2101,7 +2096,7 @@ impl EditorElement { .max(MIN_POPOVER_LINE_HEIGHT * line_height), // Apply minimum height of 4 lines ); - let mut hover = editor.hover_state.render( + let hover = editor.hover_state.render( &snapshot, &style, visible_rows, @@ -2110,7 +2105,7 @@ impl EditorElement { cx, ); - let mut fold_indicators = cx.with_element_id(Some("gutter_fold_indicators"), |cx| { + let fold_indicators = cx.with_element_id(Some("gutter_fold_indicators"), |cx| { editor.render_fold_indicators( fold_statuses, &style, @@ -2212,7 +2207,6 @@ impl EditorElement { cx: &mut ViewContext, ) -> (Pixels, Vec) { let mut block_id = 0; - let scroll_x = snapshot.scroll_anchor.offset.x; let (fixed_blocks, non_fixed_blocks) = snapshot .blocks_in_range(rows.clone()) .partition::, _>(|(_, block)| match block { @@ -2220,11 +2214,11 @@ impl EditorElement { TransformBlock::Custom(block) => block.style() == BlockStyle::Fixed, }); - let mut render_block = |block: &TransformBlock, - available_space: Size, - block_id: usize, - editor: &mut Editor, - cx: &mut ViewContext| { + let render_block = |block: &TransformBlock, + available_space: Size, + block_id: usize, + editor: &mut Editor, + cx: &mut ViewContext| { let mut element = match block { TransformBlock::Custom(block) => { let align_to = block @@ -2277,7 +2271,7 @@ impl EditorElement { .map_or(range.context.start, |primary| primary.start); let jump_position = language::ToPoint::to_point(&jump_anchor, buffer); - let jump_handler = cx.listener_for(&self.editor, move |editor, e, cx| { + let jump_handler = cx.listener_for(&self.editor, move |editor, _, cx| { editor.jump(jump_path.clone(), jump_position, jump_anchor, cx); }); @@ -2296,8 +2290,6 @@ impl EditorElement { .map(|p| SharedString::from(p.to_string_lossy().to_string() + "/")); } - let is_open = true; - div().id("path header container").size_full().p_1p5().child( h_stack() .id("path header block") @@ -2336,7 +2328,6 @@ impl EditorElement { })), // .p_x(gutter_padding) ) } else { - let text_style = style.text.clone(); h_stack() .id("collapsed context") .size_full() @@ -2447,7 +2438,6 @@ impl EditorElement { layout: &LayoutState, cx: &mut WindowContext, ) { - let content_origin = text_bounds.origin + point(layout.gutter_margin, Pixels::ZERO); let interactive_bounds = InteractiveBounds { bounds: bounds.intersect(&cx.content_mask().bounds), stacking_order: cx.stacking_order().clone(), @@ -2764,7 +2754,7 @@ impl Element for EditorElement { fn layout( &mut self, - element_state: Option, + _element_state: Option, cx: &mut gpui::WindowContext, ) -> (gpui::LayoutId, Self::State) { self.editor.update(cx, |editor, cx| { @@ -2782,22 +2772,19 @@ impl Element for EditorElement { let editor_handle = cx.view().clone(); let max_line_number_width = self.max_line_number_width(&editor.snapshot(cx), cx); - cx.request_measured_layout( - Style::default(), - move |known_dimensions, available_space, cx| { - editor_handle - .update(cx, |editor, cx| { - compute_auto_height_layout( - editor, - max_lines, - max_line_number_width, - known_dimensions, - cx, - ) - }) - .unwrap_or_default() - }, - ) + cx.request_measured_layout(Style::default(), move |known_dimensions, _, cx| { + editor_handle + .update(cx, |editor, cx| { + compute_auto_height_layout( + editor, + max_lines, + max_line_number_width, + known_dimensions, + cx, + ) + }) + .unwrap_or_default() + }) } EditorMode::Full => { let mut style = Style::default(); @@ -2814,7 +2801,7 @@ impl Element for EditorElement { fn paint( &mut self, bounds: Bounds, - element_state: &mut Self::State, + _element_state: &mut Self::State, cx: &mut gpui::WindowContext, ) { let editor = self.editor.clone(); @@ -3137,7 +3124,7 @@ impl HighlightedRange { &self, start_y: Pixels, lines: &[HighlightedRangeLine], - bounds: Bounds, + _bounds: Bounds, cx: &mut WindowContext, ) { if lines.is_empty() { @@ -3755,7 +3742,7 @@ fn compute_auto_height_layout( known_dimensions: Size>, cx: &mut ViewContext, ) -> Option> { - let mut width = known_dimensions.width?; + let width = known_dimensions.width?; if let Some(height) = known_dimensions.height { return Some(size(width, height)); } From d36ec81725009745e65418a28a76425c107683ae Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 22 Dec 2023 11:55:25 +0200 Subject: [PATCH 281/644] Move multibuffer "go to file" button into the buffer header Co-Authored-By: Antonio Scandurra --- crates/editor2/src/element.rs | 99 +++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index d97883bebab24713d96c32e9df5017bfc3cbbfe2..c6d468f40b9c6a78fcc3cae6a73418175f841465 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -2290,46 +2290,55 @@ impl EditorElement { .map(|p| SharedString::from(p.to_string_lossy().to_string() + "/")); } - div().id("path header container").size_full().p_1p5().child( - h_stack() - .id("path header block") - .py_1p5() - .pl_3() - .pr_2() - .rounded_lg() - .shadow_md() - .border() - .border_color(cx.theme().colors().border) - .bg(cx.theme().colors().editor_subheader_background) - .justify_between() - .cursor_pointer() - .hover(|style| style.bg(cx.theme().colors().element_hover)) - .child( - h_stack().gap_3().child( - h_stack() - .gap_2() - .child(Label::new( - filename - .map(SharedString::from) - .unwrap_or_else(|| "untitled".into()), - )) - .when_some(parent_path, |then, path| { - then.child(Label::new(path).color(Color::Muted)) - }), - ), - ) - .children(jump_handler.map(|jump_handler| { - IconButton::new(block_id, Icon::ArrowUpRight) - .style(ButtonStyle::Subtle) - .on_click(jump_handler) - .tooltip(|cx| { - Tooltip::for_action("Jump to Buffer", &OpenExcerpts, cx) - }) - })), // .p_x(gutter_padding) - ) + div() + .id(("path header container", block_id)) + .size_full() + .p_1p5() + .child( + h_stack() + .id("path header block") + .py_1p5() + .pl_3() + .pr_2() + .rounded_lg() + .shadow_md() + .border() + .border_color(cx.theme().colors().border) + .bg(cx.theme().colors().editor_subheader_background) + .justify_between() + .hover(|style| style.bg(cx.theme().colors().element_hover)) + .child( + h_stack().gap_3().child( + h_stack() + .gap_2() + .child(Label::new( + filename + .map(SharedString::from) + .unwrap_or_else(|| "untitled".into()), + )) + .when_some(parent_path, |then, path| { + then.child(Label::new(path).color(Color::Muted)) + }), + ), + ) + .when_some(jump_handler, |this, jump_handler| { + this.cursor_pointer() + .tooltip(|cx| { + Tooltip::for_action( + "Jump to Buffer", + &OpenExcerpts, + cx, + ) + }) + .on_mouse_down(MouseButton::Left, |_, cx| { + cx.stop_propagation() + }) + .on_click(jump_handler) + }), + ) } else { h_stack() - .id("collapsed context") + .id(("collapsed context", block_id)) .size_full() .gap(gutter_padding) .child( @@ -2834,17 +2843,19 @@ impl Element for EditorElement { cx.with_z_index(0, |cx| { self.paint_mouse_listeners(bounds, gutter_bounds, text_bounds, &layout, cx); + }); + + cx.with_z_index(1, |cx| self.paint_scrollbar(bounds, &mut layout, cx)); - if !layout.blocks.is_empty() { + if !layout.blocks.is_empty() { + cx.with_z_index(2, |cx| { cx.with_element_id(Some("editor_blocks"), |cx| { self.paint_blocks(bounds, &mut layout, cx); }); - } - }); - - cx.with_z_index(1, |cx| self.paint_scrollbar(bounds, &mut layout, cx)); + }) + } - cx.with_z_index(2, |cx| { + cx.with_z_index(3, |cx| { self.paint_overlays(text_bounds, &mut layout, cx); }); }); From 4d5ff77abee0a7f0891fe95fcdc200e7a454a630 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 22 Dec 2023 12:14:53 +0200 Subject: [PATCH 282/644] Fix the tests --- crates/editor2/src/element.rs | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index c6d468f40b9c6a78fcc3cae6a73418175f841465..294cc2c4e3eeb96921c6e339b12cfb426a9b6661 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -1806,23 +1806,22 @@ impl EditorElement { let text_width = bounds.size.width - gutter_width; let overscroll = size(em_width, px(0.)); - // todo!() - // let snapshot = { - // editor.set_visible_line_count((bounds.size.height / line_height).into(), cx); - - // let editor_width = text_width - gutter_margin - overscroll.width - em_width; - // let wrap_width = match editor.soft_wrap_mode(cx) { - // SoftWrap::None => (MAX_LINE_LEN / 2) as f32 * em_advance, - // SoftWrap::EditorWidth => editor_width, - // SoftWrap::Column(column) => editor_width.min(column as f32 * em_advance), - // }; - - // if editor.set_wrap_width(Some(wrap_width), cx) { - // editor.snapshot(cx) - // } else { - // snapshot - // } - // }; + let _snapshot = { + editor.set_visible_line_count((bounds.size.height / line_height).into(), cx); + + let editor_width = text_width - gutter_margin - overscroll.width - em_width; + let wrap_width = match editor.soft_wrap_mode(cx) { + SoftWrap::None => (MAX_LINE_LEN / 2) as f32 * em_advance, + SoftWrap::EditorWidth => editor_width, + SoftWrap::Column(column) => editor_width.min(column as f32 * em_advance), + }; + + if editor.set_wrap_width(Some(wrap_width), cx) { + editor.snapshot(cx) + } else { + snapshot + } + }; let wrap_guides = editor .wrap_guides(cx) From a551647ec1ca098caef33721c06a79b7035ded56 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 12:12:39 +0100 Subject: [PATCH 283/644] Fix panic in completions menu We were shifting all the positions while keeping the original string, which caused problems later when combining highlighted ranges with matched indices. --- crates/editor2/src/editor.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index f1f053acbb87248dd9c2bcfc60f3167601766f61..943ddf47bdad7dedc6b5d1f55a1828d80b99097b 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -1350,15 +1350,15 @@ impl CompletionsMenu { completion.sort_key(), ) }); - drop(completions); for mat in &mut matches { - let completions = self.completions.read(); - let filter_start = completions[mat.candidate_id].label.filter_range.start; + let completion = &completions[mat.candidate_id]; + mat.string = completion.label.text.clone(); for position in &mut mat.positions { - *position += filter_start; + *position += completion.label.filter_range.start; } } + drop(completions); self.matches = matches.into(); self.selected_item = 0; From c1ad079f09cfdeafa2f5228bbccae62deef82e8e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 12:27:20 +0100 Subject: [PATCH 284/644] Fix dismissing context menu when clicking on an item dispatched action --- crates/ui2/src/components/context_menu.rs | 29 ++++- crates/workspace2/src/pane.rs | 140 +++++++++++----------- 2 files changed, 94 insertions(+), 75 deletions(-) diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 85021698330f0f0c09529cdc6e7d80b49901a5a4..6df6a290964b00f3ebdf455afb2feca594eee33e 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -29,6 +29,7 @@ pub struct ContextMenu { focus_handle: FocusHandle, selected_index: Option, delayed: bool, + clicked: bool, _on_blur_subscription: Subscription, } @@ -56,6 +57,7 @@ impl ContextMenu { focus_handle, selected_index: None, delayed: false, + clicked: false, _on_blur_subscription, }, cx, @@ -187,6 +189,11 @@ impl ContextMenu { } pub fn on_action_dispatch(&mut self, dispatched: &Box, cx: &mut ViewContext) { + if self.clicked { + cx.propagate(); + return; + } + if let Some(ix) = self.items.iter().position(|item| { if let ContextMenuItem::Entry { action: Some(action), @@ -269,6 +276,7 @@ impl Render for ContextMenu { action, } => { let handler = handler.clone(); + let menu = cx.view().downgrade(); let label_element = if let Some(icon) = icon { h_stack() @@ -283,10 +291,14 @@ impl Render for ContextMenu { ListItem::new(ix) .inset(true) .selected(Some(ix) == self.selected_index) - .on_click(cx.listener(move |_, _, cx| { + .on_click(move |_, cx| { handler(cx); - cx.emit(DismissEvent); - })) + menu.update(cx, |menu, cx| { + menu.clicked = true; + cx.emit(DismissEvent); + }) + .ok(); + }) .child( h_stack() .w_full() @@ -304,13 +316,18 @@ impl Render for ContextMenu { handler, } => { let handler = handler.clone(); + let menu = cx.view().downgrade(); ListItem::new(ix) .inset(true) .selected(Some(ix) == self.selected_index) - .on_click(cx.listener(move |_, _, cx| { + .on_click(move |_, cx| { handler(cx); - cx.emit(DismissEvent); - })) + menu.update(cx, |menu, cx| { + menu.clicked = true; + cx.emit(DismissEvent); + }) + .ok(); + }) .child(entry_render(cx)) .into_any_element() } diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 96daeb24ed950e162c2fef2bcbb17f80f32c6569..911c292133a150712106c8b4776617ff7aca5e6b 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1571,78 +1571,80 @@ impl Pane { } }; - let pane = cx.view().clone(); + let pane = cx.view().downgrade(); right_click_menu(ix).trigger(tab).menu(move |cx| { let pane = pane.clone(); - ContextMenu::build(cx, move |menu, cx| { - let menu = menu - .entry( - "Close", - Some(Box::new(CloseActiveItem { save_intent: None })), - cx.handler_for(&pane, move |pane, cx| { - pane.close_item_by_id(item_id, SaveIntent::Close, cx) - .detach_and_log_err(cx); - }), - ) - .entry( - "Close Others", - Some(Box::new(CloseInactiveItems)), - cx.handler_for(&pane, move |pane, cx| { - pane.close_items(cx, SaveIntent::Close, |id| id != item_id) - .detach_and_log_err(cx); - }), - ) - .separator() - .entry( - "Close Left", - Some(Box::new(CloseItemsToTheLeft)), - cx.handler_for(&pane, move |pane, cx| { - pane.close_items_to_the_left_by_id(item_id, cx) - .detach_and_log_err(cx); - }), - ) - .entry( - "Close Right", - Some(Box::new(CloseItemsToTheRight)), - cx.handler_for(&pane, move |pane, cx| { - pane.close_items_to_the_right_by_id(item_id, cx) - .detach_and_log_err(cx); - }), - ) - .separator() - .entry( - "Close Clean", - Some(Box::new(CloseCleanItems)), - cx.handler_for(&pane, move |pane, cx| { - pane.close_clean_items(&CloseCleanItems, cx) - .map(|task| task.detach_and_log_err(cx)); - }), - ) - .entry( - "Close All", - Some(Box::new(CloseAllItems { save_intent: None })), - cx.handler_for(&pane, |pane, cx| { - pane.close_all_items(&CloseAllItems { save_intent: None }, cx) - .map(|task| task.detach_and_log_err(cx)); - }), - ); - - if let Some(entry) = single_entry_to_resolve { - let entry_id = entry.to_proto(); - menu.separator().entry( - "Reveal In Project Panel", - Some(Box::new(RevealInProjectPanel { entry_id })), - cx.handler_for(&pane, move |pane, cx| { - pane.project.update(cx, |_, cx| { - cx.emit(project::Event::RevealInProjectPanel( - ProjectEntryId::from_proto(entry_id), - )) - }); - }), - ) - } else { - menu + ContextMenu::build(cx, move |mut menu, cx| { + if let Some(pane) = pane.upgrade() { + menu = menu + .entry( + "Close", + Some(Box::new(CloseActiveItem { save_intent: None })), + cx.handler_for(&pane, move |pane, cx| { + pane.close_item_by_id(item_id, SaveIntent::Close, cx) + .detach_and_log_err(cx); + }), + ) + .entry( + "Close Others", + Some(Box::new(CloseInactiveItems)), + cx.handler_for(&pane, move |pane, cx| { + pane.close_items(cx, SaveIntent::Close, |id| id != item_id) + .detach_and_log_err(cx); + }), + ) + .separator() + .entry( + "Close Left", + Some(Box::new(CloseItemsToTheLeft)), + cx.handler_for(&pane, move |pane, cx| { + pane.close_items_to_the_left_by_id(item_id, cx) + .detach_and_log_err(cx); + }), + ) + .entry( + "Close Right", + Some(Box::new(CloseItemsToTheRight)), + cx.handler_for(&pane, move |pane, cx| { + pane.close_items_to_the_right_by_id(item_id, cx) + .detach_and_log_err(cx); + }), + ) + .separator() + .entry( + "Close Clean", + Some(Box::new(CloseCleanItems)), + cx.handler_for(&pane, move |pane, cx| { + pane.close_clean_items(&CloseCleanItems, cx) + .map(|task| task.detach_and_log_err(cx)); + }), + ) + .entry( + "Close All", + Some(Box::new(CloseAllItems { save_intent: None })), + cx.handler_for(&pane, |pane, cx| { + pane.close_all_items(&CloseAllItems { save_intent: None }, cx) + .map(|task| task.detach_and_log_err(cx)); + }), + ); + + if let Some(entry) = single_entry_to_resolve { + let entry_id = entry.to_proto(); + menu = menu.separator().entry( + "Reveal In Project Panel", + Some(Box::new(RevealInProjectPanel { entry_id })), + cx.handler_for(&pane, move |pane, cx| { + pane.project.update(cx, |_, cx| { + cx.emit(project::Event::RevealInProjectPanel( + ProjectEntryId::from_proto(entry_id), + )) + }); + }), + ); + } } + + menu }) }) } From 420253a75295596fb7fb9aeac025f992f428115a Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 22 Dec 2023 15:32:47 +0200 Subject: [PATCH 285/644] Restore zoom buttons in pane tab bars, fix + button in the terminal one --- crates/terminal_view2/src/terminal_panel.rs | 72 +++----- crates/workspace2/src/pane.rs | 189 ++++++++------------ 2 files changed, 103 insertions(+), 158 deletions(-) diff --git a/crates/terminal_view2/src/terminal_panel.rs b/crates/terminal_view2/src/terminal_panel.rs index 3c7b2a2e0e9d1e1d8f7a37311e4923c996da5e8b..def56f376024c16a4061b3b2cffb8d2da620bfd1 100644 --- a/crates/terminal_view2/src/terminal_panel.rs +++ b/crates/terminal_view2/src/terminal_panel.rs @@ -4,13 +4,14 @@ use crate::TerminalView; use db::kvp::KEY_VALUE_STORE; use gpui::{ actions, div, serde_json, AppContext, AsyncWindowContext, Div, Entity, EventEmitter, - ExternalPaths, FocusHandle, FocusableView, ParentElement, Render, Styled, Subscription, Task, - View, ViewContext, VisualContext, WeakView, WindowContext, + ExternalPaths, FocusHandle, FocusableView, IntoElement, ParentElement, Render, Styled, + Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext, }; use project::Fs; use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsStore}; use terminal::terminal_settings::{TerminalDockPosition, TerminalSettings}; +use ui::{h_stack, ButtonCommon, Clickable, IconButton, IconSize, Selectable, Tooltip}; use util::{ResultExt, TryFutureExt}; use workspace::{ dock::{DockPosition, Panel, PanelEvent}, @@ -51,9 +52,8 @@ pub struct TerminalPanel { impl TerminalPanel { fn new(workspace: &Workspace, cx: &mut ViewContext) -> Self { - let _weak_self = cx.view().downgrade(); + let terminal_panel = cx.view().clone(); let pane = cx.build_view(|cx| { - let _window = cx.window_handle(); let mut pane = Pane::new( workspace.weak_handle(), workspace.project().clone(), @@ -74,45 +74,31 @@ impl TerminalPanel { ); pane.set_can_split(false, cx); pane.set_can_navigate(false, cx); - // todo!() - // pane.set_render_tab_bar_buttons(cx, move |pane, cx| { - // let this = weak_self.clone(); - // Flex::row() - // .with_child(Pane::render_tab_bar_button( - // 0, - // "icons/plus.svg", - // false, - // Some(("New Terminal", Some(Box::new(workspace::NewTerminal)))), - // cx, - // move |_, cx| { - // let this = this.clone(); - // cx.window_context().defer(move |cx| { - // if let Some(this) = this.upgrade() { - // this.update(cx, |this, cx| { - // this.add_terminal(None, cx); - // }); - // } - // }) - // }, - // |_, _| {}, - // None, - // )) - // .with_child(Pane::render_tab_bar_button( - // 1, - // if pane.is_zoomed() { - // "icons/minimize.svg" - // } else { - // "icons/maximize.svg" - // }, - // pane.is_zoomed(), - // Some(("Toggle Zoom".into(), Some(Box::new(workspace::ToggleZoom)))), - // cx, - // move |pane, cx| pane.toggle_zoom(&Default::default(), cx), - // |_, _| {}, - // None, - // )) - // .into_any() - // }); + pane.set_render_tab_bar_buttons(cx, move |pane, cx| { + h_stack() + .child( + IconButton::new("plus", Icon::Plus) + .icon_size(IconSize::Small) + .on_click(cx.listener_for(&terminal_panel, |terminal_panel, _, cx| { + terminal_panel.add_terminal(None, cx); + })) + .tooltip(|cx| Tooltip::text("New Terminal", cx)), + ) + .child({ + let zoomed = pane.is_zoomed(); + IconButton::new("toggle_zoom", Icon::Maximize) + .icon_size(IconSize::Small) + .selected(zoomed) + .selected_icon(Icon::Minimize) + .on_click(cx.listener(|pane, _, cx| { + pane.toggle_zoom(&workspace::ToggleZoom, cx); + })) + .tooltip(move |cx| { + Tooltip::text(if zoomed { "Zoom Out" } else { "Zoom In" }, cx) + }) + }) + .into_any_element() + }); // let buffer_search_bar = cx.build_view(search::BufferSearchBar::new); // pane.toolbar() // .update(cx, |toolbar, cx| toolbar.add_item(buffer_search_bar, cx)); diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 911c292133a150712106c8b4776617ff7aca5e6b..86894dee46daea3d389141e6a8cc4273ae773603 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -7,7 +7,7 @@ use crate::{ use anyhow::Result; use collections::{HashMap, HashSet, VecDeque}; use gpui::{ - actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AppContext, + actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AnyElement, AppContext, AsyncWindowContext, DismissEvent, Div, DragMoveEvent, EntityId, EventEmitter, FocusHandle, Focusable, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel, Render, ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView, @@ -21,6 +21,7 @@ use std::{ any::Any, cmp, fmt, mem, path::{Path, PathBuf}, + rc::Rc, sync::{ atomic::{AtomicUsize, Ordering}, Arc, @@ -183,7 +184,7 @@ pub struct Pane { drag_split_direction: Option, can_drop_predicate: Option bool>>, can_split: bool, - // render_tab_bar_buttons: Rc) -> AnyElement>, + render_tab_bar_buttons: Rc) -> AnyElement>, _subscriptions: Vec, tab_bar_scroll_handle: ScrollHandle, } @@ -374,63 +375,66 @@ impl Pane { project, can_drop_predicate, can_split: true, - // render_tab_bar_buttons: Rc::new(move |pane, cx| { - // Flex::row() - // // New menu - // .with_child(Self::render_tab_bar_button( - // 0, - // "icons/plus.svg", - // false, - // Some(("New...".into(), None)), - // cx, - // |pane, cx| pane.deploy_new_menu(cx), - // |pane, cx| { - // pane.tab_bar_context_menu - // .handle - // .update(cx, |menu, _| menu.delay_cancel()) - // }, - // pane.tab_bar_context_menu - // .handle_if_kind(TabBarContextMenuKind::New), - // )) - // .with_child(Self::render_tab_bar_button( - // 1, - // "icons/split.svg", - // false, - // Some(("Split Pane".into(), None)), - // cx, - // |pane, cx| pane.deploy_split_menu(cx), - // |pane, cx| { - // pane.tab_bar_context_menu - // .handle - // .update(cx, |menu, _| menu.delay_cancel()) - // }, - // pane.tab_bar_context_menu - // .handle_if_kind(TabBarContextMenuKind::Split), - // )) - // .with_child({ - // let icon_path; - // let tooltip_label; - // if pane.is_zoomed() { - // icon_path = "icons/minimize.svg"; - // tooltip_label = "Zoom In"; - // } else { - // icon_path = "icons/maximize.svg"; - // tooltip_label = "Zoom In"; - // } - - // Pane::render_tab_bar_button( - // 2, - // icon_path, - // pane.is_zoomed(), - // Some((tooltip_label, Some(Box::new(ToggleZoom)))), - // cx, - // move |pane, cx| pane.toggle_zoom(&Default::default(), cx), - // move |_, _| {}, - // None, - // ) - // }) - // .into_any() - // }), + render_tab_bar_buttons: Rc::new(move |pane, cx| { + h_stack() + .child( + IconButton::new("plus", Icon::Plus) + .icon_size(IconSize::Small) + .on_click(cx.listener(|pane, _, cx| { + let menu = ContextMenu::build(cx, |menu, _| { + menu.action("New File", NewFile.boxed_clone()) + .action("New Terminal", NewCenterTerminal.boxed_clone()) + .action("New Search", NewSearch.boxed_clone()) + }); + cx.subscribe(&menu, |pane, _, _: &DismissEvent, cx| { + pane.focus(cx); + pane.new_item_menu = None; + }) + .detach(); + pane.new_item_menu = Some(menu); + })) + .tooltip(|cx| Tooltip::text("New...", cx)), + ) + .when_some(pane.new_item_menu.as_ref(), |el, new_item_menu| { + el.child(Self::render_menu_overlay(new_item_menu)) + }) + .child( + IconButton::new("split", Icon::Split) + .icon_size(IconSize::Small) + .on_click(cx.listener(|pane, _, cx| { + let menu = ContextMenu::build(cx, |menu, _| { + menu.action("Split Right", SplitRight.boxed_clone()) + .action("Split Left", SplitLeft.boxed_clone()) + .action("Split Up", SplitUp.boxed_clone()) + .action("Split Down", SplitDown.boxed_clone()) + }); + cx.subscribe(&menu, |pane, _, _: &DismissEvent, cx| { + pane.focus(cx); + pane.split_item_menu = None; + }) + .detach(); + pane.split_item_menu = Some(menu); + })) + .tooltip(|cx| Tooltip::text("Split Pane", cx)), + ) + .child({ + let zoomed = pane.is_zoomed(); + IconButton::new("toggle_zoom", Icon::Maximize) + .icon_size(IconSize::Small) + .selected(zoomed) + .selected_icon(Icon::Minimize) + .on_click(cx.listener(|pane, _, cx| { + pane.toggle_zoom(&crate::ToggleZoom, cx); + })) + .tooltip(move |cx| { + Tooltip::text(if zoomed { "Zoom Out" } else { "Zoom In" }, cx) + }) + }) + .when_some(pane.split_item_menu.as_ref(), |el, split_item_menu| { + el.child(Self::render_menu_overlay(split_item_menu)) + }) + .into_any_element() + }), _subscriptions: subscriptions, } } @@ -510,13 +514,13 @@ impl Pane { cx.notify(); } - // pub fn set_render_tab_bar_buttons(&mut self, cx: &mut ViewContext, render: F) - // where - // F: 'static + Fn(&mut Pane, &mut ViewContext) -> AnyElement, - // { - // self.render_tab_bar_buttons = Rc::new(render); - // cx.notify(); - // } + pub fn set_render_tab_bar_buttons(&mut self, cx: &mut ViewContext, render: F) + where + F: 'static + Fn(&mut Pane, &mut ViewContext) -> AnyElement, + { + self.render_tab_bar_buttons = Rc::new(render); + cx.notify(); + } pub fn nav_history_for_item(&self, item: &View) -> ItemNavHistory { ItemNavHistory { @@ -1672,55 +1676,10 @@ impl Pane { .disabled(!self.can_navigate_forward()) .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)), ) - .end_child( - div() - .child( - IconButton::new("plus", Icon::Plus) - .icon_size(IconSize::Small) - .on_click(cx.listener(|this, _, cx| { - let menu = ContextMenu::build(cx, |menu, _| { - menu.action("New File", NewFile.boxed_clone()) - .action("New Terminal", NewCenterTerminal.boxed_clone()) - .action("New Search", NewSearch.boxed_clone()) - }); - cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| { - this.focus(cx); - this.new_item_menu = None; - }) - .detach(); - this.new_item_menu = Some(menu); - })) - .tooltip(|cx| Tooltip::text("New...", cx)), - ) - .when_some(self.new_item_menu.as_ref(), |el, new_item_menu| { - el.child(Self::render_menu_overlay(new_item_menu)) - }), - ) - .end_child( - div() - .child( - IconButton::new("split", Icon::Split) - .icon_size(IconSize::Small) - .on_click(cx.listener(|this, _, cx| { - let menu = ContextMenu::build(cx, |menu, _| { - menu.action("Split Right", SplitRight.boxed_clone()) - .action("Split Left", SplitLeft.boxed_clone()) - .action("Split Up", SplitUp.boxed_clone()) - .action("Split Down", SplitDown.boxed_clone()) - }); - cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| { - this.focus(cx); - this.split_item_menu = None; - }) - .detach(); - this.split_item_menu = Some(menu); - })) - .tooltip(|cx| Tooltip::text("Split Pane", cx)), - ) - .when_some(self.split_item_menu.as_ref(), |el, split_item_menu| { - el.child(Self::render_menu_overlay(split_item_menu)) - }), - ) + .end_child({ + let render_tab_buttons = self.render_tab_bar_buttons.clone(); + render_tab_buttons(self, cx) + }) .children( self.items .iter() From 68cf631cfcdb07fb7adfdd25d6ea87969f8d69a0 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 14:39:16 +0100 Subject: [PATCH 286/644] Reveal item even if project panel was closed while active entry changed The project panel was actually working just fine, the problem was due to `UniformList` not re-hydrating the element state's scroll offset when being rendered again. --- crates/gpui2/src/elements/uniform_list.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index c26cfe612141d9dc3442308012d780af7ab153c5..e38a37f90d20c8612069f13daaf94ccb06c1dc89 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -190,7 +190,15 @@ impl Element for UniformList { let shared_scroll_offset = element_state .interactive .scroll_offset - .get_or_insert_with(Rc::default) + .get_or_insert_with(|| { + if let Some(scroll_handle) = self.scroll_handle.as_ref() { + if let Some(scroll_handle) = scroll_handle.0.borrow().as_ref() { + return scroll_handle.scroll_offset.clone(); + } + } + + Rc::default() + }) .clone(); let item_height = self.measure_item(Some(padded_bounds.size.width), cx).height; From 2f3b4088803ccd8fcbf47b3425a7a7a39b8d03f5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 15:12:01 +0100 Subject: [PATCH 287/644] Dismiss mention notification when `x` icon is clicked We were emitting the wrong kind of event, which caused the workspace to never remove the notification. --- crates/collab_ui2/src/notification_panel.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/crates/collab_ui2/src/notification_panel.rs b/crates/collab_ui2/src/notification_panel.rs index d9a26b406479fcef93937d10256acc41582a8489..3ba1f0bd4742f4b7217cec63291d5b5cbc6c8524 100644 --- a/crates/collab_ui2/src/notification_panel.rs +++ b/crates/collab_ui2/src/notification_panel.rs @@ -684,10 +684,6 @@ pub struct NotificationToast { workspace: WeakView, } -pub enum ToastEvent { - Dismiss, -} - impl NotificationToast { fn focus_notification_panel(&self, cx: &mut ViewContext) { let workspace = self.workspace.clone(); @@ -721,16 +717,15 @@ impl Render for NotificationToast { .child(Label::new(self.text.clone())) .child( IconButton::new("close", Icon::Close) - .on_click(cx.listener(|_, _, cx| cx.emit(ToastEvent::Dismiss))), + .on_click(cx.listener(|_, _, cx| cx.emit(DismissEvent))), ) .on_click(cx.listener(|this, _, cx| { this.focus_notification_panel(cx); - cx.emit(ToastEvent::Dismiss); + cx.emit(DismissEvent); })) } } -impl EventEmitter for NotificationToast {} impl EventEmitter for NotificationToast {} fn format_timestamp( From dd093477a399e699592b5c5fef84002d43e7da71 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 15:56:37 +0100 Subject: [PATCH 288/644] Allow horizontal scrolling of tab bar on vertical mouse wheel Now, if we receive a scroll event for an axis, but that axis can't be scrolled (overflow != scroll), we will apply it to the opposite axis instead if that axis supports scrolling. --- crates/gpui2/src/elements/div.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 7c74eb1039f6277c99c562392b26ad925d4d6e5a..fc129b4f1df6d36e9d480b9f2da7e1c5a0ac38bf 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1,9 +1,10 @@ use crate::{ point, px, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, BorrowAppContext, BorrowWindow, Bounds, ClickEvent, DispatchPhase, Element, ElementId, FocusHandle, IntoElement, - KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, MouseButton, MouseDownEvent, MouseMoveEvent, - MouseUpEvent, ParentElement, Pixels, Point, Render, ScrollWheelEvent, SharedString, Size, - StackingOrder, Style, StyleRefinement, Styled, Task, View, Visibility, WindowContext, + IsZero, KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, MouseButton, MouseDownEvent, + MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, Render, ScrollWheelEvent, + SharedString, Size, StackingOrder, Style, StyleRefinement, Styled, Task, View, Visibility, + WindowContext, }; use collections::HashMap; @@ -1509,12 +1510,26 @@ impl Interactivity { let delta = event.delta.pixel_delta(line_height); if overflow.x == Overflow::Scroll { - scroll_offset.x = (scroll_offset.x + delta.x) + let mut delta_x = Pixels::ZERO; + if !delta.x.is_zero() { + delta_x = delta.x; + } else if overflow.y != Overflow::Scroll { + delta_x = delta.y; + } + + scroll_offset.x = (scroll_offset.x + delta_x) .clamp(-scroll_max.width, px(0.)); } if overflow.y == Overflow::Scroll { - scroll_offset.y = (scroll_offset.y + delta.y) + let mut delta_y = Pixels::ZERO; + if !delta.y.is_zero() { + delta_y = delta.y; + } else if overflow.x != Overflow::Scroll { + delta_y = delta.x; + } + + scroll_offset.y = (scroll_offset.y + delta_y) .clamp(-scroll_max.height, px(0.)); } From 5de32f7b0b7063a55b41f93b51de6915700c37bf Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 22 Dec 2023 18:06:23 +0200 Subject: [PATCH 289/644] Do not display a getting start message when the project is open --- crates/workspace2/src/pane.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 86894dee46daea3d389141e6a8cc4273ae773603..7128288e7b1cfee4d2153cc53ad9b858188d1a8c 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1930,7 +1930,8 @@ impl Render for Pane { }), ) .child(self.render_tab_bar(cx)) - .child( + .child({ + let has_worktrees = self.project.read(cx).worktrees().next().is_some(); // main content div() .flex_1() @@ -1944,10 +1945,15 @@ impl Render for Pane { .child(self.toolbar.clone()) .child(item.to_any()) } else { - div.h_flex().size_full().justify_center().child( - Label::new("Open a file or project to get started.") - .color(Color::Muted), - ) + let placeholder = div.h_flex().size_full().justify_center(); + if has_worktrees { + placeholder + } else { + placeholder.child( + Label::new("Open a file or project to get started.") + .color(Color::Muted), + ) + } } }) .child( @@ -1984,8 +1990,8 @@ impl Render for Pane { div.top_0().bottom_0().right_0().w_32() } }), - ), - ) + ) + }) .on_mouse_down( MouseButton::Navigate(NavigationDirection::Back), cx.listener(|pane, _, cx| { From dc1ed3c39d27dc1689f2565665c2d436e38db8d9 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:18:12 +0100 Subject: [PATCH 290/644] Titlebar project menu double click (#3784) This addresses a bug where popover menus in the titlebar were rendered only after a 2nd click. The first click was creating the View which the second one then rendered. In addition to this, `PopoverMenu::menu` function argument can now return an `Option>` instead of `View` as the creation of the menu can fail (as it might in case of git popover). Release Notes: - N/A --- crates/collab_ui2/src/collab_titlebar_item.rs | 99 +++++-------------- crates/copilot_button2/src/copilot_button.rs | 6 +- crates/language_tools2/src/lsp_log.rs | 1 + .../language_tools2/src/syntax_tree_view.rs | 1 + .../recent_projects2/src/recent_projects.rs | 78 ++++++--------- crates/ui2/src/components/popover_menu.rs | 10 +- 6 files changed, 68 insertions(+), 127 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index e4a6ff089a17efd8ab8abd36e0e8ade954cfb30a..75c4cc5263895a499d6865dee7c005d99026f031 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -18,7 +18,7 @@ use ui::{ }; use util::ResultExt; use vcs_menu::{build_branch_list, BranchList, OpenRecent as ToggleVcsMenu}; -use workspace::{notifications::NotifyResultExt, Workspace, WORKSPACE_DB}; +use workspace::{notifications::NotifyResultExt, Workspace}; const MAX_PROJECT_NAME_LENGTH: usize = 40; const MAX_BRANCH_NAME_LENGTH: usize = 40; @@ -52,8 +52,6 @@ pub struct CollabTitlebarItem { user_store: Model, client: Arc, workspace: WeakView, - branch_popover: Option<(View, Subscription)>, - project_popover: Option<(View, Subscription)>, _subscriptions: Vec, } @@ -291,8 +289,6 @@ impl CollabTitlebarItem { project, user_store, client, - branch_popover: None, - project_popover: None, _subscriptions: subscriptions, } } @@ -329,22 +325,15 @@ impl CollabTitlebarItem { }; let name = util::truncate_and_trailoff(name, MAX_PROJECT_NAME_LENGTH); + let workspace = self.workspace.clone(); popover_menu("project_name_trigger") .trigger( Button::new("project_name_trigger", name) .style(ButtonStyle::Subtle) .label_size(LabelSize::Small) - .tooltip(move |cx| Tooltip::text("Recent Projects", cx)) - .on_click(cx.listener(|this, _, cx| { - this.toggle_project_menu(&ToggleProjectMenu, cx); - })), - ) - .when_some( - self.project_popover - .as_ref() - .map(|(project, _)| project.clone()), - |this, project| this.menu(move |_| project.clone()), + .tooltip(move |cx| Tooltip::text("Recent Projects", cx)), ) + .menu(move |cx| Some(Self::render_project_popover(workspace.clone(), cx))) } pub fn render_project_branch(&self, cx: &mut ViewContext) -> Option { @@ -357,7 +346,7 @@ impl CollabTitlebarItem { names_and_branches.next().flatten() }; - + let workspace = self.workspace.upgrade()?; let branch_name = entry .as_ref() .and_then(RepositoryEntry::branch) @@ -376,17 +365,9 @@ impl CollabTitlebarItem { "Local branches only", cx, ) - }) - .on_click(cx.listener(|this, _, cx| { - this.toggle_vcs_menu(&ToggleVcsMenu, cx); - })), + }), ) - .when_some( - self.branch_popover - .as_ref() - .map(|(branch, _)| branch.clone()), - |this, branch| this.menu(move |_| branch.clone()), - ), + .menu(move |cx| Self::render_vcs_popover(workspace.clone(), cx)), ) } @@ -462,55 +443,25 @@ impl CollabTitlebarItem { .log_err(); } - pub fn toggle_vcs_menu(&mut self, _: &ToggleVcsMenu, cx: &mut ViewContext) { - if self.branch_popover.take().is_none() { - if let Some(workspace) = self.workspace.upgrade() { - let Some(view) = build_branch_list(workspace, cx).log_err() else { - return; - }; - self.project_popover.take(); - let focus_handle = view.focus_handle(cx); - cx.focus(&focus_handle); - let subscription = cx.subscribe(&view, |this, _, _, _| { - this.branch_popover.take(); - }); - self.branch_popover = Some((view, subscription)); - } - } - - cx.notify(); + pub fn render_vcs_popover( + workspace: View, + cx: &mut WindowContext<'_>, + ) -> Option> { + let view = build_branch_list(workspace, cx).log_err()?; + let focus_handle = view.focus_handle(cx); + cx.focus(&focus_handle); + Some(view) } - pub fn toggle_project_menu(&mut self, _: &ToggleProjectMenu, cx: &mut ViewContext) { - if self.project_popover.take().is_none() { - let workspace = self.workspace.clone(); - cx.spawn(|this, mut cx| async move { - let workspaces = WORKSPACE_DB - .recent_workspaces_on_disk() - .await - .unwrap_or_default() - .into_iter() - .map(|(_, location)| location) - .collect(); - - let workspace = workspace.clone(); - this.update(&mut cx, move |this, cx| { - let view = RecentProjects::open_popover(workspace, workspaces, cx); - - let focus_handle = view.focus_handle(cx); - cx.focus(&focus_handle); - this.branch_popover.take(); - let subscription = cx.subscribe(&view, |this, _, _, _| { - this.project_popover.take(); - }); - this.project_popover = Some((view, subscription)); - cx.notify(); - }) - .log_err(); - }) - .detach(); - } - cx.notify(); + pub fn render_project_popover( + workspace: WeakView, + cx: &mut WindowContext<'_>, + ) -> View { + let view = RecentProjects::open_popover(workspace, cx); + + let focus_handle = view.focus_handle(cx); + cx.focus(&focus_handle); + view } fn render_connection_status( @@ -587,6 +538,7 @@ impl CollabTitlebarItem { .action("Share Feedback", feedback::GiveFeedback.boxed_clone()) .action("Sign Out", client::SignOut.boxed_clone()) }) + .into() }) .trigger( ButtonLike::new("user-menu") @@ -609,6 +561,7 @@ impl CollabTitlebarItem { .separator() .action("Share Feedback", feedback::GiveFeedback.boxed_clone()) }) + .into() }) .trigger( ButtonLike::new("user-menu") diff --git a/crates/copilot_button2/src/copilot_button.rs b/crates/copilot_button2/src/copilot_button.rs index 7cd2b09db80d3ef4627cbad23f253bc766c77c4b..d3a1c1e58c0e6e0113cc965017aecf0a3c3cdca9 100644 --- a/crates/copilot_button2/src/copilot_button.rs +++ b/crates/copilot_button2/src/copilot_button.rs @@ -102,8 +102,10 @@ impl Render for CopilotButton { div().child( popover_menu("copilot") .menu(move |cx| match status { - Status::Authorized => this.update(cx, |this, cx| this.build_copilot_menu(cx)), - _ => this.update(cx, |this, cx| this.build_copilot_start_menu(cx)), + Status::Authorized => { + Some(this.update(cx, |this, cx| this.build_copilot_menu(cx))) + } + _ => Some(this.update(cx, |this, cx| this.build_copilot_start_menu(cx))), }) .anchor(AnchorCorner::BottomRight) .trigger( diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 973cd9c355713a30b03b79bc28802991db81f4da..310726e4a525c0cbd77eb0ad7092e7f86fca7a27 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -828,6 +828,7 @@ impl Render for LspLogToolbarItemView { } menu }) + .into() }); h_stack().size_full().child(lsp_menu).child( diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index c9a621f967155097a97fc9017ed6b17ccba1f7ec..e4ee4b0cfb6a7532670beb376262afeb6ca5be44 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -467,6 +467,7 @@ impl SyntaxTreeToolbarItemView { } menu }) + .into() }), ) } diff --git a/crates/recent_projects2/src/recent_projects.rs b/crates/recent_projects2/src/recent_projects.rs index 1a38a5c2004044085dbfaed394255e7dd87c1a19..2d6f4bf0e3160a214bc7a25a24a10d94129c694f 100644 --- a/crates/recent_projects2/src/recent_projects.rs +++ b/crates/recent_projects2/src/recent_projects.rs @@ -12,10 +12,7 @@ use picker::{Picker, PickerDelegate}; use std::sync::Arc; use ui::{prelude::*, ListItem, ListItemSpacing}; use util::paths::PathExt; -use workspace::{ - notifications::simple_message_notification::MessageNotification, ModalView, Workspace, - WorkspaceLocation, WORKSPACE_DB, -}; +use workspace::{ModalView, Workspace, WorkspaceLocation, WORKSPACE_DB}; pub use projects::OpenRecent; @@ -35,6 +32,25 @@ impl RecentProjects { fn new(delegate: RecentProjectsDelegate, rem_width: f32, cx: &mut ViewContext) -> Self { let picker = cx.build_view(|cx| Picker::new(delegate, cx)); let _subscription = cx.subscribe(&picker, |_, _, _, cx| cx.emit(DismissEvent)); + // We do not want to block the UI on a potentially lenghty call to DB, so we're gonna swap + // out workspace locations once the future runs to completion. + cx.spawn(|this, mut cx| async move { + let workspaces = WORKSPACE_DB + .recent_workspaces_on_disk() + .await + .unwrap_or_default() + .into_iter() + .map(|(_, location)| location) + .collect(); + this.update(&mut cx, move |this, cx| { + this.picker.update(cx, move |picker, cx| { + picker.delegate.workspace_locations = workspaces; + picker.update_matches(picker.query(cx), cx) + }) + }) + .ok() + }) + .detach(); Self { picker, rem_width, @@ -61,50 +77,20 @@ impl RecentProjects { fn open(_: &mut Workspace, cx: &mut ViewContext) -> Option>> { Some(cx.spawn(|workspace, mut cx| async move { - let workspace_locations: Vec<_> = cx - .background_executor() - .spawn(async { - WORKSPACE_DB - .recent_workspaces_on_disk() - .await - .unwrap_or_default() - .into_iter() - .map(|(_, location)| location) - .collect() - }) - .await; - workspace.update(&mut cx, |workspace, cx| { - if !workspace_locations.is_empty() { - let weak_workspace = cx.view().downgrade(); - workspace.toggle_modal(cx, |cx| { - let delegate = - RecentProjectsDelegate::new(weak_workspace, workspace_locations, true); + let weak_workspace = cx.view().downgrade(); + workspace.toggle_modal(cx, |cx| { + let delegate = RecentProjectsDelegate::new(weak_workspace, true); - let modal = RecentProjects::new(delegate, 34., cx); - modal - }); - } else { - workspace.show_notification(0, cx, |cx| { - cx.build_view(|_| MessageNotification::new("No recent projects to open.")) - }) - } + let modal = RecentProjects::new(delegate, 34., cx); + modal + }); })?; Ok(()) })) } - pub fn open_popover( - workspace: WeakView, - workspaces: Vec, - cx: &mut WindowContext<'_>, - ) -> View { - cx.build_view(|cx| { - Self::new( - RecentProjectsDelegate::new(workspace, workspaces, false), - 20., - cx, - ) - }) + pub fn open_popover(workspace: WeakView, cx: &mut WindowContext<'_>) -> View { + cx.build_view(|cx| Self::new(RecentProjectsDelegate::new(workspace, false), 20., cx)) } } @@ -140,14 +126,10 @@ pub struct RecentProjectsDelegate { } impl RecentProjectsDelegate { - fn new( - workspace: WeakView, - workspace_locations: Vec, - render_paths: bool, - ) -> Self { + fn new(workspace: WeakView, render_paths: bool) -> Self { Self { workspace, - workspace_locations, + workspace_locations: vec![], selected_match_index: 0, matches: Default::default(), render_paths, diff --git a/crates/ui2/src/components/popover_menu.rs b/crates/ui2/src/components/popover_menu.rs index 0f2fa6d23f147ba846695d1177ca5189f9130b3e..1a02dd526e464a7c9ef7483bf575afc21f24c753 100644 --- a/crates/ui2/src/components/popover_menu.rs +++ b/crates/ui2/src/components/popover_menu.rs @@ -18,19 +18,19 @@ pub struct PopoverMenu { Box< dyn FnOnce( Rc>>>, - Option View + 'static>>, + Option Option> + 'static>>, ) -> AnyElement + 'static, >, >, - menu_builder: Option View + 'static>>, + menu_builder: Option Option> + 'static>>, anchor: AnchorCorner, attach: Option, offset: Option>, } impl PopoverMenu { - pub fn menu(mut self, f: impl Fn(&mut WindowContext) -> View + 'static) -> Self { + pub fn menu(mut self, f: impl Fn(&mut WindowContext) -> Option> + 'static) -> Self { self.menu_builder = Some(Rc::new(f)); self } @@ -42,7 +42,9 @@ impl PopoverMenu { .when_some(builder, |el, builder| { el.on_click({ move |_, cx| { - let new_menu = (builder)(cx); + let Some(new_menu) = (builder)(cx) else { + return; + }; let menu2 = menu.clone(); let previous_focus_handle = cx.focused(); From a03306fd01bbc4989f03a31127d97901dcb8ecf8 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 22 Dec 2023 18:37:24 +0200 Subject: [PATCH 291/644] Fix enter, tab and shift-tab behavior in project search 2 --- crates/search2/src/project_search.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index 3e245ed72d4a9e8523b281ef79ee58387b2ad5bd..bc23f675672c2de7d5ee862342057d5a84765231 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -1730,12 +1730,15 @@ impl Render for ProjectSearchBar { .on_action(cx.listener(|this, _: &ActivateSemanticMode, cx| { this.activate_search_mode(SearchMode::Semantic, cx) })) - .on_action(cx.listener(|this, action, cx| { + .capture_action(cx.listener(|this, action, cx| { this.tab(action, cx); + cx.stop_propagation(); })) - .on_action(cx.listener(|this, action, cx| { + .capture_action(cx.listener(|this, action, cx| { this.tab_previous(action, cx); + cx.stop_propagation(); })) + .on_action(cx.listener(|this, action, cx| this.confirm(action, cx))) .on_action(cx.listener(|this, action, cx| { this.cycle_mode(action, cx); })) From 2f4cedbd5306427c3807cf6bde12fde97b89f1e9 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 22 Dec 2023 18:43:57 +0200 Subject: [PATCH 292/644] Remove the old code --- crates/search2/src/project_search.rs | 308 --------------------------- 1 file changed, 308 deletions(-) diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index bc23f675672c2de7d5ee862342057d5a84765231..9a654c9bf4d9d62947f756457599c2ea4e59af5d 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -1827,314 +1827,6 @@ impl Render for ProjectSearchBar { }) } } -// impl Entity for ProjectSearchBar { -// type Event = (); -// } - -// impl View for ProjectSearchBar { -// fn ui_name() -> &'static str { -// "ProjectSearchBar" -// } - -// fn update_keymap_context( -// &self, -// keymap: &mut gpui::keymap_matcher::KeymapContext, -// cx: &AppContext, -// ) { -// Self::reset_to_default_keymap_context(keymap); -// let in_replace = self -// .active_project_search -// .as_ref() -// .map(|search| { -// search -// .read(cx) -// .replacement_editor -// .read_with(cx, |_, cx| cx.is_self_focused()) -// }) -// .flatten() -// .unwrap_or(false); -// if in_replace { -// keymap.add_identifier("in_replace"); -// } -// } - -// fn render(&mut self, cx: &mut ViewContext) -> AnyElement { -// if let Some(_search) = self.active_project_search.as_ref() { -// let search = _search.read(cx); -// let theme = theme::current(cx).clone(); -// let query_container_style = if search.panels_with_errors.contains(&InputPanel::Query) { -// theme.search.invalid_editor -// } else { -// theme.search.editor.input.container -// }; - -// let search = _search.read(cx); -// let filter_button = render_option_button_icon( -// search.filters_enabled, -// "icons/filter.svg", -// 0, -// "Toggle filters", -// Box::new(ToggleFilters), -// move |_, this, cx| { -// this.toggle_filters(cx); -// }, -// 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| { -// crate::search_bar::render_option_button_icon( -// self.is_option_enabled(option, cx), -// path, -// option.bits as usize, -// format!("Toggle {}", option.label()), -// option.to_toggle_action(), -// move |_, this, cx| { -// this.toggle_search_option(option, cx); -// }, -// cx, -// ) -// }; -// let case_sensitive = is_semantic_disabled.then(|| { -// render_option_button_icon( -// "icons/case_insensitive.svg", -// SearchOptions::CASE_SENSITIVE, -// cx, -// ) -// }); - -// let whole_word = is_semantic_disabled.then(|| { -// render_option_button_icon("icons/word_search.svg", SearchOptions::WHOLE_WORD, cx) -// }); - -// let include_ignored = is_semantic_disabled.then(|| { -// render_option_button_icon( -// "icons/file_icons/git.svg", -// SearchOptions::INCLUDE_IGNORED, -// cx, -// ) -// }); - -// let search_button_for_mode = |mode, side, cx: &mut ViewContext| { -// 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, -// ) -// }; - -// let search = _search.read(cx); - -// let include_container_style = -// if search.panels_with_errors.contains(&InputPanel::Include) { -// theme.search.invalid_include_exclude_editor -// } else { -// theme.search.include_exclude_editor.input.container -// }; - -// let exclude_container_style = -// if search.panels_with_errors.contains(&InputPanel::Exclude) { -// theme.search.invalid_include_exclude_editor -// } else { -// theme.search.include_exclude_editor.input.container -// }; - -// let matches = search.active_match_index.map(|match_ix| { -// Label::new( -// format!( -// "{}/{}", -// match_ix + 1, -// search.model.read(cx).match_ranges.len() -// ), -// theme.search.match_index.text.clone(), -// ) -// .contained() -// .with_style(theme.search.match_index.container) -// .aligned() -// }); -// let should_show_replace_input = search.replace_enabled; -// let replacement = should_show_replace_input.then(|| { -// Flex::row() -// .with_child( -// Svg::for_style(theme.search.replace_icon.clone().icon) -// .contained() -// .with_style(theme.search.replace_icon.clone().container), -// ) -// .with_child(ChildView::new(&search.replacement_editor, cx).flex(1., true)) -// .align_children_center() -// .flex(1., true) -// .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 replace_all = should_show_replace_input.then(|| { -// super::replace_action( -// ReplaceAll, -// "Replace all", -// "icons/replace_all.svg", -// theme.tooltip.clone(), -// theme.search.action_button.clone(), -// ) -// }); -// let replace_next = should_show_replace_input.then(|| { -// super::replace_action( -// ReplaceNext, -// "Replace next", -// "icons/replace_next.svg", -// theme.tooltip.clone(), -// theme.search.action_button.clone(), -// ) -// }); -// 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), -// ) -// .with_children(search.filters_enabled.then(|| { -// Flex::row() -// .with_child( -// Flex::row() -// .with_child( -// ChildView::new(&search.included_files_editor, cx) -// .contained() -// .constrained() -// .with_height(theme.search.search_bar_row_height) -// .flex(1., true), -// ) -// .with_children(include_ignored) -// .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 switches_column = Flex::row() -// .align_children_center() -// .with_child(super::toggle_replace_button( -// search.replace_enabled, -// theme.tooltip.clone(), -// theme.search.option_button_component.clone(), -// )) -// .constrained() -// .with_height(theme.search.search_bar_row_height) -// .contained() -// .with_style(theme.search.option_button_group); -// 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| { -// render_nav_button( -// label, -// direction, -// is_active, -// move |_, this, cx| { -// if let Some(search) = this.active_project_search.as_ref() { -// search.update(cx, |search, cx| search.select_match(direction, cx)); -// } -// }, -// cx, -// ) -// }; - -// let nav_column = Flex::row() -// .with_children(replace_next) -// .with_children(replace_all) -// .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)) -// .constrained() -// .with_height(theme.search.search_bar_row_height) -// .flex_float(); - -// Flex::row() -// .with_child(query_column) -// .with_child(mode_column) -// .with_child(switches_column) -// .with_children(replacement) -// .with_child(nav_column) -// .contained() -// .with_style(theme.search.container) -// .into_any_named("project search") -// } else { -// Empty::new().into_any() -// } -// } -// } impl EventEmitter for ProjectSearchBar {} From 54e45306c59d33d44e045bbf44d9c42d9427a2df Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 18:00:03 +0100 Subject: [PATCH 293/644] Fix resizing for bottom dock We were not using `flex` on the `PaneGroup`, which caused the bottom dock to be unable to satisfy the desired resize value. --- crates/workspace2/src/pane_group.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index 06bd506e56e68b0a6932c18f3cb1ee190f45ab40..800d03a50cbc718d13566a3270ac317c28e105a5 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -242,6 +242,7 @@ impl Member { div() .relative() + .flex_1() .size_full() .child(pane.clone()) .when_some(leader_border, |this, color| { @@ -778,6 +779,9 @@ mod element { cx: &mut ui::prelude::WindowContext, ) -> (gpui::LayoutId, Self::State) { let mut style = Style::default(); + style.flex_grow = 1.; + style.flex_shrink = 1.; + style.flex_basis = relative(0.).into(); style.size.width = relative(1.).into(); style.size.height = relative(1.).into(); let layout_id = cx.request_layout(&style, None); From 25a5eda76f2b66873d80403a97e067f2ad70a24b Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:10:59 +0100 Subject: [PATCH 294/644] picker: Reintroduce headers and footers (#3786) Update VCS menu to match Zed1. image Release Notes: - N/A --- crates/picker2/src/picker2.rs | 15 +++- crates/vcs_menu2/src/lib.rs | 163 +++++++++++++++------------------- 2 files changed, 86 insertions(+), 92 deletions(-) diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index aa88d70dc44e84ee0eb25dc37f250af5a007e6c0..8585d9e73bdb7b362516ba6e81e57d7789c79b90 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -1,8 +1,8 @@ use editor::Editor; use gpui::{ - div, prelude::*, uniform_list, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, - FocusableView, Length, MouseButton, MouseDownEvent, Render, Task, UniformListScrollHandle, - View, ViewContext, WindowContext, + div, prelude::*, uniform_list, AnyElement, AppContext, DismissEvent, Div, EventEmitter, + FocusHandle, FocusableView, Length, MouseButton, MouseDownEvent, Render, Task, + UniformListScrollHandle, View, ViewContext, WindowContext, }; use std::{cmp, sync::Arc}; use ui::{prelude::*, v_stack, Color, Divider, Label, ListItem, ListItemSpacing}; @@ -40,6 +40,12 @@ pub trait PickerDelegate: Sized + 'static { selected: bool, cx: &mut ViewContext>, ) -> Option; + fn render_header(&self, _: &mut ViewContext>) -> Option { + None + } + fn render_footer(&self, _: &mut ViewContext>) -> Option { + None + } } impl FocusableView for Picker { @@ -253,6 +259,7 @@ impl Render for Picker { v_stack() .flex_grow() .py_2() + .children(self.delegate.render_header(cx)) .child( uniform_list( cx.view().clone(), @@ -286,6 +293,7 @@ impl Render for Picker { ) .track_scroll(self.scroll_handle.clone()) ) + .max_h_72() .overflow_hidden(), ) @@ -301,5 +309,6 @@ impl Render for Picker { ), ) }) + .children(self.delegate.render_footer(cx)) } } diff --git a/crates/vcs_menu2/src/lib.rs b/crates/vcs_menu2/src/lib.rs index cece283d4ee3025ea1afe0071da43839774db3b3..497ea1a0126e337cebd9bd33649b33442387ce45 100644 --- a/crates/vcs_menu2/src/lib.rs +++ b/crates/vcs_menu2/src/lib.rs @@ -2,13 +2,16 @@ use anyhow::{anyhow, bail, Result}; use fs::repository::Branch; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ - actions, rems, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, - InteractiveElement, ParentElement, Render, SharedString, Styled, Subscription, Task, View, - ViewContext, VisualContext, WindowContext, + actions, rems, AnyElement, AppContext, DismissEvent, Div, Element, EventEmitter, FocusHandle, + FocusableView, InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, + Subscription, Task, View, ViewContext, VisualContext, WindowContext, }; use picker::{Picker, PickerDelegate}; -use std::sync::Arc; -use ui::{v_stack, HighlightedLabel, ListItem, ListItemSpacing, Selectable}; +use std::{ops::Not, sync::Arc}; +use ui::{ + h_stack, v_stack, Button, ButtonCommon, Clickable, HighlightedLabel, Label, LabelCommon, + LabelSize, ListItem, ListItemSpacing, Selectable, +}; use util::ResultExt; use workspace::{ModalView, Toast, Workspace}; @@ -288,88 +291,70 @@ impl PickerDelegate for BranchListDelegate { .start_slot(HighlightedLabel::new(shortened_branch_name, highlights)), ) } - // fn render_header( - // &self, - // cx: &mut ViewContext>, - // ) -> Option>> { - // let theme = &theme::current(cx); - // let style = theme.picker.header.clone(); - // let label = if self.last_query.is_empty() { - // Flex::row() - // .with_child(Label::new("Recent branches", style.label.clone())) - // .contained() - // .with_style(style.container) - // } else { - // Flex::row() - // .with_child(Label::new("Branches", style.label.clone())) - // .with_children(self.matches.is_empty().not().then(|| { - // let suffix = if self.matches.len() == 1 { "" } else { "es" }; - // Label::new( - // format!("{} match{}", self.matches.len(), suffix), - // style.label, - // ) - // .flex_float() - // })) - // .contained() - // .with_style(style.container) - // }; - // Some(label.into_any()) - // } - // fn render_footer( - // &self, - // cx: &mut ViewContext>, - // ) -> Option>> { - // if !self.last_query.is_empty() { - // let theme = &theme::current(cx); - // let style = theme.picker.footer.clone(); - // enum BranchCreateButton {} - // Some( - // Flex::row().with_child(MouseEventHandler::new::(0, cx, |state, _| { - // let style = style.style_for(state); - // Label::new("Create branch", style.label.clone()) - // .contained() - // .with_style(style.container) - // }) - // .with_cursor_style(CursorStyle::PointingHand) - // .on_down(MouseButton::Left, |_, _, cx| { - // cx.spawn(|picker, mut cx| async move { - // picker.update(&mut cx, |this, cx| { - // let project = this.delegate().workspace.read(cx).project().read(cx); - // let current_pick = &this.delegate().last_query; - // let mut cwd = project - // .visible_worktrees(cx) - // .next() - // .ok_or_else(|| anyhow!("There are no visisible worktrees."))? - // .read(cx) - // .abs_path() - // .to_path_buf(); - // cwd.push(".git"); - // let repo = project - // .fs() - // .open_repo(&cwd) - // .ok_or_else(|| anyhow!("Could not open repository at path `{}`", cwd.as_os_str().to_string_lossy()))?; - // let repo = repo - // .lock(); - // let status = repo - // .create_branch(¤t_pick); - // if status.is_err() { - // this.delegate().display_error_toast(format!("Failed to create branch '{current_pick}', check for conflicts or unstashed files"), cx); - // status?; - // } - // let status = repo.change_branch(¤t_pick); - // if status.is_err() { - // this.delegate().display_error_toast(format!("Failed to chec branch '{current_pick}', check for conflicts or unstashed files"), cx); - // status?; - // } - // cx.emit(PickerEvent::Dismiss); - // Ok::<(), anyhow::Error>(()) - // }) - // }).detach(); - // })).aligned().right() - // .into_any(), - // ) - // } else { - // None - // } - // } + fn render_header(&self, _: &mut ViewContext>) -> Option { + let label = if self.last_query.is_empty() { + h_stack() + .ml_3() + .child(Label::new("Recent branches").size(LabelSize::Small)) + } else { + let match_label = self.matches.is_empty().not().then(|| { + let suffix = if self.matches.len() == 1 { "" } else { "es" }; + Label::new(format!("{} match{}", self.matches.len(), suffix)).size(LabelSize::Small) + }); + h_stack() + .px_3() + .h_full() + .justify_between() + .child(Label::new("Branches").size(LabelSize::Small)) + .children(match_label) + }; + Some(label.into_any()) + } + fn render_footer(&self, cx: &mut ViewContext>) -> Option { + if self.last_query.is_empty() { + return None; + } + + Some( + h_stack().mr_3().pb_2().child(h_stack().w_full()).child( + Button::new("branch-picker-create-branch-button", "Create branch").on_click( + cx.listener(|_, _, cx| { + cx.spawn(|picker, mut cx| async move { + picker.update(&mut cx, |this, cx| { + let project = this.delegate.workspace.read(cx).project().read(cx); + let current_pick = &this.delegate.last_query; + let mut cwd = project + .visible_worktrees(cx) + .next() + .ok_or_else(|| anyhow!("There are no visisible worktrees."))? + .read(cx) + .abs_path() + .to_path_buf(); + cwd.push(".git"); + let repo = project + .fs() + .open_repo(&cwd) + .ok_or_else(|| anyhow!("Could not open repository at path `{}`", cwd.as_os_str().to_string_lossy()))?; + let repo = repo + .lock(); + let status = repo + .create_branch(¤t_pick); + if status.is_err() { + this.delegate.display_error_toast(format!("Failed to create branch '{current_pick}', check for conflicts or unstashed files"), cx); + status?; + } + let status = repo.change_branch(¤t_pick); + if status.is_err() { + this.delegate.display_error_toast(format!("Failed to chec branch '{current_pick}', check for conflicts or unstashed files"), cx); + status?; + } + this.cancel(&Default::default(), cx); + Ok::<(), anyhow::Error>(()) + }) + + }).detach_and_log_err(cx); + }), + ).style(ui::ButtonStyle::Filled)).into_any_element(), + ) + } } From 3715ddfa74b08c82e0aad95802b0e2151a562526 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 18:26:33 +0100 Subject: [PATCH 295/644] Use `Pixels` instead of `f32` for panel size --- crates/assistant2/src/assistant_panel.rs | 8 ++-- crates/assistant2/src/assistant_settings.rs | 5 +- crates/collab_ui2/src/chat_panel.rs | 8 ++-- crates/collab_ui2/src/collab_panel.rs | 12 ++--- crates/collab_ui2/src/notification_panel.rs | 8 ++-- crates/collab_ui2/src/panel_settings.rs | 7 +-- crates/project_panel2/src/project_panel.rs | 20 ++++---- .../src/project_panel_settings.rs | 3 +- crates/terminal2/src/terminal_settings.rs | 4 +- crates/terminal_view2/src/terminal_panel.rs | 14 +++--- crates/workspace2/src/dock.rs | 46 +++++++++---------- crates/workspace2/src/workspace2.rs | 6 +-- 12 files changed, 69 insertions(+), 72 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 84576c5262783e66a79be96eb24e142dbd83597c..bcfb5f0fbc9ae2409b999e4d8698707d2b1f7db5 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -84,8 +84,8 @@ pub fn init(cx: &mut AppContext) { pub struct AssistantPanel { workspace: WeakView, - width: Option, - height: Option, + width: Option, + height: Option, active_editor_index: Option, prev_active_editor_index: Option, editors: Vec>, @@ -1242,7 +1242,7 @@ impl Panel for AssistantPanel { }); } - fn size(&self, cx: &WindowContext) -> f32 { + fn size(&self, cx: &WindowContext) -> Pixels { let settings = AssistantSettings::get_global(cx); match self.position(cx) { DockPosition::Left | DockPosition::Right => { @@ -1252,7 +1252,7 @@ impl Panel for AssistantPanel { } } - fn set_size(&mut self, size: Option, cx: &mut ViewContext) { + fn set_size(&mut self, size: Option, cx: &mut ViewContext) { match self.position(cx) { DockPosition::Left | DockPosition::Right => self.width = size, DockPosition::Bottom => self.height = size, diff --git a/crates/assistant2/src/assistant_settings.rs b/crates/assistant2/src/assistant_settings.rs index 5a727df621bd911ee56b4ba2b3d8b13567b35b63..c0fbc74e9ae9b465abda293aa16e529a96b830ea 100644 --- a/crates/assistant2/src/assistant_settings.rs +++ b/crates/assistant2/src/assistant_settings.rs @@ -1,4 +1,5 @@ use anyhow; +use gpui::Pixels; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use settings::Settings; @@ -51,8 +52,8 @@ pub enum AssistantDockPosition { pub struct AssistantSettings { pub button: bool, pub dock: AssistantDockPosition, - pub default_width: f32, - pub default_height: f32, + pub default_width: Pixels, + pub default_height: Pixels, pub default_open_ai_model: OpenAIModel, } diff --git a/crates/collab_ui2/src/chat_panel.rs b/crates/collab_ui2/src/chat_panel.rs index 108d53b07231ec795e983f8d6bcb681f67153984..03e9cfbb4ad64317ede58045ec2a622eda0681ad 100644 --- a/crates/collab_ui2/src/chat_panel.rs +++ b/crates/collab_ui2/src/chat_panel.rs @@ -51,7 +51,7 @@ pub struct ChatPanel { input_editor: View, local_timezone: UtcOffset, fs: Arc, - width: Option, + width: Option, active: bool, pending_serialization: Task>, subscriptions: Vec, @@ -62,7 +62,7 @@ pub struct ChatPanel { #[derive(Serialize, Deserialize)] struct SerializedChatPanel { - width: Option, + width: Option, } #[derive(Debug)] @@ -584,12 +584,12 @@ impl Panel for ChatPanel { }); } - fn size(&self, cx: &gpui::WindowContext) -> f32 { + fn size(&self, cx: &gpui::WindowContext) -> Pixels { self.width .unwrap_or_else(|| ChatPanelSettings::get_global(cx).default_width) } - fn set_size(&mut self, size: Option, cx: &mut ViewContext) { + fn set_size(&mut self, size: Option, cx: &mut ViewContext) { self.width = size; self.serialize(cx); cx.notify(); diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 3f0115e3fc8a1b40bb578f534ed518aa7b2fc3ae..8fd90af45b40cce837160c886cb5542e9a11e94c 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2314,15 +2314,13 @@ impl Panel for CollabPanel { ); } - fn size(&self, cx: &gpui::WindowContext) -> f32 { - self.width.map_or_else( - || CollaborationPanelSettings::get_global(cx).default_width, - |width| width.0, - ) + fn size(&self, cx: &gpui::WindowContext) -> Pixels { + self.width + .unwrap_or_else(|| CollaborationPanelSettings::get_global(cx).default_width) } - fn set_size(&mut self, size: Option, cx: &mut ViewContext) { - self.width = size.map(|s| px(s)); + fn set_size(&mut self, size: Option, cx: &mut ViewContext) { + self.width = size; self.serialize(cx); cx.notify(); } diff --git a/crates/collab_ui2/src/notification_panel.rs b/crates/collab_ui2/src/notification_panel.rs index 3ba1f0bd4742f4b7217cec63291d5b5cbc6c8524..4b2f38de9b8aad0072e7bc5320baaa7efc2e2779 100644 --- a/crates/collab_ui2/src/notification_panel.rs +++ b/crates/collab_ui2/src/notification_panel.rs @@ -37,7 +37,7 @@ pub struct NotificationPanel { channel_store: Model, notification_store: Model, fs: Arc, - width: Option, + width: Option, active: bool, notification_list: ListState, pending_serialization: Task>, @@ -51,7 +51,7 @@ pub struct NotificationPanel { #[derive(Serialize, Deserialize)] struct SerializedNotificationPanel { - width: Option, + width: Option, } #[derive(Debug)] @@ -639,12 +639,12 @@ impl Panel for NotificationPanel { ); } - fn size(&self, cx: &gpui::WindowContext) -> f32 { + fn size(&self, cx: &gpui::WindowContext) -> Pixels { self.width .unwrap_or_else(|| NotificationPanelSettings::get_global(cx).default_width) } - fn set_size(&mut self, size: Option, cx: &mut ViewContext) { + fn set_size(&mut self, size: Option, cx: &mut ViewContext) { self.width = size; self.serialize(cx); cx.notify(); diff --git a/crates/collab_ui2/src/panel_settings.rs b/crates/collab_ui2/src/panel_settings.rs index 3d062951a6850851aa38aad5ac97e0137677201e..250817a803e1088e21ed8965ef9bdbaaa4bf20a5 100644 --- a/crates/collab_ui2/src/panel_settings.rs +++ b/crates/collab_ui2/src/panel_settings.rs @@ -1,4 +1,5 @@ use anyhow; +use gpui::Pixels; use schemars::JsonSchema; use serde_derive::{Deserialize, Serialize}; use settings::Settings; @@ -8,21 +9,21 @@ use workspace::dock::DockPosition; pub struct CollaborationPanelSettings { pub button: bool, pub dock: DockPosition, - pub default_width: f32, + pub default_width: Pixels, } #[derive(Deserialize, Debug)] pub struct ChatPanelSettings { pub button: bool, pub dock: DockPosition, - pub default_width: f32, + pub default_width: Pixels, } #[derive(Deserialize, Debug)] pub struct NotificationPanelSettings { pub button: bool, pub dock: DockPosition, - pub default_width: f32, + pub default_width: Pixels, } #[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)] diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index 7f6ae63ee1c4a85590cebe4e22011f29d04aa819..1259fc1d612d3e4c3f8f7cfbba0ca4b5c400d257 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -156,7 +156,7 @@ pub enum Event { #[derive(Serialize, Deserialize)] struct SerializedProjectPanel { - width: Option, + width: Option, } struct DraggedProjectEntryView { @@ -333,7 +333,7 @@ impl ProjectPanel { let panel = ProjectPanel::new(workspace, cx); if let Some(serialized_panel) = serialized_panel { panel.update(cx, |panel, cx| { - panel.width = serialized_panel.width.map(px); + panel.width = serialized_panel.width; cx.notify(); }); } @@ -348,9 +348,7 @@ impl ProjectPanel { KEY_VALUE_STORE .write_kvp( PROJECT_PANEL_KEY.into(), - serde_json::to_string(&SerializedProjectPanel { - width: width.map(|p| p.0), - })?, + serde_json::to_string(&SerializedProjectPanel { width })?, ) .await?; anyhow::Ok(()) @@ -1602,15 +1600,13 @@ impl Panel for ProjectPanel { ); } - fn size(&self, cx: &WindowContext) -> f32 { - self.width.map_or_else( - || ProjectPanelSettings::get_global(cx).default_width, - |width| width.0, - ) + fn size(&self, cx: &WindowContext) -> Pixels { + self.width + .unwrap_or_else(|| ProjectPanelSettings::get_global(cx).default_width) } - fn set_size(&mut self, size: Option, cx: &mut ViewContext) { - self.width = size.map(px); + fn set_size(&mut self, size: Option, cx: &mut ViewContext) { + self.width = size; self.serialize(cx); cx.notify(); } diff --git a/crates/project_panel2/src/project_panel_settings.rs b/crates/project_panel2/src/project_panel_settings.rs index c1009648a02009d1559295c5e8a029f2e51980e3..b9a87a1a03cf3ac2164fb4ad5db6144f0a3fc6de 100644 --- a/crates/project_panel2/src/project_panel_settings.rs +++ b/crates/project_panel2/src/project_panel_settings.rs @@ -1,4 +1,5 @@ use anyhow; +use gpui::Pixels; use schemars::JsonSchema; use serde_derive::{Deserialize, Serialize}; use settings::Settings; @@ -12,7 +13,7 @@ pub enum ProjectPanelDockPosition { #[derive(Deserialize, Debug)] pub struct ProjectPanelSettings { - pub default_width: f32, + pub default_width: Pixels, pub dock: ProjectPanelDockPosition, pub file_icons: bool, pub folder_icons: bool, diff --git a/crates/terminal2/src/terminal_settings.rs b/crates/terminal2/src/terminal_settings.rs index 1038c6d0616e3b391ea7ae8dea3b68b93f1b3cde..f63b575bf214871e5391aefe9889fc5b69da2fba 100644 --- a/crates/terminal2/src/terminal_settings.rs +++ b/crates/terminal2/src/terminal_settings.rs @@ -25,8 +25,8 @@ pub struct TerminalSettings { pub option_as_meta: bool, pub copy_on_select: bool, pub dock: TerminalDockPosition, - pub default_width: f32, - pub default_height: f32, + pub default_width: Pixels, + pub default_height: Pixels, pub detect_venv: VenvSettings, } diff --git a/crates/terminal_view2/src/terminal_panel.rs b/crates/terminal_view2/src/terminal_panel.rs index def56f376024c16a4061b3b2cffb8d2da620bfd1..c2fe5de0148c2b00fe1b89913d8ef9b57c1db2b8 100644 --- a/crates/terminal_view2/src/terminal_panel.rs +++ b/crates/terminal_view2/src/terminal_panel.rs @@ -4,7 +4,7 @@ use crate::TerminalView; use db::kvp::KEY_VALUE_STORE; use gpui::{ actions, div, serde_json, AppContext, AsyncWindowContext, Div, Entity, EventEmitter, - ExternalPaths, FocusHandle, FocusableView, IntoElement, ParentElement, Render, Styled, + ExternalPaths, FocusHandle, FocusableView, IntoElement, ParentElement, Pixels, Render, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext, }; use project::Fs; @@ -44,8 +44,8 @@ pub struct TerminalPanel { pane: View, fs: Arc, workspace: WeakView, - width: Option, - height: Option, + width: Option, + height: Option, pending_serialization: Task>, _subscriptions: Vec, } @@ -364,7 +364,7 @@ impl Panel for TerminalPanel { }); } - fn size(&self, cx: &WindowContext) -> f32 { + fn size(&self, cx: &WindowContext) -> Pixels { let settings = TerminalSettings::get_global(cx); match self.position(cx) { DockPosition::Left | DockPosition::Right => { @@ -374,7 +374,7 @@ impl Panel for TerminalPanel { } } - fn set_size(&mut self, size: Option, cx: &mut ViewContext) { + fn set_size(&mut self, size: Option, cx: &mut ViewContext) { match self.position(cx) { DockPosition::Left | DockPosition::Right => self.width = size, DockPosition::Bottom => self.height = size, @@ -428,6 +428,6 @@ impl Panel for TerminalPanel { struct SerializedTerminalPanel { items: Vec, active_item_id: Option, - width: Option, - height: Option, + width: Option, + height: Option, } diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 2534e43895190a23c8137a94cba88396ae626a3b..7121f846810f69ffa2df88f1333cc9f7a903e72c 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -11,6 +11,8 @@ use std::sync::Arc; use ui::{h_stack, ContextMenu, IconButton, Tooltip}; use ui::{prelude::*, right_click_menu}; +const RESIZE_HANDLE_SIZE: Pixels = Pixels(6.); + pub enum PanelEvent { ChangePosition, ZoomIn, @@ -25,8 +27,8 @@ pub trait Panel: FocusableView + EventEmitter { fn position(&self, cx: &WindowContext) -> DockPosition; fn position_is_valid(&self, position: DockPosition) -> bool; fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext); - fn size(&self, cx: &WindowContext) -> f32; - fn set_size(&mut self, size: Option, cx: &mut ViewContext); + fn size(&self, cx: &WindowContext) -> Pixels; + fn set_size(&mut self, size: Option, cx: &mut ViewContext); // todo!("We should have a icon tooltip method, rather than using persistant_name") fn icon(&self, cx: &WindowContext) -> Option; fn toggle_action(&self) -> Box; @@ -49,8 +51,8 @@ pub trait PanelHandle: Send + Sync { fn is_zoomed(&self, cx: &WindowContext) -> bool; fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext); fn set_active(&self, active: bool, cx: &mut WindowContext); - fn size(&self, cx: &WindowContext) -> f32; - fn set_size(&self, size: Option, cx: &mut WindowContext); + fn size(&self, cx: &WindowContext) -> Pixels; + fn set_size(&self, size: Option, cx: &mut WindowContext); fn icon(&self, cx: &WindowContext) -> Option; fn toggle_action(&self, cx: &WindowContext) -> Box; fn icon_label(&self, cx: &WindowContext) -> Option; @@ -94,11 +96,11 @@ where self.update(cx, |this, cx| this.set_active(active, cx)) } - fn size(&self, cx: &WindowContext) -> f32 { + fn size(&self, cx: &WindowContext) -> Pixels { self.read(cx).size(cx) } - fn set_size(&self, size: Option, cx: &mut WindowContext) { + fn set_size(&self, size: Option, cx: &mut WindowContext) { self.update(cx, |this, cx| this.set_size(size, cx)) } @@ -446,14 +448,14 @@ impl Dock { } } - pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option { + pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option { self.panel_entries .iter() .find(|entry| entry.panel.panel_id() == panel.panel_id()) .map(|entry| entry.panel.size(cx)) } - pub fn active_panel_size(&self, cx: &WindowContext) -> Option { + pub fn active_panel_size(&self, cx: &WindowContext) -> Option { if self.is_open { self.panel_entries .get(self.active_panel_index) @@ -463,7 +465,7 @@ impl Dock { } } - pub fn resize_active_panel(&mut self, size: Option, cx: &mut ViewContext) { + pub fn resize_active_panel(&mut self, size: Option, cx: &mut ViewContext) { if let Some(entry) = self.panel_entries.get_mut(self.active_panel_index) { entry.panel.set_size(size, cx); cx.notify(); @@ -502,8 +504,6 @@ impl Render for Dock { .z_index(1) .block_mouse(); - const HANDLE_SIZE: Pixels = Pixels(6.); - match self.position() { DockPosition::Left => { handle = handle @@ -511,7 +511,7 @@ impl Render for Dock { .right(px(0.)) .top(px(0.)) .h_full() - .w(HANDLE_SIZE) + .w(RESIZE_HANDLE_SIZE) .cursor_col_resize(); } DockPosition::Bottom => { @@ -520,7 +520,7 @@ impl Render for Dock { .top(px(0.)) .left(px(0.)) .w_full() - .h(HANDLE_SIZE) + .h(RESIZE_HANDLE_SIZE) .cursor_row_resize(); } DockPosition::Right => { @@ -529,7 +529,7 @@ impl Render for Dock { .top(px(0.)) .left(px(0.)) .h_full() - .w(HANDLE_SIZE) + .w(RESIZE_HANDLE_SIZE) .cursor_col_resize(); } } @@ -539,8 +539,8 @@ impl Render for Dock { .border_color(cx.theme().colors().border) .overflow_hidden() .map(|this| match self.position().axis() { - Axis::Horizontal => this.w(px(size)).h_full().flex_row(), - Axis::Vertical => this.h(px(size)).w_full().flex_col(), + Axis::Horizontal => this.w(size).h_full().flex_row(), + Axis::Vertical => this.h(size).w_full().flex_col(), }) .map(|this| match self.position() { DockPosition::Left => this.border_r(), @@ -550,8 +550,8 @@ impl Render for Dock { .child( div() .map(|this| match self.position().axis() { - Axis::Horizontal => this.min_w(px(size)).h_full(), - Axis::Vertical => this.min_h(px(size)).w_full(), + Axis::Horizontal => this.min_w(size).h_full(), + Axis::Vertical => this.min_h(size).w_full(), }) .child(entry.panel.to_any()), ) @@ -674,7 +674,7 @@ pub mod test { pub zoomed: bool, pub active: bool, pub focus_handle: FocusHandle, - pub size: f32, + pub size: Pixels, } actions!(test, [ToggleTestPanel]); @@ -687,7 +687,7 @@ pub mod test { zoomed: false, active: false, focus_handle: cx.focus_handle(), - size: 300., + size: px(300.), } } } @@ -718,12 +718,12 @@ pub mod test { cx.emit(PanelEvent::ChangePosition); } - fn size(&self, _: &WindowContext) -> f32 { + fn size(&self, _: &WindowContext) -> Pixels { self.size } - fn set_size(&mut self, size: Option, _: &mut ViewContext) { - self.size = size.unwrap_or(300.); + fn set_size(&mut self, size: Option, _: &mut ViewContext) { + self.size = size.unwrap_or(px(300.)); } fn icon(&self, _: &WindowContext) -> Option { diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index c1695891f6abf986012948dc5f4364aebdd6e68c..f4484c827ecdb87ee9cc188def2cb39124157eed 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -3549,19 +3549,19 @@ impl Render for Workspace { DockPosition::Left => { let size = workspace.bounds.left() + e.event.position.x; workspace.left_dock.update(cx, |left_dock, cx| { - left_dock.resize_active_panel(Some(size.0), cx); + left_dock.resize_active_panel(Some(size), cx); }); } DockPosition::Right => { let size = workspace.bounds.right() - e.event.position.x; workspace.right_dock.update(cx, |right_dock, cx| { - right_dock.resize_active_panel(Some(size.0), cx); + right_dock.resize_active_panel(Some(size), cx); }); } DockPosition::Bottom => { let size = workspace.bounds.bottom() - e.event.position.y; workspace.bottom_dock.update(cx, |bottom_dock, cx| { - bottom_dock.resize_active_panel(Some(size.0), cx); + bottom_dock.resize_active_panel(Some(size), cx); }); } } From 961d8331f32f7fe0fa36533c9cead9692e01c873 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 18:28:28 +0100 Subject: [PATCH 296/644] Prevent panels from getting so small they can't be resized --- crates/workspace2/src/dock.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 7121f846810f69ffa2df88f1333cc9f7a903e72c..9c7ffc6e89d655bae71aeda049ff8034ac506492 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -467,6 +467,7 @@ impl Dock { pub fn resize_active_panel(&mut self, size: Option, cx: &mut ViewContext) { if let Some(entry) = self.panel_entries.get_mut(self.active_panel_index) { + let size = size.map(|size| size.max(RESIZE_HANDLE_SIZE)); entry.panel.set_size(size, cx); cx.notify(); } From 9a6688bdfb87a38615239a2a05ac4061bf14fdbe Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Dec 2023 18:41:43 +0100 Subject: [PATCH 297/644] Fix panic when deploying emoji picker (character palette) The panic was caused by Cocoa synchronously invoking the `selected_text_range` method on the registered input handler while we already had a borrow of the app. This commit fixes this issue by showing the character palette on the next tick of the loop (we've had this problem in other spots too and used the same technique). --- crates/gpui2/src/platform/mac/window.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/gpui2/src/platform/mac/window.rs b/crates/gpui2/src/platform/mac/window.rs index 12189e198a76343ad9478ffad2ec550b9cd0e9f0..a1fda0b75de6d37e2695c67c6047f5306bb86297 100644 --- a/crates/gpui2/src/platform/mac/window.rs +++ b/crates/gpui2/src/platform/mac/window.rs @@ -886,11 +886,16 @@ impl PlatformWindow for MacWindow { } fn show_character_palette(&self) { - unsafe { - let app = NSApplication::sharedApplication(nil); - let window = self.0.lock().native_window; - let _: () = msg_send![app, orderFrontCharacterPalette: window]; - } + let this = self.0.lock(); + let window = this.native_window; + this.executor + .spawn(async move { + unsafe { + let app = NSApplication::sharedApplication(nil); + let _: () = msg_send![app, orderFrontCharacterPalette: window]; + } + }) + .detach(); } fn minimize(&self) { From 7ef2ddd7a52df512a8f0e77e86ba2e761179b24d Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 12:46:06 -0500 Subject: [PATCH 298/644] Disambiguate GPUI2 macOS class names (#3789) This PR disambiguates the macOS class names used in GPUI2 from the ones used in GPUI1. Right now if you happen to end up with a copy of both `gpui` and `gpui2` in the dependency tree you get an unhelpful `unwrap` error when we try to build the class names. By giving them different names we are able to get to our more helpful error that informs you that both GPUI1 and GPUI2 are in the module tree. We can change these names back once we do the big "un-2-ing". Release Notes: - N/A --- crates/gpui2/src/platform/mac/platform.rs | 4 ++-- crates/gpui2/src/platform/mac/window.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/gpui2/src/platform/mac/platform.rs b/crates/gpui2/src/platform/mac/platform.rs index f3c3b8ea5d24ce552a8ade8c290d87e07c7f63f5..2dcfb1a58d026e9d3bcbb500741490a657a5b2b3 100644 --- a/crates/gpui2/src/platform/mac/platform.rs +++ b/crates/gpui2/src/platform/mac/platform.rs @@ -66,7 +66,7 @@ static mut APP_DELEGATE_CLASS: *const Class = ptr::null(); #[ctor] unsafe fn build_classes() { APP_CLASS = { - let mut decl = ClassDecl::new("GPUIApplication", class!(NSApplication)).unwrap(); + let mut decl = ClassDecl::new("GPUI2Application", class!(NSApplication)).unwrap(); decl.add_ivar::<*mut c_void>(MAC_PLATFORM_IVAR); decl.add_method( sel!(sendEvent:), @@ -76,7 +76,7 @@ unsafe fn build_classes() { }; APP_DELEGATE_CLASS = { - let mut decl = ClassDecl::new("GPUIApplicationDelegate", class!(NSResponder)).unwrap(); + let mut decl = ClassDecl::new("GPUI2ApplicationDelegate", class!(NSResponder)).unwrap(); decl.add_ivar::<*mut c_void>(MAC_PLATFORM_IVAR); decl.add_method( sel!(applicationDidFinishLaunching:), diff --git a/crates/gpui2/src/platform/mac/window.rs b/crates/gpui2/src/platform/mac/window.rs index 12189e198a76343ad9478ffad2ec550b9cd0e9f0..de2fa42141f126ecd310a48c8c7806d88e9f81bf 100644 --- a/crates/gpui2/src/platform/mac/window.rs +++ b/crates/gpui2/src/platform/mac/window.rs @@ -85,10 +85,10 @@ const NSDragOperationCopy: NSDragOperation = 1; unsafe fn build_classes() { ::util::gpui2_loaded(); - WINDOW_CLASS = build_window_class("GPUIWindow", class!(NSWindow)); - PANEL_CLASS = build_window_class("GPUIPanel", class!(NSPanel)); + WINDOW_CLASS = build_window_class("GPUI2Window", class!(NSWindow)); + PANEL_CLASS = build_window_class("GPUI2Panel", class!(NSPanel)); VIEW_CLASS = { - let mut decl = ClassDecl::new("GPUIView", class!(NSView)).unwrap(); + let mut decl = ClassDecl::new("GPUI2View", class!(NSView)).unwrap(); decl.add_ivar::<*mut c_void>(WINDOW_STATE_IVAR); decl.add_method(sel!(dealloc), dealloc_view as extern "C" fn(&Object, Sel)); From dc64411ccab069d9fd52d8d2868238467c8169a1 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 13:47:30 -0500 Subject: [PATCH 299/644] Extend `theme_importer` in preparation for importing Zed1 themes (#3791) This PR extends the `theme_importer` with the overall structure required to support importing themes from Zed1. Release Notes: - N/A --- Cargo.lock | 2 + crates/gpui/src/platform/mac.rs | 2 +- crates/gpui2/Cargo.toml | 6 + crates/theme2/src/themes/mod.rs | 16 +- crates/theme_importer/Cargo.toml | 6 +- crates/theme_importer/src/assets.rs | 26 +++ crates/theme_importer/src/main.rs | 118 ++++++++++++- crates/theme_importer/src/zed1.rs | 3 + crates/theme_importer/src/zed1/converter.rs | 176 ++++++++++++++++++++ crates/util/Cargo.toml | 6 + crates/util/src/util.rs | 7 +- 11 files changed, 352 insertions(+), 16 deletions(-) create mode 100644 crates/theme_importer/src/assets.rs create mode 100644 crates/theme_importer/src/zed1.rs create mode 100644 crates/theme_importer/src/zed1/converter.rs diff --git a/Cargo.lock b/Cargo.lock index 1bcbd3be387341da6da2e0c2ae041a5edead8ba1..01230cd8052a477214946a30d30362b87de8cd88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9834,6 +9834,7 @@ dependencies = [ "anyhow", "clap 4.4.4", "convert_case 0.6.0", + "gpui", "gpui2", "indexmap 1.9.3", "json_comments", @@ -9843,6 +9844,7 @@ dependencies = [ "serde", "simplelog", "strum", + "theme", "theme2", "uuid 1.4.1", ] diff --git a/crates/gpui/src/platform/mac.rs b/crates/gpui/src/platform/mac.rs index 92ab53f15e34dae90db9635d95eb6721c3a53ee6..193651c0876b0afb2703922b84bb32ddc76cb897 100644 --- a/crates/gpui/src/platform/mac.rs +++ b/crates/gpui/src/platform/mac.rs @@ -25,7 +25,7 @@ use window::MacWindow; use crate::executor; -pub(crate) fn platform() -> Arc { +pub fn platform() -> Arc { Arc::new(MacPlatform::new()) } diff --git a/crates/gpui2/Cargo.toml b/crates/gpui2/Cargo.toml index bf0ac955a5ec20d8a9ca6d0c0bac0bc5e7c95542..cb3e1af70bc8fc8878cc22e3df6afb2fed83c62c 100644 --- a/crates/gpui2/Cargo.toml +++ b/crates/gpui2/Cargo.toml @@ -9,6 +9,12 @@ publish = false [features] test-support = ["backtrace", "dhat", "env_logger", "collections/test-support", "util/test-support"] +# Suppress a panic when both GPUI1 and GPUI2 are loaded. +# +# This is used in the `theme_importer` where we need to depend on both +# GPUI1 and GPUI2 in order to convert Zed1 themes to Zed2 themes. +allow-multiple-gpui-versions = ["util/allow-multiple-gpui-versions"] + [lib] path = "src/gpui2.rs" doctest = false diff --git a/crates/theme2/src/themes/mod.rs b/crates/theme2/src/themes/mod.rs index 4059d3751ea9178f76e703225f322a0beba33b5c..aaf111703f207047fd71275ca3010f64374b18cc 100644 --- a/crates/theme2/src/themes/mod.rs +++ b/crates/theme2/src/themes/mod.rs @@ -29,16 +29,16 @@ use crate::UserThemeFamily; pub(crate) fn all_user_themes() -> Vec { vec![ - rose_pine(), - night_owl(), andromeda(), - synthwave_84(), - palenight(), - dracula(), - solarized(), - nord(), - noctis(), ayu(), + dracula(), gruvbox(), + night_owl(), + noctis(), + nord(), + palenight(), + rose_pine(), + solarized(), + synthwave_84(), ] } diff --git a/crates/theme_importer/Cargo.toml b/crates/theme_importer/Cargo.toml index 23a53053cecd76a151fd29152f86c1a73a15ac67..2841839c0996b9bc25cb559fe01239430e06fad3 100644 --- a/crates/theme_importer/Cargo.toml +++ b/crates/theme_importer/Cargo.toml @@ -4,14 +4,13 @@ version = "0.1.0" edition = "2021" publish = false -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] any_ascii = "0.3.2" anyhow.workspace = true clap = { version = "4.4", features = ["derive"] } convert_case = "0.6.0" -gpui = { package = "gpui2", path = "../gpui2" } +gpui = { package = "gpui2", path = "../gpui2", features = ["allow-multiple-gpui-versions"] } +gpui1 = { package = "gpui", path = "../gpui" } indexmap = { version = "1.6.2", features = ["serde"] } json_comments = "0.2.2" log.workspace = true @@ -21,4 +20,5 @@ serde.workspace = true simplelog = "0.9" strum = { version = "0.25.0", features = ["derive"] } theme = { package = "theme2", path = "../theme2", features = ["importing-themes"] } +theme1 = { package = "theme", path = "../theme" } uuid.workspace = true diff --git a/crates/theme_importer/src/assets.rs b/crates/theme_importer/src/assets.rs new file mode 100644 index 0000000000000000000000000000000000000000..9009b4c144cd7b73132a7cc3246bab627e4894bc --- /dev/null +++ b/crates/theme_importer/src/assets.rs @@ -0,0 +1,26 @@ +use std::borrow::Cow; + +use anyhow::{anyhow, Result}; +use gpui::{AssetSource, SharedString}; +use rust_embed::RustEmbed; + +#[derive(RustEmbed)] +#[folder = "../../assets"] +#[include = "fonts/**/*"] +#[exclude = "*.DS_Store"] +pub struct Assets; + +impl AssetSource for Assets { + fn load(&self, path: &str) -> Result> { + Self::get(path) + .map(|f| f.data) + .ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path)) + } + + fn list(&self, path: &str) -> Result> { + Ok(Self::iter() + .filter(|p| p.starts_with(path)) + .map(SharedString::from) + .collect()) + } +} diff --git a/crates/theme_importer/src/main.rs b/crates/theme_importer/src/main.rs index 01ab1915718b45a5ff988a438ee9adf65e96301e..e6cf8952d15671875106252c1845bf1138142431 100644 --- a/crates/theme_importer/src/main.rs +++ b/crates/theme_importer/src/main.rs @@ -1,29 +1,36 @@ +mod assets; mod color; mod theme_printer; mod util; mod vscode; +mod zed1; +use std::collections::HashMap; use std::fs::{self, File}; use std::io::Write; use std::path::PathBuf; use std::process::Command; use std::str::FromStr; +use std::sync::Arc; use any_ascii::any_ascii; use anyhow::{anyhow, Context, Result}; use clap::Parser; use convert_case::{Case, Casing}; -use gpui::serde_json; +use gpui::{serde_json, AssetSource}; use indexmap::IndexMap; use json_comments::StripComments; use log::LevelFilter; use serde::Deserialize; use simplelog::{TermLogger, TerminalMode}; -use theme::{Appearance, UserThemeFamily}; +use theme::{Appearance, UserTheme, UserThemeFamily}; +use theme1::Theme as Zed1Theme; +use crate::assets::Assets; use crate::theme_printer::UserThemeFamilyPrinter; use crate::vscode::VsCodeTheme; use crate::vscode::VsCodeThemeConverter; +use crate::zed1::Zed1ThemeConverter; #[derive(Debug, Deserialize)] struct FamilyMetadata { @@ -66,6 +73,10 @@ pub struct ThemeMetadata { #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Args { + /// Whether to import Zed1 themes. + #[arg(long)] + zed1: bool, + /// Whether to warn when values are missing from the theme. #[arg(long)] warn_on_missing: bool, @@ -176,6 +187,102 @@ fn main() -> Result<()> { theme_families.push(theme_family); } + if args.zed1 { + let zed1_themes_path = PathBuf::from_str("assets/themes")?; + + let zed1_theme_familes = [ + "Andromeda", + "Atelier", + "Ayu", + "Gruvbox", + "One", + "Rosé Pine", + "Sandcastle", + "Solarized", + "Summercamp", + ]; + + let mut zed1_themes_by_family: HashMap> = HashMap::from_iter( + zed1_theme_familes + .into_iter() + .map(|family| (family.to_string(), Vec::new())), + ); + + let platform = gpui1::platform::current::platform(); + let zed1_font_cache = Arc::new(gpui1::FontCache::new(platform.fonts())); + + let mut embedded_fonts = Vec::new(); + for font_path in Assets.list("fonts")? { + if font_path.ends_with(".ttf") { + let font_bytes = Assets.load(&font_path)?.to_vec(); + embedded_fonts.push(Arc::from(font_bytes)); + } + } + + platform.fonts().add_fonts(&embedded_fonts)?; + + for entry in fs::read_dir(&zed1_themes_path)? { + let entry = entry?; + + if entry.file_type()?.is_dir() { + continue; + } + + match entry.path().extension() { + None => continue, + Some(extension) => { + if extension != "json" { + continue; + } + } + } + + let theme_file_path = entry.path(); + + let theme_file = match File::open(&theme_file_path) { + Ok(file) => file, + Err(_) => { + log::info!("Failed to open file at path: {:?}", theme_file_path); + continue; + } + }; + + let theme_without_comments = StripComments::new(theme_file); + + let zed1_theme: Zed1Theme = + gpui1::fonts::with_font_cache(zed1_font_cache.clone(), || { + serde_json::from_reader(theme_without_comments) + .context(format!("failed to parse theme {theme_file_path:?}")) + })?; + + let theme_name = zed1_theme.meta.name.clone(); + + let converter = Zed1ThemeConverter::new(zed1_theme); + + let theme = converter.convert()?; + + let Some((_, themes_for_family)) = zed1_themes_by_family + .iter_mut() + .find(|(family, _)| theme_name.starts_with(*family)) + else { + log::warn!("No theme family found for '{}'.", theme_name); + continue; + }; + + themes_for_family.push(theme); + } + + for (family, themes) in zed1_themes_by_family { + let theme_family = UserThemeFamily { + name: format!("{family} (Zed1)"), + author: "Zed Industries".to_string(), + themes, + }; + + theme_families.push(theme_family); + } + } + let themes_output_path = PathBuf::from_str(OUT_PATH)?; if !themes_output_path.exists() { @@ -188,7 +295,10 @@ fn main() -> Result<()> { let mut theme_modules = Vec::new(); for theme_family in theme_families { - let theme_family_slug = any_ascii(&theme_family.name).to_case(Case::Snake); + let theme_family_slug = any_ascii(&theme_family.name) + .replace("(", "") + .replace(")", "") + .to_case(Case::Snake); let mut output_file = File::create(themes_output_path.join(format!("{theme_family_slug}.rs")))?; @@ -222,6 +332,8 @@ fn main() -> Result<()> { theme_modules.push(theme_family_slug); } + theme_modules.sort(); + let themes_vector_contents = format!( r#" use crate::UserThemeFamily; diff --git a/crates/theme_importer/src/zed1.rs b/crates/theme_importer/src/zed1.rs new file mode 100644 index 0000000000000000000000000000000000000000..11bc94497ff276db0dab108e611b855f8c3b68ed --- /dev/null +++ b/crates/theme_importer/src/zed1.rs @@ -0,0 +1,3 @@ +mod converter; + +pub use converter::*; diff --git a/crates/theme_importer/src/zed1/converter.rs b/crates/theme_importer/src/zed1/converter.rs new file mode 100644 index 0000000000000000000000000000000000000000..1a5f7af8b7020f59f292f561c9912af095e364be --- /dev/null +++ b/crates/theme_importer/src/zed1/converter.rs @@ -0,0 +1,176 @@ +use anyhow::Result; +use gpui::{Hsla, Rgba}; +use gpui1::color::Color as Zed1Color; +use gpui1::fonts::HighlightStyle as Zed1HighlightStyle; +use theme::{ + Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, + UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeStylesRefinement, +}; +use theme1::Theme as Zed1Theme; + +fn zed1_color_to_hsla(color: Zed1Color) -> Hsla { + let r = color.r as f32 / 255.; + let g = color.g as f32 / 255.; + let b = color.b as f32 / 255.; + let a = color.a as f32 / 255.; + + Hsla::from(Rgba { r, g, b, a }) +} + +fn zed1_highlight_style_to_user_highlight_style( + highlight: Zed1HighlightStyle, +) -> UserHighlightStyle { + UserHighlightStyle { + color: highlight.color.map(zed1_color_to_hsla), + font_style: highlight.italic.map(|is_italic| { + if is_italic { + UserFontStyle::Italic + } else { + UserFontStyle::Normal + } + }), + font_weight: highlight.weight.map(|weight| UserFontWeight(weight.0)), + } +} + +pub struct Zed1ThemeConverter { + theme: Zed1Theme, +} + +impl Zed1ThemeConverter { + pub fn new(theme: Zed1Theme) -> Self { + Self { theme } + } + + pub fn convert(self) -> Result { + let appearance = match self.theme.meta.is_light { + true => Appearance::Light, + false => Appearance::Dark, + }; + + let status_colors_refinement = self.convert_status_colors()?; + let theme_colors_refinement = self.convert_theme_colors()?; + let syntax_theme = self.convert_syntax_theme()?; + + Ok(UserTheme { + name: format!("{} (Zed1)", self.theme.meta.name), + appearance, + styles: UserThemeStylesRefinement { + colors: theme_colors_refinement, + status: status_colors_refinement, + syntax: Some(syntax_theme), + }, + }) + } + + fn convert_status_colors(&self) -> Result { + fn convert(color: Zed1Color) -> Option { + Some(zed1_color_to_hsla(color)) + } + + let diff_style = self.theme.editor.diff.clone(); + + Ok(StatusColorsRefinement { + created: convert(diff_style.inserted), + modified: convert(diff_style.modified), + deleted: convert(diff_style.deleted), + ..Default::default() + }) + } + + fn convert_theme_colors(&self) -> Result { + fn convert(color: Zed1Color) -> Option { + Some(zed1_color_to_hsla(color)) + } + + let tab_bar = self.theme.workspace.tab_bar.clone(); + let active_tab = self.theme.workspace.tab_bar.tab_style(true, true).clone(); + let inactive_tab = self.theme.workspace.tab_bar.tab_style(true, false).clone(); + let toolbar = self.theme.workspace.toolbar.clone(); + let scrollbar = self.theme.editor.scrollbar.clone(); + + let zed1_titlebar_border = convert(self.theme.titlebar.container.border.color); + + Ok(ThemeColorsRefinement { + border: zed1_titlebar_border, + border_variant: zed1_titlebar_border, + background: convert(self.theme.workspace.background), + title_bar_background: self + .theme + .titlebar + .container + .background_color + .map(zed1_color_to_hsla), + status_bar_background: self + .theme + .workspace + .status_bar + .container + .background_color + .map(zed1_color_to_hsla), + text: convert(self.theme.editor.text_color), + tab_bar_background: tab_bar.container.background_color.map(zed1_color_to_hsla), + tab_active_background: active_tab + .container + .background_color + .map(zed1_color_to_hsla), + tab_inactive_background: inactive_tab + .container + .background_color + .map(zed1_color_to_hsla), + toolbar_background: toolbar.container.background_color.map(zed1_color_to_hsla), + editor_foreground: convert(self.theme.editor.text_color), + editor_background: convert(self.theme.editor.background), + editor_gutter_background: convert(self.theme.editor.gutter_background), + editor_line_number: convert(self.theme.editor.line_number), + editor_active_line_number: convert(self.theme.editor.line_number_active), + editor_wrap_guide: convert(self.theme.editor.wrap_guide), + editor_active_wrap_guide: convert(self.theme.editor.active_wrap_guide), + scrollbar_track_background: scrollbar.track.background_color.map(zed1_color_to_hsla), + scrollbar_track_border: convert(scrollbar.track.border.color), + scrollbar_thumb_background: scrollbar.thumb.background_color.map(zed1_color_to_hsla), + scrollbar_thumb_border: convert(scrollbar.thumb.border.color), + scrollbar_thumb_hover_background: scrollbar + .thumb + .background_color + .map(zed1_color_to_hsla), + terminal_background: convert(self.theme.terminal.background), + terminal_ansi_bright_black: convert(self.theme.terminal.bright_black), + terminal_ansi_bright_red: convert(self.theme.terminal.bright_red), + terminal_ansi_bright_green: convert(self.theme.terminal.bright_green), + terminal_ansi_bright_yellow: convert(self.theme.terminal.bright_yellow), + terminal_ansi_bright_blue: convert(self.theme.terminal.bright_blue), + terminal_ansi_bright_magenta: convert(self.theme.terminal.bright_magenta), + terminal_ansi_bright_cyan: convert(self.theme.terminal.bright_cyan), + terminal_ansi_bright_white: convert(self.theme.terminal.bright_white), + terminal_ansi_black: convert(self.theme.terminal.black), + terminal_ansi_red: convert(self.theme.terminal.red), + terminal_ansi_green: convert(self.theme.terminal.green), + terminal_ansi_yellow: convert(self.theme.terminal.yellow), + terminal_ansi_blue: convert(self.theme.terminal.blue), + terminal_ansi_magenta: convert(self.theme.terminal.magenta), + terminal_ansi_cyan: convert(self.theme.terminal.cyan), + terminal_ansi_white: convert(self.theme.terminal.white), + ..Default::default() + }) + } + + fn convert_syntax_theme(&self) -> Result { + Ok(UserSyntaxTheme { + highlights: self + .theme + .editor + .syntax + .highlights + .clone() + .into_iter() + .map(|(name, highlight_style)| { + ( + name, + zed1_highlight_style_to_user_highlight_style(highlight_style), + ) + }) + .collect(), + }) + } +} diff --git a/crates/util/Cargo.toml b/crates/util/Cargo.toml index cfbd7551f9b27665857954ab0e9926d3fbe6702b..4320983c2f761034ce93ea94ac26cd1ff826663c 100644 --- a/crates/util/Cargo.toml +++ b/crates/util/Cargo.toml @@ -11,6 +11,12 @@ doctest = true [features] test-support = ["tempdir", "git2"] +# Suppress a panic when both GPUI1 and GPUI2 are loaded. +# +# This is used in the `theme_importer` where we need to depend on both +# GPUI1 and GPUI2 in order to convert Zed1 themes to Zed2 themes. +allow-multiple-gpui-versions = [] + [dependencies] anyhow.workspace = true backtrace = "0.3" diff --git a/crates/util/src/util.rs b/crates/util/src/util.rs index 3f2371121ccb2c8de641d0d7f4c8b7175ac6ba72..ac96cc665209002c47019c5319181d07488b392b 100644 --- a/crates/util/src/util.rs +++ b/crates/util/src/util.rs @@ -13,10 +13,12 @@ use std::{ ops::{AddAssign, Range, RangeInclusive}, panic::Location, pin::Pin, - sync::atomic::AtomicU32, task::{Context, Poll}, }; +#[cfg(not(feature = "allow-multiple-gpui-versions"))] +use std::sync::atomic::AtomicU32; + pub use backtrace::Backtrace; use futures::Future; use rand::{seq::SliceRandom, Rng}; @@ -434,15 +436,18 @@ impl RangeExt for RangeInclusive { } } +#[cfg(not(feature = "allow-multiple-gpui-versions"))] static GPUI_LOADED: AtomicU32 = AtomicU32::new(0); pub fn gpui2_loaded() { + #[cfg(not(feature = "allow-multiple-gpui-versions"))] if GPUI_LOADED.fetch_add(2, std::sync::atomic::Ordering::SeqCst) != 0 { panic!("=========\nYou are loading both GPUI1 and GPUI2 in the same build!\nFix Your Dependencies with cargo tree!\n=========") } } pub fn gpui1_loaded() { + #[cfg(not(feature = "allow-multiple-gpui-versions"))] if GPUI_LOADED.fetch_add(1, std::sync::atomic::Ordering::SeqCst) != 0 { panic!("=========\nYou are loading both GPUI1 and GPUI2 in the same build!\nFix Your Dependencies with cargo tree!\n=========") } From 764a2755e259eb090ade88fe328e302a7c53f457 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 22 Dec 2023 22:56:35 +0200 Subject: [PATCH 300/644] Fix multibuffer scroll by reordering z-index of its elements 1. Blocks (with their headers) and mouse listeners should be drawn together otherwise either starts to loose mouse events. 2. Scrollbar should be above all to match zed1 look and avoid buffer headers popping slightly to the right of the scrollbar. --- crates/editor2/src/element.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 294cc2c4e3eeb96921c6e339b12cfb426a9b6661..9e1d8e641f0964319e123476fa608484ce6320ea 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -2840,23 +2840,26 @@ impl Element for EditorElement { } self.paint_text(text_bounds, &mut layout, cx); - cx.with_z_index(0, |cx| { - self.paint_mouse_listeners(bounds, gutter_bounds, text_bounds, &layout, cx); - }); - - cx.with_z_index(1, |cx| self.paint_scrollbar(bounds, &mut layout, cx)); - if !layout.blocks.is_empty() { - cx.with_z_index(2, |cx| { + cx.with_z_index(0, |cx| { cx.with_element_id(Some("editor_blocks"), |cx| { self.paint_blocks(bounds, &mut layout, cx); + self.paint_mouse_listeners( + bounds, + gutter_bounds, + text_bounds, + &layout, + cx, + ); }); }) } - cx.with_z_index(3, |cx| { + cx.with_z_index(1, |cx| { self.paint_overlays(text_bounds, &mut layout, cx); }); + + cx.with_z_index(2, |cx| self.paint_scrollbar(bounds, &mut layout, cx)); }); }) } From b501f4eafc782c5a186e03453461f81458cf0b06 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 17:37:53 -0500 Subject: [PATCH 301/644] Begin porting Zed1 themes to Zed2 (#3793) This PR is a first pass at porting the Zed1 themes to Zed2. For the initial release of Zed2 we'll be shipping just the themes that existed in Zed1, ported to Zed2. The new themes that were previously added just in Zed2 have been removed. Release Notes: - N/A --- crates/file_finder2/src/file_finder.rs | 5 +- crates/theme2/src/registry.rs | 19 +- crates/theme2/src/themes/andromeda.rs | 768 +- crates/theme2/src/themes/atelier.rs | 7159 +++++++++++++++++ crates/theme2/src/themes/ayu.rs | 666 +- crates/theme2/src/themes/dracula.rs | 250 - crates/theme2/src/themes/gruvbox.rs | 1390 ++-- crates/theme2/src/themes/mod.rs | 30 +- crates/theme2/src/themes/night_owl.rs | 547 -- crates/theme2/src/themes/noctis.rs | 3110 ------- crates/theme2/src/themes/nord.rs | 277 - .../src/themes/{palenight.rs => one.rs} | 718 +- crates/theme2/src/themes/rose_pine.rs | 791 +- crates/theme2/src/themes/sandcastle.rs | 353 + crates/theme2/src/themes/solarized.rs | 487 +- crates/theme2/src/themes/summercamp.rs | 353 + crates/theme2/src/themes/synthwave_84.rs | 248 - crates/theme_importer/src/main.rs | 278 +- crates/theme_importer/src/theme_printer.rs | 1 + crates/theme_importer/src/zed1/converter.rs | 56 +- crates/workspace2/src/dock.rs | 1 + 21 files changed, 10746 insertions(+), 6761 deletions(-) create mode 100644 crates/theme2/src/themes/atelier.rs delete mode 100644 crates/theme2/src/themes/dracula.rs delete mode 100644 crates/theme2/src/themes/night_owl.rs delete mode 100644 crates/theme2/src/themes/noctis.rs delete mode 100644 crates/theme2/src/themes/nord.rs rename crates/theme2/src/themes/{palenight.rs => one.rs} (50%) create mode 100644 crates/theme2/src/themes/sandcastle.rs create mode 100644 crates/theme2/src/themes/summercamp.rs delete mode 100644 crates/theme2/src/themes/synthwave_84.rs diff --git a/crates/file_finder2/src/file_finder.rs b/crates/file_finder2/src/file_finder.rs index 369128a753754f3e53de84f2701fc74a947f9f1a..7410ed765886843026d60779bb1f413548352d7a 100644 --- a/crates/file_finder2/src/file_finder.rs +++ b/crates/file_finder2/src/file_finder.rs @@ -721,10 +721,7 @@ impl PickerDelegate for FileFinderDelegate { .child( v_stack() .child(HighlightedLabel::new(file_name, file_name_positions)) - .child( - HighlightedLabel::new(full_path, full_path_positions) - .color(Color::Muted), - ), + .child(HighlightedLabel::new(full_path, full_path_positions)), ), ) } diff --git a/crates/theme2/src/registry.rs b/crates/theme2/src/registry.rs index ec88fecd99beab5740aeab7b2db5dec501ef7dcb..ac94d93bcd3784483f8cd88f14ba94a05ad6750b 100644 --- a/crates/theme2/src/registry.rs +++ b/crates/theme2/src/registry.rs @@ -6,8 +6,8 @@ use gpui::{HighlightStyle, SharedString}; use refineable::Refineable; use crate::{ - one_themes::one_family, zed_pro_family, Appearance, PlayerColors, StatusColors, SyntaxTheme, - SystemColors, Theme, ThemeColors, ThemeFamily, ThemeStyles, UserTheme, UserThemeFamily, + Appearance, PlayerColors, StatusColors, SyntaxTheme, SystemColors, Theme, ThemeColors, + ThemeFamily, ThemeStyles, UserTheme, UserThemeFamily, }; #[derive(Debug, Clone)] @@ -34,7 +34,7 @@ impl ThemeRegistry { } #[allow(unused)] - fn insert_user_theme_familes(&mut self, families: impl IntoIterator) { + fn insert_user_theme_families(&mut self, families: impl IntoIterator) { for family in families.into_iter() { self.insert_user_themes(family.themes); } @@ -117,18 +117,23 @@ impl ThemeRegistry { pub fn load_user_themes(&mut self) { #[cfg(not(feature = "importing-themes"))] - self.insert_user_theme_familes(crate::all_user_themes()); + self.insert_user_theme_families(crate::all_user_themes()); } } impl Default for ThemeRegistry { fn default() -> Self { - let mut this = Self { + let mut registry = Self { themes: HashMap::default(), }; - this.insert_theme_families([zed_pro_family(), one_family()]); + // We're loading our new versions of the One themes by default, as + // we need them to be loaded for tests. + // + // These themes will get overwritten when `load_user_themes` is called + // when Zed starts, so the One variants used will be the ones ported from Zed1. + registry.insert_theme_families([crate::one_themes::one_family()]); - this + registry } } diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index 513b6f02123552f35ee2606bfd74332265f9d736..5affa63fb09d866ba2e92be3ad326016c0448495 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -12,442 +12,342 @@ use crate::{ pub fn andromeda() -> UserThemeFamily { UserThemeFamily { name: "Andromeda".into(), - author: "Eliver Lara (EliverLara)".into(), - themes: vec![ - UserTheme { - name: "Andromeda".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x1b1d23ff).into()), - border_variant: Some(rgba(0x1b1d23ff).into()), - border_focused: Some(rgba(0x746f77ff).into()), - border_selected: Some(rgba(0x1b1d23ff).into()), - border_transparent: Some(rgba(0x1b1d23ff).into()), - border_disabled: Some(rgba(0x1b1d23ff).into()), - elevated_surface_background: Some(rgba(0x2b303bff).into()), - surface_background: Some(rgba(0x23262eff).into()), - background: Some(rgba(0x23262eff).into()), - element_background: Some(rgba(0x00e8c5cc).into()), - element_hover: Some(rgba(0x23262eff).into()), - element_selected: Some(rgba(0x23262eff).into()), - drop_target_background: Some(rgba(0x3a404eff).into()), - ghost_element_hover: Some(rgba(0x23262eff).into()), - ghost_element_selected: Some(rgba(0x23262eff).into()), - text: Some(rgba(0xd5ced9ff).into()), - text_muted: Some(rgba(0x746f77ff).into()), - status_bar_background: Some(rgba(0x23262eff).into()), - title_bar_background: Some(rgba(0x23262eff).into()), - toolbar_background: Some(rgba(0x23262eff).into()), - tab_bar_background: Some(rgba(0x23262eff).into()), - tab_inactive_background: Some(rgba(0x23262eff).into()), - tab_active_background: Some(rgba(0x23262eff).into()), - scrollbar_thumb_background: Some(rgba(0x3a3f4c77).into()), - scrollbar_thumb_hover_background: Some(rgba(0x3a3f4caa).into()), - scrollbar_thumb_border: Some(rgba(0x3a3f4c77).into()), - scrollbar_track_background: Some(rgba(0x23262eff).into()), - scrollbar_track_border: Some(rgba(0x1b1d23ff).into()), - editor_foreground: Some(rgba(0xd5ced9ff).into()), - editor_background: Some(rgba(0x23262eff).into()), - editor_gutter_background: Some(rgba(0x23262eff).into()), - editor_line_number: Some(rgba(0x746f77ff).into()), - editor_active_line_number: Some(rgba(0xd5ced9ff).into()), - editor_wrap_guide: Some(rgba(0x1b1d23ff).into()), - editor_active_wrap_guide: Some(rgba(0x1b1d23ff).into()), - terminal_ansi_bright_red: Some(rgba(0xee5d43ff).into()), - terminal_ansi_bright_green: Some(rgba(0x96e072ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xffe66dff).into()), - terminal_ansi_bright_blue: Some(rgba(0x7cb7ffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xff00aaff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x00e8c6ff).into()), - terminal_ansi_red: Some(rgba(0xee5d43ff).into()), - terminal_ansi_green: Some(rgba(0x96e072ff).into()), - terminal_ansi_yellow: Some(rgba(0xffe66dff).into()), - terminal_ansi_blue: Some(rgba(0x7cb7ffff).into()), - terminal_ansi_magenta: Some(rgba(0xff00aaff).into()), - terminal_ansi_cyan: Some(rgba(0x00e8c6ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - created: Some(rgba(0x9bc53dbb).into()), - deleted: Some(rgba(0xfc644dbb).into()), - error: Some(rgba(0xfc644dff).into()), - hidden: Some(rgba(0x746f77ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x555555ff).into()), - modified: Some(rgba(0x5bc0ebbb).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "attribute".into(), - UserHighlightStyle { - color: Some(rgba(0xffe66dff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0xa0a1a7cc).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0xa0a1a7cc).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xee5d43ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xf92672ff).into()), - ..Default::default() - }, - ), - ( - "emphasis".into(), - UserHighlightStyle { - color: Some(rgba(0xc74dedff).into()), - ..Default::default() - }, - ), - ( - "emphasis.strong".into(), - UserHighlightStyle { - color: Some(rgba(0xf39c12ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0xffe66dff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xc74dedff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0xf39c12ff).into()), - ..Default::default() - }, - ), - ( - "operator".into(), - UserHighlightStyle { - color: Some(rgba(0xee5d43ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xf92672ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xffe66dff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0x00e8c6ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0x00e8c6ff).into()), - ..Default::default() - }, - ), - ], - }), + author: "Zed Industries".into(), + themes: vec![UserTheme { + name: "Andromeda".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x2b2f39ff).into()), + border_variant: Some(rgba(0x2b2f39ff).into()), + elevated_surface_background: Some(rgba(0x262a33ff).into()), + background: Some(rgba(0x262a33ff).into()), + panel_background: Some(rgba(0x21242bff).into()), + element_hover: Some(rgba(0x2b2f3980).into()), + element_selected: Some(rgba(0x383b4580).into()), + text: Some(rgba(0xaca8aeff).into()), + text_muted: Some(rgba(0x474a53ff).into()), + status_bar_background: Some(rgba(0x262a33ff).into()), + title_bar_background: Some(rgba(0x262a33ff).into()), + toolbar_background: Some(rgba(0x1e2025ff).into()), + tab_bar_background: Some(rgba(0x21242bff).into()), + tab_inactive_background: Some(rgba(0x21242bff).into()), + tab_active_background: Some(rgba(0x1e2025ff).into()), + scrollbar_thumb_background: Some(rgba(0xf7f7f84d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xf7f7f84d).into()), + scrollbar_thumb_border: Some(rgba(0x21232aff).into()), + scrollbar_track_border: Some(rgba(0x21232aff).into()), + editor_foreground: Some(rgba(0xf7f7f8ff).into()), + editor_background: Some(rgba(0x1e2025ff).into()), + editor_gutter_background: Some(rgba(0x1e2025ff).into()), + editor_line_number: Some(rgba(0xf7f7f859).into()), + editor_active_line_number: Some(rgba(0xf7f7f8ff).into()), + editor_wrap_guide: Some(rgba(0xf7f7f80d).into()), + editor_active_wrap_guide: Some(rgba(0xf7f7f81a).into()), + terminal_background: Some(rgba(0x1e2025ff).into()), + terminal_ansi_bright_black: Some(rgba(0x40434cff).into()), + terminal_ansi_bright_red: Some(rgba(0x8e103aff).into()), + terminal_ansi_bright_green: Some(rgba(0x457c38ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x958435ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x1b5148ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x682781ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x018169ff).into()), + terminal_ansi_bright_white: Some(rgba(0xf7f7f8ff).into()), + terminal_ansi_black: Some(rgba(0x1e2025ff).into()), + terminal_ansi_red: Some(rgba(0xf82872ff).into()), + terminal_ansi_green: Some(rgba(0x96df72ff).into()), + terminal_ansi_yellow: Some(rgba(0xfee56dff).into()), + terminal_ansi_blue: Some(rgba(0x11a793ff).into()), + terminal_ansi_magenta: Some(rgba(0xc74decff).into()), + terminal_ansi_cyan: Some(rgba(0x09e7c6ff).into()), + terminal_ansi_white: Some(rgba(0xf7f7f8ff).into()), + ..Default::default() }, - }, - UserTheme { - name: "Andromeda Bordered".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x1b1d23ff).into()), - border_variant: Some(rgba(0x1b1d23ff).into()), - border_focused: Some(rgba(0x746f77ff).into()), - border_selected: Some(rgba(0x1b1d23ff).into()), - border_transparent: Some(rgba(0x1b1d23ff).into()), - border_disabled: Some(rgba(0x1b1d23ff).into()), - elevated_surface_background: Some(rgba(0x2b303bff).into()), - surface_background: Some(rgba(0x23262eff).into()), - background: Some(rgba(0x262a33ff).into()), - element_background: Some(rgba(0x00e8c5cc).into()), - element_hover: Some(rgba(0x23262eff).into()), - element_selected: Some(rgba(0x23262eff).into()), - drop_target_background: Some(rgba(0x3a404eff).into()), - ghost_element_hover: Some(rgba(0x23262eff).into()), - ghost_element_selected: Some(rgba(0x23262eff).into()), - text: Some(rgba(0xd5ced9ff).into()), - text_muted: Some(rgba(0x746f77ff).into()), - status_bar_background: Some(rgba(0x23262eff).into()), - title_bar_background: Some(rgba(0x23262eff).into()), - toolbar_background: Some(rgba(0x262a33ff).into()), - tab_bar_background: Some(rgba(0x23262eff).into()), - tab_inactive_background: Some(rgba(0x23262eff).into()), - tab_active_background: Some(rgba(0x262a33ff).into()), - scrollbar_thumb_background: Some(rgba(0x3a3f4c77).into()), - scrollbar_thumb_hover_background: Some(rgba(0x3a3f4caa).into()), - scrollbar_thumb_border: Some(rgba(0x3a3f4c77).into()), - scrollbar_track_background: Some(rgba(0x262a33ff).into()), - scrollbar_track_border: Some(rgba(0x1b1d23ff).into()), - editor_foreground: Some(rgba(0xd5ced9ff).into()), - editor_background: Some(rgba(0x262a33ff).into()), - editor_gutter_background: Some(rgba(0x262a33ff).into()), - editor_line_number: Some(rgba(0x746f77ff).into()), - editor_active_line_number: Some(rgba(0xd5ced9ff).into()), - editor_wrap_guide: Some(rgba(0x1b1d23ff).into()), - editor_active_wrap_guide: Some(rgba(0x1b1d23ff).into()), - terminal_ansi_bright_red: Some(rgba(0xee5d43ff).into()), - terminal_ansi_bright_green: Some(rgba(0x96e072ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xffe66dff).into()), - terminal_ansi_bright_blue: Some(rgba(0x7cb7ffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xff00aaff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x00e8c6ff).into()), - terminal_ansi_red: Some(rgba(0xee5d43ff).into()), - terminal_ansi_green: Some(rgba(0x96e072ff).into()), - terminal_ansi_yellow: Some(rgba(0xffe66dff).into()), - terminal_ansi_blue: Some(rgba(0x7cb7ffff).into()), - terminal_ansi_magenta: Some(rgba(0xff00aaff).into()), - terminal_ansi_cyan: Some(rgba(0x00e8c6ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - created: Some(rgba(0x9bc53dbb).into()), - deleted: Some(rgba(0xfc644dbb).into()), - error: Some(rgba(0xfc644dff).into()), - hidden: Some(rgba(0x746f77ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x555555ff).into()), - modified: Some(rgba(0x5bc0ebbb).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "attribute".into(), - UserHighlightStyle { - color: Some(rgba(0xffe66dff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0xa0a1a7cc).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0xa0a1a7cc).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xee5d43ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xf92672ff).into()), - ..Default::default() - }, - ), - ( - "emphasis".into(), - UserHighlightStyle { - color: Some(rgba(0xc74dedff).into()), - ..Default::default() - }, - ), - ( - "emphasis.strong".into(), - UserHighlightStyle { - color: Some(rgba(0xf39c12ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0xffe66dff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xc74dedff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0xf39c12ff).into()), - ..Default::default() - }, - ), - ( - "operator".into(), - UserHighlightStyle { - color: Some(rgba(0xee5d43ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xf92672ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x96e072ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xffe66dff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0x00e8c6ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0x00e8c6ff).into()), - ..Default::default() - }, - ), - ], - }), + status: StatusColorsRefinement { + created: Some(rgba(0x96df72ff).into()), + deleted: Some(rgba(0xcd1d5aff).into()), + error: Some(rgba(0xf82872ff).into()), + modified: Some(rgba(0xfee56dff).into()), + success: Some(rgba(0xf7f7f8ff).into()), + warning: Some(rgba(0xfee56dff).into()), + ..Default::default() }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x11a793ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x96df72ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0xafabb1ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0xafabb1ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x96df72ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x11a793ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xf7f7f8ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x11a793ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x11a793ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xf29c14ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0xfee56dff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x618399ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x11a793ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x11a793ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xf29c14ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x96df72ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0x96df72ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0xf29c14ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x315f70ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xf7f7f8ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xf7f7f8ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0x11a793ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xd8d5dbff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0xd8d5dbff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0xd8d5dbff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xd8d5dbff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xd8d5dbff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0xf29c14ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0xafabb1ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0xf29c14ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xf29c14ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0xf29c14ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x11a793ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xf29c14ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xf7f7f8ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0x09e7c6ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xf7f7f8ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x11a793ff).into()), + ..Default::default() + }, + ), + ], + }), }, - ], + }], } } diff --git a/crates/theme2/src/themes/atelier.rs b/crates/theme2/src/themes/atelier.rs new file mode 100644 index 0000000000000000000000000000000000000000..f1ec02cb75764e7f85763ecfeae4aaf35fa553db --- /dev/null +++ b/crates/theme2/src/themes/atelier.rs @@ -0,0 +1,7159 @@ +// This file was generated by the `theme_importer`. +// Be careful when modifying it by hand. + +use gpui::rgba; + +#[allow(unused)] +use crate::{ + Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, + UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, +}; + +pub fn atelier() -> UserThemeFamily { + UserThemeFamily { + name: "Atelier".into(), + author: "Zed Industries".into(), + themes: vec![ + UserTheme { + name: "Atelier Estuary Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x969585ff).into()), + border_variant: Some(rgba(0x969585ff).into()), + elevated_surface_background: Some(rgba(0xc5c4b9ff).into()), + background: Some(rgba(0xc5c4b9ff).into()), + panel_background: Some(rgba(0xebeae3ff).into()), + element_hover: Some(rgba(0x96958580).into()), + element_selected: Some(rgba(0x8b8a7880).into()), + text: Some(rgba(0x61604fff).into()), + text_muted: Some(rgba(0x878573ff).into()), + status_bar_background: Some(rgba(0xc5c4b9ff).into()), + title_bar_background: Some(rgba(0xc5c4b9ff).into()), + toolbar_background: Some(rgba(0xf4f3ecff).into()), + tab_bar_background: Some(rgba(0xebeae3ff).into()), + tab_inactive_background: Some(rgba(0xebeae3ff).into()), + tab_active_background: Some(rgba(0xf4f3ecff).into()), + scrollbar_thumb_background: Some(rgba(0x22221b4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x22221b4d).into()), + scrollbar_thumb_border: Some(rgba(0xedece5ff).into()), + scrollbar_track_border: Some(rgba(0xedece5ff).into()), + editor_foreground: Some(rgba(0x302f27ff).into()), + editor_background: Some(rgba(0xf4f3ecff).into()), + editor_gutter_background: Some(rgba(0xf4f3ecff).into()), + editor_line_number: Some(rgba(0x22221b59).into()), + editor_active_line_number: Some(rgba(0x22221bff).into()), + editor_wrap_guide: Some(rgba(0x22221b0d).into()), + editor_active_wrap_guide: Some(rgba(0x22221b1a).into()), + terminal_background: Some(rgba(0xf4f3ecff).into()), + terminal_ansi_bright_black: Some(rgba(0x898775ff).into()), + terminal_ansi_bright_red: Some(rgba(0xe4af96ff).into()), + terminal_ansi_bright_green: Some(rgba(0xc0ca93ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xd7ca8dff).into()), + terminal_ansi_bright_blue: Some(rgba(0xa0d1b0ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xcfb4bcff).into()), + terminal_ansi_bright_cyan: Some(rgba(0xaecea1ff).into()), + terminal_ansi_bright_white: Some(rgba(0x22221bff).into()), + terminal_ansi_black: Some(rgba(0xf4f3ecff).into()), + terminal_ansi_red: Some(rgba(0xba6337ff).into()), + terminal_ansi_green: Some(rgba(0x7d9728ff).into()), + terminal_ansi_yellow: Some(rgba(0xa59810ff).into()), + terminal_ansi_blue: Some(rgba(0x38a166ff).into()), + terminal_ansi_magenta: Some(rgba(0x9d6c7cff).into()), + terminal_ansi_cyan: Some(rgba(0x5c9d49ff).into()), + terminal_ansi_white: Some(rgba(0x22221bff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x98ab54ff).into()), + deleted: Some(rgba(0xba6337ff).into()), + error: Some(rgba(0xba6337ff).into()), + modified: Some(rgba(0xa59810ff).into()), + success: Some(rgba(0x22221bff).into()), + warning: Some(rgba(0xa59810ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x38a166ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9728ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x878573ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x5f5e4eff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9728ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x38a166ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x22221bff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x38a166ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x38a166ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xae7315ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x36a166ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x36a166ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xa5980dff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x768962ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x5f9182ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x38a166ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xae7315ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9728ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xae7313ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x5f5e4eff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x879a72ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x22221bff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x302f27ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xba6236ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x302f27ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x5f5e4eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x5f5e4eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x302f27ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0x9d6c7cff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9726ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x5f5e4eff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x5b9d48ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0x9d6c7cff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9726ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x38a166ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xae7315ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x22221bff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xa5980dff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x302f27ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x5f9182ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xa5980dff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Forest Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x665f5cff).into()), + border_variant: Some(rgba(0x665f5cff).into()), + elevated_surface_background: Some(rgba(0x443c39ff).into()), + background: Some(rgba(0x443c39ff).into()), + panel_background: Some(rgba(0x27211eff).into()), + element_hover: Some(rgba(0x665f5c80).into()), + element_selected: Some(rgba(0x71696680).into()), + text: Some(rgba(0xa79f9dff).into()), + text_muted: Some(rgba(0x766e6bff).into()), + status_bar_background: Some(rgba(0x443c39ff).into()), + title_bar_background: Some(rgba(0x443c39ff).into()), + toolbar_background: Some(rgba(0x1b1918ff).into()), + tab_bar_background: Some(rgba(0x27211eff).into()), + tab_inactive_background: Some(rgba(0x27211eff).into()), + tab_active_background: Some(rgba(0x1b1918ff).into()), + scrollbar_thumb_background: Some(rgba(0xf1efee4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xf1efee4d).into()), + scrollbar_thumb_border: Some(rgba(0x251f1dff).into()), + scrollbar_track_border: Some(rgba(0x251f1dff).into()), + editor_foreground: Some(rgba(0xe6e2e0ff).into()), + editor_background: Some(rgba(0x1b1918ff).into()), + editor_gutter_background: Some(rgba(0x1b1918ff).into()), + editor_line_number: Some(rgba(0xf1efee59).into()), + editor_active_line_number: Some(rgba(0xf1efeeff).into()), + editor_wrap_guide: Some(rgba(0xf1efee0d).into()), + editor_active_wrap_guide: Some(rgba(0xf1efee1a).into()), + terminal_background: Some(rgba(0x1b1918ff).into()), + terminal_ansi_bright_black: Some(rgba(0x746c69ff).into()), + terminal_ansi_bright_red: Some(rgba(0x8c1223ff).into()), + terminal_ansi_bright_green: Some(rgba(0x3e491aff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x674115ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x213f78ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x662186ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x264958ff).into()), + terminal_ansi_bright_white: Some(rgba(0xf1efeeff).into()), + terminal_ansi_black: Some(rgba(0x1b1918ff).into()), + terminal_ansi_red: Some(rgba(0xf22d40ff).into()), + terminal_ansi_green: Some(rgba(0x7b9727ff).into()), + terminal_ansi_yellow: Some(rgba(0xc38419ff).into()), + terminal_ansi_blue: Some(rgba(0x417ee6ff).into()), + terminal_ansi_magenta: Some(rgba(0xc340f2ff).into()), + terminal_ansi_cyan: Some(rgba(0x3e97b8ff).into()), + terminal_ansi_white: Some(rgba(0xf1efeeff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x7b9727ff).into()), + deleted: Some(rgba(0xc82234ff).into()), + error: Some(rgba(0xf22d40ff).into()), + modified: Some(rgba(0xc38419ff).into()), + success: Some(rgba(0xf1efeeff).into()), + warning: Some(rgba(0xc38419ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9727ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x766e6bff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0xa8a19fff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9727ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xf1efeeff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xdf5321ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x407ee7ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x407ee7ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xc38418ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0xa87187ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x6666eaff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xdf5321ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9727ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xdf5320ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0xa8a19fff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x8f5b71ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xf1efeeff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xe6e2e0ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xf22c40ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xe6e2e0ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0xa8a19fff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0xa8a19fff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xe6e2e0ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xc33ff3ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9726ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0xa8a19fff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x3d97b8ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xc33ff3ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9726ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xdf5321ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xf1efeeff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xc38418ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xe6e2e0ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x6666eaff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xc38418ff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Savanna Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x8b968eff).into()), + border_variant: Some(rgba(0x8b968eff).into()), + elevated_surface_background: Some(rgba(0xbcc5bfff).into()), + background: Some(rgba(0xbcc5bfff).into()), + panel_background: Some(rgba(0xe3ebe6ff).into()), + element_hover: Some(rgba(0x8b968e80).into()), + element_selected: Some(rgba(0x7e8b8280).into()), + text: Some(rgba(0x546259ff).into()), + text_muted: Some(rgba(0x79877dff).into()), + status_bar_background: Some(rgba(0xbcc5bfff).into()), + title_bar_background: Some(rgba(0xbcc5bfff).into()), + toolbar_background: Some(rgba(0xecf4eeff).into()), + tab_bar_background: Some(rgba(0xe3ebe6ff).into()), + tab_inactive_background: Some(rgba(0xe3ebe6ff).into()), + tab_active_background: Some(rgba(0xecf4eeff).into()), + scrollbar_thumb_background: Some(rgba(0x171c194d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x171c194d).into()), + scrollbar_thumb_border: Some(rgba(0xe5ede7ff).into()), + scrollbar_track_border: Some(rgba(0xe5ede7ff).into()), + editor_foreground: Some(rgba(0x232a25ff).into()), + editor_background: Some(rgba(0xecf4eeff).into()), + editor_gutter_background: Some(rgba(0xecf4eeff).into()), + editor_line_number: Some(rgba(0x171c1959).into()), + editor_active_line_number: Some(rgba(0x171c19ff).into()), + editor_wrap_guide: Some(rgba(0x171c190d).into()), + editor_active_wrap_guide: Some(rgba(0x171c191a).into()), + terminal_background: Some(rgba(0xecf4eeff).into()), + terminal_ansi_bright_black: Some(rgba(0x7b897fff).into()), + terminal_ansi_bright_red: Some(rgba(0xdeae97ff).into()), + terminal_ansi_bright_green: Some(rgba(0xa5ccafff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xd3bd9aff).into()), + terminal_ansi_bright_blue: Some(rgba(0xa5c5c6ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xc2b7b1ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x9dcdcfff).into()), + terminal_ansi_bright_white: Some(rgba(0x171c19ff).into()), + terminal_ansi_black: Some(rgba(0xecf4eeff).into()), + terminal_ansi_red: Some(rgba(0xb1623aff).into()), + terminal_ansi_green: Some(rgba(0x499963ff).into()), + terminal_ansi_yellow: Some(rgba(0xa07e3cff).into()), + terminal_ansi_blue: Some(rgba(0x488c90ff).into()), + terminal_ansi_magenta: Some(rgba(0x867469ff).into()), + terminal_ansi_cyan: Some(rgba(0x1f9aa0ff).into()), + terminal_ansi_white: Some(rgba(0x171c19ff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x6fae80ff).into()), + deleted: Some(rgba(0xb1623aff).into()), + error: Some(rgba(0xb1623aff).into()), + modified: Some(rgba(0xa07e3cff).into()), + success: Some(rgba(0x171c19ff).into()), + warning: Some(rgba(0xa07e3cff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x488c90ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x499963ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x78877dff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x526057ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x499963ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x488c90ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x171c19ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x488c90ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x488c90ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0x9f713dff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x66847cff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x55859bff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x488c90ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0x9f713dff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x499963ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0x9f713cff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x526057ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x76958cff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x171c19ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x232a25ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xb16139ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x232a25ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x526057ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x526057ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x232a25ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0x867469ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x489963ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x526057ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x1c9aa0ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0x867469ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x489963ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x488c90ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0x9f713dff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x171c19ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x232a25ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x55859bff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Cave Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x56505eff).into()), + border_variant: Some(rgba(0x56505eff).into()), + elevated_surface_background: Some(rgba(0x3a353fff).into()), + background: Some(rgba(0x3a353fff).into()), + panel_background: Some(rgba(0x221f26ff).into()), + element_hover: Some(rgba(0x56505e80).into()), + element_selected: Some(rgba(0x605a6880).into()), + text: Some(rgba(0x898591ff).into()), + text_muted: Some(rgba(0x655f6dff).into()), + status_bar_background: Some(rgba(0x3a353fff).into()), + title_bar_background: Some(rgba(0x3a353fff).into()), + toolbar_background: Some(rgba(0x19171cff).into()), + tab_bar_background: Some(rgba(0x221f26ff).into()), + tab_inactive_background: Some(rgba(0x221f26ff).into()), + tab_active_background: Some(rgba(0x19171cff).into()), + scrollbar_thumb_background: Some(rgba(0xefecf44d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xefecf44d).into()), + scrollbar_thumb_border: Some(rgba(0x201e24ff).into()), + scrollbar_track_border: Some(rgba(0x201e24ff).into()), + editor_foreground: Some(rgba(0xe2dfe7ff).into()), + editor_background: Some(rgba(0x19171cff).into()), + editor_gutter_background: Some(rgba(0x19171cff).into()), + editor_line_number: Some(rgba(0xefecf459).into()), + editor_active_line_number: Some(rgba(0xefecf4ff).into()), + editor_wrap_guide: Some(rgba(0xefecf40d).into()), + editor_active_wrap_guide: Some(rgba(0xefecf41a).into()), + terminal_background: Some(rgba(0x19171cff).into()), + terminal_ansi_bright_black: Some(rgba(0x635d6bff).into()), + terminal_ansi_bright_red: Some(rgba(0x5c283cff).into()), + terminal_ansi_bright_green: Some(rgba(0x1f4747ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x4e3821ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x2d376fff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x60255bff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x26445eff).into()), + terminal_ansi_bright_white: Some(rgba(0xefecf4ff).into()), + terminal_ansi_black: Some(rgba(0x19171cff).into()), + terminal_ansi_red: Some(rgba(0xbe4678ff).into()), + terminal_ansi_green: Some(rgba(0x2c9292ff).into()), + terminal_ansi_yellow: Some(rgba(0xa06e3bff).into()), + terminal_ansi_blue: Some(rgba(0x576ddaff).into()), + terminal_ansi_magenta: Some(rgba(0xbf41bfff).into()), + terminal_ansi_cyan: Some(rgba(0x3a8bc6ff).into()), + terminal_ansi_white: Some(rgba(0xefecf4ff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x2c9292ff).into()), + deleted: Some(rgba(0x953a5fff).into()), + error: Some(rgba(0xbe4678ff).into()), + modified: Some(rgba(0xa06e3bff).into()), + success: Some(rgba(0xefecf4ff).into()), + warning: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddaff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x2c9292ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x655f6dff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x8b8792ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x2c9292ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddaff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xefecf4ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddaff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddaff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xaa573cff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddbff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddbff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x716998ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x955ae7ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddaff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xaa573cff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x2c9292ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xaa573cff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x8b8792ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x625887ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xefecf4ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xe2dfe7ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xbe4678ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xe2dfe7ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x8b8792ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x8b8792ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xe2dfe7ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xbf40bfff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x2a9292ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x8b8792ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x398bc6ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xbf40bfff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x2a9292ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddaff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xaa573cff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xefecf4ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xe2dfe7ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x955ae7ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Estuary Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x5d5c4cff).into()), + border_variant: Some(rgba(0x5d5c4cff).into()), + elevated_surface_background: Some(rgba(0x424136ff).into()), + background: Some(rgba(0x424136ff).into()), + panel_background: Some(rgba(0x2c2b23ff).into()), + element_hover: Some(rgba(0x5d5c4c80).into()), + element_selected: Some(rgba(0x67665580).into()), + text: Some(rgba(0x91907fff).into()), + text_muted: Some(rgba(0x6c6b5aff).into()), + status_bar_background: Some(rgba(0x424136ff).into()), + title_bar_background: Some(rgba(0x424136ff).into()), + toolbar_background: Some(rgba(0x22221bff).into()), + tab_bar_background: Some(rgba(0x2c2b23ff).into()), + tab_inactive_background: Some(rgba(0x2c2b23ff).into()), + tab_active_background: Some(rgba(0x22221bff).into()), + scrollbar_thumb_background: Some(rgba(0xf4f3ec4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xf4f3ec4d).into()), + scrollbar_thumb_border: Some(rgba(0x2a2922ff).into()), + scrollbar_track_border: Some(rgba(0x2a2922ff).into()), + editor_foreground: Some(rgba(0xe7e6dfff).into()), + editor_background: Some(rgba(0x22221bff).into()), + editor_gutter_background: Some(rgba(0x22221bff).into()), + editor_line_number: Some(rgba(0xf4f3ec59).into()), + editor_active_line_number: Some(rgba(0xf4f3ecff).into()), + editor_wrap_guide: Some(rgba(0xf4f3ec0d).into()), + editor_active_wrap_guide: Some(rgba(0xf4f3ec1a).into()), + terminal_background: Some(rgba(0x22221bff).into()), + terminal_ansi_bright_black: Some(rgba(0x6a6958ff).into()), + terminal_ansi_bright_red: Some(rgba(0x5c331fff).into()), + terminal_ansi_bright_green: Some(rgba(0x3f491aff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x514a14ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x234e34ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x4c373eff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x314c27ff).into()), + terminal_ansi_bright_white: Some(rgba(0xf4f3ecff).into()), + terminal_ansi_black: Some(rgba(0x22221bff).into()), + terminal_ansi_red: Some(rgba(0xba6237ff).into()), + terminal_ansi_green: Some(rgba(0x7d9727ff).into()), + terminal_ansi_yellow: Some(rgba(0xa59810ff).into()), + terminal_ansi_blue: Some(rgba(0x37a166ff).into()), + terminal_ansi_magenta: Some(rgba(0x9d6c7cff).into()), + terminal_ansi_cyan: Some(rgba(0x5b9d48ff).into()), + terminal_ansi_white: Some(rgba(0xf4f3ecff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x7d9727ff).into()), + deleted: Some(rgba(0x934e2dff).into()), + error: Some(rgba(0xba6237ff).into()), + modified: Some(rgba(0xa59810ff).into()), + success: Some(rgba(0xf4f3ecff).into()), + warning: Some(rgba(0xa59810ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x37a166ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9727ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x6c6b5aff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x929181ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9727ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x37a166ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xf4f3ecff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x37a166ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x37a166ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xae7315ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x36a166ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x36a166ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xa5980dff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x70825bff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x5f9182ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x37a166ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xae7315ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9727ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xae7313ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x929181ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x5f724cff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xf4f3ecff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xe7e6dfff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xba6236ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xe7e6dfff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x929181ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x929181ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xe7e6dfff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0x9d6c7cff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9726ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x929181ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x5b9d48ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0x9d6c7cff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9726ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x37a166ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xae7315ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xf4f3ecff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xa5980dff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xe7e6dfff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x5f9182ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xa5980dff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Sulphurpool Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x5c6485ff).into()), + border_variant: Some(rgba(0x5c6485ff).into()), + elevated_surface_background: Some(rgba(0x3e4769ff).into()), + background: Some(rgba(0x3e4769ff).into()), + panel_background: Some(rgba(0x262f51ff).into()), + element_hover: Some(rgba(0x5c648580).into()), + element_selected: Some(rgba(0x666e8f80).into()), + text: Some(rgba(0x959bb2ff).into()), + text_muted: Some(rgba(0x6b7394ff).into()), + status_bar_background: Some(rgba(0x3e4769ff).into()), + title_bar_background: Some(rgba(0x3e4769ff).into()), + toolbar_background: Some(rgba(0x202746ff).into()), + tab_bar_background: Some(rgba(0x262f51ff).into()), + tab_inactive_background: Some(rgba(0x262f51ff).into()), + tab_active_background: Some(rgba(0x202746ff).into()), + scrollbar_thumb_background: Some(rgba(0xf5f7ff4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xf5f7ff4d).into()), + scrollbar_thumb_border: Some(rgba(0x252d4fff).into()), + scrollbar_track_border: Some(rgba(0x252d4fff).into()), + editor_foreground: Some(rgba(0xdfe2f1ff).into()), + editor_background: Some(rgba(0x202746ff).into()), + editor_gutter_background: Some(rgba(0x202746ff).into()), + editor_line_number: Some(rgba(0xf5f7ff59).into()), + editor_active_line_number: Some(rgba(0xf5f7ffff).into()), + editor_wrap_guide: Some(rgba(0xf5f7ff0d).into()), + editor_active_wrap_guide: Some(rgba(0xf5f7ff1a).into()), + terminal_background: Some(rgba(0x202746ff).into()), + terminal_ansi_bright_black: Some(rgba(0x697192ff).into()), + terminal_ansi_bright_red: Some(rgba(0x6d2616ff).into()), + terminal_ansi_bright_green: Some(rgba(0x534921ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x63441eff).into()), + terminal_ansi_bright_blue: Some(rgba(0x274664ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x4c333dff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x214e5fff).into()), + terminal_ansi_bright_white: Some(rgba(0xf5f7ffff).into()), + terminal_ansi_black: Some(rgba(0x202746ff).into()), + terminal_ansi_red: Some(rgba(0xc94923ff).into()), + terminal_ansi_green: Some(rgba(0xac973aff).into()), + terminal_ansi_yellow: Some(rgba(0xc08b31ff).into()), + terminal_ansi_blue: Some(rgba(0x3e8fd0ff).into()), + terminal_ansi_magenta: Some(rgba(0x9c637aff).into()), + terminal_ansi_cyan: Some(rgba(0x25a2c9ff).into()), + terminal_ansi_white: Some(rgba(0xf5f7ffff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0xac973aff).into()), + deleted: Some(rgba(0xa33a1eff).into()), + error: Some(rgba(0xc94923ff).into()), + modified: Some(rgba(0xc08b31ff).into()), + success: Some(rgba(0xf5f7ffff).into()), + warning: Some(rgba(0xc08b31ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x3e8fd0ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0xac973aff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x6b7394ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x979db4ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0xac973aff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x3e8fd0ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xf5f7ffff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x3e8fd0ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x3e8fd0ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xc76b2aff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x3d8fd1ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x3d8fd1ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xc08b30ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x6d82a6ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x6679ccff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x3e8fd0ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xc76b2aff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0xac973aff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xc76b29ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x979db4ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x58709aff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xf5f7ffff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xdfe2f1ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xc94922ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xdfe2f1ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x979db4ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x979db4ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xdfe2f1ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0x9c637aff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0xac9739ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x979db4ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x22a2c9ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0x9c637aff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0xac9739ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x3e8fd0ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xc76b2aff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xf5f7ffff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xc08b30ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xdfe2f1ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x6679ccff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xc08b30ff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Sulphurpool Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x9a9fb6ff).into()), + border_variant: Some(rgba(0x9a9fb6ff).into()), + elevated_surface_background: Some(rgba(0xc2c6d9ff).into()), + background: Some(rgba(0xc2c6d9ff).into()), + panel_background: Some(rgba(0xe5e8f5ff).into()), + element_hover: Some(rgba(0x9a9fb680).into()), + element_selected: Some(rgba(0x8e94aa80).into()), + text: Some(rgba(0x606889ff).into()), + text_muted: Some(rgba(0x898fa5ff).into()), + status_bar_background: Some(rgba(0xc2c6d9ff).into()), + title_bar_background: Some(rgba(0xc2c6d9ff).into()), + toolbar_background: Some(rgba(0xf5f7ffff).into()), + tab_bar_background: Some(rgba(0xe5e8f5ff).into()), + tab_inactive_background: Some(rgba(0xe5e8f5ff).into()), + tab_active_background: Some(rgba(0xf5f7ffff).into()), + scrollbar_thumb_background: Some(rgba(0x2027464d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x2027464d).into()), + scrollbar_thumb_border: Some(rgba(0xe9ebf7ff).into()), + scrollbar_track_border: Some(rgba(0xe9ebf7ff).into()), + editor_foreground: Some(rgba(0x293256ff).into()), + editor_background: Some(rgba(0xf5f7ffff).into()), + editor_gutter_background: Some(rgba(0xf5f7ffff).into()), + editor_line_number: Some(rgba(0x20274659).into()), + editor_active_line_number: Some(rgba(0x202746ff).into()), + editor_wrap_guide: Some(rgba(0x2027460d).into()), + editor_active_wrap_guide: Some(rgba(0x2027461a).into()), + terminal_background: Some(rgba(0xf5f7ffff).into()), + terminal_ansi_bright_black: Some(rgba(0x8b91a7ff).into()), + terminal_ansi_bright_red: Some(rgba(0xefa58cff).into()), + terminal_ansi_bright_green: Some(rgba(0xd9ca9bff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xe5c497ff).into()), + terminal_ansi_bright_blue: Some(rgba(0xa9c6e8ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xcfafbbff).into()), + terminal_ansi_bright_cyan: Some(rgba(0xa4d0e4ff).into()), + terminal_ansi_bright_white: Some(rgba(0x202746ff).into()), + terminal_ansi_black: Some(rgba(0xf5f7ffff).into()), + terminal_ansi_red: Some(rgba(0xc94a23ff).into()), + terminal_ansi_green: Some(rgba(0xac973aff).into()), + terminal_ansi_yellow: Some(rgba(0xc08b31ff).into()), + terminal_ansi_blue: Some(rgba(0x3f8fd0ff).into()), + terminal_ansi_magenta: Some(rgba(0x9c637aff).into()), + terminal_ansi_cyan: Some(rgba(0x25a2c9ff).into()), + terminal_ansi_white: Some(rgba(0x202746ff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0xbfab61ff).into()), + deleted: Some(rgba(0xc94a23ff).into()), + error: Some(rgba(0xc94a23ff).into()), + modified: Some(rgba(0xc08b31ff).into()), + success: Some(rgba(0x202746ff).into()), + warning: Some(rgba(0xc08b31ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x3f8fd0ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0xac973aff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x898ea4ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6687ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0xac973aff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x3f8fd0ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x202746ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x3f8fd0ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x3f8fd0ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xc76b2aff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x3d8fd1ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x3d8fd1ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xc08b30ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x7087b2ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x6679ccff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x3f8fd0ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xc76b2aff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0xac973aff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xc76b29ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6687ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x8599beff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x202746ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x293256ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xc94922ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x293256ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6687ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6687ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x293256ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0x9c637aff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0xac9739ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6687ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x22a2c9ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0x9c637aff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0xac9739ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x3f8fd0ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xc76b2aff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x202746ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xc08b30ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x293256ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x6679ccff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xc08b30ff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Dune Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x6c695cff).into()), + border_variant: Some(rgba(0x6c695cff).into()), + elevated_surface_background: Some(rgba(0x45433bff).into()), + background: Some(rgba(0x45433bff).into()), + panel_background: Some(rgba(0x262622ff).into()), + element_hover: Some(rgba(0x6c695c80).into()), + element_selected: Some(rgba(0x77746480).into()), + text: Some(rgba(0xa4a08bff).into()), + text_muted: Some(rgba(0x7c7968ff).into()), + status_bar_background: Some(rgba(0x45433bff).into()), + title_bar_background: Some(rgba(0x45433bff).into()), + toolbar_background: Some(rgba(0x20201dff).into()), + tab_bar_background: Some(rgba(0x262622ff).into()), + tab_inactive_background: Some(rgba(0x262622ff).into()), + tab_active_background: Some(rgba(0x20201dff).into()), + scrollbar_thumb_background: Some(rgba(0xfefbec4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xfefbec4d).into()), + scrollbar_thumb_border: Some(rgba(0x252521ff).into()), + scrollbar_track_border: Some(rgba(0x252521ff).into()), + editor_foreground: Some(rgba(0xe8e4cfff).into()), + editor_background: Some(rgba(0x20201dff).into()), + editor_gutter_background: Some(rgba(0x20201dff).into()), + editor_line_number: Some(rgba(0xfefbec59).into()), + editor_active_line_number: Some(rgba(0xfefbecff).into()), + editor_wrap_guide: Some(rgba(0xfefbec0d).into()), + editor_active_wrap_guide: Some(rgba(0xfefbec1a).into()), + terminal_background: Some(rgba(0x20201dff).into()), + terminal_ansi_bright_black: Some(rgba(0x7a7766ff).into()), + terminal_ansi_bright_red: Some(rgba(0x781c1fff).into()), + terminal_ansi_bright_green: Some(rgba(0x335322ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x574815ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x334173ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x721d2bff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x1e5341ff).into()), + terminal_ansi_bright_white: Some(rgba(0xfefbecff).into()), + terminal_ansi_black: Some(rgba(0x20201dff).into()), + terminal_ansi_red: Some(rgba(0xd73837ff).into()), + terminal_ansi_green: Some(rgba(0x60ac3aff).into()), + terminal_ansi_yellow: Some(rgba(0xae9515ff).into()), + terminal_ansi_blue: Some(rgba(0x6684e0ff).into()), + terminal_ansi_magenta: Some(rgba(0xd43652ff).into()), + terminal_ansi_cyan: Some(rgba(0x21ad83ff).into()), + terminal_ansi_white: Some(rgba(0xfefbecff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x60ac3aff).into()), + deleted: Some(rgba(0xaf2c2eff).into()), + error: Some(rgba(0xd73837ff).into()), + modified: Some(rgba(0xae9515ff).into()), + success: Some(rgba(0xfefbecff).into()), + warning: Some(rgba(0xae9515ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e0ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x60ac3aff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x7d7a68ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0xa6a28cff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x60ac3aff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e0ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xfefbecff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e0ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e0ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xb65612ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e1ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e1ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xae9513ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0xb17272ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0xb854d4ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e0ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xb65612ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x60ac3aff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xb65611ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0xa6a28cff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x9c6262ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xfefbecff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xe8e4cfff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xd73737ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xe8e4cfff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0xa6a28cff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0xa6a28cff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xe8e4cfff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xd43552ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x60ac39ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0xa6a28cff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x1fad83ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xd43552ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x60ac39ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e0ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xb65612ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xfefbecff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xae9513ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xe8e4cfff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0xb854d4ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xae9513ff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Seaside Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x5c6c5cff).into()), + border_variant: Some(rgba(0x5c6c5cff).into()), + elevated_surface_background: Some(rgba(0x3b453bff).into()), + background: Some(rgba(0x3b453bff).into()), + panel_background: Some(rgba(0x1f231fff).into()), + element_hover: Some(rgba(0x5c6c5c80).into()), + element_selected: Some(rgba(0x64776480).into()), + text: Some(rgba(0x8ba48bff).into()), + text_muted: Some(rgba(0x687c68ff).into()), + status_bar_background: Some(rgba(0x3b453bff).into()), + title_bar_background: Some(rgba(0x3b453bff).into()), + toolbar_background: Some(rgba(0x131513ff).into()), + tab_bar_background: Some(rgba(0x1f231fff).into()), + tab_inactive_background: Some(rgba(0x1f231fff).into()), + tab_active_background: Some(rgba(0x131513ff).into()), + scrollbar_thumb_background: Some(rgba(0xf4fbf44d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xf4fbf44d).into()), + scrollbar_thumb_border: Some(rgba(0x1d201dff).into()), + scrollbar_track_border: Some(rgba(0x1d201dff).into()), + editor_foreground: Some(rgba(0xcfe8cfff).into()), + editor_background: Some(rgba(0x131513ff).into()), + editor_gutter_background: Some(rgba(0x131513ff).into()), + editor_line_number: Some(rgba(0xf4fbf459).into()), + editor_active_line_number: Some(rgba(0xf4fbf4ff).into()), + editor_wrap_guide: Some(rgba(0xf4fbf40d).into()), + editor_active_wrap_guide: Some(rgba(0xf4fbf41a).into()), + terminal_background: Some(rgba(0x131513ff).into()), + terminal_ansi_bright_black: Some(rgba(0x667a66ff).into()), + terminal_ansi_bright_red: Some(rgba(0x840b21ff).into()), + terminal_ansi_bright_green: Some(rgba(0x204f1bff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x4b4a17ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x193385ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x810e60ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x1d4a56ff).into()), + terminal_ansi_bright_white: Some(rgba(0xf4fbf4ff).into()), + terminal_ansi_black: Some(rgba(0x131513ff).into()), + terminal_ansi_red: Some(rgba(0xe61c3cff).into()), + terminal_ansi_green: Some(rgba(0x2ba32aff).into()), + terminal_ansi_yellow: Some(rgba(0x98981cff).into()), + terminal_ansi_blue: Some(rgba(0x3e62f4ff).into()), + terminal_ansi_magenta: Some(rgba(0xe61cc3ff).into()), + terminal_ansi_cyan: Some(rgba(0x1c99b3ff).into()), + terminal_ansi_white: Some(rgba(0xf4fbf4ff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x2ba32aff).into()), + deleted: Some(rgba(0xbd1331ff).into()), + error: Some(rgba(0xe61c3cff).into()), + modified: Some(rgba(0x98981cff).into()), + success: Some(rgba(0xf4fbf4ff).into()), + warning: Some(rgba(0x98981cff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x3e62f4ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x2ba32aff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x687d68ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x8ca68cff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x2ba32aff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x3e62f4ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xf4fbf4ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x3e62f4ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x3e62f4ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0x87711eff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x3d62f5ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x3d62f5ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0x98981bff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x008b9fff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0xad2beeff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x3e62f4ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0x87711eff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x2ba32aff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0x87711dff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x8ca68cff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x00788bff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xf4fbf4ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xcfe8cfff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xe6193cff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xcfe8cfff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x8ca68cff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x8ca68cff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xcfe8cfff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xe619c3ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x29a329ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x8ca68cff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x1999b3ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xe619c3ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x29a329ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x3e62f4ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0x87711eff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xf4fbf4ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0x98981bff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xcfe8cfff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0xad2beeff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x98981bff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Cave Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x8f8b96ff).into()), + border_variant: Some(rgba(0x8f8b96ff).into()), + elevated_surface_background: Some(rgba(0xbfbcc5ff).into()), + background: Some(rgba(0xbfbcc5ff).into()), + panel_background: Some(rgba(0xe6e3ebff).into()), + element_hover: Some(rgba(0x8f8b9680).into()), + element_selected: Some(rgba(0x837e8b80).into()), + text: Some(rgba(0x5a5462ff).into()), + text_muted: Some(rgba(0x7e7987ff).into()), + status_bar_background: Some(rgba(0xbfbcc5ff).into()), + title_bar_background: Some(rgba(0xbfbcc5ff).into()), + toolbar_background: Some(rgba(0xefecf4ff).into()), + tab_bar_background: Some(rgba(0xe6e3ebff).into()), + tab_inactive_background: Some(rgba(0xe6e3ebff).into()), + tab_active_background: Some(rgba(0xefecf4ff).into()), + scrollbar_thumb_background: Some(rgba(0x19171c4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x19171c4d).into()), + scrollbar_thumb_border: Some(rgba(0xe8e5edff).into()), + scrollbar_track_border: Some(rgba(0xe8e5edff).into()), + editor_foreground: Some(rgba(0x26232aff).into()), + editor_background: Some(rgba(0xefecf4ff).into()), + editor_gutter_background: Some(rgba(0xefecf4ff).into()), + editor_line_number: Some(rgba(0x19171c59).into()), + editor_active_line_number: Some(rgba(0x19171cff).into()), + editor_wrap_guide: Some(rgba(0x19171c0d).into()), + editor_active_wrap_guide: Some(rgba(0x19171c1a).into()), + terminal_background: Some(rgba(0xefecf4ff).into()), + terminal_ansi_bright_black: Some(rgba(0x807b89ff).into()), + terminal_ansi_bright_red: Some(rgba(0xe3a4b9ff).into()), + terminal_ansi_bright_green: Some(rgba(0x9dc8c8ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xd4b499ff).into()), + terminal_ansi_bright_blue: Some(rgba(0xb3b3eeff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xe3a4dfff).into()), + terminal_ansi_bright_cyan: Some(rgba(0xa6c4e3ff).into()), + terminal_ansi_bright_white: Some(rgba(0x19171cff).into()), + terminal_ansi_black: Some(rgba(0xefecf4ff).into()), + terminal_ansi_red: Some(rgba(0xbe4778ff).into()), + terminal_ansi_green: Some(rgba(0x2c9292ff).into()), + terminal_ansi_yellow: Some(rgba(0xa06e3cff).into()), + terminal_ansi_blue: Some(rgba(0x586ddaff).into()), + terminal_ansi_magenta: Some(rgba(0xbf41bfff).into()), + terminal_ansi_cyan: Some(rgba(0x3b8bc6ff).into()), + terminal_ansi_white: Some(rgba(0x19171cff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x5fa8a7ff).into()), + deleted: Some(rgba(0xbe4778ff).into()), + error: Some(rgba(0xbe4778ff).into()), + modified: Some(rgba(0xa06e3cff).into()), + success: Some(rgba(0x19171cff).into()), + warning: Some(rgba(0xa06e3cff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x586ddaff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x2c9292ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x7e7887ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x585260ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x2c9292ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x586ddaff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x19171cff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x586ddaff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x586ddaff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xaa583dff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddbff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x576ddbff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x786e9dff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x955ae7ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x586ddaff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xaa583dff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x2c9292ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xaa573cff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x585260ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x887fafff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x19171cff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x26232aff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xbe4678ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x26232aff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x585260ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x585260ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x26232aff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xbf40bfff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x2a9292ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x585260ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x398bc6ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xbf40bfff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x2a9292ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x586ddaff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xaa583dff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x19171cff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x26232aff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x955ae7ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Plateau Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x564e4eff).into()), + border_variant: Some(rgba(0x564e4eff).into()), + elevated_surface_background: Some(rgba(0x3b3535ff).into()), + background: Some(rgba(0x3b3535ff).into()), + panel_background: Some(rgba(0x252020ff).into()), + element_hover: Some(rgba(0x564e4e80).into()), + element_selected: Some(rgba(0x60585880).into()), + text: Some(rgba(0x898383ff).into()), + text_muted: Some(rgba(0x655d5dff).into()), + status_bar_background: Some(rgba(0x3b3535ff).into()), + title_bar_background: Some(rgba(0x3b3535ff).into()), + toolbar_background: Some(rgba(0x1b1818ff).into()), + tab_bar_background: Some(rgba(0x252020ff).into()), + tab_inactive_background: Some(rgba(0x252020ff).into()), + tab_active_background: Some(rgba(0x1b1818ff).into()), + scrollbar_thumb_background: Some(rgba(0xf4ecec4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xf4ecec4d).into()), + scrollbar_thumb_border: Some(rgba(0x231f1fff).into()), + scrollbar_track_border: Some(rgba(0x231f1fff).into()), + editor_foreground: Some(rgba(0xe7dfdfff).into()), + editor_background: Some(rgba(0x1b1818ff).into()), + editor_gutter_background: Some(rgba(0x1b1818ff).into()), + editor_line_number: Some(rgba(0xf4ecec59).into()), + editor_active_line_number: Some(rgba(0xf4ececff).into()), + editor_wrap_guide: Some(rgba(0xf4ecec0d).into()), + editor_active_wrap_guide: Some(rgba(0xf4ecec1a).into()), + terminal_background: Some(rgba(0x1b1818ff).into()), + terminal_ansi_bright_black: Some(rgba(0x635b5bff).into()), + terminal_ansi_bright_red: Some(rgba(0x692727ff).into()), + terminal_ansi_bright_green: Some(rgba(0x2a4444ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x4e3821ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x3b3960ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x5b2c42ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x2e4257ff).into()), + terminal_ansi_bright_white: Some(rgba(0xf4ececff).into()), + terminal_ansi_black: Some(rgba(0x1b1818ff).into()), + terminal_ansi_red: Some(rgba(0xca4949ff).into()), + terminal_ansi_green: Some(rgba(0x4b8b8bff).into()), + terminal_ansi_yellow: Some(rgba(0xa06e3bff).into()), + terminal_ansi_blue: Some(rgba(0x7272caff).into()), + terminal_ansi_magenta: Some(rgba(0xbd5187ff).into()), + terminal_ansi_cyan: Some(rgba(0x5485b6ff).into()), + terminal_ansi_white: Some(rgba(0xf4ececff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x4b8b8bff).into()), + deleted: Some(rgba(0xa23b3bff).into()), + error: Some(rgba(0xca4949ff).into()), + modified: Some(rgba(0xa06e3bff).into()), + success: Some(rgba(0xf4ececff).into()), + warning: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x4b8b8bff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x655d5dff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8585ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x4b8b8bff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xf4ececff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xb45a3cff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x8a647aff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x8464c4ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xb45a3cff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x4b8b8bff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xb45a3cff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8585ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x795369ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xf4ececff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xe7dfdfff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xca4949ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xe7dfdfff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8585ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8585ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xe7dfdfff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xbd5187ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x4b8b8bff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8585ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x5485b6ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xbd5187ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x4b8b8bff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xb45a3cff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xf4ececff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xe7dfdfff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x8464c4ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Heath Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x675b67ff).into()), + border_variant: Some(rgba(0x675b67ff).into()), + elevated_surface_background: Some(rgba(0x433a43ff).into()), + background: Some(rgba(0x433a43ff).into()), + panel_background: Some(rgba(0x252025ff).into()), + element_hover: Some(rgba(0x675b6780).into()), + element_selected: Some(rgba(0x72647280).into()), + text: Some(rgba(0xa99aa9ff).into()), + text_muted: Some(rgba(0x776977ff).into()), + status_bar_background: Some(rgba(0x433a43ff).into()), + title_bar_background: Some(rgba(0x433a43ff).into()), + toolbar_background: Some(rgba(0x1b181bff).into()), + tab_bar_background: Some(rgba(0x252025ff).into()), + tab_inactive_background: Some(rgba(0x252025ff).into()), + tab_active_background: Some(rgba(0x1b181bff).into()), + scrollbar_thumb_background: Some(rgba(0xf7f3f74d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xf7f3f74d).into()), + scrollbar_thumb_border: Some(rgba(0x231e23ff).into()), + scrollbar_track_border: Some(rgba(0x231e23ff).into()), + editor_foreground: Some(rgba(0xd8cad8ff).into()), + editor_background: Some(rgba(0x1b181bff).into()), + editor_gutter_background: Some(rgba(0x1b181bff).into()), + editor_line_number: Some(rgba(0xf7f3f759).into()), + editor_active_line_number: Some(rgba(0xf7f3f7ff).into()), + editor_wrap_guide: Some(rgba(0xf7f3f70d).into()), + editor_active_wrap_guide: Some(rgba(0xf7f3f71a).into()), + terminal_background: Some(rgba(0x1b181bff).into()), + terminal_ansi_bright_black: Some(rgba(0x756775ff).into()), + terminal_ansi_bright_red: Some(rgba(0x6d221aff).into()), + terminal_ansi_bright_green: Some(rgba(0x474422ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x5e441fff).into()), + terminal_ansi_bright_blue: Some(rgba(0x26367eff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x6c1e67ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x1a4848ff).into()), + terminal_ansi_bright_white: Some(rgba(0xf7f3f7ff).into()), + terminal_ansi_black: Some(rgba(0x1b181bff).into()), + terminal_ansi_red: Some(rgba(0xca402cff).into()), + terminal_ansi_green: Some(rgba(0x918b3bff).into()), + terminal_ansi_yellow: Some(rgba(0xbb8a36ff).into()), + terminal_ansi_blue: Some(rgba(0x526aebff).into()), + terminal_ansi_magenta: Some(rgba(0xcc34ccff).into()), + terminal_ansi_cyan: Some(rgba(0x189393ff).into()), + terminal_ansi_white: Some(rgba(0xf7f3f7ff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x918b3bff).into()), + deleted: Some(rgba(0xa43424ff).into()), + error: Some(rgba(0xca402cff).into()), + modified: Some(rgba(0xbb8a36ff).into()), + success: Some(rgba(0xf7f3f7ff).into()), + warning: Some(rgba(0xbb8a36ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3bff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x776977ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0xab9babff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3bff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xf7f3f7ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xa65927ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x516aecff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x516aecff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xbb8a35ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x8d70a8ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x7b59c0ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xa65927ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3bff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xa65926ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0xab9babff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x765990ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xf7f3f7ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xd8cad8ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xca402bff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xd8cad8ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0xab9babff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0xab9babff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xd8cad8ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xcc33ccff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3bff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0xab9babff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x159393ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xcc33ccff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3bff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xa65927ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xf7f3f7ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xbb8a35ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xd8cad8ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x7b59c0ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xbb8a35ff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Lakeside Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x4f6b78ff).into()), + border_variant: Some(rgba(0x4f6b78ff).into()), + elevated_surface_background: Some(rgba(0x33444dff).into()), + background: Some(rgba(0x33444dff).into()), + panel_background: Some(rgba(0x1c2529ff).into()), + element_hover: Some(rgba(0x4f6b7880).into()), + element_selected: Some(rgba(0x57768580).into()), + text: Some(rgba(0x7ca0b3ff).into()), + text_muted: Some(rgba(0x5a7b8bff).into()), + status_bar_background: Some(rgba(0x33444dff).into()), + title_bar_background: Some(rgba(0x33444dff).into()), + toolbar_background: Some(rgba(0x161b1dff).into()), + tab_bar_background: Some(rgba(0x1c2529ff).into()), + tab_inactive_background: Some(rgba(0x1c2529ff).into()), + tab_active_background: Some(rgba(0x161b1dff).into()), + scrollbar_thumb_background: Some(rgba(0xebf8ff4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xebf8ff4d).into()), + scrollbar_thumb_border: Some(rgba(0x1b2327ff).into()), + scrollbar_track_border: Some(rgba(0x1b2327ff).into()), + editor_foreground: Some(rgba(0xc1e4f6ff).into()), + editor_background: Some(rgba(0x161b1dff).into()), + editor_gutter_background: Some(rgba(0x161b1dff).into()), + editor_line_number: Some(rgba(0xebf8ff59).into()), + editor_active_line_number: Some(rgba(0xebf8ffff).into()), + editor_wrap_guide: Some(rgba(0xebf8ff0d).into()), + editor_active_wrap_guide: Some(rgba(0xebf8ff1a).into()), + terminal_background: Some(rgba(0x161b1dff).into()), + terminal_ansi_bright_black: Some(rgba(0x587989ff).into()), + terminal_ansi_bright_red: Some(rgba(0x6f1c3aff).into()), + terminal_ansi_bright_green: Some(rgba(0x2e4522ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x454413ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x1e3f53ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x5c1e6bff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x1f4638ff).into()), + terminal_ansi_bright_white: Some(rgba(0xebf8ffff).into()), + terminal_ansi_black: Some(rgba(0x161b1dff).into()), + terminal_ansi_red: Some(rgba(0xd22e72ff).into()), + terminal_ansi_green: Some(rgba(0x568c3bff).into()), + terminal_ansi_yellow: Some(rgba(0x8a8a11ff).into()), + terminal_ansi_blue: Some(rgba(0x277fadff).into()), + terminal_ansi_magenta: Some(rgba(0xb72ed2ff).into()), + terminal_ansi_cyan: Some(rgba(0x2e8f6fff).into()), + terminal_ansi_white: Some(rgba(0xebf8ffff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x568c3bff).into()), + deleted: Some(rgba(0xa9275aff).into()), + error: Some(rgba(0xd22e72ff).into()), + modified: Some(rgba(0x8a8a11ff).into()), + success: Some(rgba(0xebf8ffff).into()), + warning: Some(rgba(0x8a8a11ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x568c3bff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x5a7b8cff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x7ea2b4ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x568c3bff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xebf8ffff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0x935c26ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x257fadff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x257fadff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8a0fff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x52809aff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x6b6bb8ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0x935c26ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x568c3bff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0x935c25ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x7ea2b4ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x427088ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xebf8ffff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xc1e4f6ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xd22d72ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xc1e4f6ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x7ea2b4ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x7ea2b4ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xc1e4f6ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xb72dd2ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x568c3bff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x7ea2b4ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x2d8f6fff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xb72dd2ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x568c3bff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0x935c26ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xebf8ffff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8a0fff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xc1e4f6ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x6b6bb8ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8a0fff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Forest Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0xaaa3a1ff).into()), + border_variant: Some(rgba(0xaaa3a1ff).into()), + elevated_surface_background: Some(rgba(0xcdc8c6ff).into()), + background: Some(rgba(0xcdc8c6ff).into()), + panel_background: Some(rgba(0xe9e6e4ff).into()), + element_hover: Some(rgba(0xaaa3a180).into()), + element_selected: Some(rgba(0xa1999680).into()), + text: Some(rgba(0x6a6360ff).into()), + text_muted: Some(rgba(0x9c9491ff).into()), + status_bar_background: Some(rgba(0xcdc8c6ff).into()), + title_bar_background: Some(rgba(0xcdc8c6ff).into()), + toolbar_background: Some(rgba(0xf1efeeff).into()), + tab_bar_background: Some(rgba(0xe9e6e4ff).into()), + tab_inactive_background: Some(rgba(0xe9e6e4ff).into()), + tab_active_background: Some(rgba(0xf1efeeff).into()), + scrollbar_thumb_background: Some(rgba(0x1b19184d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x1b19184d).into()), + scrollbar_thumb_border: Some(rgba(0xebe8e6ff).into()), + scrollbar_track_border: Some(rgba(0xebe8e6ff).into()), + editor_foreground: Some(rgba(0x2c2421ff).into()), + editor_background: Some(rgba(0xf1efeeff).into()), + editor_gutter_background: Some(rgba(0xf1efeeff).into()), + editor_line_number: Some(rgba(0x1b191859).into()), + editor_active_line_number: Some(rgba(0x1b1918ff).into()), + editor_wrap_guide: Some(rgba(0x1b19180d).into()), + editor_active_wrap_guide: Some(rgba(0x1b19181a).into()), + terminal_background: Some(rgba(0xf1efeeff).into()), + terminal_ansi_bright_black: Some(rgba(0x9e9693ff).into()), + terminal_ansi_bright_red: Some(rgba(0xffa29aff).into()), + terminal_ansi_bright_green: Some(rgba(0xbfca93ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xe9c08eff).into()), + terminal_ansi_bright_blue: Some(rgba(0xaebcf4ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xe7a6fbff).into()), + terminal_ansi_bright_cyan: Some(rgba(0xa6cadbff).into()), + terminal_ansi_bright_white: Some(rgba(0x1b1918ff).into()), + terminal_ansi_black: Some(rgba(0xf1efeeff).into()), + terminal_ansi_red: Some(rgba(0xf22e41ff).into()), + terminal_ansi_green: Some(rgba(0x7b9728ff).into()), + terminal_ansi_yellow: Some(rgba(0xc3841aff).into()), + terminal_ansi_blue: Some(rgba(0x417ee6ff).into()), + terminal_ansi_magenta: Some(rgba(0xc340f2ff).into()), + terminal_ansi_cyan: Some(rgba(0x3f97b8ff).into()), + terminal_ansi_white: Some(rgba(0x1b1918ff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x97ab54ff).into()), + deleted: Some(rgba(0xf22e41ff).into()), + error: Some(rgba(0xf22e41ff).into()), + modified: Some(rgba(0xc3841aff).into()), + success: Some(rgba(0x1b1918ff).into()), + warning: Some(rgba(0xc3841aff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9728ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x9c9491ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x68615eff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9728ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x1b1918ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xdf5421ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x407ee7ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x407ee7ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xc38418ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0xa67287ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x6666eaff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xdf5421ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9728ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xdf5320ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x68615eff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0xbe899eff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x1b1918ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x2c2421ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xf22c40ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x2c2421ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x68615eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x68615eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x2c2421ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xc33ff3ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9726ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x68615eff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x3d97b8ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xc33ff3ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x7b9726ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x417ee6ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xdf5421ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x1b1918ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xc38418ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x2c2421ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x6666eaff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xc38418ff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Dune Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0xa8a48eff).into()), + border_variant: Some(rgba(0xa8a48eff).into()), + elevated_surface_background: Some(rgba(0xcecab4ff).into()), + background: Some(rgba(0xcecab4ff).into()), + panel_background: Some(rgba(0xeeebd7ff).into()), + element_hover: Some(rgba(0xa8a48e80).into()), + element_selected: Some(rgba(0x9e9a8580).into()), + text: Some(rgba(0x706d5fff).into()), + text_muted: Some(rgba(0x999580ff).into()), + status_bar_background: Some(rgba(0xcecab4ff).into()), + title_bar_background: Some(rgba(0xcecab4ff).into()), + toolbar_background: Some(rgba(0xfefbecff).into()), + tab_bar_background: Some(rgba(0xeeebd7ff).into()), + tab_inactive_background: Some(rgba(0xeeebd7ff).into()), + tab_active_background: Some(rgba(0xfefbecff).into()), + scrollbar_thumb_background: Some(rgba(0x20201d4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x20201d4d).into()), + scrollbar_thumb_border: Some(rgba(0xf2eedcff).into()), + scrollbar_track_border: Some(rgba(0xf2eedcff).into()), + editor_foreground: Some(rgba(0x292824ff).into()), + editor_background: Some(rgba(0xfefbecff).into()), + editor_gutter_background: Some(rgba(0xfefbecff).into()), + editor_line_number: Some(rgba(0x20201d59).into()), + editor_active_line_number: Some(rgba(0x20201dff).into()), + editor_wrap_guide: Some(rgba(0x20201d0d).into()), + editor_active_wrap_guide: Some(rgba(0x20201d1a).into()), + terminal_background: Some(rgba(0xfefbecff).into()), + terminal_ansi_bright_black: Some(rgba(0x9b9782ff).into()), + terminal_ansi_bright_red: Some(rgba(0xf7a195ff).into()), + terminal_ansi_bright_green: Some(rgba(0xb3d69cff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xdcc98eff).into()), + terminal_ansi_bright_blue: Some(rgba(0xb8c0f1ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xf3a0a4ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x9ed7c0ff).into()), + terminal_ansi_bright_white: Some(rgba(0x20201dff).into()), + terminal_ansi_black: Some(rgba(0xfefbecff).into()), + terminal_ansi_red: Some(rgba(0xd73838ff).into()), + terminal_ansi_green: Some(rgba(0x61ac3aff).into()), + terminal_ansi_yellow: Some(rgba(0xae9515ff).into()), + terminal_ansi_blue: Some(rgba(0x6784e0ff).into()), + terminal_ansi_magenta: Some(rgba(0xd43753ff).into()), + terminal_ansi_cyan: Some(rgba(0x22ad83ff).into()), + terminal_ansi_white: Some(rgba(0x20201dff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x83bd62ff).into()), + deleted: Some(rgba(0xd73838ff).into()), + error: Some(rgba(0xd73838ff).into()), + modified: Some(rgba(0xae9515ff).into()), + success: Some(rgba(0x20201dff).into()), + warning: Some(rgba(0xae9515ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x6784e0ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x61ac3aff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x999580ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x6e6b5eff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x61ac3aff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x6784e0ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x20201dff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x6784e0ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x6784e0ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xb65713ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e1ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x6684e1ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xae9513ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0xb37979ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0xb854d4ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x6784e0ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xb65713ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x61ac3aff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xb65611ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x6e6b5eff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0xc88a8aff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x20201dff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x292824ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xd73737ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x292824ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x6e6b5eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x6e6b5eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x292824ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xd43552ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x60ac39ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x6e6b5eff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x1fad83ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xd43552ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x60ac39ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x6784e0ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xb65713ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x20201dff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xae9513ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x292824ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0xb854d4ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xae9513ff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Plateau Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x8e8989ff).into()), + border_variant: Some(rgba(0x8e8989ff).into()), + elevated_surface_background: Some(rgba(0xc1bbbbff).into()), + background: Some(rgba(0xc1bbbbff).into()), + panel_background: Some(rgba(0xebe3e3ff).into()), + element_hover: Some(rgba(0x8e898980).into()), + element_selected: Some(rgba(0x837c7c80).into()), + text: Some(rgba(0x5a5252ff).into()), + text_muted: Some(rgba(0x7e7777ff).into()), + status_bar_background: Some(rgba(0xc1bbbbff).into()), + title_bar_background: Some(rgba(0xc1bbbbff).into()), + toolbar_background: Some(rgba(0xf4ececff).into()), + tab_bar_background: Some(rgba(0xebe3e3ff).into()), + tab_inactive_background: Some(rgba(0xebe3e3ff).into()), + tab_active_background: Some(rgba(0xf4ececff).into()), + scrollbar_thumb_background: Some(rgba(0x1b18184d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x1b18184d).into()), + scrollbar_thumb_border: Some(rgba(0xede5e5ff).into()), + scrollbar_track_border: Some(rgba(0xede5e5ff).into()), + editor_foreground: Some(rgba(0x292424ff).into()), + editor_background: Some(rgba(0xf4ececff).into()), + editor_gutter_background: Some(rgba(0xf4ececff).into()), + editor_line_number: Some(rgba(0x1b181859).into()), + editor_active_line_number: Some(rgba(0x1b1818ff).into()), + editor_wrap_guide: Some(rgba(0x1b18180d).into()), + editor_active_wrap_guide: Some(rgba(0x1b18181a).into()), + terminal_background: Some(rgba(0xf4ececff).into()), + terminal_ansi_bright_black: Some(rgba(0x807979ff).into()), + terminal_ansi_bright_red: Some(rgba(0xeda69fff).into()), + terminal_ansi_bright_green: Some(rgba(0xa6c4c4ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xd4b499ff).into()), + terminal_ansi_bright_blue: Some(rgba(0xbbb6e5ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xe2a9c2ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0xacc0daff).into()), + terminal_ansi_bright_white: Some(rgba(0x1b1818ff).into()), + terminal_ansi_black: Some(rgba(0xf4ececff).into()), + terminal_ansi_red: Some(rgba(0xca4a4aff).into()), + terminal_ansi_green: Some(rgba(0x4c8b8bff).into()), + terminal_ansi_yellow: Some(rgba(0xa06e3cff).into()), + terminal_ansi_blue: Some(rgba(0x7372caff).into()), + terminal_ansi_magenta: Some(rgba(0xbd5287ff).into()), + terminal_ansi_cyan: Some(rgba(0x5585b6ff).into()), + terminal_ansi_white: Some(rgba(0x1b1818ff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x70a2a1ff).into()), + deleted: Some(rgba(0xca4a4aff).into()), + error: Some(rgba(0xca4a4aff).into()), + modified: Some(rgba(0xa06e3cff).into()), + success: Some(rgba(0x1b1818ff).into()), + warning: Some(rgba(0xa06e3cff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x7372caff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x4c8b8bff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x7e7777ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x585050ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x4c8b8bff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x7372caff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x1b1818ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x7372caff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x7372caff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xb45b3dff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x7272caff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x916a80ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x8464c4ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x7372caff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xb45b3dff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x4c8b8bff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xb45a3cff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x585050ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0xa27a91ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x1b1818ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x292424ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xca4949ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x292424ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x585050ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x585050ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x292424ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xbd5187ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x4b8b8bff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x585050ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x5485b6ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xbd5187ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x4b8b8bff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x7372caff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xb45b3dff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x1b1818ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x292424ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x8464c4ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xa06e3bff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Seaside Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x8ea88eff).into()), + border_variant: Some(rgba(0x8ea88eff).into()), + elevated_surface_background: Some(rgba(0xb4ceb4ff).into()), + background: Some(rgba(0xb4ceb4ff).into()), + panel_background: Some(rgba(0xdaeedaff).into()), + element_hover: Some(rgba(0x8ea88e80).into()), + element_selected: Some(rgba(0x859e8580).into()), + text: Some(rgba(0x5f705fff).into()), + text_muted: Some(rgba(0x809980ff).into()), + status_bar_background: Some(rgba(0xb4ceb4ff).into()), + title_bar_background: Some(rgba(0xb4ceb4ff).into()), + toolbar_background: Some(rgba(0xf4fbf4ff).into()), + tab_bar_background: Some(rgba(0xdaeedaff).into()), + tab_inactive_background: Some(rgba(0xdaeedaff).into()), + tab_active_background: Some(rgba(0xf4fbf4ff).into()), + scrollbar_thumb_background: Some(rgba(0x1315134d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x1315134d).into()), + scrollbar_thumb_border: Some(rgba(0xdff0dfff).into()), + scrollbar_track_border: Some(rgba(0xdff0dfff).into()), + editor_foreground: Some(rgba(0x242924ff).into()), + editor_background: Some(rgba(0xf4fbf4ff).into()), + editor_gutter_background: Some(rgba(0xf4fbf4ff).into()), + editor_line_number: Some(rgba(0x13151359).into()), + editor_active_line_number: Some(rgba(0x131513ff).into()), + editor_wrap_guide: Some(rgba(0x1315130d).into()), + editor_active_wrap_guide: Some(rgba(0x1315131a).into()), + terminal_background: Some(rgba(0xf4fbf4ff).into()), + terminal_ansi_bright_black: Some(rgba(0x829b82ff).into()), + terminal_ansi_bright_red: Some(rgba(0xff9d98ff).into()), + terminal_ansi_bright_green: Some(rgba(0xa0d294ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xd0ca90ff).into()), + terminal_ansi_bright_blue: Some(rgba(0xb1adfcff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xf9a1e1ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x9fccd9ff).into()), + terminal_ansi_bright_white: Some(rgba(0x131513ff).into()), + terminal_ansi_black: Some(rgba(0xf4fbf4ff).into()), + terminal_ansi_red: Some(rgba(0xe61c3dff).into()), + terminal_ansi_green: Some(rgba(0x2ba32bff).into()), + terminal_ansi_yellow: Some(rgba(0x98981dff).into()), + terminal_ansi_blue: Some(rgba(0x3f62f4ff).into()), + terminal_ansi_magenta: Some(rgba(0xe61dc3ff).into()), + terminal_ansi_cyan: Some(rgba(0x1d99b3ff).into()), + terminal_ansi_white: Some(rgba(0x131513ff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x61b656ff).into()), + deleted: Some(rgba(0xe61c3dff).into()), + error: Some(rgba(0xe61c3dff).into()), + modified: Some(rgba(0x98981dff).into()), + success: Some(rgba(0x131513ff).into()), + warning: Some(rgba(0x98981dff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x3f62f4ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x2ba32bff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x809980ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6e5eff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x2ba32bff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x3f62f4ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x131513ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x3f62f4ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x3f62f4ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0x87711fff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x3d62f5ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x3d62f5ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0x98981bff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x008fa1ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0xad2beeff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x3f62f4ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0x87711fff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x2ba32bff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0x87711dff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6e5eff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x00a2b5ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x131513ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x242924ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xe6193cff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x242924ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6e5eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6e5eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x242924ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xe619c3ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x29a329ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x5e6e5eff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x1999b3ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xe619c3ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x29a329ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x3f62f4ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0x87711fff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x131513ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0x98981bff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x242924ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0xad2beeff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x98981bff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Savanna Dark".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x505e55ff).into()), + border_variant: Some(rgba(0x505e55ff).into()), + elevated_surface_background: Some(rgba(0x353f39ff).into()), + background: Some(rgba(0x353f39ff).into()), + panel_background: Some(rgba(0x1f2621ff).into()), + element_hover: Some(rgba(0x505e5580).into()), + element_selected: Some(rgba(0x5a685f80).into()), + text: Some(rgba(0x859188ff).into()), + text_muted: Some(rgba(0x5f6d64ff).into()), + status_bar_background: Some(rgba(0x353f39ff).into()), + title_bar_background: Some(rgba(0x353f39ff).into()), + toolbar_background: Some(rgba(0x171c19ff).into()), + tab_bar_background: Some(rgba(0x1f2621ff).into()), + tab_inactive_background: Some(rgba(0x1f2621ff).into()), + tab_active_background: Some(rgba(0x171c19ff).into()), + scrollbar_thumb_background: Some(rgba(0xecf4ee4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xecf4ee4d).into()), + scrollbar_thumb_border: Some(rgba(0x1e2420ff).into()), + scrollbar_track_border: Some(rgba(0x1e2420ff).into()), + editor_foreground: Some(rgba(0xdfe7e2ff).into()), + editor_background: Some(rgba(0x171c19ff).into()), + editor_gutter_background: Some(rgba(0x171c19ff).into()), + editor_line_number: Some(rgba(0xecf4ee59).into()), + editor_active_line_number: Some(rgba(0xecf4eeff).into()), + editor_wrap_guide: Some(rgba(0xecf4ee0d).into()), + editor_active_wrap_guide: Some(rgba(0xecf4ee1a).into()), + terminal_background: Some(rgba(0x171c19ff).into()), + terminal_ansi_bright_black: Some(rgba(0x5d6b62ff).into()), + terminal_ansi_bright_red: Some(rgba(0x563220ff).into()), + terminal_ansi_bright_green: Some(rgba(0x294a33ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x4e3f22ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x284546ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x423a36ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x1d4b4dff).into()), + terminal_ansi_bright_white: Some(rgba(0xecf4eeff).into()), + terminal_ansi_black: Some(rgba(0x171c19ff).into()), + terminal_ansi_red: Some(rgba(0xb16139ff).into()), + terminal_ansi_green: Some(rgba(0x489963ff).into()), + terminal_ansi_yellow: Some(rgba(0xa07e3bff).into()), + terminal_ansi_blue: Some(rgba(0x478c90ff).into()), + terminal_ansi_magenta: Some(rgba(0x867469ff).into()), + terminal_ansi_cyan: Some(rgba(0x1e9aa0ff).into()), + terminal_ansi_white: Some(rgba(0xecf4eeff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x489963ff).into()), + deleted: Some(rgba(0x8b4d2fff).into()), + error: Some(rgba(0xb16139ff).into()), + modified: Some(rgba(0xa07e3bff).into()), + success: Some(rgba(0xecf4eeff).into()), + warning: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x489963ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x5f6d64ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x87928aff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x489963ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xecf4eeff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0x9f713cff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x607e76ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x55859bff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0x9f713cff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x489963ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0x9f713cff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x87928aff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x506d66ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xecf4eeff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xdfe7e2ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xb16139ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xdfe7e2ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x87928aff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x87928aff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xdfe7e2ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0x867469ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x489963ff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x87928aff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x1c9aa0ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0x867469ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x489963ff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x478c90ff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0x9f713cff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xecf4eeff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xdfe7e2ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x55859bff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Heath Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0xad9dadff).into()), + border_variant: Some(rgba(0xad9dadff).into()), + elevated_surface_background: Some(rgba(0xc6b8c6ff).into()), + background: Some(rgba(0xc6b8c6ff).into()), + panel_background: Some(rgba(0xe1d6e1ff).into()), + element_hover: Some(rgba(0xad9dad80).into()), + element_selected: Some(rgba(0xa394a380).into()), + text: Some(rgba(0x6b5e6bff).into()), + text_muted: Some(rgba(0x9e8f9eff).into()), + status_bar_background: Some(rgba(0xc6b8c6ff).into()), + title_bar_background: Some(rgba(0xc6b8c6ff).into()), + toolbar_background: Some(rgba(0xf7f3f7ff).into()), + tab_bar_background: Some(rgba(0xe1d6e1ff).into()), + tab_inactive_background: Some(rgba(0xe1d6e1ff).into()), + tab_active_background: Some(rgba(0xf7f3f7ff).into()), + scrollbar_thumb_background: Some(rgba(0x1b181b4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x1b181b4d).into()), + scrollbar_thumb_border: Some(rgba(0xe5dce5ff).into()), + scrollbar_track_border: Some(rgba(0xe5dce5ff).into()), + editor_foreground: Some(rgba(0x292329ff).into()), + editor_background: Some(rgba(0xf7f3f7ff).into()), + editor_gutter_background: Some(rgba(0xf7f3f7ff).into()), + editor_line_number: Some(rgba(0x1b181b59).into()), + editor_active_line_number: Some(rgba(0x1b181bff).into()), + editor_wrap_guide: Some(rgba(0x1b181b0d).into()), + editor_active_wrap_guide: Some(rgba(0x1b181b1a).into()), + terminal_background: Some(rgba(0xf7f3f7ff).into()), + terminal_ansi_bright_black: Some(rgba(0xa091a0ff).into()), + terminal_ansi_bright_red: Some(rgba(0xf0a28fff).into()), + terminal_ansi_bright_green: Some(rgba(0xcac49aff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xe2c398ff).into()), + terminal_ansi_bright_blue: Some(rgba(0xb4b2f7ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xeba2e6ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x9ac9c8ff).into()), + terminal_ansi_bright_white: Some(rgba(0x1b181bff).into()), + terminal_ansi_black: Some(rgba(0xf7f3f7ff).into()), + terminal_ansi_red: Some(rgba(0xca412cff).into()), + terminal_ansi_green: Some(rgba(0x918b3cff).into()), + terminal_ansi_yellow: Some(rgba(0xbb8a36ff).into()), + terminal_ansi_blue: Some(rgba(0x526aebff).into()), + terminal_ansi_magenta: Some(rgba(0xcc35ccff).into()), + terminal_ansi_cyan: Some(rgba(0x199393ff).into()), + terminal_ansi_white: Some(rgba(0x1b181bff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0xa8a161ff).into()), + deleted: Some(rgba(0xca412cff).into()), + error: Some(rgba(0xca412cff).into()), + modified: Some(rgba(0xbb8a36ff).into()), + success: Some(rgba(0x1b181bff).into()), + warning: Some(rgba(0xbb8a36ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3cff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x9e8f9eff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x695d69ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3cff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x1b181bff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xa65a27ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x516aecff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x516aecff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0xbb8a35ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x8c70a6ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x7b59c0ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xa65a27ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3cff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0xa65926ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x695d69ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0xa587bfff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x1b181bff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x292329ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xca402bff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x292329ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x695d69ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x695d69ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x292329ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xcc33ccff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3bff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x695d69ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x159393ff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xcc33ccff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x918b3bff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x526aebff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xa65a27ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x1b181bff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0xbb8a35ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x292329ff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x7b59c0ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0xbb8a35ff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + UserTheme { + name: "Atelier Lakeside Light".into(), + appearance: Appearance::Light, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x80a4b6ff).into()), + border_variant: Some(rgba(0x80a4b6ff).into()), + elevated_surface_background: Some(rgba(0xa6cadcff).into()), + background: Some(rgba(0xa6cadcff).into()), + panel_background: Some(rgba(0xcdeaf9ff).into()), + element_hover: Some(rgba(0x80a4b680).into()), + element_selected: Some(rgba(0x769aad80).into()), + text: Some(rgba(0x526f7dff).into()), + text_muted: Some(rgba(0x7195a8ff).into()), + status_bar_background: Some(rgba(0xa6cadcff).into()), + title_bar_background: Some(rgba(0xa6cadcff).into()), + toolbar_background: Some(rgba(0xebf8ffff).into()), + tab_bar_background: Some(rgba(0xcdeaf9ff).into()), + tab_inactive_background: Some(rgba(0xcdeaf9ff).into()), + tab_active_background: Some(rgba(0xebf8ffff).into()), + scrollbar_thumb_background: Some(rgba(0x161b1d4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x161b1d4d).into()), + scrollbar_thumb_border: Some(rgba(0xd3edfaff).into()), + scrollbar_track_border: Some(rgba(0xd3edfaff).into()), + editor_foreground: Some(rgba(0x1f292eff).into()), + editor_background: Some(rgba(0xebf8ffff).into()), + editor_gutter_background: Some(rgba(0xebf8ffff).into()), + editor_line_number: Some(rgba(0x161b1d59).into()), + editor_active_line_number: Some(rgba(0x161b1dff).into()), + editor_wrap_guide: Some(rgba(0x161b1d0d).into()), + editor_active_wrap_guide: Some(rgba(0x161b1d1a).into()), + terminal_background: Some(rgba(0xebf8ffff).into()), + terminal_ansi_bright_black: Some(rgba(0x7397aaff).into()), + terminal_ansi_bright_red: Some(rgba(0xf09fb6ff).into()), + terminal_ansi_bright_green: Some(rgba(0xabc59aff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xc8c38bff).into()), + terminal_ansi_bright_blue: Some(rgba(0x9ebdd6ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xe09fe9ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x9bc7b5ff).into()), + terminal_ansi_bright_white: Some(rgba(0x161b1dff).into()), + terminal_ansi_black: Some(rgba(0xebf8ffff).into()), + terminal_ansi_red: Some(rgba(0xd22f72ff).into()), + terminal_ansi_green: Some(rgba(0x578c3cff).into()), + terminal_ansi_yellow: Some(rgba(0x8a8a11ff).into()), + terminal_ansi_blue: Some(rgba(0x277fadff).into()), + terminal_ansi_magenta: Some(rgba(0xb72fd2ff).into()), + terminal_ansi_cyan: Some(rgba(0x2f8f6fff).into()), + terminal_ansi_white: Some(rgba(0x161b1dff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x78a361ff).into()), + deleted: Some(rgba(0xd22f72ff).into()), + error: Some(rgba(0xd22f72ff).into()), + modified: Some(rgba(0x8a8a11ff).into()), + success: Some(rgba(0x161b1dff).into()), + warning: Some(rgba(0x8a8a11ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x578c3cff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x7195a8ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x516d7bff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x578c3cff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x161b1dff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0x935d26ff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0x257fadff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0x257fadff).into()), + ..Default::default() + }, + ), + ( + "function.special.definition".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8a0fff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x5a87a0ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x6b6bb8ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0x935d26ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x578c3cff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0x935c25ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x516d7bff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x6a97b2ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x161b1dff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x1f292eff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0xd22d72ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0x1f292eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0x516d7bff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0x516d7bff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0x1f292eff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xb72dd2ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0x568c3bff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x516d7bff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0x2d8f6fff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xb72dd2ff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0x568c3bff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x277fadff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0x935d26ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x161b1dff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8a0fff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0x1f292eff).into()), + ..Default::default() + }, + ), + ( + "variable.special".into(), + UserHighlightStyle { + color: Some(rgba(0x6b6bb8ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x8a8a0fff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }, + ], + } +} diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index 9c977234b98802a6932cd89bfa79e7e39e2b9739..4bd39894db4de57dce964279bac09d577bcdd256 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -12,75 +12,65 @@ use crate::{ pub fn ayu() -> UserThemeFamily { UserThemeFamily { name: "Ayu".into(), - author: "dempfi (Ike Ku)".into(), + author: "Zed Industries".into(), themes: vec![ UserTheme { - name: "Ayu Light".into(), - appearance: Appearance::Light, + name: "Ayu Dark".into(), + appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x6b7d8f1f).into()), - border_variant: Some(rgba(0x6b7d8f1f).into()), - border_focused: Some(rgba(0xffaa33b3).into()), - border_selected: Some(rgba(0x6b7d8f1f).into()), - border_transparent: Some(rgba(0x6b7d8f1f).into()), - border_disabled: Some(rgba(0x6b7d8f1f).into()), - elevated_surface_background: Some(rgba(0xfcfcfcff).into()), - surface_background: Some(rgba(0xf8f9faff).into()), - background: Some(rgba(0xf8f9faff).into()), - element_background: Some(rgba(0xffaa33ff).into()), - element_hover: Some(rgba(0x56728f1f).into()), - element_selected: Some(rgba(0x56728f1f).into()), - ghost_element_hover: Some(rgba(0x56728f1f).into()), - ghost_element_selected: Some(rgba(0x56728f1f).into()), - text: Some(rgba(0x8a9199ff).into()), - text_muted: Some(rgba(0x8a9199ff).into()), - status_bar_background: Some(rgba(0xf8f9faff).into()), - title_bar_background: Some(rgba(0xf8f9faff).into()), - toolbar_background: Some(rgba(0xf8f9faff).into()), - tab_bar_background: Some(rgba(0xf8f9faff).into()), - tab_inactive_background: Some(rgba(0xf8f9faff).into()), - tab_active_background: Some(rgba(0xf8f9faff).into()), - scrollbar_thumb_background: Some(rgba(0x8a919966).into()), - scrollbar_thumb_hover_background: Some(rgba(0x8a919999).into()), - scrollbar_thumb_border: Some(rgba(0x8a919966).into()), - scrollbar_track_background: Some(rgba(0xf8f9faff).into()), - scrollbar_track_border: Some(rgba(0x6b7d8f1f).into()), - editor_foreground: Some(rgba(0x5c6166ff).into()), - editor_background: Some(rgba(0xf8f9faff).into()), - editor_gutter_background: Some(rgba(0xf8f9faff).into()), - editor_line_number: Some(rgba(0x8a919966).into()), - editor_active_line_number: Some(rgba(0x5c6166ff).into()), - editor_wrap_guide: Some(rgba(0x6b7d8f1f).into()), - editor_active_wrap_guide: Some(rgba(0x6b7d8f1f).into()), - terminal_background: Some(rgba(0xf8f9faff).into()), - terminal_ansi_bright_black: Some(rgba(0x686868ff).into()), - terminal_ansi_bright_red: Some(rgba(0xf07171ff).into()), - terminal_ansi_bright_green: Some(rgba(0x86b300ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xf2ae49ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x399ee6ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xa37accff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x4cbf99ff).into()), - terminal_ansi_bright_white: Some(rgba(0xd1d1d1ff).into()), - terminal_ansi_black: Some(rgba(0x000000ff).into()), - terminal_ansi_red: Some(rgba(0xea6c6dff).into()), - terminal_ansi_green: Some(rgba(0x6cbf43ff).into()), - terminal_ansi_yellow: Some(rgba(0xeca944ff).into()), - terminal_ansi_blue: Some(rgba(0x3199e1ff).into()), - terminal_ansi_magenta: Some(rgba(0x9e75c7ff).into()), - terminal_ansi_cyan: Some(rgba(0x46ba94ff).into()), - terminal_ansi_white: Some(rgba(0xc7c7c7ff).into()), - link_text_hover: Some(rgba(0xffaa33ff).into()), + border: Some(rgba(0x3f4043ff).into()), + border_variant: Some(rgba(0x3f4043ff).into()), + elevated_surface_background: Some(rgba(0x313337ff).into()), + background: Some(rgba(0x313337ff).into()), + panel_background: Some(rgba(0x1f2127ff).into()), + element_hover: Some(rgba(0x3f404380).into()), + element_selected: Some(rgba(0x50515280).into()), + text: Some(rgba(0x8a8986ff).into()), + text_muted: Some(rgba(0x58595aff).into()), + status_bar_background: Some(rgba(0x313337ff).into()), + title_bar_background: Some(rgba(0x313337ff).into()), + toolbar_background: Some(rgba(0x0d1017ff).into()), + tab_bar_background: Some(rgba(0x1f2127ff).into()), + tab_inactive_background: Some(rgba(0x1f2127ff).into()), + tab_active_background: Some(rgba(0x0d1017ff).into()), + scrollbar_thumb_background: Some(rgba(0xbfbdb64d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xbfbdb64d).into()), + scrollbar_thumb_border: Some(rgba(0x1b1e24ff).into()), + scrollbar_track_border: Some(rgba(0x1b1e24ff).into()), + editor_foreground: Some(rgba(0xbfbdb6ff).into()), + editor_background: Some(rgba(0x0d1017ff).into()), + editor_gutter_background: Some(rgba(0x0d1017ff).into()), + editor_line_number: Some(rgba(0xbfbdb659).into()), + editor_active_line_number: Some(rgba(0xbfbdb6ff).into()), + editor_wrap_guide: Some(rgba(0xbfbdb60d).into()), + editor_active_wrap_guide: Some(rgba(0xbfbdb61a).into()), + terminal_background: Some(rgba(0x0d1017ff).into()), + terminal_ansi_bright_black: Some(rgba(0x545557ff).into()), + terminal_ansi_bright_red: Some(rgba(0x83363cff).into()), + terminal_ansi_bright_green: Some(rgba(0x567627ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x92592cff).into()), + terminal_ansi_bright_blue: Some(rgba(0x28628cff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x205b78ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x4c806fff).into()), + terminal_ansi_bright_white: Some(rgba(0xbfbdb6ff).into()), + terminal_ansi_black: Some(rgba(0x0d1017ff).into()), + terminal_ansi_red: Some(rgba(0xef7178ff).into()), + terminal_ansi_green: Some(rgba(0xaad84cff).into()), + terminal_ansi_yellow: Some(rgba(0xfeb454ff).into()), + terminal_ansi_blue: Some(rgba(0x5ac2feff).into()), + terminal_ansi_magenta: Some(rgba(0x3abae5ff).into()), + terminal_ansi_cyan: Some(rgba(0x95e5cbff).into()), + terminal_ansi_white: Some(rgba(0xbfbdb6ff).into()), ..Default::default() }, status: StatusColorsRefinement { - created: Some(rgba(0x6cbf43cc).into()), - deleted: Some(rgba(0xff7383cc).into()), - error: Some(rgba(0xe65050ff).into()), - hidden: Some(rgba(0x8a9199ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x8a919980).into()), - modified: Some(rgba(0x478acccc).into()), + created: Some(rgba(0xaad84cff).into()), + deleted: Some(rgba(0xc3595fff).into()), + error: Some(rgba(0xef7178ff).into()), + modified: Some(rgba(0xfeb454ff).into()), + success: Some(rgba(0xbfbdb6ff).into()), + warning: Some(rgba(0xfeb454ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -88,235 +78,271 @@ pub fn ayu() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xf2ae49ff).into()), + color: Some(rgba(0x5ac2feff).into()), ..Default::default() }, ), ( "boolean".into(), UserHighlightStyle { - color: Some(rgba(0xa37accff).into()), + color: Some(rgba(0xd2a6ffff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x787b8099).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xacb6bf8c).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x787b8099).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x8c8b88ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0xa37accff).into()), + color: Some(rgba(0xd2a6ffff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x55b4d4ff).into()), + color: Some(rgba(0x5ac2feff).into()), ..Default::default() }, ), ( "embedded".into(), UserHighlightStyle { - color: Some(rgba(0x5c6166ff).into()), + color: Some(rgba(0xbfbdb6ff).into()), ..Default::default() }, ), ( "emphasis".into(), UserHighlightStyle { - color: Some(rgba(0xf07171ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x5ac2feff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xf07171ff).into()), + color: Some(rgba(0x5ac2feff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xfe8f40ff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0xf2ae49ff).into()), + color: Some(rgba(0xffb454ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x638c81ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0xfa8d3eff).into()), + color: Some(rgba(0xff8f40ff).into()), ..Default::default() }, ), ( "label".into(), UserHighlightStyle { - color: Some(rgba(0x86b300ff).into()), + color: Some(rgba(0x5ac2feff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0x55b4d4ff).into()), + color: Some(rgba(0xfe8f40ff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "link_uri".into(), UserHighlightStyle { - color: Some(rgba(0x55b4d4ff).into()), + color: Some(rgba(0xaad84cff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xa37accff).into()), + color: Some(rgba(0xd2a6ffff).into()), ..Default::default() }, ), ( "operator".into(), UserHighlightStyle { - color: Some(rgba(0xed9366ff).into()), + color: Some(rgba(0xf29668ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x5b728cff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xbfbdb6ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xbfbdb6ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0xf07171ff).into()), + color: Some(rgba(0x5ac2feff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0x5c6166ff).into()), + color: Some(rgba(0xa6a5a0ff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x55b4d480).into()), + color: Some(rgba(0xa6a5a0ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0x5c6166b3).into()), + color: Some(rgba(0xa6a5a0ff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0xf2ae49ff).into()), + color: Some(rgba(0xa6a5a0ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0x5c6166ff).into()), + color: Some(rgba(0xd2a6ffff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0x86b300ff).into()), + color: Some(rgba(0xaad94cff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0x4cbf99ff).into()), + color: Some(rgba(0x8c8b88ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0x86b300ff).into()), + color: Some(rgba(0x95e6cbff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0x86b300ff).into()), + color: Some(rgba(0xe6b673ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0x86b300ff).into()), + color: Some(rgba(0xfe8f40ff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x55b4d4ff).into()), + color: Some(rgba(0x5ac2feff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0x86b300ff).into()), + color: Some(rgba(0xfe8f40ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0x399ee6ff).into()), + color: Some(rgba(0xbfbdb6ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0x55b4d4ff).into()), + color: Some(rgba(0x59c2ffff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0x5c6166ff).into()), + color: Some(rgba(0xbfbdb6ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0xf07171ff).into()), + color: Some(rgba(0x5ac2feff).into()), ..Default::default() }, ), @@ -325,72 +351,62 @@ pub fn ayu() -> UserThemeFamily { }, }, UserTheme { - name: "Ayu Mirage".into(), - appearance: Appearance::Dark, + name: "Ayu Light".into(), + appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x171b24ff).into()), - border_variant: Some(rgba(0x171b24ff).into()), - border_focused: Some(rgba(0xffcc66b3).into()), - border_selected: Some(rgba(0x171b24ff).into()), - border_transparent: Some(rgba(0x171b24ff).into()), - border_disabled: Some(rgba(0x171b24ff).into()), - elevated_surface_background: Some(rgba(0x242936ff).into()), - surface_background: Some(rgba(0x1f2430ff).into()), - background: Some(rgba(0x1f2430ff).into()), - element_background: Some(rgba(0xffcc66ff).into()), - element_hover: Some(rgba(0x63759926).into()), - element_selected: Some(rgba(0x63759926).into()), - ghost_element_hover: Some(rgba(0x63759926).into()), - ghost_element_selected: Some(rgba(0x63759926).into()), - text: Some(rgba(0x707a8cff).into()), - text_muted: Some(rgba(0x707a8cff).into()), - status_bar_background: Some(rgba(0x1f2430ff).into()), - title_bar_background: Some(rgba(0x1f2430ff).into()), - toolbar_background: Some(rgba(0x1f2430ff).into()), - tab_bar_background: Some(rgba(0x1f2430ff).into()), - tab_inactive_background: Some(rgba(0x1f2430ff).into()), - tab_active_background: Some(rgba(0x1f2430ff).into()), - scrollbar_thumb_background: Some(rgba(0x707a8c66).into()), - scrollbar_thumb_hover_background: Some(rgba(0x707a8c99).into()), - scrollbar_thumb_border: Some(rgba(0x707a8c66).into()), - scrollbar_track_background: Some(rgba(0x1f2430ff).into()), - scrollbar_track_border: Some(rgba(0x171b24ff).into()), - editor_foreground: Some(rgba(0xcccac2ff).into()), - editor_background: Some(rgba(0x1f2430ff).into()), - editor_gutter_background: Some(rgba(0x1f2430ff).into()), - editor_line_number: Some(rgba(0x8a919966).into()), - editor_active_line_number: Some(rgba(0xcccac2ff).into()), - editor_wrap_guide: Some(rgba(0x171b24ff).into()), - editor_active_wrap_guide: Some(rgba(0x171b24ff).into()), - terminal_background: Some(rgba(0x1f2430ff).into()), - terminal_ansi_bright_black: Some(rgba(0x686868ff).into()), - terminal_ansi_bright_red: Some(rgba(0xf28779ff).into()), - terminal_ansi_bright_green: Some(rgba(0xd5ff80ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xffd173ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x73d0ffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xdfbfffff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x95e6cbff).into()), - terminal_ansi_bright_white: Some(rgba(0xffffffff).into()), - terminal_ansi_black: Some(rgba(0x171b24ff).into()), - terminal_ansi_red: Some(rgba(0xed8274ff).into()), - terminal_ansi_green: Some(rgba(0x87d96cff).into()), - terminal_ansi_yellow: Some(rgba(0xfacc6eff).into()), - terminal_ansi_blue: Some(rgba(0x6dcbfaff).into()), - terminal_ansi_magenta: Some(rgba(0xdabafaff).into()), - terminal_ansi_cyan: Some(rgba(0x90e1c6ff).into()), - terminal_ansi_white: Some(rgba(0xc7c7c7ff).into()), - link_text_hover: Some(rgba(0xffcc66ff).into()), + border: Some(rgba(0xcfd1d2ff).into()), + border_variant: Some(rgba(0xcfd1d2ff).into()), + elevated_surface_background: Some(rgba(0xdcdddeff).into()), + background: Some(rgba(0xdcdddeff).into()), + panel_background: Some(rgba(0xececedff).into()), + element_hover: Some(rgba(0xcfd1d280).into()), + element_selected: Some(rgba(0xc0c2c480).into()), + text: Some(rgba(0x8c8f93ff).into()), + text_muted: Some(rgba(0xb9bbbdff).into()), + status_bar_background: Some(rgba(0xdcdddeff).into()), + title_bar_background: Some(rgba(0xdcdddeff).into()), + toolbar_background: Some(rgba(0xfcfcfcff).into()), + tab_bar_background: Some(rgba(0xececedff).into()), + tab_inactive_background: Some(rgba(0xececedff).into()), + tab_active_background: Some(rgba(0xfcfcfcff).into()), + scrollbar_thumb_background: Some(rgba(0x5c61664d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x5c61664d).into()), + scrollbar_thumb_border: Some(rgba(0xefeff0ff).into()), + scrollbar_track_border: Some(rgba(0xefeff0ff).into()), + editor_foreground: Some(rgba(0x5c6166ff).into()), + editor_background: Some(rgba(0xfcfcfcff).into()), + editor_gutter_background: Some(rgba(0xfcfcfcff).into()), + editor_line_number: Some(rgba(0x5c616659).into()), + editor_active_line_number: Some(rgba(0x5c6166ff).into()), + editor_wrap_guide: Some(rgba(0x5c61660d).into()), + editor_active_wrap_guide: Some(rgba(0x5c61661a).into()), + terminal_background: Some(rgba(0xfcfcfcff).into()), + terminal_ansi_bright_black: Some(rgba(0xbcbec0ff).into()), + terminal_ansi_bright_red: Some(rgba(0xfebab6ff).into()), + terminal_ansi_bright_green: Some(rgba(0xc7d98fff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xffd6a4ff).into()), + terminal_ansi_bright_blue: Some(rgba(0xaccef3ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xb2d9e9ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0xace0cbff).into()), + terminal_ansi_bright_white: Some(rgba(0x5c6166ff).into()), + terminal_ansi_black: Some(rgba(0xfcfcfcff).into()), + terminal_ansi_red: Some(rgba(0xef7271ff).into()), + terminal_ansi_green: Some(rgba(0x86b305ff).into()), + terminal_ansi_yellow: Some(rgba(0xf1ae4aff).into()), + terminal_ansi_blue: Some(rgba(0x3b9ee5ff).into()), + terminal_ansi_magenta: Some(rgba(0x56b4d3ff).into()), + terminal_ansi_cyan: Some(rgba(0x4dbf99ff).into()), + terminal_ansi_white: Some(rgba(0x5c6166ff).into()), ..Default::default() }, status: StatusColorsRefinement { - created: Some(rgba(0x87d96ccc).into()), - deleted: Some(rgba(0xf27983cc).into()), - error: Some(rgba(0xff6666ff).into()), - hidden: Some(rgba(0x707a8cff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x707a8c80).into()), - modified: Some(rgba(0x80bfffcc).into()), + created: Some(rgba(0xa1c24bff).into()), + deleted: Some(rgba(0xef7271ff).into()), + error: Some(rgba(0xef7271ff).into()), + modified: Some(rgba(0xf1ae4aff).into()), + success: Some(rgba(0x5c6166ff).into()), + warning: Some(rgba(0xf1ae4aff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -398,235 +414,271 @@ pub fn ayu() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xffd173ff).into()), + color: Some(rgba(0x3b9ee5ff).into()), ..Default::default() }, ), ( "boolean".into(), UserHighlightStyle { - color: Some(rgba(0xdfbfffff).into()), + color: Some(rgba(0xa37accff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0xb8cfe680).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x787b8099).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0xb8cfe680).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x8a8e91ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0xdfbfffff).into()), + color: Some(rgba(0xa37accff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x5ccfe6ff).into()), + color: Some(rgba(0x3b9ee5ff).into()), ..Default::default() }, ), ( "embedded".into(), UserHighlightStyle { - color: Some(rgba(0xcccac2ff).into()), + color: Some(rgba(0x5c6166ff).into()), ..Default::default() }, ), ( "emphasis".into(), UserHighlightStyle { - color: Some(rgba(0xf28779ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x3b9ee5ff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xf28779ff).into()), + color: Some(rgba(0x3b9ee5ff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xf98d3fff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0xffd173ff).into()), + color: Some(rgba(0xf2ae49ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x8ca7c2ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0xffad66ff).into()), + color: Some(rgba(0xfa8d3eff).into()), ..Default::default() }, ), ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xd5ff80ff).into()), + color: Some(rgba(0x3b9ee5ff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0x5ccfe6ff).into()), + color: Some(rgba(0xf98d3fff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "link_uri".into(), UserHighlightStyle { - color: Some(rgba(0x5ccfe6ff).into()), + color: Some(rgba(0x86b305ff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xdfbfffff).into()), + color: Some(rgba(0xa37accff).into()), ..Default::default() }, ), ( "operator".into(), UserHighlightStyle { - color: Some(rgba(0xf29e74ff).into()), + color: Some(rgba(0xed9366ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x9eb9d3ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x5c6166ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x5c6166ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0xf28779ff).into()), + color: Some(rgba(0x3b9ee5ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0xcccac2ff).into()), + color: Some(rgba(0x73777bff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x5ccfe680).into()), + color: Some(rgba(0x73777bff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0xcccac2b3).into()), + color: Some(rgba(0x73777bff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0xffd173ff).into()), + color: Some(rgba(0x73777bff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0xcccac2ff).into()), + color: Some(rgba(0xa37accff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0xd5ff80ff).into()), + color: Some(rgba(0x86b300ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0x95e6cbff).into()), + color: Some(rgba(0x8a8e91ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xd5ff80ff).into()), + color: Some(rgba(0x4cbf99ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xd5ff80ff).into()), + color: Some(rgba(0xe6ba7eff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xd5ff80ff).into()), + color: Some(rgba(0xf98d3fff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x5ccfe6ff).into()), + color: Some(rgba(0x3b9ee5ff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xd5ff80ff).into()), + color: Some(rgba(0xf98d3fff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0x73d0ffff).into()), + color: Some(rgba(0x5c6166ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0x5ccfe6ff).into()), + color: Some(rgba(0x399ee6ff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0xcccac2ff).into()), + color: Some(rgba(0x5c6166ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0xf28779ff).into()), + color: Some(rgba(0x3b9ee5ff).into()), ..Default::default() }, ), @@ -635,72 +687,62 @@ pub fn ayu() -> UserThemeFamily { }, }, UserTheme { - name: "Ayu Dark".into(), + name: "Ayu Mirage".into(), appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x1e232bff).into()), - border_variant: Some(rgba(0x1e232bff).into()), - border_focused: Some(rgba(0xe6b450b3).into()), - border_selected: Some(rgba(0x1e232bff).into()), - border_transparent: Some(rgba(0x1e232bff).into()), - border_disabled: Some(rgba(0x1e232bff).into()), - elevated_surface_background: Some(rgba(0x0d1017ff).into()), - surface_background: Some(rgba(0x0b0e14ff).into()), - background: Some(rgba(0x0b0e14ff).into()), - element_background: Some(rgba(0xe6b450ff).into()), - element_hover: Some(rgba(0x47526640).into()), - element_selected: Some(rgba(0x47526640).into()), - ghost_element_hover: Some(rgba(0x47526640).into()), - ghost_element_selected: Some(rgba(0x47526640).into()), - text: Some(rgba(0x565b66ff).into()), - text_muted: Some(rgba(0x565b66ff).into()), - status_bar_background: Some(rgba(0x0b0e14ff).into()), - title_bar_background: Some(rgba(0x0b0e14ff).into()), - toolbar_background: Some(rgba(0x0b0e14ff).into()), - tab_bar_background: Some(rgba(0x0b0e14ff).into()), - tab_inactive_background: Some(rgba(0x0b0e14ff).into()), - tab_active_background: Some(rgba(0x0b0e14ff).into()), - scrollbar_thumb_background: Some(rgba(0x565b6666).into()), - scrollbar_thumb_hover_background: Some(rgba(0x565b6699).into()), - scrollbar_thumb_border: Some(rgba(0x565b6666).into()), - scrollbar_track_background: Some(rgba(0x0b0e14ff).into()), - scrollbar_track_border: Some(rgba(0x1e232bff).into()), - editor_foreground: Some(rgba(0xbfbdb6ff).into()), - editor_background: Some(rgba(0x0b0e14ff).into()), - editor_gutter_background: Some(rgba(0x0b0e14ff).into()), - editor_line_number: Some(rgba(0x6c738099).into()), - editor_active_line_number: Some(rgba(0xbfbdb6ff).into()), - editor_wrap_guide: Some(rgba(0x1e232bff).into()), - editor_active_wrap_guide: Some(rgba(0x1e232bff).into()), - terminal_background: Some(rgba(0x0b0e14ff).into()), - terminal_ansi_bright_black: Some(rgba(0x686868ff).into()), - terminal_ansi_bright_red: Some(rgba(0xf07178ff).into()), - terminal_ansi_bright_green: Some(rgba(0xaad94cff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xffb454ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x59c2ffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xd2a6ffff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x95e6cbff).into()), - terminal_ansi_bright_white: Some(rgba(0xffffffff).into()), - terminal_ansi_black: Some(rgba(0x1e232bff).into()), - terminal_ansi_red: Some(rgba(0xea6c73ff).into()), - terminal_ansi_green: Some(rgba(0x7fd962ff).into()), - terminal_ansi_yellow: Some(rgba(0xf9af4fff).into()), - terminal_ansi_blue: Some(rgba(0x53bdfaff).into()), - terminal_ansi_magenta: Some(rgba(0xcda1faff).into()), - terminal_ansi_cyan: Some(rgba(0x90e1c6ff).into()), - terminal_ansi_white: Some(rgba(0xc7c7c7ff).into()), - link_text_hover: Some(rgba(0xe6b450ff).into()), + border: Some(rgba(0x53565dff).into()), + border_variant: Some(rgba(0x53565dff).into()), + elevated_surface_background: Some(rgba(0x464a52ff).into()), + background: Some(rgba(0x464a52ff).into()), + panel_background: Some(rgba(0x353944ff).into()), + element_hover: Some(rgba(0x53565d80).into()), + element_selected: Some(rgba(0x63656a80).into()), + text: Some(rgba(0x9a9a98ff).into()), + text_muted: Some(rgba(0x6b6d71ff).into()), + status_bar_background: Some(rgba(0x464a52ff).into()), + title_bar_background: Some(rgba(0x464a52ff).into()), + toolbar_background: Some(rgba(0x242936ff).into()), + tab_bar_background: Some(rgba(0x353944ff).into()), + tab_inactive_background: Some(rgba(0x353944ff).into()), + tab_active_background: Some(rgba(0x242936ff).into()), + scrollbar_thumb_background: Some(rgba(0xcccac24d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xcccac24d).into()), + scrollbar_thumb_border: Some(rgba(0x323641ff).into()), + scrollbar_track_border: Some(rgba(0x323641ff).into()), + editor_foreground: Some(rgba(0xcccac2ff).into()), + editor_background: Some(rgba(0x242936ff).into()), + editor_gutter_background: Some(rgba(0x242936ff).into()), + editor_line_number: Some(rgba(0xcccac259).into()), + editor_active_line_number: Some(rgba(0xcccac2ff).into()), + editor_wrap_guide: Some(rgba(0xcccac20d).into()), + editor_active_wrap_guide: Some(rgba(0xcccac21a).into()), + terminal_background: Some(rgba(0x242936ff).into()), + terminal_ansi_bright_black: Some(rgba(0x67696eff).into()), + terminal_ansi_bright_red: Some(rgba(0x83403dff).into()), + terminal_ansi_bright_green: Some(rgba(0x76993dff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x937238ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x346e8dff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x2b6c7bff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x4c806fff).into()), + terminal_ansi_bright_white: Some(rgba(0xcccac2ff).into()), + terminal_ansi_black: Some(rgba(0x242936ff).into()), + terminal_ansi_red: Some(rgba(0xf18779ff).into()), + terminal_ansi_green: Some(rgba(0xd5fe80ff).into()), + terminal_ansi_yellow: Some(rgba(0xfed073ff).into()), + terminal_ansi_blue: Some(rgba(0x73cffeff).into()), + terminal_ansi_magenta: Some(rgba(0x5ccee5ff).into()), + terminal_ansi_cyan: Some(rgba(0x95e5cbff).into()), + terminal_ansi_white: Some(rgba(0xcccac2ff).into()), ..Default::default() }, status: StatusColorsRefinement { - created: Some(rgba(0x7fd962cc).into()), - deleted: Some(rgba(0xf26d78cc).into()), - error: Some(rgba(0xd95757ff).into()), - hidden: Some(rgba(0x565b66ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x565b6680).into()), - modified: Some(rgba(0x73b8ffcc).into()), + created: Some(rgba(0xd5fe80ff).into()), + deleted: Some(rgba(0xc46a60ff).into()), + error: Some(rgba(0xf18779ff).into()), + modified: Some(rgba(0xfed073ff).into()), + success: Some(rgba(0xcccac2ff).into()), + warning: Some(rgba(0xfed073ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -708,235 +750,271 @@ pub fn ayu() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xffb454ff).into()), + color: Some(rgba(0x73cffeff).into()), ..Default::default() }, ), ( "boolean".into(), UserHighlightStyle { - color: Some(rgba(0xd2a6ffff).into()), + color: Some(rgba(0xdfbfffff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0xacb6bf8c).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xb8cfe680).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0xacb6bf8c).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x9b9b99ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0xd2a6ffff).into()), + color: Some(rgba(0xdfbfffff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x39bae6ff).into()), + color: Some(rgba(0x73cffeff).into()), ..Default::default() }, ), ( "embedded".into(), UserHighlightStyle { - color: Some(rgba(0xbfbdb6ff).into()), + color: Some(rgba(0xcccac2ff).into()), ..Default::default() }, ), ( "emphasis".into(), UserHighlightStyle { - color: Some(rgba(0xf07178ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x73cffeff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xf07178ff).into()), + color: Some(rgba(0x73cffeff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xfead66ff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0xffb454ff).into()), + color: Some(rgba(0xffd173ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x7399a3ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0xff8f40ff).into()), + color: Some(rgba(0xffad66ff).into()), ..Default::default() }, ), ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xaad94cff).into()), + color: Some(rgba(0x73cffeff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0x39bae6ff).into()), + color: Some(rgba(0xfead66ff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "link_uri".into(), UserHighlightStyle { - color: Some(rgba(0x39bae6ff).into()), + color: Some(rgba(0xd5fe80ff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xd2a6ffff).into()), + color: Some(rgba(0xdfbfffff).into()), ..Default::default() }, ), ( "operator".into(), UserHighlightStyle { - color: Some(rgba(0xf29668ff).into()), + color: Some(rgba(0xf29e74ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x6d839bff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xcccac2ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xcccac2ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0xf07178ff).into()), + color: Some(rgba(0x73cffeff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0xbfbdb6ff).into()), + color: Some(rgba(0xb4b3aeff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x39bae680).into()), + color: Some(rgba(0xb4b3aeff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0xbfbdb6b3).into()), + color: Some(rgba(0xb4b3aeff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0xffb454ff).into()), + color: Some(rgba(0xb4b3aeff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0xbfbdb6ff).into()), + color: Some(rgba(0xdfbfffff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0xaad94cff).into()), + color: Some(rgba(0xd5ff80ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0x95e6cbff).into()), + color: Some(rgba(0x9b9b99ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xaad94cff).into()), + color: Some(rgba(0x95e6cbff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xaad94cff).into()), + color: Some(rgba(0xffdfb3ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xaad94cff).into()), + color: Some(rgba(0xfead66ff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x39bae6ff).into()), + color: Some(rgba(0x73cffeff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xaad94cff).into()), + color: Some(rgba(0xfead66ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0x59c2ffff).into()), + color: Some(rgba(0xcccac2ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0x39bae6ff).into()), + color: Some(rgba(0x73d0ffff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0xbfbdb6ff).into()), + color: Some(rgba(0xcccac2ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0xf07178ff).into()), + color: Some(rgba(0x73cffeff).into()), ..Default::default() }, ), diff --git a/crates/theme2/src/themes/dracula.rs b/crates/theme2/src/themes/dracula.rs deleted file mode 100644 index 9d9da27eed7a9bfa9a767d43d01d26888cd6eb25..0000000000000000000000000000000000000000 --- a/crates/theme2/src/themes/dracula.rs +++ /dev/null @@ -1,250 +0,0 @@ -// This file was generated by the `theme_importer`. -// Be careful when modifying it by hand. - -use gpui::rgba; - -#[allow(unused)] -use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, -}; - -pub fn dracula() -> UserThemeFamily { - UserThemeFamily { - name: "Dracula".into(), - author: "Zeno Rocha".into(), - themes: vec![UserTheme { - name: "Dracula".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0xbd93f9ff).into()), - border_variant: Some(rgba(0xbd93f9ff).into()), - border_focused: Some(rgba(0x6272a4ff).into()), - border_selected: Some(rgba(0xbd93f9ff).into()), - border_transparent: Some(rgba(0xbd93f9ff).into()), - border_disabled: Some(rgba(0xbd93f9ff).into()), - elevated_surface_background: Some(rgba(0x343746ff).into()), - surface_background: Some(rgba(0x282a36ff).into()), - background: Some(rgba(0x282a36ff).into()), - element_background: Some(rgba(0x44475aff).into()), - element_hover: Some(rgba(0x44475a75).into()), - element_selected: Some(rgba(0x44475aff).into()), - drop_target_background: Some(rgba(0x44475aff).into()), - ghost_element_hover: Some(rgba(0x44475a75).into()), - ghost_element_selected: Some(rgba(0x44475aff).into()), - text: Some(rgba(0xf8f8f2ff).into()), - text_muted: Some(rgba(0x6272a4ff).into()), - status_bar_background: Some(rgba(0x191a21ff).into()), - title_bar_background: Some(rgba(0x21222cff).into()), - toolbar_background: Some(rgba(0x282a36ff).into()), - tab_bar_background: Some(rgba(0x191a21ff).into()), - tab_inactive_background: Some(rgba(0x21222cff).into()), - tab_active_background: Some(rgba(0x282a36ff).into()), - scrollbar_track_background: Some(rgba(0x282a36ff).into()), - scrollbar_track_border: Some(rgba(0x191a21ff).into()), - editor_foreground: Some(rgba(0xf8f8f2ff).into()), - editor_background: Some(rgba(0x282a36ff).into()), - editor_gutter_background: Some(rgba(0x282a36ff).into()), - editor_line_number: Some(rgba(0x6272a4ff).into()), - editor_active_line_number: Some(rgba(0xf8f8f2ff).into()), - editor_wrap_guide: Some(rgba(0xbd93f9ff).into()), - editor_active_wrap_guide: Some(rgba(0xbd93f9ff).into()), - terminal_background: Some(rgba(0x282a36ff).into()), - terminal_ansi_bright_black: Some(rgba(0x6272a4ff).into()), - terminal_ansi_bright_red: Some(rgba(0xff6e6eff).into()), - terminal_ansi_bright_green: Some(rgba(0x69ff94ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xffffa5ff).into()), - terminal_ansi_bright_blue: Some(rgba(0xd6acffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xff92dfff).into()), - terminal_ansi_bright_cyan: Some(rgba(0xa4ffffff).into()), - terminal_ansi_bright_white: Some(rgba(0xffffffff).into()), - terminal_ansi_black: Some(rgba(0x21222cff).into()), - terminal_ansi_red: Some(rgba(0xff5555ff).into()), - terminal_ansi_green: Some(rgba(0x50fa7bff).into()), - terminal_ansi_yellow: Some(rgba(0xf1fa8cff).into()), - terminal_ansi_blue: Some(rgba(0xbd93f9ff).into()), - terminal_ansi_magenta: Some(rgba(0xff79c6ff).into()), - terminal_ansi_cyan: Some(rgba(0x8be9fdff).into()), - terminal_ansi_white: Some(rgba(0xf8f8f2ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xffb86cff).into()), - created: Some(rgba(0x50fa7b80).into()), - deleted: Some(rgba(0xff555580).into()), - error: Some(rgba(0xff5555ff).into()), - hidden: Some(rgba(0x6272a4ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x6272a4ff).into()), - modified: Some(rgba(0x8be9fd80).into()), - warning: Some(rgba(0xffb86cff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "attribute".into(), - UserHighlightStyle { - color: Some(rgba(0x50fa7bff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x6272a4ff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x6272a4ff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xbd93f9ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xff79c6ff).into()), - ..Default::default() - }, - ), - ( - "emphasis".into(), - UserHighlightStyle { - color: Some(rgba(0xf1fa8cff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "emphasis.strong".into(), - UserHighlightStyle { - color: Some(rgba(0xffb86cff).into()), - font_weight: Some(UserFontWeight(700.0)), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x50fa7bff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xff79c6ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x8be9fdff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x8be9fdff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0xbd93f9ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0xf1fa8cff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xf1fa8cff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0xf1fa8cff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0xf1fa8cff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0xf1fa8cff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xff79c6ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0xf1fa8cff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0x8be9fdff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xf8f8f2ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xbd93f9ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ], - }), - }, - }], - } -} diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index abce861f91dc81e4a58a51bba25ab4a35afeaf4e..e0b2e44101ee13976e95a8d7b2ca9043ca39bc64 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -12,76 +12,65 @@ use crate::{ pub fn gruvbox() -> UserThemeFamily { UserThemeFamily { name: "Gruvbox".into(), - author: "morhetz".into(), + author: "Zed Industries".into(), themes: vec![ UserTheme { - name: "Gruvbox Dark Hard".into(), - appearance: Appearance::Dark, + name: "Gruvbox Light Hard".into(), + appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x3c3836ff).into()), - border_variant: Some(rgba(0x3c3836ff).into()), - border_focused: Some(rgba(0x3c3836ff).into()), - border_selected: Some(rgba(0x3c3836ff).into()), - border_transparent: Some(rgba(0x3c3836ff).into()), - border_disabled: Some(rgba(0x3c3836ff).into()), - elevated_surface_background: Some(rgba(0x1d2021ff).into()), - background: Some(rgba(0x1d2021ff).into()), - element_background: Some(rgba(0x45858880).into()), - element_hover: Some(rgba(0x3c383680).into()), - element_selected: Some(rgba(0x3c383680).into()), - drop_target_background: Some(rgba(0x3c3836ff).into()), - ghost_element_hover: Some(rgba(0x3c383680).into()), - ghost_element_selected: Some(rgba(0x3c383680).into()), - text: Some(rgba(0xebdbb2ff).into()), - text_muted: Some(rgba(0xa89984ff).into()), - status_bar_background: Some(rgba(0x1d2021ff).into()), - title_bar_background: Some(rgba(0x1d2021ff).into()), - toolbar_background: Some(rgba(0x1d2021ff).into()), - tab_bar_background: Some(rgba(0x1d2021ff).into()), - tab_inactive_background: Some(rgba(0x1d2021ff).into()), - tab_active_background: Some(rgba(0x32302fff).into()), - scrollbar_thumb_background: Some(rgba(0x50494599).into()), - scrollbar_thumb_hover_background: Some(rgba(0x665c54ff).into()), - scrollbar_thumb_border: Some(rgba(0x50494599).into()), - scrollbar_track_background: Some(rgba(0x1d2021ff).into()), - scrollbar_track_border: Some(rgba(0x1d202100).into()), - editor_foreground: Some(rgba(0xebdbb2ff).into()), - editor_background: Some(rgba(0x1d2021ff).into()), - editor_gutter_background: Some(rgba(0x1d2021ff).into()), - editor_line_number: Some(rgba(0x665c54ff).into()), - editor_active_line_number: Some(rgba(0xebdbb2ff).into()), - editor_wrap_guide: Some(rgba(0x3c3836ff).into()), - editor_active_wrap_guide: Some(rgba(0x3c3836ff).into()), - terminal_background: Some(rgba(0x1d2021ff).into()), - terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), - terminal_ansi_bright_red: Some(rgba(0xfb4934ff).into()), - terminal_ansi_bright_green: Some(rgba(0xb8bb26ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xfabd2fff).into()), - terminal_ansi_bright_blue: Some(rgba(0x83a598ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xd3869bff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x8ec07cff).into()), - terminal_ansi_bright_white: Some(rgba(0xebdbb2ff).into()), - terminal_ansi_black: Some(rgba(0x3c3836ff).into()), - terminal_ansi_red: Some(rgba(0xcc241dff).into()), - terminal_ansi_green: Some(rgba(0x98971aff).into()), - terminal_ansi_yellow: Some(rgba(0xd79921ff).into()), - terminal_ansi_blue: Some(rgba(0x458588ff).into()), - terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), - terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), - terminal_ansi_white: Some(rgba(0xa89984ff).into()), - link_text_hover: Some(rgba(0x458588ff).into()), + border: Some(rgba(0xc9b99aff).into()), + border_variant: Some(rgba(0xc9b99aff).into()), + elevated_surface_background: Some(rgba(0xd9c8a4ff).into()), + background: Some(rgba(0xd9c8a4ff).into()), + panel_background: Some(rgba(0xecddb5ff).into()), + element_hover: Some(rgba(0xc9b99a80).into()), + element_selected: Some(rgba(0xb5a68e80).into()), + text: Some(rgba(0x5f5650ff).into()), + text_muted: Some(rgba(0xad9e87ff).into()), + status_bar_background: Some(rgba(0xd9c8a4ff).into()), + title_bar_background: Some(rgba(0xd9c8a4ff).into()), + toolbar_background: Some(rgba(0xf9f5d7ff).into()), + tab_bar_background: Some(rgba(0xecddb5ff).into()), + tab_inactive_background: Some(rgba(0xecddb5ff).into()), + tab_active_background: Some(rgba(0xf9f5d7ff).into()), + scrollbar_thumb_background: Some(rgba(0x2828284d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x2828284d).into()), + scrollbar_thumb_border: Some(rgba(0xefe2bcff).into()), + scrollbar_track_border: Some(rgba(0xefe2bcff).into()), + editor_foreground: Some(rgba(0x282828ff).into()), + editor_background: Some(rgba(0xf9f5d7ff).into()), + editor_gutter_background: Some(rgba(0xf9f5d7ff).into()), + editor_line_number: Some(rgba(0x28282859).into()), + editor_active_line_number: Some(rgba(0x282828ff).into()), + editor_wrap_guide: Some(rgba(0x2828280d).into()), + editor_active_wrap_guide: Some(rgba(0x2828281a).into()), + terminal_background: Some(rgba(0xf9f5d7ff).into()), + terminal_ansi_bright_black: Some(rgba(0xb1a28aff).into()), + terminal_ansi_bright_red: Some(rgba(0xdc8c7bff).into()), + terminal_ansi_bright_green: Some(rgba(0xbfb787ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xe2b88bff).into()), + terminal_ansi_bright_blue: Some(rgba(0x8fb0baff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xbcb5afff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x9fbca8ff).into()), + terminal_ansi_bright_white: Some(rgba(0x282828ff).into()), + terminal_ansi_black: Some(rgba(0xf9f5d7ff).into()), + terminal_ansi_red: Some(rgba(0x9d0408ff).into()), + terminal_ansi_green: Some(rgba(0x797410ff).into()), + terminal_ansi_yellow: Some(rgba(0xb57616ff).into()), + terminal_ansi_blue: Some(rgba(0x0b6678ff).into()), + terminal_ansi_magenta: Some(rgba(0x7c6f64ff).into()), + terminal_ansi_cyan: Some(rgba(0x437b59ff).into()), + terminal_ansi_white: Some(rgba(0x282828ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xb16286ff).into()), - created: Some(rgba(0xb8bb26ff).into()), - deleted: Some(rgba(0xfb4934ff).into()), - error: Some(rgba(0xfb4934ff).into()), - hidden: Some(rgba(0xa89984ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x7c6f64ff).into()), - modified: Some(rgba(0x83a598ff).into()), + created: Some(rgba(0x958e43ff).into()), + deleted: Some(rgba(0x9d0408ff).into()), + error: Some(rgba(0x9d0408ff).into()), + modified: Some(rgba(0xb57616ff).into()), + success: Some(rgba(0x282828ff).into()), + warning: Some(rgba(0xb57616ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -89,220 +78,278 @@ pub fn gruvbox() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0x0b6678ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x7c6f64ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x5d544eff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0xb57614ff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x8ec07cff).into()), + color: Some(rgba(0x0b6678ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x427b58ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x0b6678ff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xfe8019ff).into()), + color: Some(rgba(0x0b6678ff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xaf3a03ff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0x8ec07cff).into()), + color: Some(rgba(0x79740eff).into()), + ..Default::default() + }, + ), + ( + "function.builtin".into(), + UserHighlightStyle { + color: Some(rgba(0x9d0006ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x677562ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0xfb4934ff).into()), + color: Some(rgba(0x9d0006ff).into()), ..Default::default() }, ), ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0x0b6678ff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0x427b58ff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "link_uri".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "operator".into(), UserHighlightStyle { - color: Some(rgba(0x8ec07cff).into()), + color: Some(rgba(0x427b58ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9881ff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "preproc".into(), UserHighlightStyle { - color: Some(rgba(0xfe8019ff).into()), + color: Some(rgba(0x282828ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x282828ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0x689d6aff).into()), + color: Some(rgba(0x282828ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x3c3836ff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x665c54ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x413d3aff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x282828ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x413d3aff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x79740eff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0xfb4934ff).into()), + color: Some(rgba(0x5d544eff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0xaf3a03ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x427b58ff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x8ec07cff).into()), + color: Some(rgba(0x427b58ff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x076678ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0x79740eff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0xb57614ff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0x83a598ff).into()), + color: Some(rgba(0x076678ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0x83a598ff).into()), + color: Some(rgba(0x0b6678ff).into()), ..Default::default() }, ), @@ -311,73 +358,62 @@ pub fn gruvbox() -> UserThemeFamily { }, }, UserTheme { - name: "Gruvbox Dark Medium".into(), + name: "Gruvbox Dark Soft".into(), appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x3c3836ff).into()), - border_variant: Some(rgba(0x3c3836ff).into()), - border_focused: Some(rgba(0x3c3836ff).into()), - border_selected: Some(rgba(0x3c3836ff).into()), - border_transparent: Some(rgba(0x3c3836ff).into()), - border_disabled: Some(rgba(0x3c3836ff).into()), - elevated_surface_background: Some(rgba(0x282828ff).into()), - background: Some(rgba(0x282828ff).into()), - element_background: Some(rgba(0x45858880).into()), - element_hover: Some(rgba(0x3c383680).into()), - element_selected: Some(rgba(0x3c383680).into()), - drop_target_background: Some(rgba(0x3c3836ff).into()), - ghost_element_hover: Some(rgba(0x3c383680).into()), - ghost_element_selected: Some(rgba(0x3c383680).into()), - text: Some(rgba(0xebdbb2ff).into()), - text_muted: Some(rgba(0xa89984ff).into()), - status_bar_background: Some(rgba(0x282828ff).into()), - title_bar_background: Some(rgba(0x282828ff).into()), - toolbar_background: Some(rgba(0x282828ff).into()), - tab_bar_background: Some(rgba(0x282828ff).into()), - tab_inactive_background: Some(rgba(0x282828ff).into()), - tab_active_background: Some(rgba(0x3c3836ff).into()), - scrollbar_thumb_background: Some(rgba(0x50494599).into()), - scrollbar_thumb_hover_background: Some(rgba(0x665c54ff).into()), - scrollbar_thumb_border: Some(rgba(0x50494599).into()), - scrollbar_track_background: Some(rgba(0x282828ff).into()), - scrollbar_track_border: Some(rgba(0x28282800).into()), + border: Some(rgba(0x5b534dff).into()), + border_variant: Some(rgba(0x5b534dff).into()), + elevated_surface_background: Some(rgba(0x4c4642ff).into()), + background: Some(rgba(0x4c4642ff).into()), + panel_background: Some(rgba(0x3b3735ff).into()), + element_hover: Some(rgba(0x5b534d80).into()), + element_selected: Some(rgba(0x6e635a80).into()), + text: Some(rgba(0xc5b597ff).into()), + text_muted: Some(rgba(0x776b61ff).into()), + status_bar_background: Some(rgba(0x4c4642ff).into()), + title_bar_background: Some(rgba(0x4c4642ff).into()), + toolbar_background: Some(rgba(0x32302fff).into()), + tab_bar_background: Some(rgba(0x3b3735ff).into()), + tab_inactive_background: Some(rgba(0x3b3735ff).into()), + tab_active_background: Some(rgba(0x32302fff).into()), + scrollbar_thumb_background: Some(rgba(0xfbf1c74d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xfbf1c74d).into()), + scrollbar_thumb_border: Some(rgba(0x393634ff).into()), + scrollbar_track_border: Some(rgba(0x393634ff).into()), editor_foreground: Some(rgba(0xebdbb2ff).into()), - editor_background: Some(rgba(0x282828ff).into()), - editor_gutter_background: Some(rgba(0x282828ff).into()), - editor_line_number: Some(rgba(0x665c54ff).into()), - editor_active_line_number: Some(rgba(0xebdbb2ff).into()), - editor_wrap_guide: Some(rgba(0x3c3836ff).into()), - editor_active_wrap_guide: Some(rgba(0x3c3836ff).into()), - terminal_background: Some(rgba(0x282828ff).into()), - terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), - terminal_ansi_bright_red: Some(rgba(0xfb4934ff).into()), - terminal_ansi_bright_green: Some(rgba(0xb8bb26ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xfabd2fff).into()), - terminal_ansi_bright_blue: Some(rgba(0x83a598ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xd3869bff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x8ec07cff).into()), - terminal_ansi_bright_white: Some(rgba(0xebdbb2ff).into()), - terminal_ansi_black: Some(rgba(0x3c3836ff).into()), - terminal_ansi_red: Some(rgba(0xcc241dff).into()), - terminal_ansi_green: Some(rgba(0x98971aff).into()), - terminal_ansi_yellow: Some(rgba(0xd79921ff).into()), - terminal_ansi_blue: Some(rgba(0x458588ff).into()), - terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), - terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), - terminal_ansi_white: Some(rgba(0xa89984ff).into()), - link_text_hover: Some(rgba(0x458588ff).into()), + editor_background: Some(rgba(0x32302fff).into()), + editor_gutter_background: Some(rgba(0x32302fff).into()), + editor_line_number: Some(rgba(0xfbf1c759).into()), + editor_active_line_number: Some(rgba(0xfbf1c7ff).into()), + editor_wrap_guide: Some(rgba(0xfbf1c70d).into()), + editor_active_wrap_guide: Some(rgba(0xfbf1c71a).into()), + terminal_background: Some(rgba(0x32302fff).into()), + terminal_ansi_bright_black: Some(rgba(0x73675eff).into()), + terminal_ansi_bright_red: Some(rgba(0x93211eff).into()), + terminal_ansi_bright_green: Some(rgba(0x615d1bff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x91611cff).into()), + terminal_ansi_bright_blue: Some(rgba(0x414f4aff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x514a41ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x45603eff).into()), + terminal_ansi_bright_white: Some(rgba(0xfbf1c7ff).into()), + terminal_ansi_black: Some(rgba(0x32302fff).into()), + terminal_ansi_red: Some(rgba(0xfb4a35ff).into()), + terminal_ansi_green: Some(rgba(0xb8bb27ff).into()), + terminal_ansi_yellow: Some(rgba(0xf9bd30ff).into()), + terminal_ansi_blue: Some(rgba(0x83a598ff).into()), + terminal_ansi_magenta: Some(rgba(0xa89984ff).into()), + terminal_ansi_cyan: Some(rgba(0x8ec07cff).into()), + terminal_ansi_white: Some(rgba(0xfbf1c7ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xb16286ff).into()), - created: Some(rgba(0xb8bb26ff).into()), - deleted: Some(rgba(0xfb4934ff).into()), - error: Some(rgba(0xfb4934ff).into()), - hidden: Some(rgba(0xa89984ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x7c6f64ff).into()), - modified: Some(rgba(0x83a598ff).into()), + created: Some(rgba(0xb8bb27ff).into()), + deleted: Some(rgba(0xd0382bff).into()), + error: Some(rgba(0xfb4a35ff).into()), + modified: Some(rgba(0xf9bd30ff).into()), + success: Some(rgba(0xfbf1c7ff).into()), + warning: Some(rgba(0xf9bd30ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -385,52 +421,93 @@ pub fn gruvbox() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xa89984ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xc7b798ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0xfabd2fff).into()), ..Default::default() }, ), ( "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), UserHighlightStyle { color: Some(rgba(0x8ec07cff).into()), ..Default::default() }, ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xfe8019ff).into()), + color: Some(rgba(0x83a598ff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xfe8019ff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0x8ec07cff).into()), + color: Some(rgba(0xb8bb26ff).into()), + ..Default::default() + }, + ), + ( + "function.builtin".into(), + UserHighlightStyle { + color: Some(rgba(0xfb4934ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x8d957eff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), @@ -444,14 +521,15 @@ pub fn gruvbox() -> UserThemeFamily { ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0x8ec07cff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), @@ -476,24 +554,39 @@ pub fn gruvbox() -> UserThemeFamily { ..Default::default() }, ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x717363ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), ( "preproc".into(), UserHighlightStyle { - color: Some(rgba(0xfe8019ff).into()), + color: Some(rgba(0xfbf1c7ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xebdbb2ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0x689d6aff).into()), + color: Some(rgba(0xebdbb2ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0xd5c4a1ff).into()), ..Default::default() }, ), @@ -507,21 +600,21 @@ pub fn gruvbox() -> UserThemeFamily { ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0xe5d5adff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0xebdbb2ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0xe5d5adff).into()), ..Default::default() }, ), @@ -535,28 +628,28 @@ pub fn gruvbox() -> UserThemeFamily { ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0xfb4934ff).into()), + color: Some(rgba(0xc7b798ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0xfe8019ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x8ec07cff).into()), ..Default::default() }, ), @@ -570,14 +663,15 @@ pub fn gruvbox() -> UserThemeFamily { ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0xb8bb26ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), @@ -596,7 +690,7 @@ pub fn gruvbox() -> UserThemeFamily { }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { color: Some(rgba(0x83a598ff).into()), ..Default::default() @@ -607,73 +701,62 @@ pub fn gruvbox() -> UserThemeFamily { }, }, UserTheme { - name: "Gruvbox Dark Soft".into(), - appearance: Appearance::Dark, + name: "Gruvbox Light".into(), + appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x3c3836ff).into()), - border_variant: Some(rgba(0x3c3836ff).into()), - border_focused: Some(rgba(0x3c3836ff).into()), - border_selected: Some(rgba(0x3c3836ff).into()), - border_transparent: Some(rgba(0x3c3836ff).into()), - border_disabled: Some(rgba(0x3c3836ff).into()), - elevated_surface_background: Some(rgba(0x32302fff).into()), - background: Some(rgba(0x32302fff).into()), - element_background: Some(rgba(0x45858880).into()), - element_hover: Some(rgba(0x3c383680).into()), - element_selected: Some(rgba(0x3c383680).into()), - drop_target_background: Some(rgba(0x3c3836ff).into()), - ghost_element_hover: Some(rgba(0x3c383680).into()), - ghost_element_selected: Some(rgba(0x3c383680).into()), - text: Some(rgba(0xebdbb2ff).into()), - text_muted: Some(rgba(0xa89984ff).into()), - status_bar_background: Some(rgba(0x32302fff).into()), - title_bar_background: Some(rgba(0x32302fff).into()), - toolbar_background: Some(rgba(0x32302fff).into()), - tab_bar_background: Some(rgba(0x32302fff).into()), - tab_inactive_background: Some(rgba(0x32302fff).into()), - tab_active_background: Some(rgba(0x504945ff).into()), - scrollbar_thumb_background: Some(rgba(0x50494599).into()), - scrollbar_thumb_hover_background: Some(rgba(0x665c54ff).into()), - scrollbar_thumb_border: Some(rgba(0x50494599).into()), - scrollbar_track_background: Some(rgba(0x32302fff).into()), - scrollbar_track_border: Some(rgba(0x32302f00).into()), - editor_foreground: Some(rgba(0xebdbb2ff).into()), - editor_background: Some(rgba(0x32302fff).into()), - editor_gutter_background: Some(rgba(0x32302fff).into()), - editor_line_number: Some(rgba(0x665c54ff).into()), - editor_active_line_number: Some(rgba(0xebdbb2ff).into()), - editor_wrap_guide: Some(rgba(0x3c3836ff).into()), - editor_active_wrap_guide: Some(rgba(0x3c3836ff).into()), - terminal_background: Some(rgba(0x32302fff).into()), - terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), - terminal_ansi_bright_red: Some(rgba(0xfb4934ff).into()), - terminal_ansi_bright_green: Some(rgba(0xb8bb26ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xfabd2fff).into()), - terminal_ansi_bright_blue: Some(rgba(0x83a598ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xd3869bff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x8ec07cff).into()), - terminal_ansi_bright_white: Some(rgba(0xebdbb2ff).into()), - terminal_ansi_black: Some(rgba(0x3c3836ff).into()), - terminal_ansi_red: Some(rgba(0xcc241dff).into()), - terminal_ansi_green: Some(rgba(0x98971aff).into()), - terminal_ansi_yellow: Some(rgba(0xd79921ff).into()), - terminal_ansi_blue: Some(rgba(0x458588ff).into()), - terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), - terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), - terminal_ansi_white: Some(rgba(0xa89984ff).into()), - link_text_hover: Some(rgba(0x458588ff).into()), + border: Some(rgba(0xc9b99aff).into()), + border_variant: Some(rgba(0xc9b99aff).into()), + elevated_surface_background: Some(rgba(0xd9c8a4ff).into()), + background: Some(rgba(0xd9c8a4ff).into()), + panel_background: Some(rgba(0xecddb4ff).into()), + element_hover: Some(rgba(0xc9b99a80).into()), + element_selected: Some(rgba(0xb5a68e80).into()), + text: Some(rgba(0x5f5650ff).into()), + text_muted: Some(rgba(0xad9e87ff).into()), + status_bar_background: Some(rgba(0xd9c8a4ff).into()), + title_bar_background: Some(rgba(0xd9c8a4ff).into()), + toolbar_background: Some(rgba(0xfbf1c7ff).into()), + tab_bar_background: Some(rgba(0xecddb4ff).into()), + tab_inactive_background: Some(rgba(0xecddb4ff).into()), + tab_active_background: Some(rgba(0xfbf1c7ff).into()), + scrollbar_thumb_background: Some(rgba(0x2828284d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x2828284d).into()), + scrollbar_thumb_border: Some(rgba(0xefe1b8ff).into()), + scrollbar_track_border: Some(rgba(0xefe1b8ff).into()), + editor_foreground: Some(rgba(0x282828ff).into()), + editor_background: Some(rgba(0xfbf1c7ff).into()), + editor_gutter_background: Some(rgba(0xfbf1c7ff).into()), + editor_line_number: Some(rgba(0x28282859).into()), + editor_active_line_number: Some(rgba(0x282828ff).into()), + editor_wrap_guide: Some(rgba(0x2828280d).into()), + editor_active_wrap_guide: Some(rgba(0x2828281a).into()), + terminal_background: Some(rgba(0xfbf1c7ff).into()), + terminal_ansi_bright_black: Some(rgba(0xb1a28aff).into()), + terminal_ansi_bright_red: Some(rgba(0xdc8c7bff).into()), + terminal_ansi_bright_green: Some(rgba(0xbfb787ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xe2b88bff).into()), + terminal_ansi_bright_blue: Some(rgba(0x8fb0baff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xbcb5afff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x9fbca8ff).into()), + terminal_ansi_bright_white: Some(rgba(0x282828ff).into()), + terminal_ansi_black: Some(rgba(0xfbf1c7ff).into()), + terminal_ansi_red: Some(rgba(0x9d0408ff).into()), + terminal_ansi_green: Some(rgba(0x797410ff).into()), + terminal_ansi_yellow: Some(rgba(0xb57616ff).into()), + terminal_ansi_blue: Some(rgba(0x0b6678ff).into()), + terminal_ansi_magenta: Some(rgba(0x7c6f64ff).into()), + terminal_ansi_cyan: Some(rgba(0x437b59ff).into()), + terminal_ansi_white: Some(rgba(0x282828ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xb16286ff).into()), - created: Some(rgba(0xb8bb26ff).into()), - deleted: Some(rgba(0xfb4934ff).into()), - error: Some(rgba(0xfb4934ff).into()), - hidden: Some(rgba(0xa89984ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x7c6f64ff).into()), - modified: Some(rgba(0x83a598ff).into()), + created: Some(rgba(0x958e43ff).into()), + deleted: Some(rgba(0x9d0408ff).into()), + error: Some(rgba(0x9d0408ff).into()), + modified: Some(rgba(0xb57616ff).into()), + success: Some(rgba(0x282828ff).into()), + warning: Some(rgba(0xb57616ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -681,220 +764,278 @@ pub fn gruvbox() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0x0b6678ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x7c6f64ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x5d544eff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0xb57614ff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x8ec07cff).into()), + color: Some(rgba(0x0b6678ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x427b58ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x0b6678ff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xfe8019ff).into()), + color: Some(rgba(0x0b6678ff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xaf3a03ff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0x8ec07cff).into()), + color: Some(rgba(0x79740eff).into()), + ..Default::default() + }, + ), + ( + "function.builtin".into(), + UserHighlightStyle { + color: Some(rgba(0x9d0006ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x677562ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0xfb4934ff).into()), + color: Some(rgba(0x9d0006ff).into()), ..Default::default() }, ), ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0x0b6678ff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0x427b58ff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "link_uri".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xd3869bff).into()), + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "operator".into(), UserHighlightStyle { - color: Some(rgba(0x8ec07cff).into()), + color: Some(rgba(0x427b58ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9881ff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "preproc".into(), UserHighlightStyle { - color: Some(rgba(0xfe8019ff).into()), + color: Some(rgba(0x282828ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x282828ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0x689d6aff).into()), + color: Some(rgba(0x282828ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x3c3836ff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x665c54ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x413d3aff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x282828ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0xa89984ff).into()), + color: Some(rgba(0x413d3aff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x79740eff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0xfb4934ff).into()), + color: Some(rgba(0x5d544eff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0xaf3a03ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x427b58ff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x8ec07cff).into()), + color: Some(rgba(0x427b58ff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xb8bb26ff).into()), + color: Some(rgba(0x076678ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0x79740eff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0xfabd2fff).into()), + color: Some(rgba(0xb57614ff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0x83a598ff).into()), + color: Some(rgba(0x076678ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0x83a598ff).into()), + color: Some(rgba(0x0b6678ff).into()), ..Default::default() }, ), @@ -903,73 +1044,62 @@ pub fn gruvbox() -> UserThemeFamily { }, }, UserTheme { - name: "Gruvbox Light Hard".into(), - appearance: Appearance::Light, + name: "Gruvbox Dark".into(), + appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xebdbb2ff).into()), - border_variant: Some(rgba(0xebdbb2ff).into()), - border_focused: Some(rgba(0xebdbb2ff).into()), - border_selected: Some(rgba(0xebdbb2ff).into()), - border_transparent: Some(rgba(0xebdbb2ff).into()), - border_disabled: Some(rgba(0xebdbb2ff).into()), - elevated_surface_background: Some(rgba(0xf9f5d7ff).into()), - background: Some(rgba(0xf9f5d7ff).into()), - element_background: Some(rgba(0x45858880).into()), - element_hover: Some(rgba(0xebdbb280).into()), - element_selected: Some(rgba(0xebdbb280).into()), - drop_target_background: Some(rgba(0xebdbb2ff).into()), - ghost_element_hover: Some(rgba(0xebdbb280).into()), - ghost_element_selected: Some(rgba(0xebdbb280).into()), - text: Some(rgba(0x3c3836ff).into()), - text_muted: Some(rgba(0x7c6f64ff).into()), - status_bar_background: Some(rgba(0xf9f5d7ff).into()), - title_bar_background: Some(rgba(0xf9f5d7ff).into()), - toolbar_background: Some(rgba(0xf9f5d7ff).into()), - tab_bar_background: Some(rgba(0xf9f5d7ff).into()), - tab_inactive_background: Some(rgba(0xf9f5d7ff).into()), - tab_active_background: Some(rgba(0xf2e5bcff).into()), - scrollbar_thumb_background: Some(rgba(0xd5c4a199).into()), - scrollbar_thumb_hover_background: Some(rgba(0xbdae93ff).into()), - scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()), - scrollbar_track_background: Some(rgba(0xf9f5d7ff).into()), - scrollbar_track_border: Some(rgba(0xf9f5d700).into()), - editor_foreground: Some(rgba(0x3c3836ff).into()), - editor_background: Some(rgba(0xf9f5d7ff).into()), - editor_gutter_background: Some(rgba(0xf9f5d7ff).into()), - editor_line_number: Some(rgba(0xbdae93ff).into()), - editor_active_line_number: Some(rgba(0x3c3836ff).into()), - editor_wrap_guide: Some(rgba(0xebdbb2ff).into()), - editor_active_wrap_guide: Some(rgba(0xebdbb2ff).into()), - terminal_background: Some(rgba(0xf9f5d7ff).into()), - terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), - terminal_ansi_bright_red: Some(rgba(0x9d0006ff).into()), - terminal_ansi_bright_green: Some(rgba(0x79740eff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xb57614ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x076678ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0x8f3f71ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x427b58ff).into()), - terminal_ansi_bright_white: Some(rgba(0x3c3836ff).into()), - terminal_ansi_black: Some(rgba(0xebdbb2ff).into()), - terminal_ansi_red: Some(rgba(0xcc241dff).into()), - terminal_ansi_green: Some(rgba(0x98971aff).into()), - terminal_ansi_yellow: Some(rgba(0xd79921ff).into()), - terminal_ansi_blue: Some(rgba(0x458588ff).into()), - terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), - terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), - terminal_ansi_white: Some(rgba(0x7c6f64ff).into()), - link_text_hover: Some(rgba(0x458588ff).into()), + border: Some(rgba(0x5b534dff).into()), + border_variant: Some(rgba(0x5b534dff).into()), + elevated_surface_background: Some(rgba(0x4c4642ff).into()), + background: Some(rgba(0x4c4642ff).into()), + panel_background: Some(rgba(0x3a3735ff).into()), + element_hover: Some(rgba(0x5b534d80).into()), + element_selected: Some(rgba(0x6e635a80).into()), + text: Some(rgba(0xc5b597ff).into()), + text_muted: Some(rgba(0x776b61ff).into()), + status_bar_background: Some(rgba(0x4c4642ff).into()), + title_bar_background: Some(rgba(0x4c4642ff).into()), + toolbar_background: Some(rgba(0x282828ff).into()), + tab_bar_background: Some(rgba(0x3a3735ff).into()), + tab_inactive_background: Some(rgba(0x3a3735ff).into()), + tab_active_background: Some(rgba(0x282828ff).into()), + scrollbar_thumb_background: Some(rgba(0xfbf1c74d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xfbf1c74d).into()), + scrollbar_thumb_border: Some(rgba(0x373432ff).into()), + scrollbar_track_border: Some(rgba(0x373432ff).into()), + editor_foreground: Some(rgba(0xebdbb2ff).into()), + editor_background: Some(rgba(0x282828ff).into()), + editor_gutter_background: Some(rgba(0x282828ff).into()), + editor_line_number: Some(rgba(0xfbf1c759).into()), + editor_active_line_number: Some(rgba(0xfbf1c7ff).into()), + editor_wrap_guide: Some(rgba(0xfbf1c70d).into()), + editor_active_wrap_guide: Some(rgba(0xfbf1c71a).into()), + terminal_background: Some(rgba(0x282828ff).into()), + terminal_ansi_bright_black: Some(rgba(0x73675eff).into()), + terminal_ansi_bright_red: Some(rgba(0x93211eff).into()), + terminal_ansi_bright_green: Some(rgba(0x615d1bff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x91611cff).into()), + terminal_ansi_bright_blue: Some(rgba(0x414f4aff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x514a41ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x45603eff).into()), + terminal_ansi_bright_white: Some(rgba(0xfbf1c7ff).into()), + terminal_ansi_black: Some(rgba(0x282828ff).into()), + terminal_ansi_red: Some(rgba(0xfb4a35ff).into()), + terminal_ansi_green: Some(rgba(0xb8bb27ff).into()), + terminal_ansi_yellow: Some(rgba(0xf9bd30ff).into()), + terminal_ansi_blue: Some(rgba(0x83a598ff).into()), + terminal_ansi_magenta: Some(rgba(0xa89984ff).into()), + terminal_ansi_cyan: Some(rgba(0x8ec07cff).into()), + terminal_ansi_white: Some(rgba(0xfbf1c7ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xb16286ff).into()), - created: Some(rgba(0x79740eff).into()), - deleted: Some(rgba(0x9d0006ff).into()), - error: Some(rgba(0x9d0006ff).into()), - hidden: Some(rgba(0x7c6f64ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0xa89984ff).into()), - modified: Some(rgba(0x076678ff).into()), + created: Some(rgba(0xb8bb27ff).into()), + deleted: Some(rgba(0xd0382bff).into()), + error: Some(rgba(0xfb4a35ff).into()), + modified: Some(rgba(0xf9bd30ff).into()), + success: Some(rgba(0xfbf1c7ff).into()), + warning: Some(rgba(0xf9bd30ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -977,220 +1107,278 @@ pub fn gruvbox() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xa89984ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xc7b798ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0xfabd2fff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x427b58ff).into()), + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x8ec07cff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xaf3a03ff).into()), + color: Some(rgba(0x83a598ff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xfe8019ff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0x427b58ff).into()), + color: Some(rgba(0xb8bb26ff).into()), + ..Default::default() + }, + ), + ( + "function.builtin".into(), + UserHighlightStyle { + color: Some(rgba(0xfb4934ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x8d957eff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0x9d0006ff).into()), + color: Some(rgba(0xfb4934ff).into()), ..Default::default() }, ), ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0x8ec07cff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "link_uri".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "operator".into(), UserHighlightStyle { - color: Some(rgba(0x427b58ff).into()), + color: Some(rgba(0x8ec07cff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x717363ff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "preproc".into(), UserHighlightStyle { - color: Some(rgba(0xaf3a03ff).into()), + color: Some(rgba(0xfbf1c7ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xebdbb2ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0x689d6aff).into()), + color: Some(rgba(0xebdbb2ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xd5c4a1ff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xa89984ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xe5d5adff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xebdbb2ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xe5d5adff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0xb8bb26ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0x9d0006ff).into()), + color: Some(rgba(0xc7b798ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0xfe8019ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0x8ec07cff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x427b58ff).into()), + color: Some(rgba(0x8ec07cff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0xb8bb26ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0xfabd2fff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0x076678ff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0x076678ff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), @@ -1199,73 +1387,62 @@ pub fn gruvbox() -> UserThemeFamily { }, }, UserTheme { - name: "Gruvbox Light Medium".into(), + name: "Gruvbox Light Soft".into(), appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xebdbb2ff).into()), - border_variant: Some(rgba(0xebdbb2ff).into()), - border_focused: Some(rgba(0xebdbb2ff).into()), - border_selected: Some(rgba(0xebdbb2ff).into()), - border_transparent: Some(rgba(0xebdbb2ff).into()), - border_disabled: Some(rgba(0xebdbb2ff).into()), - elevated_surface_background: Some(rgba(0xfbf1c7ff).into()), - background: Some(rgba(0xfbf1c7ff).into()), - element_background: Some(rgba(0x45858880).into()), - element_hover: Some(rgba(0xebdbb280).into()), - element_selected: Some(rgba(0xebdbb280).into()), - drop_target_background: Some(rgba(0xebdbb2ff).into()), - ghost_element_hover: Some(rgba(0xebdbb280).into()), - ghost_element_selected: Some(rgba(0xebdbb280).into()), - text: Some(rgba(0x3c3836ff).into()), - text_muted: Some(rgba(0x7c6f64ff).into()), - status_bar_background: Some(rgba(0xfbf1c7ff).into()), - title_bar_background: Some(rgba(0xfbf1c7ff).into()), - toolbar_background: Some(rgba(0xfbf1c7ff).into()), - tab_bar_background: Some(rgba(0xfbf1c7ff).into()), - tab_inactive_background: Some(rgba(0xfbf1c7ff).into()), - tab_active_background: Some(rgba(0xebdbb2ff).into()), - scrollbar_thumb_background: Some(rgba(0xd5c4a199).into()), - scrollbar_thumb_hover_background: Some(rgba(0xbdae93ff).into()), - scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()), - scrollbar_track_background: Some(rgba(0xfbf1c7ff).into()), - scrollbar_track_border: Some(rgba(0xfbf1c700).into()), - editor_foreground: Some(rgba(0x3c3836ff).into()), - editor_background: Some(rgba(0xfbf1c7ff).into()), - editor_gutter_background: Some(rgba(0xfbf1c7ff).into()), - editor_line_number: Some(rgba(0xbdae93ff).into()), - editor_active_line_number: Some(rgba(0x3c3836ff).into()), - editor_wrap_guide: Some(rgba(0xebdbb2ff).into()), - editor_active_wrap_guide: Some(rgba(0xebdbb2ff).into()), - terminal_background: Some(rgba(0xfbf1c7ff).into()), - terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), - terminal_ansi_bright_red: Some(rgba(0x9d0006ff).into()), - terminal_ansi_bright_green: Some(rgba(0x79740eff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xb57614ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x076678ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0x8f3f71ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x427b58ff).into()), - terminal_ansi_bright_white: Some(rgba(0x3c3836ff).into()), - terminal_ansi_black: Some(rgba(0xebdbb2ff).into()), - terminal_ansi_red: Some(rgba(0xcc241dff).into()), - terminal_ansi_green: Some(rgba(0x98971aff).into()), - terminal_ansi_yellow: Some(rgba(0xd79921ff).into()), - terminal_ansi_blue: Some(rgba(0x458588ff).into()), - terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), - terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), - terminal_ansi_white: Some(rgba(0x7c6f64ff).into()), - link_text_hover: Some(rgba(0x458588ff).into()), + border: Some(rgba(0xc9b99aff).into()), + border_variant: Some(rgba(0xc9b99aff).into()), + elevated_surface_background: Some(rgba(0xd9c8a4ff).into()), + background: Some(rgba(0xd9c8a4ff).into()), + panel_background: Some(rgba(0xecdcb3ff).into()), + element_hover: Some(rgba(0xc9b99a80).into()), + element_selected: Some(rgba(0xb5a68e80).into()), + text: Some(rgba(0x5f5650ff).into()), + text_muted: Some(rgba(0xad9e87ff).into()), + status_bar_background: Some(rgba(0xd9c8a4ff).into()), + title_bar_background: Some(rgba(0xd9c8a4ff).into()), + toolbar_background: Some(rgba(0xf2e5bcff).into()), + tab_bar_background: Some(rgba(0xecdcb3ff).into()), + tab_inactive_background: Some(rgba(0xecdcb3ff).into()), + tab_active_background: Some(rgba(0xf2e5bcff).into()), + scrollbar_thumb_background: Some(rgba(0x2828284d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x2828284d).into()), + scrollbar_thumb_border: Some(rgba(0xeddeb5ff).into()), + scrollbar_track_border: Some(rgba(0xeddeb5ff).into()), + editor_foreground: Some(rgba(0x282828ff).into()), + editor_background: Some(rgba(0xf2e5bcff).into()), + editor_gutter_background: Some(rgba(0xf2e5bcff).into()), + editor_line_number: Some(rgba(0x28282859).into()), + editor_active_line_number: Some(rgba(0x282828ff).into()), + editor_wrap_guide: Some(rgba(0x2828280d).into()), + editor_active_wrap_guide: Some(rgba(0x2828281a).into()), + terminal_background: Some(rgba(0xf2e5bcff).into()), + terminal_ansi_bright_black: Some(rgba(0xb1a28aff).into()), + terminal_ansi_bright_red: Some(rgba(0xdc8c7bff).into()), + terminal_ansi_bright_green: Some(rgba(0xbfb787ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xe2b88bff).into()), + terminal_ansi_bright_blue: Some(rgba(0x8fb0baff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xbcb5afff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x9fbca8ff).into()), + terminal_ansi_bright_white: Some(rgba(0x282828ff).into()), + terminal_ansi_black: Some(rgba(0xf2e5bcff).into()), + terminal_ansi_red: Some(rgba(0x9d0408ff).into()), + terminal_ansi_green: Some(rgba(0x797410ff).into()), + terminal_ansi_yellow: Some(rgba(0xb57616ff).into()), + terminal_ansi_blue: Some(rgba(0x0b6678ff).into()), + terminal_ansi_magenta: Some(rgba(0x7c6f64ff).into()), + terminal_ansi_cyan: Some(rgba(0x437b59ff).into()), + terminal_ansi_white: Some(rgba(0x282828ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xb16286ff).into()), - created: Some(rgba(0x79740eff).into()), - deleted: Some(rgba(0x9d0006ff).into()), - error: Some(rgba(0x9d0006ff).into()), - hidden: Some(rgba(0x7c6f64ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0xa89984ff).into()), - modified: Some(rgba(0x076678ff).into()), + created: Some(rgba(0x958e43ff).into()), + deleted: Some(rgba(0x9d0408ff).into()), + error: Some(rgba(0x9d0408ff).into()), + modified: Some(rgba(0xb57616ff).into()), + success: Some(rgba(0x282828ff).into()), + warning: Some(rgba(0xb57616ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -1273,52 +1450,93 @@ pub fn gruvbox() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0x0b6678ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x7c6f64ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x5d544eff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0xb57614ff).into()), ..Default::default() }, ), ( "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x0b6678ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), UserHighlightStyle { color: Some(rgba(0x427b58ff).into()), ..Default::default() }, ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x0b6678ff).into()), + ..Default::default() + }, + ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xaf3a03ff).into()), + color: Some(rgba(0x0b6678ff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xaf3a03ff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0x427b58ff).into()), + color: Some(rgba(0x79740eff).into()), + ..Default::default() + }, + ), + ( + "function.builtin".into(), + UserHighlightStyle { + color: Some(rgba(0x9d0006ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x677562ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), @@ -1332,14 +1550,15 @@ pub fn gruvbox() -> UserThemeFamily { ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0x0b6678ff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0x427b58ff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), @@ -1364,52 +1583,67 @@ pub fn gruvbox() -> UserThemeFamily { ..Default::default() }, ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x7d9881ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), ( "preproc".into(), UserHighlightStyle { - color: Some(rgba(0xaf3a03ff).into()), + color: Some(rgba(0x282828ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x282828ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0x689d6aff).into()), + color: Some(rgba(0x282828ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0x3c3836ff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0x665c54ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0x413d3aff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0x282828ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0x413d3aff).into()), ..Default::default() }, ), @@ -1423,28 +1657,28 @@ pub fn gruvbox() -> UserThemeFamily { ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0x9d0006ff).into()), + color: Some(rgba(0x5d544eff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0xaf3a03ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0x8f3f71ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0x427b58ff).into()), ..Default::default() }, ), @@ -1458,14 +1692,15 @@ pub fn gruvbox() -> UserThemeFamily { ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0x076678ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0x79740eff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), @@ -1484,9 +1719,9 @@ pub fn gruvbox() -> UserThemeFamily { }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0x076678ff).into()), + color: Some(rgba(0x0b6678ff).into()), ..Default::default() }, ), @@ -1495,73 +1730,62 @@ pub fn gruvbox() -> UserThemeFamily { }, }, UserTheme { - name: "Gruvbox Light Soft".into(), - appearance: Appearance::Light, + name: "Gruvbox Dark Hard".into(), + appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xebdbb2ff).into()), - border_variant: Some(rgba(0xebdbb2ff).into()), - border_focused: Some(rgba(0xebdbb2ff).into()), - border_selected: Some(rgba(0xebdbb2ff).into()), - border_transparent: Some(rgba(0xebdbb2ff).into()), - border_disabled: Some(rgba(0xebdbb2ff).into()), - elevated_surface_background: Some(rgba(0xf2e5bcff).into()), - background: Some(rgba(0xf2e5bcff).into()), - element_background: Some(rgba(0x45858880).into()), - element_hover: Some(rgba(0xebdbb280).into()), - element_selected: Some(rgba(0xebdbb280).into()), - drop_target_background: Some(rgba(0xebdbb2ff).into()), - ghost_element_hover: Some(rgba(0xebdbb280).into()), - ghost_element_selected: Some(rgba(0xebdbb280).into()), - text: Some(rgba(0x3c3836ff).into()), - text_muted: Some(rgba(0x7c6f64ff).into()), - status_bar_background: Some(rgba(0xf2e5bcff).into()), - title_bar_background: Some(rgba(0xf2e5bcff).into()), - toolbar_background: Some(rgba(0xf2e5bcff).into()), - tab_bar_background: Some(rgba(0xf2e5bcff).into()), - tab_inactive_background: Some(rgba(0xf2e5bcff).into()), - tab_active_background: Some(rgba(0xd5c4a1ff).into()), - scrollbar_thumb_background: Some(rgba(0xd5c4a199).into()), - scrollbar_thumb_hover_background: Some(rgba(0xbdae93ff).into()), - scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()), - scrollbar_track_background: Some(rgba(0xf2e5bcff).into()), - scrollbar_track_border: Some(rgba(0xf2e5bc00).into()), - editor_foreground: Some(rgba(0x3c3836ff).into()), - editor_background: Some(rgba(0xf2e5bcff).into()), - editor_gutter_background: Some(rgba(0xf2e5bcff).into()), - editor_line_number: Some(rgba(0xbdae93ff).into()), - editor_active_line_number: Some(rgba(0x3c3836ff).into()), - editor_wrap_guide: Some(rgba(0xebdbb2ff).into()), - editor_active_wrap_guide: Some(rgba(0xebdbb2ff).into()), - terminal_background: Some(rgba(0xf2e5bcff).into()), - terminal_ansi_bright_black: Some(rgba(0x928374ff).into()), - terminal_ansi_bright_red: Some(rgba(0x9d0006ff).into()), - terminal_ansi_bright_green: Some(rgba(0x79740eff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xb57614ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x076678ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0x8f3f71ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x427b58ff).into()), - terminal_ansi_bright_white: Some(rgba(0x3c3836ff).into()), - terminal_ansi_black: Some(rgba(0xebdbb2ff).into()), - terminal_ansi_red: Some(rgba(0xcc241dff).into()), - terminal_ansi_green: Some(rgba(0x98971aff).into()), - terminal_ansi_yellow: Some(rgba(0xd79921ff).into()), - terminal_ansi_blue: Some(rgba(0x458588ff).into()), - terminal_ansi_magenta: Some(rgba(0xb16286ff).into()), - terminal_ansi_cyan: Some(rgba(0x689d6aff).into()), - terminal_ansi_white: Some(rgba(0x7c6f64ff).into()), - link_text_hover: Some(rgba(0x458588ff).into()), + border: Some(rgba(0x5b534dff).into()), + border_variant: Some(rgba(0x5b534dff).into()), + elevated_surface_background: Some(rgba(0x4c4642ff).into()), + background: Some(rgba(0x4c4642ff).into()), + panel_background: Some(rgba(0x393634ff).into()), + element_hover: Some(rgba(0x5b534d80).into()), + element_selected: Some(rgba(0x6e635a80).into()), + text: Some(rgba(0xc5b597ff).into()), + text_muted: Some(rgba(0x776b61ff).into()), + status_bar_background: Some(rgba(0x4c4642ff).into()), + title_bar_background: Some(rgba(0x4c4642ff).into()), + toolbar_background: Some(rgba(0x1d2021ff).into()), + tab_bar_background: Some(rgba(0x393634ff).into()), + tab_inactive_background: Some(rgba(0x393634ff).into()), + tab_active_background: Some(rgba(0x1d2021ff).into()), + scrollbar_thumb_background: Some(rgba(0xfbf1c74d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xfbf1c74d).into()), + scrollbar_thumb_border: Some(rgba(0x343130ff).into()), + scrollbar_track_border: Some(rgba(0x343130ff).into()), + editor_foreground: Some(rgba(0xebdbb2ff).into()), + editor_background: Some(rgba(0x1d2021ff).into()), + editor_gutter_background: Some(rgba(0x1d2021ff).into()), + editor_line_number: Some(rgba(0xfbf1c759).into()), + editor_active_line_number: Some(rgba(0xfbf1c7ff).into()), + editor_wrap_guide: Some(rgba(0xfbf1c70d).into()), + editor_active_wrap_guide: Some(rgba(0xfbf1c71a).into()), + terminal_background: Some(rgba(0x1d2021ff).into()), + terminal_ansi_bright_black: Some(rgba(0x73675eff).into()), + terminal_ansi_bright_red: Some(rgba(0x93211eff).into()), + terminal_ansi_bright_green: Some(rgba(0x615d1bff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x91611cff).into()), + terminal_ansi_bright_blue: Some(rgba(0x414f4aff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x514a41ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x45603eff).into()), + terminal_ansi_bright_white: Some(rgba(0xfbf1c7ff).into()), + terminal_ansi_black: Some(rgba(0x1d2021ff).into()), + terminal_ansi_red: Some(rgba(0xfb4a35ff).into()), + terminal_ansi_green: Some(rgba(0xb8bb27ff).into()), + terminal_ansi_yellow: Some(rgba(0xf9bd30ff).into()), + terminal_ansi_blue: Some(rgba(0x83a598ff).into()), + terminal_ansi_magenta: Some(rgba(0xa89984ff).into()), + terminal_ansi_cyan: Some(rgba(0x8ec07cff).into()), + terminal_ansi_white: Some(rgba(0xfbf1c7ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xb16286ff).into()), - created: Some(rgba(0x79740eff).into()), - deleted: Some(rgba(0x9d0006ff).into()), - error: Some(rgba(0x9d0006ff).into()), - hidden: Some(rgba(0x7c6f64ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0xa89984ff).into()), - modified: Some(rgba(0x076678ff).into()), + created: Some(rgba(0xb8bb27ff).into()), + deleted: Some(rgba(0xd0382bff).into()), + error: Some(rgba(0xfb4a35ff).into()), + modified: Some(rgba(0xf9bd30ff).into()), + success: Some(rgba(0xfbf1c7ff).into()), + warning: Some(rgba(0xf9bd30ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -1569,220 +1793,278 @@ pub fn gruvbox() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xa89984ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x928374ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xc7b798ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0xfabd2fff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x427b58ff).into()), + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x8ec07cff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xaf3a03ff).into()), + color: Some(rgba(0x83a598ff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xfe8019ff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0x427b58ff).into()), + color: Some(rgba(0xb8bb26ff).into()), + ..Default::default() + }, + ), + ( + "function.builtin".into(), + UserHighlightStyle { + color: Some(rgba(0xfb4934ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x8d957eff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0x9d0006ff).into()), + color: Some(rgba(0xfb4934ff).into()), ..Default::default() }, ), ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0x8ec07cff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "link_uri".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0x8f3f71ff).into()), + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "operator".into(), UserHighlightStyle { - color: Some(rgba(0x427b58ff).into()), + color: Some(rgba(0x8ec07cff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x717363ff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "preproc".into(), UserHighlightStyle { - color: Some(rgba(0xaf3a03ff).into()), + color: Some(rgba(0xfbf1c7ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xebdbb2ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0x689d6aff).into()), + color: Some(rgba(0xebdbb2ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xd5c4a1ff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xa89984ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xe5d5adff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xebdbb2ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0x7c6f64ff).into()), + color: Some(rgba(0xe5d5adff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0xb8bb26ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0x9d0006ff).into()), + color: Some(rgba(0xc7b798ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0xfe8019ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0xd3869bff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0x8ec07cff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x427b58ff).into()), + color: Some(rgba(0x8ec07cff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0x79740eff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0xb8bb26ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0xb57614ff).into()), + color: Some(rgba(0xfabd2fff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0x076678ff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0x076678ff).into()), + color: Some(rgba(0x83a598ff).into()), ..Default::default() }, ), diff --git a/crates/theme2/src/themes/mod.rs b/crates/theme2/src/themes/mod.rs index aaf111703f207047fd71275ca3010f64374b18cc..a0ab44c871aae5578fa358f0101f1fb6dd5df116 100644 --- a/crates/theme2/src/themes/mod.rs +++ b/crates/theme2/src/themes/mod.rs @@ -2,43 +2,37 @@ // Be careful when modifying it by hand. mod andromeda; +mod atelier; mod ayu; -mod dracula; mod gruvbox; -mod night_owl; -mod noctis; -mod nord; -mod palenight; +mod one; mod rose_pine; +mod sandcastle; mod solarized; -mod synthwave_84; +mod summercamp; pub use andromeda::*; +pub use atelier::*; pub use ayu::*; -pub use dracula::*; pub use gruvbox::*; -pub use night_owl::*; -pub use noctis::*; -pub use nord::*; -pub use palenight::*; +pub use one::*; pub use rose_pine::*; +pub use sandcastle::*; pub use solarized::*; -pub use synthwave_84::*; +pub use summercamp::*; use crate::UserThemeFamily; pub(crate) fn all_user_themes() -> Vec { vec![ andromeda(), + atelier(), ayu(), - dracula(), gruvbox(), - night_owl(), - noctis(), - nord(), - palenight(), + one(), rose_pine(), + sandcastle(), solarized(), - synthwave_84(), + summercamp(), ] } diff --git a/crates/theme2/src/themes/night_owl.rs b/crates/theme2/src/themes/night_owl.rs deleted file mode 100644 index 437f79d4c7b594672d0cefd2dd8f433d3bc187e1..0000000000000000000000000000000000000000 --- a/crates/theme2/src/themes/night_owl.rs +++ /dev/null @@ -1,547 +0,0 @@ -// This file was generated by the `theme_importer`. -// Be careful when modifying it by hand. - -use gpui::rgba; - -#[allow(unused)] -use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, -}; - -pub fn night_owl() -> UserThemeFamily { - UserThemeFamily { - name: "Night Owl".into(), - author: "Sarah Drasner (sdras)".into(), - themes: vec![ - UserTheme { - name: "Night Owl".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x5f7e97ff).into()), - border_variant: Some(rgba(0x5f7e97ff).into()), - border_focused: Some(rgba(0x122d42ff).into()), - border_selected: Some(rgba(0x5f7e97ff).into()), - border_transparent: Some(rgba(0x5f7e97ff).into()), - border_disabled: Some(rgba(0x5f7e97ff).into()), - elevated_surface_background: Some(rgba(0x011627ff).into()), - surface_background: Some(rgba(0x011627ff).into()), - background: Some(rgba(0x011627ff).into()), - element_background: Some(rgba(0x7e57c2cc).into()), - element_hover: Some(rgba(0x011627ff).into()), - element_selected: Some(rgba(0x234d708c).into()), - drop_target_background: Some(rgba(0x011627ff).into()), - ghost_element_hover: Some(rgba(0x011627ff).into()), - ghost_element_selected: Some(rgba(0x234d708c).into()), - text: Some(rgba(0xd6deebff).into()), - text_muted: Some(rgba(0x5f7e97ff).into()), - status_bar_background: Some(rgba(0x011627ff).into()), - title_bar_background: Some(rgba(0x011627ff).into()), - toolbar_background: Some(rgba(0x011627ff).into()), - tab_bar_background: Some(rgba(0x011627ff).into()), - tab_inactive_background: Some(rgba(0x01111dff).into()), - tab_active_background: Some(rgba(0x0b2942ff).into()), - scrollbar_thumb_background: Some(rgba(0x084d8180).into()), - scrollbar_thumb_hover_background: Some(rgba(0x084d8180).into()), - scrollbar_thumb_border: Some(rgba(0x084d8180).into()), - scrollbar_track_background: Some(rgba(0x011627ff).into()), - editor_foreground: Some(rgba(0xd6deebff).into()), - editor_background: Some(rgba(0x011627ff).into()), - editor_gutter_background: Some(rgba(0x011627ff).into()), - editor_line_number: Some(rgba(0x4b6479ff).into()), - editor_active_line_number: Some(rgba(0xd6deebff).into()), - editor_wrap_guide: Some(rgba(0x5f7e97ff).into()), - editor_active_wrap_guide: Some(rgba(0x5f7e97ff).into()), - terminal_ansi_bright_black: Some(rgba(0x575656ff).into()), - terminal_ansi_bright_red: Some(rgba(0xef5350ff).into()), - terminal_ansi_bright_green: Some(rgba(0x22da6eff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xffeb95ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x82aaffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xc792eaff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x7fdbcaff).into()), - terminal_ansi_bright_white: Some(rgba(0xffffffff).into()), - terminal_ansi_black: Some(rgba(0x011627ff).into()), - terminal_ansi_red: Some(rgba(0xef5350ff).into()), - terminal_ansi_green: Some(rgba(0x22da6eff).into()), - terminal_ansi_yellow: Some(rgba(0xc5e478ff).into()), - terminal_ansi_blue: Some(rgba(0x82aaffff).into()), - terminal_ansi_magenta: Some(rgba(0xc792eaff).into()), - terminal_ansi_cyan: Some(rgba(0x21c7a8ff).into()), - terminal_ansi_white: Some(rgba(0xffffffff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xffeb95cc).into()), - created: Some(rgba(0x9ccc65ff).into()), - deleted: Some(rgba(0xef5350ff).into()), - error: Some(rgba(0xef5350ff).into()), - hidden: Some(rgba(0x5f7e97ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x395a75ff).into()), - modified: Some(rgba(0xe2b93dff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "attribute".into(), - UserHighlightStyle { - color: Some(rgba(0xc5e478ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x637777ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x637777ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xcaece6ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0xf78c6cff).into()), - ..Default::default() - }, - ), - ( - "operator".into(), - UserHighlightStyle { - color: Some(rgba(0x7fdbcaff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x80cbc4ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0xecc48dff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0xecc48dff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0xecc48dff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0xecc48dff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xcaece6ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0xecc48dff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xc5e478ff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xc5e478ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0x7fdbcaff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Night Owl Light".into(), - appearance: Appearance::Light, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0xd9d9d9ff).into()), - border_variant: Some(rgba(0xd9d9d9ff).into()), - border_focused: Some(rgba(0x93a1a1ff).into()), - border_selected: Some(rgba(0xd9d9d9ff).into()), - border_transparent: Some(rgba(0xd9d9d9ff).into()), - border_disabled: Some(rgba(0xd9d9d9ff).into()), - elevated_surface_background: Some(rgba(0xf0f0f0ff).into()), - surface_background: Some(rgba(0xf0f0f0ff).into()), - background: Some(rgba(0xfbfbfbff).into()), - element_background: Some(rgba(0x2aa298ff).into()), - element_hover: Some(rgba(0xd3e8f8ff).into()), - element_selected: Some(rgba(0xd3e8f8ff).into()), - ghost_element_hover: Some(rgba(0xd3e8f8ff).into()), - ghost_element_selected: Some(rgba(0xd3e8f8ff).into()), - text: Some(rgba(0x403f53ff).into()), - text_muted: Some(rgba(0x403f53ff).into()), - status_bar_background: Some(rgba(0xf0f0f0ff).into()), - title_bar_background: Some(rgba(0xf0f0f0ff).into()), - toolbar_background: Some(rgba(0xfbfbfbff).into()), - tab_bar_background: Some(rgba(0xf0f0f0ff).into()), - tab_inactive_background: Some(rgba(0xf0f0f0ff).into()), - tab_active_background: Some(rgba(0xf6f6f6ff).into()), - scrollbar_track_background: Some(rgba(0xfbfbfbff).into()), - editor_foreground: Some(rgba(0x403f53ff).into()), - editor_background: Some(rgba(0xfbfbfbff).into()), - editor_gutter_background: Some(rgba(0xfbfbfbff).into()), - editor_line_number: Some(rgba(0x90a7b2ff).into()), - editor_active_line_number: Some(rgba(0x403f53ff).into()), - editor_wrap_guide: Some(rgba(0xd9d9d9ff).into()), - editor_active_wrap_guide: Some(rgba(0xd9d9d9ff).into()), - terminal_background: Some(rgba(0xf6f6f6ff).into()), - terminal_ansi_bright_black: Some(rgba(0x403f53ff).into()), - terminal_ansi_bright_red: Some(rgba(0xde3d3bff).into()), - terminal_ansi_bright_green: Some(rgba(0x08916aff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xdaaa01ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x288ed7ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xd6438aff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x2aa298ff).into()), - terminal_ansi_bright_white: Some(rgba(0xf0f0f0ff).into()), - terminal_ansi_black: Some(rgba(0x403f53ff).into()), - terminal_ansi_red: Some(rgba(0xde3d3bff).into()), - terminal_ansi_green: Some(rgba(0x08916aff).into()), - terminal_ansi_yellow: Some(rgba(0xe0af02ff).into()), - terminal_ansi_blue: Some(rgba(0x288ed7ff).into()), - terminal_ansi_magenta: Some(rgba(0xd6438aff).into()), - terminal_ansi_cyan: Some(rgba(0x2aa298ff).into()), - terminal_ansi_white: Some(rgba(0xf0f0f0ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - created: Some(rgba(0x49d0c5ff).into()), - deleted: Some(rgba(0xf76e6eff).into()), - error: Some(rgba(0x403f53ff).into()), - hidden: Some(rgba(0x403f53ff).into()), - hint: Some(rgba(0x969696ff).into()), - modified: Some(rgba(0x6fbef6ff).into()), - warning: Some(rgba(0xdaaa01ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "attribute".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x989fb1ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x989fb1ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0x994cc3ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0x994cc3ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0xaa0982ff).into()), - ..Default::default() - }, - ), - ( - "operator".into(), - UserHighlightStyle { - color: Some(rgba(0x0c969bff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x0c969bff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0x994cc3ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0x994cc3ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0x994cc3ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0x994cc3ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0x994cc3ff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0x994cc3ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0x4876d6ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0x0c969bff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - ], - } -} diff --git a/crates/theme2/src/themes/noctis.rs b/crates/theme2/src/themes/noctis.rs deleted file mode 100644 index 55aea3d24c04ff59f23be080f4b0a3436f9020fa..0000000000000000000000000000000000000000 --- a/crates/theme2/src/themes/noctis.rs +++ /dev/null @@ -1,3110 +0,0 @@ -// This file was generated by the `theme_importer`. -// Be careful when modifying it by hand. - -use gpui::rgba; - -#[allow(unused)] -use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, -}; - -pub fn noctis() -> UserThemeFamily { - UserThemeFamily { - name: "Noctis".into(), - author: "Liviu Schera (liviuschera)".into(), - themes: vec![ - UserTheme { - name: "Noctis Azureus".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x1679b6ff).into()), - border_variant: Some(rgba(0x1679b6ff).into()), - border_focused: Some(rgba(0x09334eff).into()), - border_selected: Some(rgba(0x1679b6ff).into()), - border_transparent: Some(rgba(0x1679b6ff).into()), - border_disabled: Some(rgba(0x1679b6ff).into()), - elevated_surface_background: Some(rgba(0x09334eff).into()), - surface_background: Some(rgba(0x051b29ff).into()), - background: Some(rgba(0x07273bff).into()), - element_background: Some(rgba(0x007f99ff).into()), - element_hover: Some(rgba(0x00558a65).into()), - element_selected: Some(rgba(0x0c3f5fff).into()), - drop_target_background: Some(rgba(0x002a4dff).into()), - ghost_element_hover: Some(rgba(0x00558a65).into()), - ghost_element_selected: Some(rgba(0x0c3f5fff).into()), - text: Some(rgba(0xbecfdaff).into()), - text_muted: Some(rgba(0x9fb6c6ff).into()), - status_bar_background: Some(rgba(0x07273bff).into()), - title_bar_background: Some(rgba(0x07273bff).into()), - toolbar_background: Some(rgba(0x07273bff).into()), - tab_bar_background: Some(rgba(0x09334eff).into()), - tab_inactive_background: Some(rgba(0x09334eff).into()), - tab_active_background: Some(rgba(0x07273bff).into()), - scrollbar_thumb_background: Some(rgba(0x008ee633).into()), - scrollbar_thumb_hover_background: Some(rgba(0x008ee655).into()), - scrollbar_thumb_border: Some(rgba(0x008ee633).into()), - scrollbar_track_background: Some(rgba(0x07273bff).into()), - scrollbar_track_border: Some(rgba(0x07273bff).into()), - editor_foreground: Some(rgba(0xbecfdaff).into()), - editor_background: Some(rgba(0x07273bff).into()), - editor_gutter_background: Some(rgba(0x07273bff).into()), - editor_line_number: Some(rgba(0x4d6c80ff).into()), - editor_active_line_number: Some(rgba(0xbecfdaff).into()), - editor_wrap_guide: Some(rgba(0x1679b6ff).into()), - editor_active_wrap_guide: Some(rgba(0x1679b6ff).into()), - terminal_background: Some(rgba(0x051b29ff).into()), - terminal_ansi_bright_black: Some(rgba(0x475e6cff).into()), - terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), - terminal_ansi_bright_green: Some(rgba(0x60ebb1ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xe69533ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x60b6ebff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xe798b3ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x60dbebff).into()), - terminal_ansi_bright_white: Some(rgba(0xbecfdaff).into()), - terminal_ansi_black: Some(rgba(0x28353eff).into()), - terminal_ansi_red: Some(rgba(0xe66533ff).into()), - terminal_ansi_green: Some(rgba(0x49e9a6ff).into()), - terminal_ansi_yellow: Some(rgba(0xe4b781ff).into()), - terminal_ansi_blue: Some(rgba(0x49ace9ff).into()), - terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), - terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), - terminal_ansi_white: Some(rgba(0xaec3d0ff).into()), - link_text_hover: Some(rgba(0x49ace9ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xffc180ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xe34e1cff).into()), - error: Some(rgba(0xe34e1cff).into()), - hidden: Some(rgba(0x9fb6c6ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x5b788bff).into()), - modified: Some(rgba(0xffc180ff).into()), - warning: Some(rgba(0xffa857ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x5988a6ff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x5988a6ff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xd5971aff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xdf769bff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xbecfdaff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xbecfdaff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xbecfdaff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xbecfdaff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xbecfdaff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xbecfdaff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xd67e5cff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xe4b781ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis Bordo".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x997582ff).into()), - border_variant: Some(rgba(0x997582ff).into()), - border_focused: Some(rgba(0x413036ff).into()), - border_selected: Some(rgba(0x997582ff).into()), - border_transparent: Some(rgba(0x997582ff).into()), - border_disabled: Some(rgba(0x997582ff).into()), - elevated_surface_background: Some(rgba(0x413036ff).into()), - surface_background: Some(rgba(0x272022ff).into()), - background: Some(rgba(0x322a2dff).into()), - element_background: Some(rgba(0x007f99ff).into()), - element_hover: Some(rgba(0x533641ff).into()), - element_selected: Some(rgba(0x5c2e3e99).into()), - drop_target_background: Some(rgba(0x38292eff).into()), - ghost_element_hover: Some(rgba(0x533641ff).into()), - ghost_element_selected: Some(rgba(0x5c2e3e99).into()), - text: Some(rgba(0xcbbec2ff).into()), - text_muted: Some(rgba(0xbbaab0ff).into()), - status_bar_background: Some(rgba(0x322a2dff).into()), - title_bar_background: Some(rgba(0x322a2dff).into()), - toolbar_background: Some(rgba(0x322a2dff).into()), - tab_bar_background: Some(rgba(0x413036ff).into()), - tab_inactive_background: Some(rgba(0x413036ff).into()), - tab_active_background: Some(rgba(0x322a2dff).into()), - scrollbar_thumb_background: Some(rgba(0xeb609133).into()), - scrollbar_thumb_hover_background: Some(rgba(0xeb609144).into()), - scrollbar_thumb_border: Some(rgba(0xeb609133).into()), - scrollbar_track_background: Some(rgba(0x322a2dff).into()), - scrollbar_track_border: Some(rgba(0x322a2dff).into()), - editor_foreground: Some(rgba(0xcbbec2ff).into()), - editor_background: Some(rgba(0x322a2dff).into()), - editor_gutter_background: Some(rgba(0x322a2dff).into()), - editor_line_number: Some(rgba(0x715b63ff).into()), - editor_active_line_number: Some(rgba(0xcbbec2ff).into()), - editor_wrap_guide: Some(rgba(0x997582ff).into()), - editor_active_wrap_guide: Some(rgba(0x997582ff).into()), - terminal_background: Some(rgba(0x272022ff).into()), - terminal_ansi_bright_black: Some(rgba(0x69545bff).into()), - terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), - terminal_ansi_bright_green: Some(rgba(0x60ebb1ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xe69533ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x60b6ebff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xe798b3ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x60dbebff).into()), - terminal_ansi_bright_white: Some(rgba(0xcbbec2ff).into()), - terminal_ansi_black: Some(rgba(0x47393eff).into()), - terminal_ansi_red: Some(rgba(0xe66533ff).into()), - terminal_ansi_green: Some(rgba(0x49e9a6ff).into()), - terminal_ansi_yellow: Some(rgba(0xe4b781ff).into()), - terminal_ansi_blue: Some(rgba(0x49ace9ff).into()), - terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), - terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), - terminal_ansi_white: Some(rgba(0xb9acb0ff).into()), - link_text_hover: Some(rgba(0xf18eb0ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xffc180ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xe34e1cff).into()), - error: Some(rgba(0xe34e1cff).into()), - hidden: Some(rgba(0xbbaab0ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x5b788bff).into()), - modified: Some(rgba(0xffc180ff).into()), - warning: Some(rgba(0xffa857ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x8b747cff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x8b747cff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xd5971aff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xdf769bff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xcbbec2ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xcbbec2ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xcbbec2ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xcbbec2ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xcbbec2ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xcbbec2ff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xd67e5cff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xe4b781ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis Hibernus".into(), - appearance: Appearance::Light, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x00c6e0ff).into()), - border_variant: Some(rgba(0x00c6e0ff).into()), - border_focused: Some(rgba(0xe0eff1ff).into()), - border_selected: Some(rgba(0x00c6e0ff).into()), - border_transparent: Some(rgba(0x00c6e0ff).into()), - border_disabled: Some(rgba(0x00c6e0ff).into()), - elevated_surface_background: Some(rgba(0xf4f6f6ff).into()), - surface_background: Some(rgba(0xe1eeefff).into()), - background: Some(rgba(0xf4f6f6ff).into()), - element_background: Some(rgba(0x099099ff).into()), - element_hover: Some(rgba(0xd1eafaff).into()), - element_selected: Some(rgba(0xb6e1e7ff).into()), - drop_target_background: Some(rgba(0xb2cacdff).into()), - ghost_element_hover: Some(rgba(0xd1eafaff).into()), - ghost_element_selected: Some(rgba(0xb6e1e7ff).into()), - text: Some(rgba(0x005661ff).into()), - text_muted: Some(rgba(0x71838eff).into()), - status_bar_background: Some(rgba(0xcaedf2ff).into()), - title_bar_background: Some(rgba(0xe7f2f3ff).into()), - toolbar_background: Some(rgba(0xf4f6f6ff).into()), - tab_bar_background: Some(rgba(0xcaedf2ff).into()), - tab_inactive_background: Some(rgba(0xcaedf2ff).into()), - tab_active_background: Some(rgba(0xf4f6f6ff).into()), - scrollbar_thumb_background: Some(rgba(0x6a90955b).into()), - scrollbar_thumb_hover_background: Some(rgba(0x0099ad62).into()), - scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), - scrollbar_track_background: Some(rgba(0xf4f6f6ff).into()), - scrollbar_track_border: Some(rgba(0xf4f6f6ff).into()), - editor_foreground: Some(rgba(0x005661ff).into()), - editor_background: Some(rgba(0xf4f6f6ff).into()), - editor_gutter_background: Some(rgba(0xf4f6f6ff).into()), - editor_line_number: Some(rgba(0xa0abacff).into()), - editor_active_line_number: Some(rgba(0x005661ff).into()), - editor_wrap_guide: Some(rgba(0x00c6e0ff).into()), - editor_active_wrap_guide: Some(rgba(0x00c6e0ff).into()), - terminal_background: Some(rgba(0xe1eeefff).into()), - terminal_ansi_bright_black: Some(rgba(0x004d57ff).into()), - terminal_ansi_bright_red: Some(rgba(0xff4000ff).into()), - terminal_ansi_bright_green: Some(rgba(0x00d17aff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xff8c00ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x0fa3ffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xff6b9fff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x00cbe6ff).into()), - terminal_ansi_bright_white: Some(rgba(0xbbc3c4ff).into()), - terminal_ansi_black: Some(rgba(0x003b42ff).into()), - terminal_ansi_red: Some(rgba(0xe34e1cff).into()), - terminal_ansi_green: Some(rgba(0x00b368ff).into()), - terminal_ansi_yellow: Some(rgba(0xf49725ff).into()), - terminal_ansi_blue: Some(rgba(0x0094f0ff).into()), - terminal_ansi_magenta: Some(rgba(0xff5792ff).into()), - terminal_ansi_cyan: Some(rgba(0x00bdd6ff).into()), - terminal_ansi_white: Some(rgba(0x8ca6a6ff).into()), - link_text_hover: Some(rgba(0x00c6e0ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xe9a149ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xff4000ff).into()), - error: Some(rgba(0xff4000ff).into()), - hidden: Some(rgba(0x71838eff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0xa8a28faa).into()), - modified: Some(rgba(0xe9a149ff).into()), - warning: Some(rgba(0xe07a52ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x5842ffff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x8ca6a6ff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x8ca6a6ff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xa88c00ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x0095a8ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x5842ffff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xff5792ff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x0095a8ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xb3694dff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xfa8900ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis Lilac".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0xaea4f4ff).into()), - border_variant: Some(rgba(0xaea4f4ff).into()), - border_focused: Some(rgba(0xdedbf5ff).into()), - border_selected: Some(rgba(0xaea4f4ff).into()), - border_transparent: Some(rgba(0xaea4f4ff).into()), - border_disabled: Some(rgba(0xaea4f4ff).into()), - elevated_surface_background: Some(rgba(0xf2f1f8ff).into()), - surface_background: Some(rgba(0xe9e7f3ff).into()), - background: Some(rgba(0xf2f1f8ff).into()), - element_background: Some(rgba(0x8e80ffff).into()), - element_hover: Some(rgba(0xd2ccffff).into()), - element_selected: Some(rgba(0xbcb6e7ff).into()), - drop_target_background: Some(rgba(0xafaad4aa).into()), - ghost_element_hover: Some(rgba(0xd2ccffff).into()), - ghost_element_selected: Some(rgba(0xbcb6e7ff).into()), - text: Some(rgba(0x0c006bff).into()), - text_muted: Some(rgba(0x75718eff).into()), - status_bar_background: Some(rgba(0xe2dff6ff).into()), - title_bar_background: Some(rgba(0xedecf8ff).into()), - toolbar_background: Some(rgba(0xf2f1f8ff).into()), - tab_bar_background: Some(rgba(0xe2dff6ff).into()), - tab_inactive_background: Some(rgba(0xe2dff6ff).into()), - tab_active_background: Some(rgba(0xf2f1f8ff).into()), - scrollbar_thumb_background: Some(rgba(0x6a90955b).into()), - scrollbar_thumb_hover_background: Some(rgba(0x7060eb62).into()), - scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), - scrollbar_track_background: Some(rgba(0xf2f1f8ff).into()), - scrollbar_track_border: Some(rgba(0xf2f1f8ff).into()), - editor_foreground: Some(rgba(0x0c006bff).into()), - editor_background: Some(rgba(0xf2f1f8ff).into()), - editor_gutter_background: Some(rgba(0xf2f1f8ff).into()), - editor_line_number: Some(rgba(0x9d9ab1ff).into()), - editor_active_line_number: Some(rgba(0x0c006bff).into()), - editor_wrap_guide: Some(rgba(0xaea4f4ff).into()), - editor_active_wrap_guide: Some(rgba(0xaea4f4ff).into()), - terminal_background: Some(rgba(0xe9e7f3ff).into()), - terminal_ansi_bright_black: Some(rgba(0x0f0080ff).into()), - terminal_ansi_bright_red: Some(rgba(0xff4000ff).into()), - terminal_ansi_bright_green: Some(rgba(0x00d17aff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xff8c00ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x0fa3ffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xff6b9fff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x00cbe6ff).into()), - terminal_ansi_bright_white: Some(rgba(0xbbc3c4ff).into()), - terminal_ansi_black: Some(rgba(0x0c006bff).into()), - terminal_ansi_red: Some(rgba(0xe34e1cff).into()), - terminal_ansi_green: Some(rgba(0x00b368ff).into()), - terminal_ansi_yellow: Some(rgba(0xf49725ff).into()), - terminal_ansi_blue: Some(rgba(0x0094f0ff).into()), - terminal_ansi_magenta: Some(rgba(0xff5792ff).into()), - terminal_ansi_cyan: Some(rgba(0x00bdd6ff).into()), - terminal_ansi_white: Some(rgba(0x8ca6a6ff).into()), - link_text_hover: Some(rgba(0x00c6e0ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xe9a149ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xff4000ff).into()), - error: Some(rgba(0xff4000ff).into()), - hidden: Some(rgba(0x75718eff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0xa8a28faa).into()), - modified: Some(rgba(0xe9a149ff).into()), - warning: Some(rgba(0xe07a52ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x5842ffff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x9995b7ff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x9995b7ff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xa88c00ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x0095a8ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x5842ffff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xff5792ff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x0095a8ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0x0c006bff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0x0c006bff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0x0c006bff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0x0c006bff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0x0c006bff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0x0c006bff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xb3694dff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xfa8900ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis Lux".into(), - appearance: Appearance::Light, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x00c6e0ff).into()), - border_variant: Some(rgba(0x00c6e0ff).into()), - border_focused: Some(rgba(0xf2eddeff).into()), - border_selected: Some(rgba(0x00c6e0ff).into()), - border_transparent: Some(rgba(0x00c6e0ff).into()), - border_disabled: Some(rgba(0x00c6e0ff).into()), - elevated_surface_background: Some(rgba(0xfef8ecff).into()), - surface_background: Some(rgba(0xf6eddaff).into()), - background: Some(rgba(0xfef8ecff).into()), - element_background: Some(rgba(0x099099ff).into()), - element_hover: Some(rgba(0xd2f3f9ff).into()), - element_selected: Some(rgba(0xb6e1e7ff).into()), - drop_target_background: Some(rgba(0xcdcbb2ff).into()), - ghost_element_hover: Some(rgba(0xd2f3f9ff).into()), - ghost_element_selected: Some(rgba(0xb6e1e7ff).into()), - text: Some(rgba(0x005661ff).into()), - text_muted: Some(rgba(0x888477ff).into()), - status_bar_background: Some(rgba(0xf0e9d6ff).into()), - title_bar_background: Some(rgba(0xf9f1e1ff).into()), - toolbar_background: Some(rgba(0xfef8ecff).into()), - tab_bar_background: Some(rgba(0xf0e9d6ff).into()), - tab_inactive_background: Some(rgba(0xf0e9d6ff).into()), - tab_active_background: Some(rgba(0xfef8ecff).into()), - scrollbar_thumb_background: Some(rgba(0x6a90955b).into()), - scrollbar_thumb_hover_background: Some(rgba(0x0099ad62).into()), - scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), - scrollbar_track_background: Some(rgba(0xfef8ecff).into()), - scrollbar_track_border: Some(rgba(0xfef8ecff).into()), - editor_foreground: Some(rgba(0x005661ff).into()), - editor_background: Some(rgba(0xfef8ecff).into()), - editor_gutter_background: Some(rgba(0xfef8ecff).into()), - editor_line_number: Some(rgba(0xa0abacff).into()), - editor_active_line_number: Some(rgba(0x005661ff).into()), - editor_wrap_guide: Some(rgba(0x00c6e0ff).into()), - editor_active_wrap_guide: Some(rgba(0x00c6e0ff).into()), - terminal_background: Some(rgba(0xf6eddaff).into()), - terminal_ansi_bright_black: Some(rgba(0x004d57ff).into()), - terminal_ansi_bright_red: Some(rgba(0xff4000ff).into()), - terminal_ansi_bright_green: Some(rgba(0x00d17aff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xff8c00ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x0fa3ffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xff6b9fff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x00cbe6ff).into()), - terminal_ansi_bright_white: Some(rgba(0xbbc3c4ff).into()), - terminal_ansi_black: Some(rgba(0x003b42ff).into()), - terminal_ansi_red: Some(rgba(0xe34e1cff).into()), - terminal_ansi_green: Some(rgba(0x00b368ff).into()), - terminal_ansi_yellow: Some(rgba(0xf49725ff).into()), - terminal_ansi_blue: Some(rgba(0x0094f0ff).into()), - terminal_ansi_magenta: Some(rgba(0xff5792ff).into()), - terminal_ansi_cyan: Some(rgba(0x00bdd6ff).into()), - terminal_ansi_white: Some(rgba(0x8ca6a6ff).into()), - link_text_hover: Some(rgba(0x00c6e0ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xe9a149ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xff4000ff).into()), - error: Some(rgba(0xff4000ff).into()), - hidden: Some(rgba(0x888477ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0xa8a28faa).into()), - modified: Some(rgba(0xe9a149ff).into()), - warning: Some(rgba(0xe07a52ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x5842ffff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x8ca6a6ff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x8ca6a6ff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xa88c00ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x0095a8ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x5842ffff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xff5792ff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x0095a8ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0x004d57ff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x00b368ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x00bdd6ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xb3694dff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xfa8900ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe64100ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis Minimus".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x496d83ff).into()), - border_variant: Some(rgba(0x496d83ff).into()), - border_focused: Some(rgba(0x202e37ff).into()), - border_selected: Some(rgba(0x496d83ff).into()), - border_transparent: Some(rgba(0x496d83ff).into()), - border_disabled: Some(rgba(0x496d83ff).into()), - elevated_surface_background: Some(rgba(0x202e37ff).into()), - surface_background: Some(rgba(0x0e1920ff).into()), - background: Some(rgba(0x1b2932ff).into()), - element_background: Some(rgba(0x2e616bff).into()), - element_hover: Some(rgba(0x00558aff).into()), - element_selected: Some(rgba(0x2c414eff).into()), - drop_target_background: Some(rgba(0x152837ff).into()), - ghost_element_hover: Some(rgba(0x00558aff).into()), - ghost_element_selected: Some(rgba(0x2c414eff).into()), - text: Some(rgba(0xc5cdd3ff).into()), - text_muted: Some(rgba(0x96a8b6ff).into()), - status_bar_background: Some(rgba(0x1b2932ff).into()), - title_bar_background: Some(rgba(0x1b2932ff).into()), - toolbar_background: Some(rgba(0x1b2932ff).into()), - tab_bar_background: Some(rgba(0x24333dff).into()), - tab_inactive_background: Some(rgba(0x202e37ff).into()), - tab_active_background: Some(rgba(0x1b2932ff).into()), - scrollbar_thumb_background: Some(rgba(0x3f7fa633).into()), - scrollbar_thumb_hover_background: Some(rgba(0x3f7fa655).into()), - scrollbar_thumb_border: Some(rgba(0x3f7fa633).into()), - scrollbar_track_background: Some(rgba(0x1b2932ff).into()), - scrollbar_track_border: Some(rgba(0x1b2932ff).into()), - editor_foreground: Some(rgba(0xc5cdd3ff).into()), - editor_background: Some(rgba(0x1b2932ff).into()), - editor_gutter_background: Some(rgba(0x1b2932ff).into()), - editor_line_number: Some(rgba(0x5d6e79ff).into()), - editor_active_line_number: Some(rgba(0xc5cdd3ff).into()), - editor_wrap_guide: Some(rgba(0x496d83ff).into()), - editor_active_wrap_guide: Some(rgba(0x496d83ff).into()), - terminal_background: Some(rgba(0x0e1920ff).into()), - terminal_ansi_bright_black: Some(rgba(0x425866ff).into()), - terminal_ansi_bright_red: Some(rgba(0xca8468ff).into()), - terminal_ansi_bright_green: Some(rgba(0x84c8abff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xd1aa7bff).into()), - terminal_ansi_bright_blue: Some(rgba(0x68a4caff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xc88da2ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x84c0c8ff).into()), - terminal_ansi_bright_white: Some(rgba(0xc5d1d3ff).into()), - terminal_ansi_black: Some(rgba(0x182a35ff).into()), - terminal_ansi_red: Some(rgba(0xc08872ff).into()), - terminal_ansi_green: Some(rgba(0x72c09fff).into()), - terminal_ansi_yellow: Some(rgba(0xc8a984ff).into()), - terminal_ansi_blue: Some(rgba(0x6196b8ff).into()), - terminal_ansi_magenta: Some(rgba(0xc28097ff).into()), - terminal_ansi_cyan: Some(rgba(0x72b7c0ff).into()), - terminal_ansi_white: Some(rgba(0xc5cdd3ff).into()), - link_text_hover: Some(rgba(0x5998c0ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xdfc09fff).into()), - created: Some(rgba(0xa0d4a8ff).into()), - deleted: Some(rgba(0xb96346ff).into()), - error: Some(rgba(0xb96346ff).into()), - hidden: Some(rgba(0x96a8b6ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x5b788bff).into()), - modified: Some(rgba(0xdfc09fff).into()), - warning: Some(rgba(0xffa857ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x7068b1ff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x5e7887ff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x5e7887ff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xa88c00ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xc37455ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x3f848dff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xc37455ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x72b7c0ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x72b7c0ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x72b7c0ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x7068b1ff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xc88da2ff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x3f848dff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xc5cdd3ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xc5cdd3ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xc5cdd3ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xc5cdd3ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xc5cdd3ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x72c09fff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xc5cdd3ff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x72c09fff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x72c09fff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x72c09fff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xc37455ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x72c09fff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x72b7c0ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xbe856fff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xd3b692ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xc37455ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x0e6671ff).into()), - border_variant: Some(rgba(0x0e6671ff).into()), - border_focused: Some(rgba(0x073940ff).into()), - border_selected: Some(rgba(0x0e6671ff).into()), - border_transparent: Some(rgba(0x0e6671ff).into()), - border_disabled: Some(rgba(0x0e6671ff).into()), - elevated_surface_background: Some(rgba(0x073940ff).into()), - surface_background: Some(rgba(0x03191bff).into()), - background: Some(rgba(0x052529ff).into()), - element_background: Some(rgba(0x099099ff).into()), - element_hover: Some(rgba(0x0b515bff).into()), - element_selected: Some(rgba(0x0e6671ff).into()), - drop_target_background: Some(rgba(0x00404dff).into()), - ghost_element_hover: Some(rgba(0x0b515bff).into()), - ghost_element_selected: Some(rgba(0x0e6671ff).into()), - text: Some(rgba(0xb2cacdff).into()), - text_muted: Some(rgba(0x87a7abff).into()), - status_bar_background: Some(rgba(0x041d20ff).into()), - title_bar_background: Some(rgba(0x041d20ff).into()), - toolbar_background: Some(rgba(0x052529ff).into()), - tab_bar_background: Some(rgba(0x062e32ff).into()), - tab_inactive_background: Some(rgba(0x062e32ff).into()), - tab_active_background: Some(rgba(0x052529ff).into()), - scrollbar_thumb_background: Some(rgba(0x6a90955b).into()), - scrollbar_thumb_hover_background: Some(rgba(0x169fb162).into()), - scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), - scrollbar_track_background: Some(rgba(0x052529ff).into()), - scrollbar_track_border: Some(rgba(0x052529ff).into()), - editor_foreground: Some(rgba(0xb2cacdff).into()), - editor_background: Some(rgba(0x052529ff).into()), - editor_gutter_background: Some(rgba(0x052529ff).into()), - editor_line_number: Some(rgba(0x4e6b6eff).into()), - editor_active_line_number: Some(rgba(0xb2cacdff).into()), - editor_wrap_guide: Some(rgba(0x0e6671ff).into()), - editor_active_wrap_guide: Some(rgba(0x0e6671ff).into()), - terminal_background: Some(rgba(0x03191bff).into()), - terminal_ansi_bright_black: Some(rgba(0x47686cff).into()), - terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), - terminal_ansi_bright_green: Some(rgba(0x60ebb1ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xe69533ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x60b6ebff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xe798b3ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x60dbebff).into()), - terminal_ansi_bright_white: Some(rgba(0xc1d4d7ff).into()), - terminal_ansi_black: Some(rgba(0x324a4dff).into()), - terminal_ansi_red: Some(rgba(0xe66533ff).into()), - terminal_ansi_green: Some(rgba(0x49e9a6ff).into()), - terminal_ansi_yellow: Some(rgba(0xe4b781ff).into()), - terminal_ansi_blue: Some(rgba(0x49ace9ff).into()), - terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), - terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), - terminal_ansi_white: Some(rgba(0xb2cacdff).into()), - link_text_hover: Some(rgba(0x40d4e7ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xe4b781ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xe34e1cff).into()), - error: Some(rgba(0xe34e1cff).into()), - hidden: Some(rgba(0x87a7abff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x5b858bff).into()), - modified: Some(rgba(0xe0c184ff).into()), - warning: Some(rgba(0xffa487ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x5b858bff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x5b858bff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xd5971aff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xdf769bff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xd67e5cff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xe4b781ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis Obscuro".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x0e6671ff).into()), - border_variant: Some(rgba(0x0e6671ff).into()), - border_focused: Some(rgba(0x062e32ff).into()), - border_selected: Some(rgba(0x0e6671ff).into()), - border_transparent: Some(rgba(0x0e6671ff).into()), - border_disabled: Some(rgba(0x0e6671ff).into()), - elevated_surface_background: Some(rgba(0x031417ff).into()), - surface_background: Some(rgba(0x020c0eff).into()), - background: Some(rgba(0x031417ff).into()), - element_background: Some(rgba(0x099099ff).into()), - element_hover: Some(rgba(0x0b515bff).into()), - element_selected: Some(rgba(0x0e6671ff).into()), - drop_target_background: Some(rgba(0x00404dff).into()), - ghost_element_hover: Some(rgba(0x0b515bff).into()), - ghost_element_selected: Some(rgba(0x0e6671ff).into()), - text: Some(rgba(0xb2cacdff).into()), - text_muted: Some(rgba(0x87a7abff).into()), - status_bar_background: Some(rgba(0x031417ff).into()), - title_bar_background: Some(rgba(0x031417ff).into()), - toolbar_background: Some(rgba(0x031417ff).into()), - tab_bar_background: Some(rgba(0x062e32ff).into()), - tab_inactive_background: Some(rgba(0x062e32ff).into()), - tab_active_background: Some(rgba(0x031417ff).into()), - scrollbar_thumb_background: Some(rgba(0x6a90955b).into()), - scrollbar_thumb_hover_background: Some(rgba(0x169fb162).into()), - scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), - scrollbar_track_background: Some(rgba(0x031417ff).into()), - scrollbar_track_border: Some(rgba(0x031417ff).into()), - editor_foreground: Some(rgba(0xb2cacdff).into()), - editor_background: Some(rgba(0x031417ff).into()), - editor_gutter_background: Some(rgba(0x031417ff).into()), - editor_line_number: Some(rgba(0x4e6b6eff).into()), - editor_active_line_number: Some(rgba(0xb2cacdff).into()), - editor_wrap_guide: Some(rgba(0x0e6671ff).into()), - editor_active_wrap_guide: Some(rgba(0x0e6671ff).into()), - terminal_background: Some(rgba(0x020c0eff).into()), - terminal_ansi_bright_black: Some(rgba(0x47686cff).into()), - terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), - terminal_ansi_bright_green: Some(rgba(0x60ebb1ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xe69533ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x60b6ebff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xe798b3ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x60dbebff).into()), - terminal_ansi_bright_white: Some(rgba(0xc1d4d7ff).into()), - terminal_ansi_black: Some(rgba(0x324a4dff).into()), - terminal_ansi_red: Some(rgba(0xe66533ff).into()), - terminal_ansi_green: Some(rgba(0x49e9a6ff).into()), - terminal_ansi_yellow: Some(rgba(0xe4b781ff).into()), - terminal_ansi_blue: Some(rgba(0x49ace9ff).into()), - terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), - terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), - terminal_ansi_white: Some(rgba(0xb2cacdff).into()), - link_text_hover: Some(rgba(0x40d4e7ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xe4b781ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xe34e1cff).into()), - error: Some(rgba(0xe34e1cff).into()), - hidden: Some(rgba(0x87a7abff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x647e82ff).into()), - modified: Some(rgba(0xe4b781ff).into()), - warning: Some(rgba(0xffa487ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x5b858bff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x5b858bff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xd5971aff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xdf769bff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xd67e5cff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xe4b781ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis Sereno".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x0e6671ff).into()), - border_variant: Some(rgba(0x0e6671ff).into()), - border_focused: Some(rgba(0x062e32ff).into()), - border_selected: Some(rgba(0x0e6671ff).into()), - border_transparent: Some(rgba(0x0e6671ff).into()), - border_disabled: Some(rgba(0x0e6671ff).into()), - elevated_surface_background: Some(rgba(0x031417ff).into()), - surface_background: Some(rgba(0x020c0eff).into()), - background: Some(rgba(0x031417ff).into()), - element_background: Some(rgba(0x099099ff).into()), - element_hover: Some(rgba(0x0b515bff).into()), - element_selected: Some(rgba(0x0e6671ff).into()), - drop_target_background: Some(rgba(0x00404dff).into()), - ghost_element_hover: Some(rgba(0x0b515bff).into()), - ghost_element_selected: Some(rgba(0x0e6671ff).into()), - text: Some(rgba(0xb2cacdff).into()), - text_muted: Some(rgba(0x87a7abff).into()), - status_bar_background: Some(rgba(0x031417ff).into()), - title_bar_background: Some(rgba(0x031417ff).into()), - toolbar_background: Some(rgba(0x031417ff).into()), - tab_bar_background: Some(rgba(0x062e32ff).into()), - tab_inactive_background: Some(rgba(0x062e32ff).into()), - tab_active_background: Some(rgba(0x031417ff).into()), - scrollbar_thumb_background: Some(rgba(0x6a90955b).into()), - scrollbar_thumb_hover_background: Some(rgba(0x169fb162).into()), - scrollbar_thumb_border: Some(rgba(0x6a90955b).into()), - scrollbar_track_background: Some(rgba(0x031417ff).into()), - scrollbar_track_border: Some(rgba(0x031417ff).into()), - editor_foreground: Some(rgba(0xb2cacdff).into()), - editor_background: Some(rgba(0x031417ff).into()), - editor_gutter_background: Some(rgba(0x031417ff).into()), - editor_line_number: Some(rgba(0x4e6b6eff).into()), - editor_active_line_number: Some(rgba(0xb2cacdff).into()), - editor_wrap_guide: Some(rgba(0x0e6671ff).into()), - editor_active_wrap_guide: Some(rgba(0x0e6671ff).into()), - terminal_background: Some(rgba(0x020c0eff).into()), - terminal_ansi_bright_black: Some(rgba(0x47686cff).into()), - terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), - terminal_ansi_bright_green: Some(rgba(0x60ebb1ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xe69533ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x60b6ebff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xe798b3ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x60dbebff).into()), - terminal_ansi_bright_white: Some(rgba(0xc1d4d7ff).into()), - terminal_ansi_black: Some(rgba(0x324a4dff).into()), - terminal_ansi_red: Some(rgba(0xe66533ff).into()), - terminal_ansi_green: Some(rgba(0x49e9a6ff).into()), - terminal_ansi_yellow: Some(rgba(0xe4b781ff).into()), - terminal_ansi_blue: Some(rgba(0x49ace9ff).into()), - terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), - terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), - terminal_ansi_white: Some(rgba(0xb2cacdff).into()), - link_text_hover: Some(rgba(0x40d4e7ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xe4b781ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xe34e1cff).into()), - error: Some(rgba(0xe34e1cff).into()), - hidden: Some(rgba(0x87a7abff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x647e82ff).into()), - modified: Some(rgba(0xe4b781ff).into()), - warning: Some(rgba(0xffa487ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x5b858bff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x5b858bff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xd5971aff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xdf769bff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xb2cacdff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xd67e5cff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xe4b781ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis Uva".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x6e67a8ff).into()), - border_variant: Some(rgba(0x6e67a8ff).into()), - border_focused: Some(rgba(0x2f2c49ff).into()), - border_selected: Some(rgba(0x6e67a8ff).into()), - border_transparent: Some(rgba(0x6e67a8ff).into()), - border_disabled: Some(rgba(0x6e67a8ff).into()), - elevated_surface_background: Some(rgba(0x2f2c49ff).into()), - surface_background: Some(rgba(0x1f1d30ff).into()), - background: Some(rgba(0x292640ff).into()), - element_background: Some(rgba(0x007f99ff).into()), - element_hover: Some(rgba(0x383866ff).into()), - element_selected: Some(rgba(0x332e5cff).into()), - drop_target_background: Some(rgba(0x202040ff).into()), - ghost_element_hover: Some(rgba(0x383866ff).into()), - ghost_element_selected: Some(rgba(0x332e5cff).into()), - text: Some(rgba(0xc5c2d6ff).into()), - text_muted: Some(rgba(0xa9a5c0ff).into()), - status_bar_background: Some(rgba(0x292640ff).into()), - title_bar_background: Some(rgba(0x292640ff).into()), - toolbar_background: Some(rgba(0x292640ff).into()), - tab_bar_background: Some(rgba(0x2f2c49ff).into()), - tab_inactive_background: Some(rgba(0x2f2c49ff).into()), - tab_active_background: Some(rgba(0x292640ff).into()), - scrollbar_thumb_background: Some(rgba(0x7060eb33).into()), - scrollbar_thumb_hover_background: Some(rgba(0x7060eb55).into()), - scrollbar_thumb_border: Some(rgba(0x7060eb33).into()), - scrollbar_track_background: Some(rgba(0x292640ff).into()), - scrollbar_track_border: Some(rgba(0x292640ff).into()), - editor_foreground: Some(rgba(0xc5c2d6ff).into()), - editor_background: Some(rgba(0x292640ff).into()), - editor_gutter_background: Some(rgba(0x292640ff).into()), - editor_line_number: Some(rgba(0x5c5973ff).into()), - editor_active_line_number: Some(rgba(0xc5c2d6ff).into()), - editor_wrap_guide: Some(rgba(0x6e67a8ff).into()), - editor_active_wrap_guide: Some(rgba(0x6e67a8ff).into()), - terminal_background: Some(rgba(0x1f1d30ff).into()), - terminal_ansi_bright_black: Some(rgba(0x504e65ff).into()), - terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), - terminal_ansi_bright_green: Some(rgba(0x60ebb1ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xe69533ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x60b6ebff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xe798b3ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x60dbebff).into()), - terminal_ansi_bright_white: Some(rgba(0xc5c2d6ff).into()), - terminal_ansi_black: Some(rgba(0x302f3dff).into()), - terminal_ansi_red: Some(rgba(0xe66533ff).into()), - terminal_ansi_green: Some(rgba(0x49e9a6ff).into()), - terminal_ansi_yellow: Some(rgba(0xe4b781ff).into()), - terminal_ansi_blue: Some(rgba(0x49ace9ff).into()), - terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), - terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), - terminal_ansi_white: Some(rgba(0xb6b3ccff).into()), - link_text_hover: Some(rgba(0x998ef1ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xffc180ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xe34e1cff).into()), - error: Some(rgba(0xe34e1cff).into()), - hidden: Some(rgba(0xa9a5c0ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x5b788bff).into()), - modified: Some(rgba(0xffc180ff).into()), - warning: Some(rgba(0xffa857ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x716c93ff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x716c93ff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xd5971aff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xdf769bff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xc5c2d6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xc5c2d6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xc5c2d6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xc5c2d6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xc5c2d6ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xc5c2d6ff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xd67e5cff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xe4b781ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - UserTheme { - name: "Noctis Viola".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x8767a8ff).into()), - border_variant: Some(rgba(0x8767a8ff).into()), - border_focused: Some(rgba(0x3d2e4dff).into()), - border_selected: Some(rgba(0x8767a8ff).into()), - border_transparent: Some(rgba(0x8767a8ff).into()), - border_disabled: Some(rgba(0x8767a8ff).into()), - elevated_surface_background: Some(rgba(0x3d2e4dff).into()), - surface_background: Some(rgba(0x291d35ff).into()), - background: Some(rgba(0x30243dff).into()), - element_background: Some(rgba(0x007f99ff).into()), - element_hover: Some(rgba(0x6a448dff).into()), - element_selected: Some(rgba(0x472e60ff).into()), - drop_target_background: Some(rgba(0x302040ff).into()), - ghost_element_hover: Some(rgba(0x6a448dff).into()), - ghost_element_selected: Some(rgba(0x472e60ff).into()), - text: Some(rgba(0xccbfd9ff).into()), - text_muted: Some(rgba(0xb3a5c0ff).into()), - status_bar_background: Some(rgba(0x30243dff).into()), - title_bar_background: Some(rgba(0x30243dff).into()), - toolbar_background: Some(rgba(0x30243dff).into()), - tab_bar_background: Some(rgba(0x3d2e4dff).into()), - tab_inactive_background: Some(rgba(0x3d2e4dff).into()), - tab_active_background: Some(rgba(0x30243dff).into()), - scrollbar_thumb_background: Some(rgba(0xa660eb33).into()), - scrollbar_thumb_hover_background: Some(rgba(0xa660eb55).into()), - scrollbar_thumb_border: Some(rgba(0xa660eb33).into()), - scrollbar_track_background: Some(rgba(0x30243dff).into()), - scrollbar_track_border: Some(rgba(0x30243dff).into()), - editor_foreground: Some(rgba(0xccbfd9ff).into()), - editor_background: Some(rgba(0x30243dff).into()), - editor_gutter_background: Some(rgba(0x30243dff).into()), - editor_line_number: Some(rgba(0x665973ff).into()), - editor_active_line_number: Some(rgba(0xccbfd9ff).into()), - editor_wrap_guide: Some(rgba(0x8767a8ff).into()), - editor_active_wrap_guide: Some(rgba(0x8767a8ff).into()), - terminal_background: Some(rgba(0x291d35ff).into()), - terminal_ansi_bright_black: Some(rgba(0x594e65ff).into()), - terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()), - terminal_ansi_bright_green: Some(rgba(0x60ebb1ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xe69533ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x60b6ebff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xe798b3ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x60dbebff).into()), - terminal_ansi_bright_white: Some(rgba(0xccbfd9ff).into()), - terminal_ansi_black: Some(rgba(0x362f3dff).into()), - terminal_ansi_red: Some(rgba(0xe66533ff).into()), - terminal_ansi_green: Some(rgba(0x49e9a6ff).into()), - terminal_ansi_yellow: Some(rgba(0xe4b781ff).into()), - terminal_ansi_blue: Some(rgba(0x49ace9ff).into()), - terminal_ansi_magenta: Some(rgba(0xdf769bff).into()), - terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()), - terminal_ansi_white: Some(rgba(0xbfafcfff).into()), - link_text_hover: Some(rgba(0xbf8ef1ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xffc180ff).into()), - created: Some(rgba(0x8ce99aff).into()), - deleted: Some(rgba(0xe34e1cff).into()), - error: Some(rgba(0xe34e1cff).into()), - hidden: Some(rgba(0xb3a5c0ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x5b788bff).into()), - modified: Some(rgba(0xffc180ff).into()), - warning: Some(rgba(0xffa857ff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x7f659aff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x7f659aff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xd5971aff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0x7060ebff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0xdf769bff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x16a3b6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xccbfd9ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xccbfd9ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xccbfd9ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xccbfd9ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xccbfd9ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xccbfd9ff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0x49e9a6ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0x49d6e9ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xd67e5cff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xe4b781ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xe66533ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }, - ], - } -} diff --git a/crates/theme2/src/themes/nord.rs b/crates/theme2/src/themes/nord.rs deleted file mode 100644 index c44076c1f85079cb207c5518c9468e000f40ef93..0000000000000000000000000000000000000000 --- a/crates/theme2/src/themes/nord.rs +++ /dev/null @@ -1,277 +0,0 @@ -// This file was generated by the `theme_importer`. -// Be careful when modifying it by hand. - -use gpui::rgba; - -#[allow(unused)] -use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, -}; - -pub fn nord() -> UserThemeFamily { - UserThemeFamily { - name: "Nord".into(), - author: "Sven Greb (svengreb)".into(), - themes: vec![UserTheme { - name: "Nord".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x3b4252ff).into()), - border_variant: Some(rgba(0x3b4252ff).into()), - border_focused: Some(rgba(0x3b4252ff).into()), - border_selected: Some(rgba(0x3b4252ff).into()), - border_transparent: Some(rgba(0x3b4252ff).into()), - border_disabled: Some(rgba(0x3b4252ff).into()), - elevated_surface_background: Some(rgba(0x3b4252ff).into()), - surface_background: Some(rgba(0x2e3440ff).into()), - background: Some(rgba(0x2e3440ff).into()), - element_background: Some(rgba(0x88c0d0ee).into()), - element_hover: Some(rgba(0x3b4252ff).into()), - element_selected: Some(rgba(0x88c0d0ff).into()), - drop_target_background: Some(rgba(0x88c0d099).into()), - ghost_element_hover: Some(rgba(0x3b4252ff).into()), - ghost_element_selected: Some(rgba(0x88c0d0ff).into()), - text: Some(rgba(0xd8dee9ff).into()), - text_muted: Some(rgba(0xd8dee966).into()), - status_bar_background: Some(rgba(0x3b4252ff).into()), - title_bar_background: Some(rgba(0x2e3440ff).into()), - toolbar_background: Some(rgba(0x2e3440ff).into()), - tab_bar_background: Some(rgba(0x2e3440ff).into()), - tab_inactive_background: Some(rgba(0x2e3440ff).into()), - tab_active_background: Some(rgba(0x3b4252ff).into()), - scrollbar_thumb_background: Some(rgba(0x434c5e99).into()), - scrollbar_thumb_hover_background: Some(rgba(0x434c5eaa).into()), - scrollbar_thumb_border: Some(rgba(0x434c5e99).into()), - scrollbar_track_background: Some(rgba(0x2e3440ff).into()), - scrollbar_track_border: Some(rgba(0x3b4252ff).into()), - editor_foreground: Some(rgba(0xd8dee9ff).into()), - editor_background: Some(rgba(0x2e3440ff).into()), - editor_gutter_background: Some(rgba(0x2e3440ff).into()), - editor_line_number: Some(rgba(0x4c566aff).into()), - editor_active_line_number: Some(rgba(0xd8dee9ff).into()), - editor_wrap_guide: Some(rgba(0x3b4252ff).into()), - editor_active_wrap_guide: Some(rgba(0x3b4252ff).into()), - terminal_background: Some(rgba(0x2e3440ff).into()), - terminal_ansi_bright_black: Some(rgba(0x4c566aff).into()), - terminal_ansi_bright_red: Some(rgba(0xbf616aff).into()), - terminal_ansi_bright_green: Some(rgba(0xa3be8cff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xebcb8bff).into()), - terminal_ansi_bright_blue: Some(rgba(0x81a1c1ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xb48eadff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x8fbcbbff).into()), - terminal_ansi_bright_white: Some(rgba(0xeceff4ff).into()), - terminal_ansi_black: Some(rgba(0x3b4252ff).into()), - terminal_ansi_red: Some(rgba(0xbf616aff).into()), - terminal_ansi_green: Some(rgba(0xa3be8cff).into()), - terminal_ansi_yellow: Some(rgba(0xebcb8bff).into()), - terminal_ansi_blue: Some(rgba(0x81a1c1ff).into()), - terminal_ansi_magenta: Some(rgba(0xb48eadff).into()), - terminal_ansi_cyan: Some(rgba(0x88c0d0ff).into()), - terminal_ansi_white: Some(rgba(0xe5e9f0ff).into()), - link_text_hover: Some(rgba(0x88c0d0ff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0x5e81acff).into()), - created: Some(rgba(0xa3be8cff).into()), - deleted: Some(rgba(0xbf616aff).into()), - error: Some(rgba(0xbf616aff).into()), - hidden: Some(rgba(0xd8dee966).into()), - hint: Some(rgba(0xd8dee9ff).into()), - ignored: Some(rgba(0xd8dee966).into()), - modified: Some(rgba(0xebcb8bff).into()), - warning: Some(rgba(0xebcb8bff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "attribute".into(), - UserHighlightStyle { - color: Some(rgba(0x8fbcbbff).into()), - ..Default::default() - }, - ), - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0x81a1c1ff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x616e88ff).into()), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x616e88ff).into()), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0x81a1c1ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0x81a1c1ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x88c0d0ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0x81a1c1ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0xb48eadff).into()), - ..Default::default() - }, - ), - ( - "operator".into(), - UserHighlightStyle { - color: Some(rgba(0x81a1c1ff).into()), - ..Default::default() - }, - ), - ( - "preproc".into(), - UserHighlightStyle { - color: Some(rgba(0x5e81acff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xeceff4ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xeceff4ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0x81a1c1ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xeceff4ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xeceff4ff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0xa3be8cff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0xebcb8bff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0xa3be8cff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0xa3be8cff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0xa3be8cff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0x81a1c1ff).into()), - ..Default::default() - }, - ), - ( - "text.literal".into(), - UserHighlightStyle { - color: Some(rgba(0xa3be8cff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0x8fbcbbff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0x81a1c1ff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0x81a1c1ff).into()), - ..Default::default() - }, - ), - ], - }), - }, - }], - } -} diff --git a/crates/theme2/src/themes/palenight.rs b/crates/theme2/src/themes/one.rs similarity index 50% rename from crates/theme2/src/themes/palenight.rs rename to crates/theme2/src/themes/one.rs index 2fceb8055ec253bbe6e9b71794ce0f0debf449c4..089e3b3bcda383f276cd318dc495f0d7433cc05c 100644 --- a/crates/theme2/src/themes/palenight.rs +++ b/crates/theme2/src/themes/one.rs @@ -9,77 +9,68 @@ use crate::{ UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, }; -pub fn palenight() -> UserThemeFamily { +pub fn one() -> UserThemeFamily { UserThemeFamily { - name: "Palenight".into(), - author: "Olaolu Olawuyi (whizkydee)".into(), + name: "One".into(), + author: "Zed Industries".into(), themes: vec![ UserTheme { - name: "Palenight".into(), - appearance: Appearance::Dark, + name: "One Light".into(), + appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x282b3cff).into()), - border_variant: Some(rgba(0x282b3cff).into()), - border_focused: Some(rgba(0x282b3cff).into()), - border_selected: Some(rgba(0x282b3cff).into()), - border_transparent: Some(rgba(0x282b3cff).into()), - border_disabled: Some(rgba(0x282b3cff).into()), - elevated_surface_background: Some(rgba(0x292d3eff).into()), - surface_background: Some(rgba(0x292d3eff).into()), - background: Some(rgba(0x292d3eff).into()), - element_background: Some(rgba(0x7e57c2cc).into()), - element_hover: Some(rgba(0x0000001a).into()), - element_selected: Some(rgba(0x7e57c2ff).into()), - drop_target_background: Some(rgba(0x2e3245ff).into()), - ghost_element_hover: Some(rgba(0x0000001a).into()), - ghost_element_selected: Some(rgba(0x7e57c2ff).into()), - text: Some(rgba(0xffffffff).into()), - text_muted: Some(rgba(0x929ac9ff).into()), - status_bar_background: Some(rgba(0x282c3dff).into()), - title_bar_background: Some(rgba(0x292d3eff).into()), - toolbar_background: Some(rgba(0x292d3eff).into()), - tab_bar_background: Some(rgba(0x31364aff).into()), - tab_inactive_background: Some(rgba(0x31364aff).into()), - tab_active_background: Some(rgba(0x292d3eff).into()), - scrollbar_thumb_background: Some(rgba(0x694ca466).into()), - scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()), - scrollbar_thumb_border: Some(rgba(0x694ca466).into()), - scrollbar_track_background: Some(rgba(0x292d3eff).into()), - editor_foreground: Some(rgba(0xbfc7d5ff).into()), - editor_background: Some(rgba(0x292d3eff).into()), - editor_gutter_background: Some(rgba(0x292d3eff).into()), - editor_line_number: Some(rgba(0x4c5374ff).into()), - editor_active_line_number: Some(rgba(0xbfc7d5ff).into()), - editor_wrap_guide: Some(rgba(0x282b3cff).into()), - editor_active_wrap_guide: Some(rgba(0x282b3cff).into()), - terminal_ansi_bright_black: Some(rgba(0x676e95ff).into()), - terminal_ansi_bright_red: Some(rgba(0xff5572ff).into()), - terminal_ansi_bright_green: Some(rgba(0xc3e88dff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xffcb6bff).into()), - terminal_ansi_bright_blue: Some(rgba(0x82aaffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xc792eaff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x89ddffff).into()), - terminal_ansi_bright_white: Some(rgba(0xffffffff).into()), - terminal_ansi_black: Some(rgba(0x676e95ff).into()), - terminal_ansi_red: Some(rgba(0xff5572ff).into()), - terminal_ansi_green: Some(rgba(0xa9c77dff).into()), - terminal_ansi_yellow: Some(rgba(0xffcb6bff).into()), - terminal_ansi_blue: Some(rgba(0x82aaffff).into()), - terminal_ansi_magenta: Some(rgba(0xc792eaff).into()), - terminal_ansi_cyan: Some(rgba(0x89ddffff).into()), - terminal_ansi_white: Some(rgba(0xffffffff).into()), + border: Some(rgba(0xc9c9caff).into()), + border_variant: Some(rgba(0xc9c9caff).into()), + elevated_surface_background: Some(rgba(0xdcdcddff).into()), + background: Some(rgba(0xdcdcddff).into()), + panel_background: Some(rgba(0xebebecff).into()), + element_hover: Some(rgba(0xc9c9ca80).into()), + element_selected: Some(rgba(0xafafaf80).into()), + text: Some(rgba(0x7f8188ff).into()), + text_muted: Some(rgba(0xa7a7a8ff).into()), + status_bar_background: Some(rgba(0xdcdcddff).into()), + title_bar_background: Some(rgba(0xdcdcddff).into()), + toolbar_background: Some(rgba(0xfafafaff).into()), + tab_bar_background: Some(rgba(0xebebecff).into()), + tab_inactive_background: Some(rgba(0xebebecff).into()), + tab_active_background: Some(rgba(0xfafafaff).into()), + scrollbar_thumb_background: Some(rgba(0x383a414d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x383a414d).into()), + scrollbar_thumb_border: Some(rgba(0xeeeeeeff).into()), + scrollbar_track_border: Some(rgba(0xeeeeeeff).into()), + editor_foreground: Some(rgba(0x383a41ff).into()), + editor_background: Some(rgba(0xfafafaff).into()), + editor_gutter_background: Some(rgba(0xfafafaff).into()), + editor_line_number: Some(rgba(0x383a4159).into()), + editor_active_line_number: Some(rgba(0x383a41ff).into()), + editor_wrap_guide: Some(rgba(0x383a410d).into()), + editor_active_wrap_guide: Some(rgba(0x383a411a).into()), + terminal_background: Some(rgba(0xfafafaff).into()), + terminal_ansi_bright_black: Some(rgba(0xaaaaaaff).into()), + terminal_ansi_bright_red: Some(rgba(0xf0b0a4ff).into()), + terminal_ansi_bright_green: Some(rgba(0xb2cfa9ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xf1dfc1ff).into()), + terminal_ansi_bright_blue: Some(rgba(0xb5baf2ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xcea6d3ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0xa4bfdbff).into()), + terminal_ansi_bright_white: Some(rgba(0x383a41ff).into()), + terminal_ansi_black: Some(rgba(0xfafafaff).into()), + terminal_ansi_red: Some(rgba(0xd36151ff).into()), + terminal_ansi_green: Some(rgba(0x669f59ff).into()), + terminal_ansi_yellow: Some(rgba(0xdec184ff).into()), + terminal_ansi_blue: Some(rgba(0x5c79e2ff).into()), + terminal_ansi_magenta: Some(rgba(0x994fa6ff).into()), + terminal_ansi_cyan: Some(rgba(0x3b82b7ff).into()), + terminal_ansi_white: Some(rgba(0x383a41ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xffeb95cc).into()), - created: Some(rgba(0x9ccc65ff).into()), - deleted: Some(rgba(0xef5350ff).into()), - error: Some(rgba(0xef5350ff).into()), - hidden: Some(rgba(0x929ac9ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x69709890).into()), - modified: Some(rgba(0xe2b93dff).into()), + created: Some(rgba(0x84b278ff).into()), + deleted: Some(rgba(0xd36151ff).into()), + error: Some(rgba(0xd36151ff).into()), + modified: Some(rgba(0xdec184ff).into()), + success: Some(rgba(0x383a41ff).into()), + warning: Some(rgba(0xdec184ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -87,502 +78,278 @@ pub fn palenight() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0x5c79e2ff).into()), ..Default::default() }, ), ( "boolean".into(), UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), + color: Some(rgba(0xad6f26ff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x697098ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xa2a3a7ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x697098ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x7c7e86ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), + color: Some(rgba(0x669f59ff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0xff5572ff).into()), - ..Default::default() - }, - ), - ( - "emphasis".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "emphasis.strong".into(), - UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), - font_weight: Some(UserFontWeight(700.0)), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0xff869aff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0xff869aff).into()), + color: Some(rgba(0x5c79e2ff).into()), ..Default::default() }, ), ( - "number".into(), + "embedded".into(), UserHighlightStyle { - color: Some(rgba(0xf78c6cff).into()), + color: Some(rgba(0x383a41ff).into()), ..Default::default() }, ), ( - "operator".into(), - UserHighlightStyle { - color: Some(rgba(0x89ddffff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0x80cbc4ff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - ..Default::default() - }, - ), - ( - "string".into(), - UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), - ..Default::default() - }, - ), - ( - "string.escape".into(), - UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), - ..Default::default() - }, - ), - ( - "string.regex".into(), - UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), - ..Default::default() - }, - ), - ( - "string.special".into(), - UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), - ..Default::default() - }, - ), - ( - "string.special.symbol".into(), - UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), + "emphasis".into(), UserHighlightStyle { - color: Some(rgba(0xff5572ff).into()), + color: Some(rgba(0x5c79e2ff).into()), ..Default::default() }, ), ( - "text.literal".into(), + "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0xad6f26ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( - "type".into(), + "enum".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0xd36050ff).into()), ..Default::default() }, ), ( - "variable".into(), + "function".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0x5b79e3ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "hint".into(), UserHighlightStyle { - color: Some(rgba(0xff5572ff).into()), + color: Some(rgba(0x9295beff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), - ], - }), - }, - }, - UserTheme { - name: "Palenight Operator".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border: Some(rgba(0x282b3cff).into()), - border_variant: Some(rgba(0x282b3cff).into()), - border_focused: Some(rgba(0x282b3cff).into()), - border_selected: Some(rgba(0x282b3cff).into()), - border_transparent: Some(rgba(0x282b3cff).into()), - border_disabled: Some(rgba(0x282b3cff).into()), - elevated_surface_background: Some(rgba(0x292d3eff).into()), - surface_background: Some(rgba(0x292d3eff).into()), - background: Some(rgba(0x292d3eff).into()), - element_background: Some(rgba(0x7e57c2cc).into()), - element_hover: Some(rgba(0x0000001a).into()), - element_selected: Some(rgba(0x7e57c2ff).into()), - drop_target_background: Some(rgba(0x2e3245ff).into()), - ghost_element_hover: Some(rgba(0x0000001a).into()), - ghost_element_selected: Some(rgba(0x7e57c2ff).into()), - text: Some(rgba(0xffffffff).into()), - text_muted: Some(rgba(0x929ac9ff).into()), - status_bar_background: Some(rgba(0x282c3dff).into()), - title_bar_background: Some(rgba(0x292d3eff).into()), - toolbar_background: Some(rgba(0x292d3eff).into()), - tab_bar_background: Some(rgba(0x31364aff).into()), - tab_inactive_background: Some(rgba(0x31364aff).into()), - tab_active_background: Some(rgba(0x292d3eff).into()), - scrollbar_thumb_background: Some(rgba(0x694ca466).into()), - scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()), - scrollbar_thumb_border: Some(rgba(0x694ca466).into()), - scrollbar_track_background: Some(rgba(0x292d3eff).into()), - editor_foreground: Some(rgba(0xbfc7d5ff).into()), - editor_background: Some(rgba(0x292d3eff).into()), - editor_gutter_background: Some(rgba(0x292d3eff).into()), - editor_line_number: Some(rgba(0x4c5374ff).into()), - editor_active_line_number: Some(rgba(0xbfc7d5ff).into()), - editor_wrap_guide: Some(rgba(0x282b3cff).into()), - editor_active_wrap_guide: Some(rgba(0x282b3cff).into()), - terminal_ansi_bright_black: Some(rgba(0x676e95ff).into()), - terminal_ansi_bright_red: Some(rgba(0xff5572ff).into()), - terminal_ansi_bright_green: Some(rgba(0xc3e88dff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xffcb6bff).into()), - terminal_ansi_bright_blue: Some(rgba(0x82aaffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xc792eaff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x89ddffff).into()), - terminal_ansi_bright_white: Some(rgba(0xffffffff).into()), - terminal_ansi_black: Some(rgba(0x676e95ff).into()), - terminal_ansi_red: Some(rgba(0xff5572ff).into()), - terminal_ansi_green: Some(rgba(0xa9c77dff).into()), - terminal_ansi_yellow: Some(rgba(0xffcb6bff).into()), - terminal_ansi_blue: Some(rgba(0x82aaffff).into()), - terminal_ansi_magenta: Some(rgba(0xc792eaff).into()), - terminal_ansi_cyan: Some(rgba(0x89ddffff).into()), - terminal_ansi_white: Some(rgba(0xffffffff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - conflict: Some(rgba(0xffeb95cc).into()), - created: Some(rgba(0x9ccc65ff).into()), - deleted: Some(rgba(0xef5350ff).into()), - error: Some(rgba(0xef5350ff).into()), - hidden: Some(rgba(0x929ac9ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x69709890).into()), - modified: Some(rgba(0xe2b93dff).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ ( - "attribute".into(), + "keyword".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0xa449abff).into()), ..Default::default() }, ), ( - "boolean".into(), + "label".into(), UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), + color: Some(rgba(0x5c79e2ff).into()), ..Default::default() }, ), ( - "comment".into(), + "link_text".into(), UserHighlightStyle { - color: Some(rgba(0x697098ff).into()), + color: Some(rgba(0x5b79e3ff).into()), font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( - "comment.doc".into(), + "link_uri".into(), UserHighlightStyle { - color: Some(rgba(0x697098ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x3982b7ff).into()), ..Default::default() }, ), ( - "constant".into(), + "number".into(), UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), + color: Some(rgba(0xad6f26ff).into()), ..Default::default() }, ), ( - "constructor".into(), + "operator".into(), UserHighlightStyle { - color: Some(rgba(0xff5572ff).into()), + color: Some(rgba(0x3982b7ff).into()), ..Default::default() }, ), ( - "emphasis".into(), + "predictive".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0x9c9fc7ff).into()), font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( - "emphasis.strong".into(), - UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), - font_weight: Some(UserFontWeight(700.0)), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0xff869aff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0xff869aff).into()), - ..Default::default() - }, - ), - ( - "number".into(), + "preproc".into(), UserHighlightStyle { - color: Some(rgba(0xf78c6cff).into()), + color: Some(rgba(0x383a41ff).into()), ..Default::default() }, ), ( - "operator".into(), + "primary".into(), UserHighlightStyle { - color: Some(rgba(0x89ddffff).into()), + color: Some(rgba(0x383a41ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0x80cbc4ff).into()), + color: Some(rgba(0xd36050ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0x383a41ff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0x4d4f52ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0x4d4f52ff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0xd36050ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0xb92c46ff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0x659f58ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), + color: Some(rgba(0x7c7e86ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0xad6f27ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0xad6f27ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0xad6f27ff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0xff5572ff).into()), + color: Some(rgba(0x5c79e2ff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0x659f58ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xd36050ff).into()), + font_weight: Some(UserFontWeight(400.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0x3982b7ff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0x383a41ff).into()), ..Default::default() }, ), ( "variable.special".into(), UserHighlightStyle { - color: Some(rgba(0xff5572ff).into()), + color: Some(rgba(0xad6f26ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x5b79e3ff).into()), ..Default::default() }, ), @@ -591,71 +358,62 @@ pub fn palenight() -> UserThemeFamily { }, }, UserTheme { - name: "Palenight (Mild Contrast)".into(), + name: "One Dark".into(), appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x2c2f40ff).into()), - border_variant: Some(rgba(0x2c2f40ff).into()), - border_focused: Some(rgba(0x2c2f40ff).into()), - border_selected: Some(rgba(0x2c2f40ff).into()), - border_transparent: Some(rgba(0x2c2f40ff).into()), - border_disabled: Some(rgba(0x2c2f40ff).into()), - elevated_surface_background: Some(rgba(0x292d3eff).into()), - surface_background: Some(rgba(0x25293aff).into()), - background: Some(rgba(0x292d3eff).into()), - element_background: Some(rgba(0x7e57c2cc).into()), - element_hover: Some(rgba(0x0000001a).into()), - element_selected: Some(rgba(0x7e57c2ff).into()), - drop_target_background: Some(rgba(0x2e3245ff).into()), - ghost_element_hover: Some(rgba(0x0000001a).into()), - ghost_element_selected: Some(rgba(0x7e57c2ff).into()), - text: Some(rgba(0xffffffff).into()), - text_muted: Some(rgba(0x929ac9ff).into()), - status_bar_background: Some(rgba(0x25293aff).into()), - title_bar_background: Some(rgba(0x25293aff).into()), - toolbar_background: Some(rgba(0x292d3eff).into()), - tab_bar_background: Some(rgba(0x31364aff).into()), - tab_inactive_background: Some(rgba(0x31364aff).into()), - tab_active_background: Some(rgba(0x25293aff).into()), - scrollbar_thumb_background: Some(rgba(0x694ca466).into()), - scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()), - scrollbar_thumb_border: Some(rgba(0x694ca466).into()), - scrollbar_track_background: Some(rgba(0x292d3eff).into()), - editor_foreground: Some(rgba(0xbfc7d5ff).into()), - editor_background: Some(rgba(0x292d3eff).into()), - editor_gutter_background: Some(rgba(0x292d3eff).into()), - editor_line_number: Some(rgba(0x4c5374ff).into()), - editor_active_line_number: Some(rgba(0xbfc7d5ff).into()), - editor_wrap_guide: Some(rgba(0x2c2f40ff).into()), - editor_active_wrap_guide: Some(rgba(0x2c2f40ff).into()), - terminal_ansi_bright_black: Some(rgba(0x676e95ff).into()), - terminal_ansi_bright_red: Some(rgba(0xff5572ff).into()), - terminal_ansi_bright_green: Some(rgba(0xc3e88dff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xffcb6bff).into()), - terminal_ansi_bright_blue: Some(rgba(0x82aaffff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xc792eaff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x89ddffff).into()), - terminal_ansi_bright_white: Some(rgba(0xffffffff).into()), - terminal_ansi_black: Some(rgba(0x676e95ff).into()), - terminal_ansi_red: Some(rgba(0xff5572ff).into()), - terminal_ansi_green: Some(rgba(0xa9c77dff).into()), - terminal_ansi_yellow: Some(rgba(0xffcb6bff).into()), - terminal_ansi_blue: Some(rgba(0x82aaffff).into()), - terminal_ansi_magenta: Some(rgba(0xc792eaff).into()), - terminal_ansi_cyan: Some(rgba(0x89ddffff).into()), - terminal_ansi_white: Some(rgba(0xffffffff).into()), + border: Some(rgba(0x464b57ff).into()), + border_variant: Some(rgba(0x464b57ff).into()), + elevated_surface_background: Some(rgba(0x3b414dff).into()), + background: Some(rgba(0x3b414dff).into()), + panel_background: Some(rgba(0x2f343eff).into()), + element_hover: Some(rgba(0x464b5780).into()), + element_selected: Some(rgba(0x4f545e80).into()), + text: Some(rgba(0x838994ff).into()), + text_muted: Some(rgba(0x545862ff).into()), + status_bar_background: Some(rgba(0x3b414dff).into()), + title_bar_background: Some(rgba(0x3b414dff).into()), + toolbar_background: Some(rgba(0x282c34ff).into()), + tab_bar_background: Some(rgba(0x2f343eff).into()), + tab_inactive_background: Some(rgba(0x2f343eff).into()), + tab_active_background: Some(rgba(0x282c34ff).into()), + scrollbar_thumb_background: Some(rgba(0xc8ccd44d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xc8ccd44d).into()), + scrollbar_thumb_border: Some(rgba(0x2e333cff).into()), + scrollbar_track_border: Some(rgba(0x2e333cff).into()), + editor_foreground: Some(rgba(0xacb2beff).into()), + editor_background: Some(rgba(0x282c34ff).into()), + editor_gutter_background: Some(rgba(0x282c34ff).into()), + editor_line_number: Some(rgba(0xc8ccd459).into()), + editor_active_line_number: Some(rgba(0xc8ccd4ff).into()), + editor_wrap_guide: Some(rgba(0xc8ccd40d).into()), + editor_active_wrap_guide: Some(rgba(0xc8ccd41a).into()), + terminal_background: Some(rgba(0x282c34ff).into()), + terminal_ansi_bright_black: Some(rgba(0x525661ff).into()), + terminal_ansi_bright_red: Some(rgba(0x673a3cff).into()), + terminal_ansi_bright_green: Some(rgba(0x4d6140ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x786441ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x385378ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x5e2b26ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x3a565bff).into()), + terminal_ansi_bright_white: Some(rgba(0xc8ccd4ff).into()), + terminal_ansi_black: Some(rgba(0x282c34ff).into()), + terminal_ansi_red: Some(rgba(0xd07277ff).into()), + terminal_ansi_green: Some(rgba(0xa1c181ff).into()), + terminal_ansi_yellow: Some(rgba(0xdec184ff).into()), + terminal_ansi_blue: Some(rgba(0x74ade8ff).into()), + terminal_ansi_magenta: Some(rgba(0xbe5046ff).into()), + terminal_ansi_cyan: Some(rgba(0x6fb4c0ff).into()), + terminal_ansi_white: Some(rgba(0xc8ccd4ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xffeb95cc).into()), - created: Some(rgba(0x9ccc65ff).into()), - deleted: Some(rgba(0xef5350ff).into()), - error: Some(rgba(0xef5350ff).into()), - hidden: Some(rgba(0x929ac9ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0x69709890).into()), - modified: Some(rgba(0xe2b93dff).into()), + created: Some(rgba(0xa1c181ff).into()), + deleted: Some(rgba(0xa45a5eff).into()), + error: Some(rgba(0xd07277ff).into()), + modified: Some(rgba(0xdec184ff).into()), + success: Some(rgba(0xc8ccd4ff).into()), + warning: Some(rgba(0xdec184ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -663,214 +421,278 @@ pub fn palenight() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0x74ade8ff).into()), ..Default::default() }, ), ( "boolean".into(), UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), + color: Some(rgba(0xc0966bff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x697098ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x5d636fff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x697098ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x878e98ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), + color: Some(rgba(0xdfc184ff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0xff5572ff).into()), + color: Some(rgba(0x74ade9ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xc8ccd4ff).into()), ..Default::default() }, ), ( "emphasis".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x74ade8ff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0xc0966bff).into()), font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xd07277ff).into()), + ..Default::default() + }, + ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), + color: Some(rgba(0x74ade9ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x5b708aff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0xb478cfff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x74ade8ff).into()), ..Default::default() }, ), ( "link_text".into(), UserHighlightStyle { - color: Some(rgba(0xff869aff).into()), + color: Some(rgba(0x74ade9ff).into()), + font_style: Some(UserFontStyle::Normal), ..Default::default() }, ), ( "link_uri".into(), UserHighlightStyle { - color: Some(rgba(0xff869aff).into()), + color: Some(rgba(0x6fb4c0ff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xf78c6cff).into()), + color: Some(rgba(0xc0966bff).into()), ..Default::default() }, ), ( "operator".into(), UserHighlightStyle { - color: Some(rgba(0x89ddffff).into()), + color: Some(rgba(0x6fb4c0ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x5b6b88ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xc8ccd4ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xacb2beff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0x80cbc4ff).into()), + color: Some(rgba(0xd07277ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0xacb2beff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0xb2b9c6ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0xb2b9c6ff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0xd07277ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0xc792eaff).into()), + color: Some(rgba(0xb1574bff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0xa1c181ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0x82aaffff).into()), + color: Some(rgba(0x878e98ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0xc0966bff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0xc0966bff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0xc0966bff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0xff5572ff).into()), + color: Some(rgba(0x74ade8ff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xc3e88dff).into()), + color: Some(rgba(0xa1c181ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xd07277ff).into()), + font_weight: Some(UserFontWeight(400.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0x6fb4c0ff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0xffcb6bff).into()), + color: Some(rgba(0xc8ccd4ff).into()), ..Default::default() }, ), ( "variable.special".into(), UserHighlightStyle { - color: Some(rgba(0xff5572ff).into()), + color: Some(rgba(0xc0966bff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x74ade9ff).into()), ..Default::default() }, ), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index a24c7ef80d5a530cff0e335f537f554506f3856e..abefb32f4e338baa5b369f3ecdf73b21429c9365 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -12,77 +12,65 @@ use crate::{ pub fn rose_pine() -> UserThemeFamily { UserThemeFamily { name: "Rosé Pine".into(), - author: "Rosé Pine".into(), + author: "Zed Industries".into(), themes: vec![ UserTheme { - name: "Rosé Pine".into(), - appearance: Appearance::Dark, + name: "Rosé Pine Dawn".into(), + appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x00000000).into()), - border_variant: Some(rgba(0x00000000).into()), - border_focused: Some(rgba(0x6e6a8633).into()), - border_selected: Some(rgba(0x00000000).into()), - border_transparent: Some(rgba(0x00000000).into()), - border_disabled: Some(rgba(0x00000000).into()), - elevated_surface_background: Some(rgba(0x1f1d2eff).into()), - surface_background: Some(rgba(0x1f1d2eff).into()), - background: Some(rgba(0x191724ff).into()), - element_background: Some(rgba(0xebbcbaff).into()), - element_hover: Some(rgba(0x6e6a861a).into()), - element_selected: Some(rgba(0x6e6a8633).into()), - drop_target_background: Some(rgba(0x1f1d2eff).into()), - ghost_element_hover: Some(rgba(0x6e6a861a).into()), - ghost_element_selected: Some(rgba(0x6e6a8633).into()), - text: Some(rgba(0xe0def4ff).into()), - text_muted: Some(rgba(0x908caaff).into()), - status_bar_background: Some(rgba(0x191724ff).into()), - title_bar_background: Some(rgba(0x191724ff).into()), - toolbar_background: Some(rgba(0x191724ff).into()), - tab_bar_background: Some(rgba(0x00000000).into()), - tab_inactive_background: Some(rgba(0x00000000).into()), - tab_active_background: Some(rgba(0x6e6a861a).into()), - scrollbar_thumb_background: Some(rgba(0x6e6a8633).into()), - scrollbar_thumb_hover_background: Some(rgba(0x6e6a8666).into()), - scrollbar_thumb_border: Some(rgba(0x6e6a8633).into()), - scrollbar_track_background: Some(rgba(0x191724ff).into()), - scrollbar_track_border: Some(rgba(0x6e6a8666).into()), - editor_foreground: Some(rgba(0xe0def4ff).into()), - editor_background: Some(rgba(0x191724ff).into()), - editor_gutter_background: Some(rgba(0x191724ff).into()), - editor_line_number: Some(rgba(0x908caaff).into()), - editor_active_line_number: Some(rgba(0xe0def4ff).into()), - editor_wrap_guide: Some(rgba(0x00000000).into()), - editor_active_wrap_guide: Some(rgba(0x00000000).into()), - terminal_ansi_bright_black: Some(rgba(0x908caaff).into()), - terminal_ansi_bright_red: Some(rgba(0xeb6f92ff).into()), - terminal_ansi_bright_green: Some(rgba(0x31748fff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xf6c177ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x9ccfd8ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xc4a7e7ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0xebbcbaff).into()), - terminal_ansi_bright_white: Some(rgba(0xe0def4ff).into()), - terminal_ansi_black: Some(rgba(0x26233aff).into()), - terminal_ansi_red: Some(rgba(0xeb6f92ff).into()), - terminal_ansi_green: Some(rgba(0x31748fff).into()), - terminal_ansi_yellow: Some(rgba(0xf6c177ff).into()), - terminal_ansi_blue: Some(rgba(0x9ccfd8ff).into()), - terminal_ansi_magenta: Some(rgba(0xc4a7e7ff).into()), - terminal_ansi_cyan: Some(rgba(0xebbcbaff).into()), - terminal_ansi_white: Some(rgba(0xe0def4ff).into()), - link_text_hover: Some(rgba(0xc4a7e7e6).into()), + border: Some(rgba(0xdcd6d5ff).into()), + border_variant: Some(rgba(0xdcd6d5ff).into()), + elevated_surface_background: Some(rgba(0xdcd8d8ff).into()), + background: Some(rgba(0xdcd8d8ff).into()), + panel_background: Some(rgba(0xfef9f2ff).into()), + element_hover: Some(rgba(0xdcd6d580).into()), + element_selected: Some(rgba(0xc1bac180).into()), + text: Some(rgba(0x706c8cff).into()), + text_muted: Some(rgba(0xb1abb5ff).into()), + status_bar_background: Some(rgba(0xdcd8d8ff).into()), + title_bar_background: Some(rgba(0xdcd8d8ff).into()), + toolbar_background: Some(rgba(0xfaf4edff).into()), + tab_bar_background: Some(rgba(0xfef9f2ff).into()), + tab_inactive_background: Some(rgba(0xfef9f2ff).into()), + tab_active_background: Some(rgba(0xfaf4edff).into()), + scrollbar_thumb_background: Some(rgba(0x5752794d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x5752794d).into()), + scrollbar_thumb_border: Some(rgba(0xfdf8f1ff).into()), + scrollbar_track_border: Some(rgba(0xfdf8f1ff).into()), + editor_foreground: Some(rgba(0x575279ff).into()), + editor_background: Some(rgba(0xfaf4edff).into()), + editor_gutter_background: Some(rgba(0xfaf4edff).into()), + editor_line_number: Some(rgba(0x57527959).into()), + editor_active_line_number: Some(rgba(0x575279ff).into()), + editor_wrap_guide: Some(rgba(0x5752790d).into()), + editor_active_wrap_guide: Some(rgba(0x5752791a).into()), + terminal_background: Some(rgba(0xfaf4edff).into()), + terminal_ansi_bright_black: Some(rgba(0xb8b2baff).into()), + terminal_ansi_bright_red: Some(rgba(0xdcb0bbff).into()), + terminal_ansi_bright_green: Some(rgba(0xa5d5c5ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xfccd9bff).into()), + terminal_ansi_bright_blue: Some(rgba(0xacc9ceff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xbcb1bdff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x97b1c0ff).into()), + terminal_ansi_bright_white: Some(rgba(0x575279ff).into()), + terminal_ansi_black: Some(rgba(0xfaf4edff).into()), + terminal_ansi_red: Some(rgba(0xb4647aff).into()), + terminal_ansi_green: Some(rgba(0x3eaa8eff).into()), + terminal_ansi_yellow: Some(rgba(0xe99d35ff).into()), + terminal_ansi_blue: Some(rgba(0x57949fff).into()), + terminal_ansi_magenta: Some(rgba(0x7c697fff).into()), + terminal_ansi_cyan: Some(rgba(0x2a6983ff).into()), + terminal_ansi_white: Some(rgba(0x575279ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xeb6f92ff).into()), - created: Some(rgba(0x9ccfd8ff).into()), - deleted: Some(rgba(0xeb6f92ff).into()), - error: Some(rgba(0xeb6f92ff).into()), - hidden: Some(rgba(0x908caaff).into()), - hint: Some(rgba(0x908caaff).into()), - ignored: Some(rgba(0x6e6a86ff).into()), - modified: Some(rgba(0xebbcbaff).into()), - warning: Some(rgba(0xf6c177ff).into()), + created: Some(rgba(0x6bbca3ff).into()), + deleted: Some(rgba(0xb4647aff).into()), + error: Some(rgba(0xb4647aff).into()), + modified: Some(rgba(0xe99d35ff).into()), + success: Some(rgba(0x575279ff).into()), + warning: Some(rgba(0xe99d35ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -90,186 +78,285 @@ pub fn rose_pine() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xc4a7e7ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x57949fff).into()), ..Default::default() }, ), ( "boolean".into(), UserHighlightStyle { - color: Some(rgba(0xebbcbaff).into()), + color: Some(rgba(0xd7827eff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x6e6a86ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x9893a5ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x6e6a86ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x6f6b8cff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0x31748fff).into()), + color: Some(rgba(0x3eaa8eff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x9ccfd8ff).into()), + color: Some(rgba(0x57949fff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0x575279ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x57949fff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x57949fff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0x907aa9ff).into()), ..Default::default() }, ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0xebbcbaff).into()), + color: Some(rgba(0xd7827eff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0xd7827eff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x7a92aaff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0x31748fff).into()), + color: Some(rgba(0x286983ff).into()), ..Default::default() }, ), ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xebbcbaff).into()), + color: Some(rgba(0x57949fff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0x56949fff).into()), + font_style: Some(UserFontStyle::Normal), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0xd7827eff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xebbcbaff).into()), + color: Some(rgba(0x3eaa8eff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x286983ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0xa2acbeff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0x575279ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x575279ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0x57949fff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0x908caaff).into()), + color: Some(rgba(0x797593ff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x908caaff).into()), + color: Some(rgba(0x635e82ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0x908caaff).into()), + color: Some(rgba(0x635e82ff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0x908caaff).into()), + color: Some(rgba(0x635e82ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0x908caaff).into()), + color: Some(rgba(0x635e82ff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0xea9d34ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0x6f6b8cff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0x907aa9ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0x907aa9ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0x907aa9ff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x9ccfd8ff).into()), + color: Some(rgba(0x56949fff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0x907aa9ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0xebbcbaff).into()), + color: Some(rgba(0xea9d34ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0x9ccfd8ff).into()), + color: Some(rgba(0x56949fff).into()), + ..Default::default() + }, + ), + ( + "type.builtin".into(), + UserHighlightStyle { + color: Some(rgba(0x56949fff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0xebbcbaff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x575279ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0xe0def4ff).into()), + color: Some(rgba(0x57949fff).into()), ..Default::default() }, ), @@ -282,70 +369,58 @@ pub fn rose_pine() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x00000000).into()), - border_variant: Some(rgba(0x00000000).into()), - border_focused: Some(rgba(0x817c9c26).into()), - border_selected: Some(rgba(0x00000000).into()), - border_transparent: Some(rgba(0x00000000).into()), - border_disabled: Some(rgba(0x00000000).into()), - elevated_surface_background: Some(rgba(0x2a273fff).into()), - surface_background: Some(rgba(0x2a273fff).into()), - background: Some(rgba(0x232136ff).into()), - element_background: Some(rgba(0xea9a97ff).into()), - element_hover: Some(rgba(0x817c9c14).into()), - element_selected: Some(rgba(0x817c9c26).into()), - drop_target_background: Some(rgba(0x2a273fff).into()), - ghost_element_hover: Some(rgba(0x817c9c14).into()), - ghost_element_selected: Some(rgba(0x817c9c26).into()), - text: Some(rgba(0xe0def4ff).into()), - text_muted: Some(rgba(0x908caaff).into()), - status_bar_background: Some(rgba(0x232136ff).into()), - title_bar_background: Some(rgba(0x232136ff).into()), + border: Some(rgba(0x504c68ff).into()), + border_variant: Some(rgba(0x504c68ff).into()), + elevated_surface_background: Some(rgba(0x38354eff).into()), + background: Some(rgba(0x38354eff).into()), + panel_background: Some(rgba(0x28253cff).into()), + element_hover: Some(rgba(0x504c6880).into()), + element_selected: Some(rgba(0x45415d80).into()), + text: Some(rgba(0x85819eff).into()), + text_muted: Some(rgba(0x3a3653ff).into()), + status_bar_background: Some(rgba(0x38354eff).into()), + title_bar_background: Some(rgba(0x38354eff).into()), toolbar_background: Some(rgba(0x232136ff).into()), - tab_bar_background: Some(rgba(0x00000000).into()), - tab_inactive_background: Some(rgba(0x00000000).into()), - tab_active_background: Some(rgba(0x817c9c14).into()), - scrollbar_thumb_background: Some(rgba(0x817c9c26).into()), - scrollbar_thumb_hover_background: Some(rgba(0x817c9c4d).into()), - scrollbar_thumb_border: Some(rgba(0x817c9c26).into()), - scrollbar_track_background: Some(rgba(0x232136ff).into()), - scrollbar_track_border: Some(rgba(0x817c9c4d).into()), + tab_bar_background: Some(rgba(0x28253cff).into()), + tab_inactive_background: Some(rgba(0x28253cff).into()), + tab_active_background: Some(rgba(0x232136ff).into()), + scrollbar_thumb_background: Some(rgba(0xe0def44d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xe0def44d).into()), + scrollbar_thumb_border: Some(rgba(0x27243bff).into()), + scrollbar_track_border: Some(rgba(0x27243bff).into()), editor_foreground: Some(rgba(0xe0def4ff).into()), editor_background: Some(rgba(0x232136ff).into()), editor_gutter_background: Some(rgba(0x232136ff).into()), - editor_line_number: Some(rgba(0x908caaff).into()), + editor_line_number: Some(rgba(0xe0def459).into()), editor_active_line_number: Some(rgba(0xe0def4ff).into()), - editor_wrap_guide: Some(rgba(0x00000000).into()), - editor_active_wrap_guide: Some(rgba(0x00000000).into()), - terminal_ansi_bright_black: Some(rgba(0x908caaff).into()), - terminal_ansi_bright_red: Some(rgba(0xeb6f92ff).into()), - terminal_ansi_bright_green: Some(rgba(0x3e8fb0ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xf6c177ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x9ccfd8ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xc4a7e7ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0xea9a97ff).into()), + editor_wrap_guide: Some(rgba(0xe0def40d).into()), + editor_active_wrap_guide: Some(rgba(0xe0def41a).into()), + terminal_background: Some(rgba(0x232136ff).into()), + terminal_ansi_bright_black: Some(rgba(0x3f3b58ff).into()), + terminal_ansi_bright_red: Some(rgba(0x7e3647ff).into()), + terminal_ansi_bright_green: Some(rgba(0x31614fff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x8a653bff).into()), + terminal_ansi_bright_blue: Some(rgba(0x566c70ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x51414eff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x264654ff).into()), terminal_ansi_bright_white: Some(rgba(0xe0def4ff).into()), - terminal_ansi_black: Some(rgba(0x393552ff).into()), - terminal_ansi_red: Some(rgba(0xeb6f92ff).into()), - terminal_ansi_green: Some(rgba(0x3e8fb0ff).into()), - terminal_ansi_yellow: Some(rgba(0xf6c177ff).into()), - terminal_ansi_blue: Some(rgba(0x9ccfd8ff).into()), - terminal_ansi_magenta: Some(rgba(0xc4a7e7ff).into()), - terminal_ansi_cyan: Some(rgba(0xea9a97ff).into()), + terminal_ansi_black: Some(rgba(0x232136ff).into()), + terminal_ansi_red: Some(rgba(0xea6f92ff).into()), + terminal_ansi_green: Some(rgba(0x5dc2a3ff).into()), + terminal_ansi_yellow: Some(rgba(0xf5c177ff).into()), + terminal_ansi_blue: Some(rgba(0x9cced7ff).into()), + terminal_ansi_magenta: Some(rgba(0xa784a1ff).into()), + terminal_ansi_cyan: Some(rgba(0x3f8fb0ff).into()), terminal_ansi_white: Some(rgba(0xe0def4ff).into()), - link_text_hover: Some(rgba(0xc4a7e7e6).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xeb6f92ff).into()), - created: Some(rgba(0x9ccfd8ff).into()), - deleted: Some(rgba(0xeb6f92ff).into()), - error: Some(rgba(0xeb6f92ff).into()), - hidden: Some(rgba(0x908caaff).into()), - hint: Some(rgba(0x908caaff).into()), - ignored: Some(rgba(0x6e6a86ff).into()), - modified: Some(rgba(0xea9a97ff).into()), - warning: Some(rgba(0xf6c177ff).into()), + created: Some(rgba(0x5dc2a3ff).into()), + deleted: Some(rgba(0xbe5773ff).into()), + error: Some(rgba(0xea6f92ff).into()), + modified: Some(rgba(0xf5c177ff).into()), + success: Some(rgba(0xe0def4ff).into()), + warning: Some(rgba(0xf5c177ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -353,8 +428,7 @@ pub fn rose_pine() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0xc4a7e7ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x9cced7ff).into()), ..Default::default() }, ), @@ -369,29 +443,56 @@ pub fn rose_pine() -> UserThemeFamily { "comment".into(), UserHighlightStyle { color: Some(rgba(0x6e6a86ff).into()), - font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x6e6a86ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x8682a0ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0x3e8fb0ff).into()), + color: Some(rgba(0x5dc2a3ff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x9ccfd8ff).into()), + color: Some(rgba(0x9cced7ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xe0def4ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x9cced7ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x9cced7ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), @@ -402,6 +503,21 @@ pub fn rose_pine() -> UserThemeFamily { ..Default::default() }, ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0xea9a97ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x728aa2ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), ( "keyword".into(), UserHighlightStyle { @@ -411,6 +527,21 @@ pub fn rose_pine() -> UserThemeFamily { ), ( "label".into(), + UserHighlightStyle { + color: Some(rgba(0x9cced7ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0x9ccfd8ff).into()), + font_style: Some(UserFontStyle::Normal), + ..Default::default() + }, + ), + ( + "link_uri".into(), UserHighlightStyle { color: Some(rgba(0xea9a97ff).into()), ..Default::default() @@ -419,7 +550,43 @@ pub fn rose_pine() -> UserThemeFamily { ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xea9a97ff).into()), + color: Some(rgba(0x5dc2a3ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x3e8fb0ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x516b83ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xe0def4ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xe0def4ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0x9cced7ff).into()), ..Default::default() }, ), @@ -433,28 +600,28 @@ pub fn rose_pine() -> UserThemeFamily { ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x908caaff).into()), + color: Some(rgba(0xaeabc6ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0x908caaff).into()), + color: Some(rgba(0xaeabc6ff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0x908caaff).into()), + color: Some(rgba(0xaeabc6ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0x908caaff).into()), + color: Some(rgba(0xaeabc6ff).into()), ..Default::default() }, ), @@ -468,28 +635,28 @@ pub fn rose_pine() -> UserThemeFamily { ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0x8682a0ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), @@ -503,14 +670,15 @@ pub fn rose_pine() -> UserThemeFamily { ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xf6c177ff).into()), + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0xea9a97ff).into()), + color: Some(rgba(0xf6c177ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), @@ -522,93 +690,87 @@ pub fn rose_pine() -> UserThemeFamily { }, ), ( - "variable".into(), + "type.builtin".into(), UserHighlightStyle { - color: Some(rgba(0xea9a97ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x9ccfd8ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variable".into(), UserHighlightStyle { color: Some(rgba(0xe0def4ff).into()), ..Default::default() }, ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x9cced7ff).into()), + ..Default::default() + }, + ), ], }), }, }, UserTheme { - name: "Rosé Pine Dawn".into(), - appearance: Appearance::Light, + name: "Rosé Pine".into(), + appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x00000000).into()), - border_variant: Some(rgba(0x00000000).into()), - border_focused: Some(rgba(0x6e6a8614).into()), - border_selected: Some(rgba(0x00000000).into()), - border_transparent: Some(rgba(0x00000000).into()), - border_disabled: Some(rgba(0x00000000).into()), - elevated_surface_background: Some(rgba(0xfffaf3ff).into()), - surface_background: Some(rgba(0xfffaf3ff).into()), - background: Some(rgba(0xfaf4edff).into()), - element_background: Some(rgba(0xd7827eff).into()), - element_hover: Some(rgba(0x6e6a860d).into()), - element_selected: Some(rgba(0x6e6a8614).into()), - drop_target_background: Some(rgba(0xfffaf3ff).into()), - ghost_element_hover: Some(rgba(0x6e6a860d).into()), - ghost_element_selected: Some(rgba(0x6e6a8614).into()), - text: Some(rgba(0x575279ff).into()), - text_muted: Some(rgba(0x797593ff).into()), - status_bar_background: Some(rgba(0xfaf4edff).into()), - title_bar_background: Some(rgba(0xfaf4edff).into()), - toolbar_background: Some(rgba(0xfaf4edff).into()), - tab_bar_background: Some(rgba(0x00000000).into()), - tab_inactive_background: Some(rgba(0x00000000).into()), - tab_active_background: Some(rgba(0x6e6a860d).into()), - scrollbar_thumb_background: Some(rgba(0x6e6a8614).into()), - scrollbar_thumb_hover_background: Some(rgba(0x6e6a8626).into()), - scrollbar_thumb_border: Some(rgba(0x6e6a8614).into()), - scrollbar_track_background: Some(rgba(0xfaf4edff).into()), - scrollbar_track_border: Some(rgba(0x6e6a8626).into()), - editor_foreground: Some(rgba(0x575279ff).into()), - editor_background: Some(rgba(0xfaf4edff).into()), - editor_gutter_background: Some(rgba(0xfaf4edff).into()), - editor_line_number: Some(rgba(0x797593ff).into()), - editor_active_line_number: Some(rgba(0x575279ff).into()), - editor_wrap_guide: Some(rgba(0x00000000).into()), - editor_active_wrap_guide: Some(rgba(0x00000000).into()), - terminal_ansi_bright_black: Some(rgba(0x797593ff).into()), - terminal_ansi_bright_red: Some(rgba(0xb4637aff).into()), - terminal_ansi_bright_green: Some(rgba(0x286983ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xea9d34ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x56949fff).into()), - terminal_ansi_bright_magenta: Some(rgba(0x907aa9ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0xd7827eff).into()), - terminal_ansi_bright_white: Some(rgba(0x575279ff).into()), - terminal_ansi_black: Some(rgba(0xf2e9e1ff).into()), - terminal_ansi_red: Some(rgba(0xb4637aff).into()), - terminal_ansi_green: Some(rgba(0x286983ff).into()), - terminal_ansi_yellow: Some(rgba(0xea9d34ff).into()), - terminal_ansi_blue: Some(rgba(0x56949fff).into()), - terminal_ansi_magenta: Some(rgba(0x907aa9ff).into()), - terminal_ansi_cyan: Some(rgba(0xd7827eff).into()), - terminal_ansi_white: Some(rgba(0x575279ff).into()), - link_text_hover: Some(rgba(0x907aa9e6).into()), + border: Some(rgba(0x423f55ff).into()), + border_variant: Some(rgba(0x423f55ff).into()), + elevated_surface_background: Some(rgba(0x292739ff).into()), + background: Some(rgba(0x292739ff).into()), + panel_background: Some(rgba(0x1d1b2aff).into()), + element_hover: Some(rgba(0x423f5580).into()), + element_selected: Some(rgba(0x47445b80).into()), + text: Some(rgba(0x75718eff).into()), + text_muted: Some(rgba(0x3b384fff).into()), + status_bar_background: Some(rgba(0x292739ff).into()), + title_bar_background: Some(rgba(0x292739ff).into()), + toolbar_background: Some(rgba(0x191724ff).into()), + tab_bar_background: Some(rgba(0x1d1b2aff).into()), + tab_inactive_background: Some(rgba(0x1d1b2aff).into()), + tab_active_background: Some(rgba(0x191724ff).into()), + scrollbar_thumb_background: Some(rgba(0xe0def44d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xe0def44d).into()), + scrollbar_thumb_border: Some(rgba(0x1c1a29ff).into()), + scrollbar_track_border: Some(rgba(0x1c1a29ff).into()), + editor_foreground: Some(rgba(0xe0def4ff).into()), + editor_background: Some(rgba(0x191724ff).into()), + editor_gutter_background: Some(rgba(0x191724ff).into()), + editor_line_number: Some(rgba(0xe0def459).into()), + editor_active_line_number: Some(rgba(0xe0def4ff).into()), + editor_wrap_guide: Some(rgba(0xe0def40d).into()), + editor_active_wrap_guide: Some(rgba(0xe0def41a).into()), + terminal_background: Some(rgba(0x191724ff).into()), + terminal_ansi_bright_black: Some(rgba(0x403d55ff).into()), + terminal_ansi_bright_red: Some(rgba(0x7e3647ff).into()), + terminal_ansi_bright_green: Some(rgba(0x31614fff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x8a653bff).into()), + terminal_ansi_bright_blue: Some(rgba(0x566c70ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x4c3b47ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x203a46ff).into()), + terminal_ansi_bright_white: Some(rgba(0xe0def4ff).into()), + terminal_ansi_black: Some(rgba(0x191724ff).into()), + terminal_ansi_red: Some(rgba(0xea6f92ff).into()), + terminal_ansi_green: Some(rgba(0x5dc2a3ff).into()), + terminal_ansi_yellow: Some(rgba(0xf5c177ff).into()), + terminal_ansi_blue: Some(rgba(0x9cced7ff).into()), + terminal_ansi_magenta: Some(rgba(0x9d7691ff).into()), + terminal_ansi_cyan: Some(rgba(0x32748fff).into()), + terminal_ansi_white: Some(rgba(0xe0def4ff).into()), ..Default::default() }, status: StatusColorsRefinement { - conflict: Some(rgba(0xb4637aff).into()), - created: Some(rgba(0x56949fff).into()), - deleted: Some(rgba(0xb4637aff).into()), - error: Some(rgba(0xb4637aff).into()), - hidden: Some(rgba(0x797593ff).into()), - hint: Some(rgba(0x797593ff).into()), - ignored: Some(rgba(0x9893a5ff).into()), - modified: Some(rgba(0xd7827eff).into()), - warning: Some(rgba(0xea9d34ff).into()), + created: Some(rgba(0x5dc2a3ff).into()), + deleted: Some(rgba(0xbe5773ff).into()), + error: Some(rgba(0xea6f92ff).into()), + modified: Some(rgba(0xf5c177ff).into()), + success: Some(rgba(0xe0def4ff).into()), + warning: Some(rgba(0xf5c177ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -616,186 +778,285 @@ pub fn rose_pine() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0x907aa9ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x9cced7ff).into()), ..Default::default() }, ), ( "boolean".into(), UserHighlightStyle { - color: Some(rgba(0xd7827eff).into()), + color: Some(rgba(0xebbcbaff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x9893a5ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x6e6a86ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x9893a5ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x777390ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0x286983ff).into()), + color: Some(rgba(0x5dc2a3ff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x56949fff).into()), + color: Some(rgba(0x9cced7ff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xe0def4ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x9cced7ff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x9cced7ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0xd7827eff).into()), + color: Some(rgba(0xebbcbaff).into()), + ..Default::default() + }, + ), + ( + "function.method".into(), + UserHighlightStyle { + color: Some(rgba(0xebbcbaff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x5e768cff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0x286983ff).into()), + color: Some(rgba(0x31748fff).into()), ..Default::default() }, ), ( "label".into(), UserHighlightStyle { - color: Some(rgba(0xd7827eff).into()), + color: Some(rgba(0x9cced7ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0x9ccfd8ff).into()), + font_style: Some(UserFontStyle::Normal), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0xebbcbaff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xd7827eff).into()), + color: Some(rgba(0x5dc2a3ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0x31748fff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x556b81ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xe0def4ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xe0def4ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0x9cced7ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0x797593ff).into()), + color: Some(rgba(0x908caaff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x797593ff).into()), + color: Some(rgba(0x9d99b6ff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0x797593ff).into()), + color: Some(rgba(0x9d99b6ff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0x797593ff).into()), + color: Some(rgba(0x9d99b6ff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0x797593ff).into()), + color: Some(rgba(0x9d99b6ff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0xea9d34ff).into()), + color: Some(rgba(0xf6c177ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0xea9d34ff).into()), + color: Some(rgba(0x777390ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0xea9d34ff).into()), + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0xea9d34ff).into()), + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0xea9d34ff).into()), + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x56949fff).into()), + color: Some(rgba(0x9ccfd8ff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0xea9d34ff).into()), + color: Some(rgba(0xc4a7e6ff).into()), ..Default::default() }, ), ( "title".into(), UserHighlightStyle { - color: Some(rgba(0xd7827eff).into()), + color: Some(rgba(0xf6c177ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0x56949fff).into()), + color: Some(rgba(0x9ccfd8ff).into()), + ..Default::default() + }, + ), + ( + "type.builtin".into(), + UserHighlightStyle { + color: Some(rgba(0x9ccfd8ff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0xd7827eff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0xe0def4ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0x575279ff).into()), + color: Some(rgba(0x9cced7ff).into()), ..Default::default() }, ), diff --git a/crates/theme2/src/themes/sandcastle.rs b/crates/theme2/src/themes/sandcastle.rs new file mode 100644 index 0000000000000000000000000000000000000000..2ee42660e3b59ef94b6e519032b6d124411cac36 --- /dev/null +++ b/crates/theme2/src/themes/sandcastle.rs @@ -0,0 +1,353 @@ +// This file was generated by the `theme_importer`. +// Be careful when modifying it by hand. + +use gpui::rgba; + +#[allow(unused)] +use crate::{ + Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, + UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, +}; + +pub fn sandcastle() -> UserThemeFamily { + UserThemeFamily { + name: "Sandcastle".into(), + author: "Zed Industries".into(), + themes: vec![UserTheme { + name: "Sandcastle".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x3d4350ff).into()), + border_variant: Some(rgba(0x3d4350ff).into()), + elevated_surface_background: Some(rgba(0x333944ff).into()), + background: Some(rgba(0x333944ff).into()), + panel_background: Some(rgba(0x2b3039ff).into()), + element_hover: Some(rgba(0x3d435080).into()), + element_selected: Some(rgba(0x57535380).into()), + text: Some(rgba(0xa69782ff).into()), + text_muted: Some(rgba(0x645b54ff).into()), + status_bar_background: Some(rgba(0x333944ff).into()), + title_bar_background: Some(rgba(0x333944ff).into()), + toolbar_background: Some(rgba(0x282c34ff).into()), + tab_bar_background: Some(rgba(0x2b3039ff).into()), + tab_inactive_background: Some(rgba(0x2b3039ff).into()), + tab_active_background: Some(rgba(0x282c34ff).into()), + scrollbar_thumb_background: Some(rgba(0xfdf4c14d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xfdf4c14d).into()), + scrollbar_thumb_border: Some(rgba(0x2a2f38ff).into()), + scrollbar_track_border: Some(rgba(0x2a2f38ff).into()), + editor_foreground: Some(rgba(0xfdf4c1ff).into()), + editor_background: Some(rgba(0x282c34ff).into()), + editor_gutter_background: Some(rgba(0x282c34ff).into()), + editor_line_number: Some(rgba(0xfdf4c159).into()), + editor_active_line_number: Some(rgba(0xfdf4c1ff).into()), + editor_wrap_guide: Some(rgba(0xfdf4c10d).into()), + editor_active_wrap_guide: Some(rgba(0xfdf4c11a).into()), + terminal_background: Some(rgba(0x282c34ff).into()), + terminal_ansi_bright_black: Some(rgba(0x5e5753ff).into()), + terminal_ansi_bright_red: Some(rgba(0x57333dff).into()), + terminal_ansi_bright_green: Some(rgba(0x414f4aff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x4e3f22ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x2c4444ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x523a18ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x414f4aff).into()), + terminal_ansi_bright_white: Some(rgba(0xfdf4c1ff).into()), + terminal_ansi_black: Some(rgba(0x282c34ff).into()), + terminal_ansi_red: Some(rgba(0xb4637aff).into()), + terminal_ansi_green: Some(rgba(0x83a598ff).into()), + terminal_ansi_yellow: Some(rgba(0xa07e3bff).into()), + terminal_ansi_blue: Some(rgba(0x528b8bff).into()), + terminal_ansi_magenta: Some(rgba(0xa87323ff).into()), + terminal_ansi_cyan: Some(rgba(0x83a598ff).into()), + terminal_ansi_white: Some(rgba(0xfdf4c1ff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x83a598ff).into()), + deleted: Some(rgba(0x8d4f61ff).into()), + error: Some(rgba(0xb4637aff).into()), + modified: Some(rgba(0xa07e3bff).into()), + success: Some(rgba(0xfdf4c1ff).into()), + warning: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x528b8bff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0xa89984ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0xa89984ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x528b8bff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xfdf4c1ff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x528b8bff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x528b8bff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x727d68ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x528b8bff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x528b8bff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x5c6152ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xfdf4c1ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xfdf4c1ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0x528b8bff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xd5c5a1ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0xd5c5a1ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0xd5c5a1ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xd5c5a1ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xd5c5a1ff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0xa89984ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x528b8bff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xa07e3bff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xfdf4c1ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0x83a598ff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xfdf4c1ff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x528b8bff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }], + } +} diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index 8a5bf96c1652a57b32c8efd881bcf428d0b9d2aa..4b8f60a61d67e8b5a2127b98541f87c3983eb2b4 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -12,64 +12,65 @@ use crate::{ pub fn solarized() -> UserThemeFamily { UserThemeFamily { name: "Solarized".into(), - author: "Ethan Schoonover (altercation)".into(), + author: "Zed Industries".into(), themes: vec![ UserTheme { - name: "Solarized Dark".into(), - appearance: Appearance::Dark, + name: "Solarized Light".into(), + appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x003847ff).into()), - border_variant: Some(rgba(0x003847ff).into()), - border_focused: Some(rgba(0x2aa19899).into()), - border_selected: Some(rgba(0x003847ff).into()), - border_transparent: Some(rgba(0x003847ff).into()), - border_disabled: Some(rgba(0x003847ff).into()), - elevated_surface_background: Some(rgba(0x00212bff).into()), - background: Some(rgba(0x002b36ff).into()), - element_background: Some(rgba(0x2aa19899).into()), - element_hover: Some(rgba(0x004454aa).into()), - element_selected: Some(rgba(0x005a6fff).into()), - drop_target_background: Some(rgba(0x00445488).into()), - ghost_element_hover: Some(rgba(0x004454aa).into()), - ghost_element_selected: Some(rgba(0x005a6fff).into()), - text: Some(rgba(0xbbbbbbff).into()), - text_muted: Some(rgba(0x93a1a1ff).into()), - status_bar_background: Some(rgba(0x00212bff).into()), - title_bar_background: Some(rgba(0x002c39ff).into()), - toolbar_background: Some(rgba(0x002b36ff).into()), - tab_bar_background: Some(rgba(0x004052ff).into()), - tab_inactive_background: Some(rgba(0x004052ff).into()), - tab_active_background: Some(rgba(0x002b37ff).into()), - scrollbar_track_background: Some(rgba(0x002b36ff).into()), - editor_foreground: Some(rgba(0xbbbbbbff).into()), - editor_background: Some(rgba(0x002b36ff).into()), - editor_gutter_background: Some(rgba(0x002b36ff).into()), - editor_line_number: Some(rgba(0x566c74ff).into()), - editor_wrap_guide: Some(rgba(0x003847ff).into()), - editor_active_wrap_guide: Some(rgba(0x003847ff).into()), - terminal_ansi_bright_black: Some(rgba(0x586e75ff).into()), - terminal_ansi_bright_red: Some(rgba(0xcb4b16ff).into()), - terminal_ansi_bright_green: Some(rgba(0x859900ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0x657b83ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x839496ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0x6c71c4ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x93a1a1ff).into()), - terminal_ansi_bright_white: Some(rgba(0x839496ff).into()), - terminal_ansi_black: Some(rgba(0x073642ff).into()), - terminal_ansi_red: Some(rgba(0xdc322fff).into()), - terminal_ansi_green: Some(rgba(0x859900ff).into()), - terminal_ansi_yellow: Some(rgba(0xb58900ff).into()), - terminal_ansi_blue: Some(rgba(0x268bd2ff).into()), - terminal_ansi_magenta: Some(rgba(0xd33682ff).into()), - terminal_ansi_cyan: Some(rgba(0x2aa198ff).into()), - terminal_ansi_white: Some(rgba(0x839496ff).into()), + border: Some(rgba(0x9faaa8ff).into()), + border_variant: Some(rgba(0x9faaa8ff).into()), + elevated_surface_background: Some(rgba(0xcfd0c4ff).into()), + background: Some(rgba(0xcfd0c4ff).into()), + panel_background: Some(rgba(0xf3eddaff).into()), + element_hover: Some(rgba(0x9faaa880).into()), + element_selected: Some(rgba(0x7f919480).into()), + text: Some(rgba(0x34555eff).into()), + text_muted: Some(rgba(0x788b8fff).into()), + status_bar_background: Some(rgba(0xcfd0c4ff).into()), + title_bar_background: Some(rgba(0xcfd0c4ff).into()), + toolbar_background: Some(rgba(0xfdf6e3ff).into()), + tab_bar_background: Some(rgba(0xf3eddaff).into()), + tab_inactive_background: Some(rgba(0xf3eddaff).into()), + tab_active_background: Some(rgba(0xfdf6e3ff).into()), + scrollbar_thumb_background: Some(rgba(0x002b364d).into()), + scrollbar_thumb_hover_background: Some(rgba(0x002b364d).into()), + scrollbar_thumb_border: Some(rgba(0xf5eedbff).into()), + scrollbar_track_border: Some(rgba(0xf5eedbff).into()), + editor_foreground: Some(rgba(0x002b36ff).into()), + editor_background: Some(rgba(0xfdf6e3ff).into()), + editor_gutter_background: Some(rgba(0xfdf6e3ff).into()), + editor_line_number: Some(rgba(0x002b3659).into()), + editor_active_line_number: Some(rgba(0x002b36ff).into()), + editor_wrap_guide: Some(rgba(0x002b360d).into()), + editor_active_wrap_guide: Some(rgba(0x002b361a).into()), + terminal_background: Some(rgba(0xfdf6e3ff).into()), + terminal_ansi_bright_black: Some(rgba(0x7b8e91ff).into()), + terminal_ansi_bright_red: Some(rgba(0xfaa091ff).into()), + terminal_ansi_bright_green: Some(rgba(0xc6cb8bff).into()), + terminal_ansi_bright_yellow: Some(rgba(0xe1c28aff).into()), + terminal_ansi_bright_blue: Some(rgba(0xa5c3e9ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0xf0a2bfff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x9fd0cbff).into()), + terminal_ansi_bright_white: Some(rgba(0x002b36ff).into()), + terminal_ansi_black: Some(rgba(0xfdf6e3ff).into()), + terminal_ansi_red: Some(rgba(0xdc3330ff).into()), + terminal_ansi_green: Some(rgba(0x859904ff).into()), + terminal_ansi_yellow: Some(rgba(0xb58904ff).into()), + terminal_ansi_blue: Some(rgba(0x298bd1ff).into()), + terminal_ansi_magenta: Some(rgba(0xd33882ff).into()), + terminal_ansi_cyan: Some(rgba(0x2ca198ff).into()), + terminal_ansi_white: Some(rgba(0x002b36ff).into()), ..Default::default() }, status: StatusColorsRefinement { - error: Some(rgba(0xffeaeaff).into()), - hidden: Some(rgba(0x93a1a1ff).into()), - hint: Some(rgba(0x969696ff).into()), + created: Some(rgba(0xa0ad46ff).into()), + deleted: Some(rgba(0xdc3330ff).into()), + error: Some(rgba(0xdc3330ff).into()), + modified: Some(rgba(0xb58904ff).into()), + success: Some(rgba(0x002b36ff).into()), + warning: Some(rgba(0xb58904ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -77,205 +78,271 @@ pub fn solarized() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0x93a1a1ff).into()), + color: Some(rgba(0x298bd1ff).into()), ..Default::default() }, ), ( "boolean".into(), UserHighlightStyle { - color: Some(rgba(0xb58900ff).into()), + color: Some(rgba(0x859904ff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x657b83ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x30525bff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x657b83ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x30525bff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0xb58900ff).into()), + color: Some(rgba(0x859904ff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x268bd2ff).into()), + color: Some(rgba(0x298bd1ff).into()), ..Default::default() }, ), ( "embedded".into(), UserHighlightStyle { - color: Some(rgba(0x93a1a1ff).into()), + color: Some(rgba(0x002b36ff).into()), ..Default::default() }, ), ( "emphasis".into(), UserHighlightStyle { - color: Some(rgba(0xd33682ff).into()), + color: Some(rgba(0x298bd1ff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xd33682ff).into()), + color: Some(rgba(0x298bd1ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xcb4c18ff).into()), ..Default::default() }, ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0x839496ff).into()), + color: Some(rgba(0xb58904ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x5889a3ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0x859900ff).into()), + color: Some(rgba(0x298bd1ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x298bd1ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xcb4c18ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x859904ff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xd33682ff).into()), + color: Some(rgba(0x859904ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0xcb4c18ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x679aafff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "preproc".into(), UserHighlightStyle { - color: Some(rgba(0xb58900ff).into()), + color: Some(rgba(0x002b36ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0x002b36ff).into()), ..Default::default() }, ), ( "property".into(), UserHighlightStyle { - color: Some(rgba(0x839496ff).into()), + color: Some(rgba(0x298bd1ff).into()), ..Default::default() }, ), ( "punctuation".into(), UserHighlightStyle { - color: Some(rgba(0x657b83ff).into()), + color: Some(rgba(0x05333eff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x657b83ff).into()), + color: Some(rgba(0x05333eff).into()), ..Default::default() }, ), ( "punctuation.delimiter".into(), UserHighlightStyle { - color: Some(rgba(0x657b83ff).into()), + color: Some(rgba(0x05333eff).into()), ..Default::default() }, ), ( "punctuation.list_marker".into(), UserHighlightStyle { - color: Some(rgba(0x657b83ff).into()), + color: Some(rgba(0x05333eff).into()), ..Default::default() }, ), ( "punctuation.special".into(), UserHighlightStyle { - color: Some(rgba(0x657b83ff).into()), + color: Some(rgba(0x05333eff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4c18ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0xcb4b16ff).into()), + color: Some(rgba(0x30525bff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4c18ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4c18ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4c18ff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x268bd2ff).into()), + color: Some(rgba(0x298bd1ff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4c18ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0x002b36ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0xb58900ff).into()), + color: Some(rgba(0x2ca198ff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0x268bd2ff).into()), + color: Some(rgba(0x002b36ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0x268bd2ff).into()), + color: Some(rgba(0x298bd1ff).into()), ..Default::default() }, ), @@ -284,59 +351,62 @@ pub fn solarized() -> UserThemeFamily { }, }, UserTheme { - name: "Solarized Light".into(), - appearance: Appearance::Light, + name: "Solarized Dark".into(), + appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xddd6c1ff).into()), - border_variant: Some(rgba(0xddd6c1ff).into()), - border_focused: Some(rgba(0xd3af86ff).into()), - border_selected: Some(rgba(0xddd6c1ff).into()), - border_transparent: Some(rgba(0xddd6c1ff).into()), - border_disabled: Some(rgba(0xddd6c1ff).into()), - elevated_surface_background: Some(rgba(0xeee8d5ff).into()), - background: Some(rgba(0xfdf6e3ff).into()), - element_background: Some(rgba(0xac9d57ff).into()), - element_hover: Some(rgba(0xdfca8844).into()), - element_selected: Some(rgba(0xdfca88ff).into()), - ghost_element_hover: Some(rgba(0xdfca8844).into()), - ghost_element_selected: Some(rgba(0xdfca88ff).into()), - text: Some(rgba(0x333333ff).into()), - text_muted: Some(rgba(0x586e75ff).into()), - status_bar_background: Some(rgba(0xeee8d5ff).into()), - title_bar_background: Some(rgba(0xeee8d5ff).into()), - toolbar_background: Some(rgba(0xfdf6e3ff).into()), - tab_bar_background: Some(rgba(0xd9d2c2ff).into()), - tab_inactive_background: Some(rgba(0xd3cbb7ff).into()), - tab_active_background: Some(rgba(0xfdf6e3ff).into()), - scrollbar_track_background: Some(rgba(0xfdf6e3ff).into()), - editor_foreground: Some(rgba(0x333333ff).into()), - editor_background: Some(rgba(0xfdf6e3ff).into()), - editor_gutter_background: Some(rgba(0xfdf6e3ff).into()), - editor_line_number: Some(rgba(0x9ca8a6ff).into()), - editor_wrap_guide: Some(rgba(0xddd6c1ff).into()), - editor_active_wrap_guide: Some(rgba(0xddd6c1ff).into()), - terminal_ansi_bright_black: Some(rgba(0x657b83ff).into()), - terminal_ansi_bright_red: Some(rgba(0xcb4b16ff).into()), - terminal_ansi_bright_green: Some(rgba(0x859900ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0x657b83ff).into()), - terminal_ansi_bright_blue: Some(rgba(0x839496ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0x6c71c4ff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x93a1a1ff).into()), - terminal_ansi_bright_white: Some(rgba(0xeee8d5ff).into()), - terminal_ansi_black: Some(rgba(0x657b83ff).into()), - terminal_ansi_red: Some(rgba(0xdc322fff).into()), - terminal_ansi_green: Some(rgba(0x859900ff).into()), - terminal_ansi_yellow: Some(rgba(0xb58900ff).into()), - terminal_ansi_blue: Some(rgba(0x268bd2ff).into()), - terminal_ansi_magenta: Some(rgba(0xd33682ff).into()), - terminal_ansi_cyan: Some(rgba(0x2aa198ff).into()), - terminal_ansi_white: Some(rgba(0xeee8d5ff).into()), + border: Some(rgba(0x2b4f58ff).into()), + border_variant: Some(rgba(0x2b4f58ff).into()), + elevated_surface_background: Some(rgba(0x083743ff).into()), + background: Some(rgba(0x083743ff).into()), + panel_background: Some(rgba(0x04313cff).into()), + element_hover: Some(rgba(0x2b4f5880).into()), + element_selected: Some(rgba(0x566d7480).into()), + text: Some(rgba(0x93a1a1ff).into()), + text_muted: Some(rgba(0x5f757dff).into()), + status_bar_background: Some(rgba(0x083743ff).into()), + title_bar_background: Some(rgba(0x083743ff).into()), + toolbar_background: Some(rgba(0x002b36ff).into()), + tab_bar_background: Some(rgba(0x04313cff).into()), + tab_inactive_background: Some(rgba(0x04313cff).into()), + tab_active_background: Some(rgba(0x002b36ff).into()), + scrollbar_thumb_background: Some(rgba(0xfdf6e34d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xfdf6e34d).into()), + scrollbar_thumb_border: Some(rgba(0x032f3bff).into()), + scrollbar_track_border: Some(rgba(0x032f3bff).into()), + editor_foreground: Some(rgba(0xfdf6e3ff).into()), + editor_background: Some(rgba(0x002b36ff).into()), + editor_gutter_background: Some(rgba(0x002b36ff).into()), + editor_line_number: Some(rgba(0xfdf6e359).into()), + editor_active_line_number: Some(rgba(0xfdf6e3ff).into()), + editor_wrap_guide: Some(rgba(0xfdf6e30d).into()), + editor_active_wrap_guide: Some(rgba(0xfdf6e31a).into()), + terminal_background: Some(rgba(0x002b36ff).into()), + terminal_ansi_bright_black: Some(rgba(0x5c7279ff).into()), + terminal_ansi_bright_red: Some(rgba(0x7d181cff).into()), + terminal_ansi_bright_green: Some(rgba(0x434a11ff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x5d4310ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x214465ff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x6f1f40ff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x204e4aff).into()), + terminal_ansi_bright_white: Some(rgba(0xfdf6e3ff).into()), + terminal_ansi_black: Some(rgba(0x002b36ff).into()), + terminal_ansi_red: Some(rgba(0xdc3330ff).into()), + terminal_ansi_green: Some(rgba(0x859904ff).into()), + terminal_ansi_yellow: Some(rgba(0xb58903ff).into()), + terminal_ansi_blue: Some(rgba(0x288bd1ff).into()), + terminal_ansi_magenta: Some(rgba(0xd33782ff).into()), + terminal_ansi_cyan: Some(rgba(0x2ca198ff).into()), + terminal_ansi_white: Some(rgba(0xfdf6e3ff).into()), ..Default::default() }, status: StatusColorsRefinement { - hidden: Some(rgba(0x586e75ff).into()), - hint: Some(rgba(0x969696ff).into()), + created: Some(rgba(0x859904ff).into()), + deleted: Some(rgba(0xb52727ff).into()), + error: Some(rgba(0xdc3330ff).into()), + modified: Some(rgba(0xb58903ff).into()), + success: Some(rgba(0xfdf6e3ff).into()), + warning: Some(rgba(0xb58903ff).into()), ..Default::default() }, syntax: Some(UserSyntaxTheme { @@ -344,170 +414,271 @@ pub fn solarized() -> UserThemeFamily { ( "attribute".into(), UserHighlightStyle { - color: Some(rgba(0x93a1a1ff).into()), + color: Some(rgba(0x288bd1ff).into()), ..Default::default() }, ), ( "boolean".into(), UserHighlightStyle { - color: Some(rgba(0xb58900ff).into()), + color: Some(rgba(0x859904ff).into()), ..Default::default() }, ), ( "comment".into(), UserHighlightStyle { - color: Some(rgba(0x93a1a1ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x99a5a4ff).into()), ..Default::default() }, ), ( "comment.doc".into(), UserHighlightStyle { - color: Some(rgba(0x93a1a1ff).into()), - font_style: Some(UserFontStyle::Italic), + color: Some(rgba(0x99a5a4ff).into()), ..Default::default() }, ), ( "constant".into(), UserHighlightStyle { - color: Some(rgba(0xb58900ff).into()), + color: Some(rgba(0x859904ff).into()), ..Default::default() }, ), ( "constructor".into(), UserHighlightStyle { - color: Some(rgba(0x268bd2ff).into()), + color: Some(rgba(0x288bd1ff).into()), ..Default::default() }, ), ( "embedded".into(), UserHighlightStyle { - color: Some(rgba(0x657b83ff).into()), + color: Some(rgba(0xfdf6e3ff).into()), ..Default::default() }, ), ( "emphasis".into(), UserHighlightStyle { - color: Some(rgba(0xd33682ff).into()), + color: Some(rgba(0x288bd1ff).into()), ..Default::default() }, ), ( "emphasis.strong".into(), UserHighlightStyle { - color: Some(rgba(0xd33682ff).into()), + color: Some(rgba(0x288bd1ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xcb4b17ff).into()), ..Default::default() }, ), ( "function".into(), UserHighlightStyle { - color: Some(rgba(0x657b83ff).into()), + color: Some(rgba(0xb58903ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x4f8297ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "keyword".into(), UserHighlightStyle { - color: Some(rgba(0x859900ff).into()), + color: Some(rgba(0x288bd1ff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x288bd1ff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xcb4b17ff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x859904ff).into()), ..Default::default() }, ), ( "number".into(), UserHighlightStyle { - color: Some(rgba(0xd33682ff).into()), + color: Some(rgba(0x859904ff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0xcb4b17ff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x40728bff).into()), + font_style: Some(UserFontStyle::Italic), ..Default::default() }, ), ( "preproc".into(), UserHighlightStyle { - color: Some(rgba(0xb58900ff).into()), + color: Some(rgba(0xfdf6e3ff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xfdf6e3ff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0x288bd1ff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xefe9d6ff).into()), ..Default::default() }, ), ( "punctuation.bracket".into(), UserHighlightStyle { - color: Some(rgba(0x93a1a1ff).into()), + color: Some(rgba(0xefe9d6ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0xefe9d6ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xefe9d6ff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xefe9d6ff).into()), ..Default::default() }, ), ( "string".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4b17ff).into()), ..Default::default() }, ), ( "string.escape".into(), UserHighlightStyle { - color: Some(rgba(0xcb4b16ff).into()), + color: Some(rgba(0x99a5a4ff).into()), ..Default::default() }, ), ( "string.regex".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4b17ff).into()), ..Default::default() }, ), ( "string.special".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4b17ff).into()), ..Default::default() }, ), ( "string.special.symbol".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4b17ff).into()), ..Default::default() }, ), ( "tag".into(), UserHighlightStyle { - color: Some(rgba(0x268bd2ff).into()), + color: Some(rgba(0x288bd1ff).into()), ..Default::default() }, ), ( "text.literal".into(), UserHighlightStyle { - color: Some(rgba(0x2aa198ff).into()), + color: Some(rgba(0xcb4b17ff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xfdf6e3ff).into()), + font_weight: Some(UserFontWeight(700.0)), ..Default::default() }, ), ( "type".into(), UserHighlightStyle { - color: Some(rgba(0xb58900ff).into()), + color: Some(rgba(0x2ca198ff).into()), ..Default::default() }, ), ( "variable".into(), UserHighlightStyle { - color: Some(rgba(0x268bd2ff).into()), + color: Some(rgba(0xfdf6e3ff).into()), ..Default::default() }, ), ( - "variable.special".into(), + "variant".into(), UserHighlightStyle { - color: Some(rgba(0x268bd2ff).into()), + color: Some(rgba(0x288bd1ff).into()), ..Default::default() }, ), diff --git a/crates/theme2/src/themes/summercamp.rs b/crates/theme2/src/themes/summercamp.rs new file mode 100644 index 0000000000000000000000000000000000000000..f4b5b6ed637e8d7df811f5ea16ba05e7ebce59f8 --- /dev/null +++ b/crates/theme2/src/themes/summercamp.rs @@ -0,0 +1,353 @@ +// This file was generated by the `theme_importer`. +// Be careful when modifying it by hand. + +use gpui::rgba; + +#[allow(unused)] +use crate::{ + Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, + UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, +}; + +pub fn summercamp() -> UserThemeFamily { + UserThemeFamily { + name: "Summercamp".into(), + author: "Zed Industries".into(), + themes: vec![UserTheme { + name: "Summercamp".into(), + appearance: Appearance::Dark, + styles: UserThemeStylesRefinement { + colors: ThemeColorsRefinement { + border: Some(rgba(0x312d21ff).into()), + border_variant: Some(rgba(0x312d21ff).into()), + elevated_surface_background: Some(rgba(0x2a261cff).into()), + background: Some(rgba(0x2a261cff).into()), + panel_background: Some(rgba(0x231f16ff).into()), + element_hover: Some(rgba(0x312d2180).into()), + element_selected: Some(rgba(0x39342780).into()), + text: Some(rgba(0x736e55ff).into()), + text_muted: Some(rgba(0x3d382aff).into()), + status_bar_background: Some(rgba(0x2a261cff).into()), + title_bar_background: Some(rgba(0x2a261cff).into()), + toolbar_background: Some(rgba(0x1c1810ff).into()), + tab_bar_background: Some(rgba(0x231f16ff).into()), + tab_inactive_background: Some(rgba(0x231f16ff).into()), + tab_active_background: Some(rgba(0x1c1810ff).into()), + scrollbar_thumb_background: Some(rgba(0xf8f5de4d).into()), + scrollbar_thumb_hover_background: Some(rgba(0xf8f5de4d).into()), + scrollbar_thumb_border: Some(rgba(0x221e15ff).into()), + scrollbar_track_border: Some(rgba(0x221e15ff).into()), + editor_foreground: Some(rgba(0xf8f5deff).into()), + editor_background: Some(rgba(0x1c1810ff).into()), + editor_gutter_background: Some(rgba(0x1c1810ff).into()), + editor_line_number: Some(rgba(0xf8f5de59).into()), + editor_active_line_number: Some(rgba(0xf8f5deff).into()), + editor_wrap_guide: Some(rgba(0xf8f5de0d).into()), + editor_active_wrap_guide: Some(rgba(0xf8f5de1a).into()), + terminal_background: Some(rgba(0x1c1810ff).into()), + terminal_ansi_bright_black: Some(rgba(0x3b3627ff).into()), + terminal_ansi_bright_red: Some(rgba(0x7f2724ff).into()), + terminal_ansi_bright_green: Some(rgba(0x28842cff).into()), + terminal_ansi_bright_yellow: Some(rgba(0x8c9a10ff).into()), + terminal_ansi_bright_blue: Some(rgba(0x234b7fff).into()), + terminal_ansi_bright_magenta: Some(rgba(0x88487eff).into()), + terminal_ansi_bright_cyan: Some(rgba(0x298462ff).into()), + terminal_ansi_bright_white: Some(rgba(0xf8f5deff).into()), + terminal_ansi_black: Some(rgba(0x1c1810ff).into()), + terminal_ansi_red: Some(rgba(0xe35142ff).into()), + terminal_ansi_green: Some(rgba(0x5dea5aff).into()), + terminal_ansi_yellow: Some(rgba(0xf1fe29ff).into()), + terminal_ansi_blue: Some(rgba(0x499befff).into()), + terminal_ansi_magenta: Some(rgba(0xf59be6ff).into()), + terminal_ansi_cyan: Some(rgba(0x5beabcff).into()), + terminal_ansi_white: Some(rgba(0xf8f5deff).into()), + ..Default::default() + }, + status: StatusColorsRefinement { + created: Some(rgba(0x5dea5aff).into()), + deleted: Some(rgba(0xb93f36ff).into()), + error: Some(rgba(0xe35142ff).into()), + modified: Some(rgba(0xf1fe29ff).into()), + success: Some(rgba(0xf8f5deff).into()), + warning: Some(rgba(0xf1fe29ff).into()), + ..Default::default() + }, + syntax: Some(UserSyntaxTheme { + highlights: vec![ + ( + "attribute".into(), + UserHighlightStyle { + color: Some(rgba(0x499befff).into()), + ..Default::default() + }, + ), + ( + "boolean".into(), + UserHighlightStyle { + color: Some(rgba(0x5dea5aff).into()), + ..Default::default() + }, + ), + ( + "comment".into(), + UserHighlightStyle { + color: Some(rgba(0x777259ff).into()), + ..Default::default() + }, + ), + ( + "comment.doc".into(), + UserHighlightStyle { + color: Some(rgba(0x777259ff).into()), + ..Default::default() + }, + ), + ( + "constant".into(), + UserHighlightStyle { + color: Some(rgba(0x5dea5aff).into()), + ..Default::default() + }, + ), + ( + "constructor".into(), + UserHighlightStyle { + color: Some(rgba(0x499befff).into()), + ..Default::default() + }, + ), + ( + "embedded".into(), + UserHighlightStyle { + color: Some(rgba(0xf8f5deff).into()), + ..Default::default() + }, + ), + ( + "emphasis".into(), + UserHighlightStyle { + color: Some(rgba(0x499befff).into()), + ..Default::default() + }, + ), + ( + "emphasis.strong".into(), + UserHighlightStyle { + color: Some(rgba(0x499befff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "enum".into(), + UserHighlightStyle { + color: Some(rgba(0xfaa11dff).into()), + ..Default::default() + }, + ), + ( + "function".into(), + UserHighlightStyle { + color: Some(rgba(0xf1fe29ff).into()), + ..Default::default() + }, + ), + ( + "hint".into(), + UserHighlightStyle { + color: Some(rgba(0x246e61ff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "keyword".into(), + UserHighlightStyle { + color: Some(rgba(0x499befff).into()), + ..Default::default() + }, + ), + ( + "label".into(), + UserHighlightStyle { + color: Some(rgba(0x499befff).into()), + ..Default::default() + }, + ), + ( + "link_text".into(), + UserHighlightStyle { + color: Some(rgba(0xfaa11dff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "link_uri".into(), + UserHighlightStyle { + color: Some(rgba(0x5dea5aff).into()), + ..Default::default() + }, + ), + ( + "number".into(), + UserHighlightStyle { + color: Some(rgba(0x5dea5aff).into()), + ..Default::default() + }, + ), + ( + "operator".into(), + UserHighlightStyle { + color: Some(rgba(0xfaa11dff).into()), + ..Default::default() + }, + ), + ( + "predictive".into(), + UserHighlightStyle { + color: Some(rgba(0x79434bff).into()), + font_style: Some(UserFontStyle::Italic), + ..Default::default() + }, + ), + ( + "preproc".into(), + UserHighlightStyle { + color: Some(rgba(0xf8f5deff).into()), + ..Default::default() + }, + ), + ( + "primary".into(), + UserHighlightStyle { + color: Some(rgba(0xf8f5deff).into()), + ..Default::default() + }, + ), + ( + "property".into(), + UserHighlightStyle { + color: Some(rgba(0x499befff).into()), + ..Default::default() + }, + ), + ( + "punctuation".into(), + UserHighlightStyle { + color: Some(rgba(0xbfbb9bff).into()), + ..Default::default() + }, + ), + ( + "punctuation.bracket".into(), + UserHighlightStyle { + color: Some(rgba(0xbfbb9bff).into()), + ..Default::default() + }, + ), + ( + "punctuation.delimiter".into(), + UserHighlightStyle { + color: Some(rgba(0xbfbb9bff).into()), + ..Default::default() + }, + ), + ( + "punctuation.list_marker".into(), + UserHighlightStyle { + color: Some(rgba(0xbfbb9bff).into()), + ..Default::default() + }, + ), + ( + "punctuation.special".into(), + UserHighlightStyle { + color: Some(rgba(0xbfbb9bff).into()), + ..Default::default() + }, + ), + ( + "string".into(), + UserHighlightStyle { + color: Some(rgba(0xfaa11dff).into()), + ..Default::default() + }, + ), + ( + "string.escape".into(), + UserHighlightStyle { + color: Some(rgba(0x777259ff).into()), + ..Default::default() + }, + ), + ( + "string.regex".into(), + UserHighlightStyle { + color: Some(rgba(0xfaa11dff).into()), + ..Default::default() + }, + ), + ( + "string.special".into(), + UserHighlightStyle { + color: Some(rgba(0xfaa11dff).into()), + ..Default::default() + }, + ), + ( + "string.special.symbol".into(), + UserHighlightStyle { + color: Some(rgba(0xfaa11dff).into()), + ..Default::default() + }, + ), + ( + "tag".into(), + UserHighlightStyle { + color: Some(rgba(0x499befff).into()), + ..Default::default() + }, + ), + ( + "text.literal".into(), + UserHighlightStyle { + color: Some(rgba(0xfaa11dff).into()), + ..Default::default() + }, + ), + ( + "title".into(), + UserHighlightStyle { + color: Some(rgba(0xf8f5deff).into()), + font_weight: Some(UserFontWeight(700.0)), + ..Default::default() + }, + ), + ( + "type".into(), + UserHighlightStyle { + color: Some(rgba(0x5beabcff).into()), + ..Default::default() + }, + ), + ( + "variable".into(), + UserHighlightStyle { + color: Some(rgba(0xf8f5deff).into()), + ..Default::default() + }, + ), + ( + "variant".into(), + UserHighlightStyle { + color: Some(rgba(0x499befff).into()), + ..Default::default() + }, + ), + ], + }), + }, + }], + } +} diff --git a/crates/theme2/src/themes/synthwave_84.rs b/crates/theme2/src/themes/synthwave_84.rs deleted file mode 100644 index d7a0ef41a0228abf015c87720d244f2faa6bc433..0000000000000000000000000000000000000000 --- a/crates/theme2/src/themes/synthwave_84.rs +++ /dev/null @@ -1,248 +0,0 @@ -// This file was generated by the `theme_importer`. -// Be careful when modifying it by hand. - -use gpui::rgba; - -#[allow(unused)] -use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, -}; - -pub fn synthwave_84() -> UserThemeFamily { - UserThemeFamily { - name: "Synthwave 84".into(), - author: "Robb Owen (robb0wen)".into(), - themes: vec![UserTheme { - name: "Synthwave 84".into(), - appearance: Appearance::Dark, - styles: UserThemeStylesRefinement { - colors: ThemeColorsRefinement { - border_focused: Some(rgba(0x1f212bff).into()), - elevated_surface_background: Some(rgba(0x232530ff).into()), - background: Some(rgba(0x262335ff).into()), - element_background: Some(rgba(0x614d85ff).into()), - element_hover: Some(rgba(0x37294d99).into()), - element_selected: Some(rgba(0xffffff20).into()), - drop_target_background: Some(rgba(0x34294f66).into()), - ghost_element_hover: Some(rgba(0x37294d99).into()), - ghost_element_selected: Some(rgba(0xffffff20).into()), - text: Some(rgba(0xffffffff).into()), - status_bar_background: Some(rgba(0x241b2fff).into()), - title_bar_background: Some(rgba(0x241b2fff).into()), - toolbar_background: Some(rgba(0x262335ff).into()), - tab_bar_background: Some(rgba(0x241b2fff).into()), - tab_inactive_background: Some(rgba(0x262335ff).into()), - tab_active_background: Some(rgba(0x262335ff).into()), - scrollbar_thumb_background: Some(rgba(0x9d8bca30).into()), - scrollbar_thumb_hover_background: Some(rgba(0x9d8bca50).into()), - scrollbar_thumb_border: Some(rgba(0x9d8bca30).into()), - scrollbar_track_background: Some(rgba(0x262335ff).into()), - scrollbar_track_border: Some(rgba(0x34294fb3).into()), - editor_background: Some(rgba(0x262335ff).into()), - editor_gutter_background: Some(rgba(0x262335ff).into()), - editor_line_number: Some(rgba(0xffffff73).into()), - terminal_ansi_bright_red: Some(rgba(0xfe4450ff).into()), - terminal_ansi_bright_green: Some(rgba(0x72f1b8ff).into()), - terminal_ansi_bright_yellow: Some(rgba(0xfede5dff).into()), - terminal_ansi_bright_blue: Some(rgba(0x03edf9ff).into()), - terminal_ansi_bright_magenta: Some(rgba(0xff7edbff).into()), - terminal_ansi_bright_cyan: Some(rgba(0x03edf9ff).into()), - terminal_ansi_red: Some(rgba(0xfe4450ff).into()), - terminal_ansi_green: Some(rgba(0x72f1b8ff).into()), - terminal_ansi_yellow: Some(rgba(0xf3e70fff).into()), - terminal_ansi_blue: Some(rgba(0x03edf9ff).into()), - terminal_ansi_magenta: Some(rgba(0xff7edbff).into()), - terminal_ansi_cyan: Some(rgba(0x03edf9ff).into()), - link_text_hover: Some(rgba(0xff7edbff).into()), - ..Default::default() - }, - status: StatusColorsRefinement { - created: Some(rgba(0x206d4bd6).into()), - deleted: Some(rgba(0xfa2e46a4).into()), - error: Some(rgba(0xfe4450ff).into()), - hint: Some(rgba(0x969696ff).into()), - ignored: Some(rgba(0xffffff59).into()), - modified: Some(rgba(0xb893ce8f).into()), - warning: Some(rgba(0x72f1b8bb).into()), - ..Default::default() - }, - syntax: Some(UserSyntaxTheme { - highlights: vec![ - ( - "attribute".into(), - UserHighlightStyle { - color: Some(rgba(0xfede5dff).into()), - ..Default::default() - }, - ), - ( - "boolean".into(), - UserHighlightStyle { - color: Some(rgba(0xf97e72ff).into()), - ..Default::default() - }, - ), - ( - "comment".into(), - UserHighlightStyle { - color: Some(rgba(0x848bbdff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "comment.doc".into(), - UserHighlightStyle { - color: Some(rgba(0x848bbdff).into()), - font_style: Some(UserFontStyle::Italic), - ..Default::default() - }, - ), - ( - "constant".into(), - UserHighlightStyle { - color: Some(rgba(0xf97e72ff).into()), - ..Default::default() - }, - ), - ( - "constructor".into(), - UserHighlightStyle { - color: Some(rgba(0x72f1b8ff).into()), - ..Default::default() - }, - ), - ( - "function".into(), - UserHighlightStyle { - color: Some(rgba(0x36f9f6ff).into()), - ..Default::default() - }, - ), - ( - "keyword".into(), - UserHighlightStyle { - color: Some(rgba(0xfede5dff).into()), - ..Default::default() - }, - ), - ( - "label".into(), - UserHighlightStyle { - color: Some(rgba(0xfe4450ff).into()), - ..Default::default() - }, - ), - ( - "link_text".into(), - UserHighlightStyle { - color: Some(rgba(0xdd5500ff).into()), - ..Default::default() - }, - ), - ( - "link_uri".into(), - UserHighlightStyle { - color: Some(rgba(0xdd5500ff).into()), - ..Default::default() - }, - ), - ( - "number".into(), - UserHighlightStyle { - color: Some(rgba(0xf97e72ff).into()), - ..Default::default() - }, - ), - ( - "operator".into(), - UserHighlightStyle { - color: Some(rgba(0xfede5dff).into()), - ..Default::default() - }, - ), - ( - "property".into(), - UserHighlightStyle { - color: Some(rgba(0xff7edbff).into()), - ..Default::default() - }, - ), - ( - "punctuation".into(), - UserHighlightStyle { - color: Some(rgba(0x36f9f6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.bracket".into(), - UserHighlightStyle { - color: Some(rgba(0x36f9f6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.delimiter".into(), - UserHighlightStyle { - color: Some(rgba(0x36f9f6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.list_marker".into(), - UserHighlightStyle { - color: Some(rgba(0x36f9f6ff).into()), - ..Default::default() - }, - ), - ( - "punctuation.special".into(), - UserHighlightStyle { - color: Some(rgba(0x36f9f6ff).into()), - ..Default::default() - }, - ), - ( - "tag".into(), - UserHighlightStyle { - color: Some(rgba(0x72f1b8ff).into()), - ..Default::default() - }, - ), - ( - "title".into(), - UserHighlightStyle { - color: Some(rgba(0xfe4450ff).into()), - ..Default::default() - }, - ), - ( - "type".into(), - UserHighlightStyle { - color: Some(rgba(0xfe4450ff).into()), - ..Default::default() - }, - ), - ( - "variable".into(), - UserHighlightStyle { - color: Some(rgba(0xff7edbff).into()), - ..Default::default() - }, - ), - ( - "variable.special".into(), - UserHighlightStyle { - color: Some(rgba(0xfe4450ff).into()), - font_weight: Some(UserFontWeight(700.0)), - ..Default::default() - }, - ), - ], - }), - }, - }], - } -} diff --git a/crates/theme_importer/src/main.rs b/crates/theme_importer/src/main.rs index e6cf8952d15671875106252c1845bf1138142431..4072a59df8d6f4a8816dd769e795b0931788fea3 100644 --- a/crates/theme_importer/src/main.rs +++ b/crates/theme_importer/src/main.rs @@ -73,10 +73,6 @@ pub struct ThemeMetadata { #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Args { - /// Whether to import Zed1 themes. - #[arg(long)] - zed1: bool, - /// Whether to warn when values are missing from the theme. #[arg(long)] warn_on_missing: bool, @@ -106,181 +102,185 @@ fn main() -> Result<()> { TermLogger::init(LevelFilter::Trace, log_config, TerminalMode::Mixed) .expect("could not initialize logger"); - log::info!("Loading themes source..."); - let vscode_themes_path = PathBuf::from_str(SOURCE_PATH)?; - if !vscode_themes_path.exists() { - return Err(anyhow!(format!( - "Couldn't find {}, make sure it exists", - SOURCE_PATH - ))); - } - let mut theme_families = Vec::new(); - for theme_family_dir in fs::read_dir(&vscode_themes_path)? { - let theme_family_dir = theme_family_dir?; - - if !theme_family_dir.file_type()?.is_dir() { - continue; + /// Whether VS Code themes should be imported. + /// + /// For the initial release of Zed2, we will just be using the Zed1 themes ported to Zed2. + const IMPORT_VS_CODE_THEMES: bool = false; + + if IMPORT_VS_CODE_THEMES { + log::info!("Loading themes source..."); + let vscode_themes_path = PathBuf::from_str(SOURCE_PATH)?; + if !vscode_themes_path.exists() { + return Err(anyhow!(format!( + "Couldn't find {}, make sure it exists", + SOURCE_PATH + ))); } - let theme_family_slug = theme_family_dir - .path() - .file_stem() - .ok_or(anyhow!("no file stem")) - .map(|stem| stem.to_string_lossy().to_string())?; + for theme_family_dir in fs::read_dir(&vscode_themes_path)? { + let theme_family_dir = theme_family_dir?; - let family_metadata_file = File::open(theme_family_dir.path().join("family.json")) - .context(format!( - "no `family.json` found for '{}'", - theme_family_slug - ))?; + if !theme_family_dir.file_type()?.is_dir() { + continue; + } - let license_file_path = theme_family_dir.path().join("LICENSE"); + let theme_family_slug = theme_family_dir + .path() + .file_stem() + .ok_or(anyhow!("no file stem")) + .map(|stem| stem.to_string_lossy().to_string())?; - if !license_file_path.exists() { - log::info!("Skipping theme family '{}' because it does not have a LICENSE file. This theme will only be imported once a LICENSE file is provided.", theme_family_slug); - continue; - } + let family_metadata_file = File::open(theme_family_dir.path().join("family.json")) + .context(format!( + "no `family.json` found for '{}'", + theme_family_slug + ))?; - let family_metadata: FamilyMetadata = serde_json::from_reader(family_metadata_file) - .context(format!( - "failed to parse `family.json` for '{theme_family_slug}'" - ))?; + let license_file_path = theme_family_dir.path().join("LICENSE"); - let mut themes = Vec::new(); + if !license_file_path.exists() { + log::info!("Skipping theme family '{}' because it does not have a LICENSE file. This theme will only be imported once a LICENSE file is provided.", theme_family_slug); + continue; + } - for theme_metadata in family_metadata.themes { - log::info!("Converting '{}' theme", &theme_metadata.name); + let family_metadata: FamilyMetadata = serde_json::from_reader(family_metadata_file) + .context(format!( + "failed to parse `family.json` for '{theme_family_slug}'" + ))?; - let theme_file_path = theme_family_dir.path().join(&theme_metadata.file_name); + let mut themes = Vec::new(); - let theme_file = match File::open(&theme_file_path) { - Ok(file) => file, - Err(_) => { - log::info!("Failed to open file at path: {:?}", theme_file_path); - continue; - } - }; + for theme_metadata in family_metadata.themes { + log::info!("Converting '{}' theme", &theme_metadata.name); - let theme_without_comments = StripComments::new(theme_file); - let vscode_theme: VsCodeTheme = serde_json::from_reader(theme_without_comments) - .context(format!("failed to parse theme {theme_file_path:?}"))?; + let theme_file_path = theme_family_dir.path().join(&theme_metadata.file_name); - let converter = VsCodeThemeConverter::new( - vscode_theme, - theme_metadata, - family_metadata.syntax.clone(), - ); + let theme_file = match File::open(&theme_file_path) { + Ok(file) => file, + Err(_) => { + log::info!("Failed to open file at path: {:?}", theme_file_path); + continue; + } + }; - let theme = converter.convert()?; + let theme_without_comments = StripComments::new(theme_file); + let vscode_theme: VsCodeTheme = serde_json::from_reader(theme_without_comments) + .context(format!("failed to parse theme {theme_file_path:?}"))?; - themes.push(theme); - } + let converter = VsCodeThemeConverter::new( + vscode_theme, + theme_metadata, + family_metadata.syntax.clone(), + ); - let theme_family = UserThemeFamily { - name: family_metadata.name.into(), - author: family_metadata.author.into(), - themes, - }; + let theme = converter.convert()?; - theme_families.push(theme_family); + themes.push(theme); + } + + let theme_family = UserThemeFamily { + name: family_metadata.name.into(), + author: family_metadata.author.into(), + themes, + }; + + theme_families.push(theme_family); + } } - if args.zed1 { - let zed1_themes_path = PathBuf::from_str("assets/themes")?; - - let zed1_theme_familes = [ - "Andromeda", - "Atelier", - "Ayu", - "Gruvbox", - "One", - "Rosé Pine", - "Sandcastle", - "Solarized", - "Summercamp", - ]; - - let mut zed1_themes_by_family: HashMap> = HashMap::from_iter( - zed1_theme_familes - .into_iter() - .map(|family| (family.to_string(), Vec::new())), - ); + let zed1_themes_path = PathBuf::from_str("assets/themes")?; + + let zed1_theme_familes = [ + "Andromeda", + "Atelier", + "Ayu", + "Gruvbox", + "One", + "Rosé Pine", + "Sandcastle", + "Solarized", + "Summercamp", + ]; + + let mut zed1_themes_by_family: HashMap> = HashMap::from_iter( + zed1_theme_familes + .into_iter() + .map(|family| (family.to_string(), Vec::new())), + ); - let platform = gpui1::platform::current::platform(); - let zed1_font_cache = Arc::new(gpui1::FontCache::new(platform.fonts())); + let platform = gpui1::platform::current::platform(); + let zed1_font_cache = Arc::new(gpui1::FontCache::new(platform.fonts())); - let mut embedded_fonts = Vec::new(); - for font_path in Assets.list("fonts")? { - if font_path.ends_with(".ttf") { - let font_bytes = Assets.load(&font_path)?.to_vec(); - embedded_fonts.push(Arc::from(font_bytes)); - } + let mut embedded_fonts = Vec::new(); + for font_path in Assets.list("fonts")? { + if font_path.ends_with(".ttf") { + let font_bytes = Assets.load(&font_path)?.to_vec(); + embedded_fonts.push(Arc::from(font_bytes)); } + } - platform.fonts().add_fonts(&embedded_fonts)?; + platform.fonts().add_fonts(&embedded_fonts)?; - for entry in fs::read_dir(&zed1_themes_path)? { - let entry = entry?; + for entry in fs::read_dir(&zed1_themes_path)? { + let entry = entry?; - if entry.file_type()?.is_dir() { - continue; - } + if entry.file_type()?.is_dir() { + continue; + } - match entry.path().extension() { - None => continue, - Some(extension) => { - if extension != "json" { - continue; - } + match entry.path().extension() { + None => continue, + Some(extension) => { + if extension != "json" { + continue; } } + } - let theme_file_path = entry.path(); + let theme_file_path = entry.path(); - let theme_file = match File::open(&theme_file_path) { - Ok(file) => file, - Err(_) => { - log::info!("Failed to open file at path: {:?}", theme_file_path); - continue; - } - }; + let theme_file = match File::open(&theme_file_path) { + Ok(file) => file, + Err(_) => { + log::info!("Failed to open file at path: {:?}", theme_file_path); + continue; + } + }; - let theme_without_comments = StripComments::new(theme_file); + let theme_without_comments = StripComments::new(theme_file); - let zed1_theme: Zed1Theme = - gpui1::fonts::with_font_cache(zed1_font_cache.clone(), || { - serde_json::from_reader(theme_without_comments) - .context(format!("failed to parse theme {theme_file_path:?}")) - })?; + let zed1_theme: Zed1Theme = gpui1::fonts::with_font_cache(zed1_font_cache.clone(), || { + serde_json::from_reader(theme_without_comments) + .context(format!("failed to parse theme {theme_file_path:?}")) + })?; - let theme_name = zed1_theme.meta.name.clone(); + let theme_name = zed1_theme.meta.name.clone(); - let converter = Zed1ThemeConverter::new(zed1_theme); + let converter = Zed1ThemeConverter::new(zed1_theme); - let theme = converter.convert()?; + let theme = converter.convert()?; - let Some((_, themes_for_family)) = zed1_themes_by_family - .iter_mut() - .find(|(family, _)| theme_name.starts_with(*family)) - else { - log::warn!("No theme family found for '{}'.", theme_name); - continue; - }; + let Some((_, themes_for_family)) = zed1_themes_by_family + .iter_mut() + .find(|(family, _)| theme_name.starts_with(*family)) + else { + log::warn!("No theme family found for '{}'.", theme_name); + continue; + }; - themes_for_family.push(theme); - } + themes_for_family.push(theme); + } - for (family, themes) in zed1_themes_by_family { - let theme_family = UserThemeFamily { - name: format!("{family} (Zed1)"), - author: "Zed Industries".to_string(), - themes, - }; + for (family, themes) in zed1_themes_by_family { + let theme_family = UserThemeFamily { + name: family, + author: "Zed Industries".to_string(), + themes, + }; - theme_families.push(theme_family); - } + theme_families.push(theme_family); } let themes_output_path = PathBuf::from_str(OUT_PATH)?; diff --git a/crates/theme_importer/src/theme_printer.rs b/crates/theme_importer/src/theme_printer.rs index eb304ff90d406be5d8d1d4e66c3782376908a10c..2116b5b6704814fedfd65faa5da72d2963c9cb62 100644 --- a/crates/theme_importer/src/theme_printer.rs +++ b/crates/theme_importer/src/theme_printer.rs @@ -160,6 +160,7 @@ impl<'a> Debug for ThemeColorsRefinementPrinter<'a> { ), ("surface_background", self.0.surface_background), ("background", self.0.background), + ("panel_background", self.0.panel_background), ("element_background", self.0.element_background), ("element_hover", self.0.element_hover), ("element_active", self.0.element_active), diff --git a/crates/theme_importer/src/zed1/converter.rs b/crates/theme_importer/src/zed1/converter.rs index 1a5f7af8b7020f59f292f561c9912af095e364be..0b932c83fb2a4f0d0cebe05a14ac0ad1065a8ad2 100644 --- a/crates/theme_importer/src/zed1/converter.rs +++ b/crates/theme_importer/src/zed1/converter.rs @@ -53,7 +53,7 @@ impl Zed1ThemeConverter { let syntax_theme = self.convert_syntax_theme()?; Ok(UserTheme { - name: format!("{} (Zed1)", self.theme.meta.name), + name: self.theme.meta.name, appearance, styles: UserThemeStylesRefinement { colors: theme_colors_refinement, @@ -68,12 +68,16 @@ impl Zed1ThemeConverter { Some(zed1_color_to_hsla(color)) } - let diff_style = self.theme.editor.diff.clone(); + let diff_style = &self.theme.editor.diff; + let diagnostic_summary = &self.theme.workspace.status_bar.diagnostic_summary; Ok(StatusColorsRefinement { created: convert(diff_style.inserted), modified: convert(diff_style.modified), deleted: convert(diff_style.deleted), + success: convert(diagnostic_summary.icon_color_ok), + warning: convert(diagnostic_summary.icon_color_warning), + error: convert(diagnostic_summary.icon_color_error), ..Default::default() }) } @@ -83,11 +87,11 @@ impl Zed1ThemeConverter { Some(zed1_color_to_hsla(color)) } - let tab_bar = self.theme.workspace.tab_bar.clone(); - let active_tab = self.theme.workspace.tab_bar.tab_style(true, true).clone(); - let inactive_tab = self.theme.workspace.tab_bar.tab_style(true, false).clone(); - let toolbar = self.theme.workspace.toolbar.clone(); - let scrollbar = self.theme.editor.scrollbar.clone(); + let tab_bar = &self.theme.workspace.tab_bar; + let active_tab = &self.theme.workspace.tab_bar.tab_style(true, true); + let inactive_tab = &self.theme.workspace.tab_bar.tab_style(true, false); + let toolbar = &self.theme.workspace.toolbar; + let scrollbar = &self.theme.editor.scrollbar; let zed1_titlebar_border = convert(self.theme.titlebar.container.border.color); @@ -95,6 +99,12 @@ impl Zed1ThemeConverter { border: zed1_titlebar_border, border_variant: zed1_titlebar_border, background: convert(self.theme.workspace.background), + elevated_surface_background: self + .theme + .picker + .container + .background_color + .map(zed1_color_to_hsla), title_bar_background: self .theme .titlebar @@ -107,8 +117,38 @@ impl Zed1ThemeConverter { .status_bar .container .background_color + .map(zed1_color_to_hsla) + .or_else(|| { + self.theme + .titlebar + .container + .background_color + .map(zed1_color_to_hsla) + }), + panel_background: self + .theme + .project_panel + .container + .background_color + .map(zed1_color_to_hsla), + text: convert(self.theme.project_panel.entry.default_style().text.color), + text_muted: convert(active_tab.description.text.color), + element_hover: self + .theme + .picker + .item + .hovered + .as_ref() + .and_then(|hovered| hovered.container.background_color) + .map(zed1_color_to_hsla), + element_selected: self + .theme + .picker + .item + .active_state() + .container + .background_color .map(zed1_color_to_hsla), - text: convert(self.theme.editor.text_color), tab_bar_background: tab_bar.container.background_color.map(zed1_color_to_hsla), tab_active_background: active_tab .container diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 9c7ffc6e89d655bae71aeda049ff8034ac506492..fbc8a1f8789460531d743def92ff40844f87f088 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -537,6 +537,7 @@ impl Render for Dock { div() .flex() + .bg(cx.theme().colors().panel_background) .border_color(cx.theme().colors().border) .overflow_hidden() .map(|this| match self.position().axis() { From 9600337d8154ad733ffc052deb9537c1d1e4a6ff Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 23 Dec 2023 01:27:41 +0200 Subject: [PATCH 302/644] Properly color file labels in project panel --- crates/project_panel2/src/project_panel.rs | 13 +++++-------- crates/ui2/src/styles/color.rs | 2 ++ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index 1259fc1d612d3e4c3f8f7cfbba0ca4b5c400d257..2966c55f79b84ddbad7dcea046541f795bc0a18b 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -1364,16 +1364,15 @@ impl ProjectPanel { .map_or(false, |selection| selection.entry_id == entry_id); let width = self.width.unwrap_or(px(0.)); - let theme = cx.theme(); let filename_text_color = details .git_status .as_ref() .map(|status| match status { - GitFileStatus::Added => theme.status().created, - GitFileStatus::Modified => theme.status().modified, - GitFileStatus::Conflict => theme.status().conflict, + GitFileStatus::Added => Color::Created, + GitFileStatus::Modified => Color::Modified, + GitFileStatus::Conflict => Color::Conflict, }) - .unwrap_or(theme.status().info); + .unwrap_or(Color::Default); let file_name = details.filename.clone(); let icon = details.icon.clone(); @@ -1407,9 +1406,7 @@ impl ProjectPanel { if let (Some(editor), true) = (Some(&self.filename_editor), show_editor) { div().h_full().w_full().child(editor.clone()) } else { - div() - .text_color(filename_text_color) - .child(Label::new(file_name)) + div().child(Label::new(file_name).color(filename_text_color)) } .ml_1(), ) diff --git a/crates/ui2/src/styles/color.rs b/crates/ui2/src/styles/color.rs index 0769558acb705415d4d00fc11cae22cb0edf7a9c..977a26dedce61d20bb27ee6b65bcc9f3f8738096 100644 --- a/crates/ui2/src/styles/color.rs +++ b/crates/ui2/src/styles/color.rs @@ -13,6 +13,7 @@ pub enum Color { Hidden, Info, Modified, + Conflict, Muted, Placeholder, Player(u32), @@ -28,6 +29,7 @@ impl Color { Color::Muted => cx.theme().colors().text_muted, Color::Created => cx.theme().status().created, Color::Modified => cx.theme().status().modified, + Color::Conflict => cx.theme().status().conflict, Color::Deleted => cx.theme().status().deleted, Color::Disabled => cx.theme().colors().text_disabled, Color::Hidden => cx.theme().status().hidden, From 1ebfafc03d97b2b18da9e2c2105a289ed50b93f9 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 18:45:58 -0500 Subject: [PATCH 303/644] Map additional text colors from Zed1 themes (#3796) This PR maps additional text colors from the Zed1 themes to the Zed2 themes. Release Notes: - N/A --- crates/editor2/src/element.rs | 2 +- crates/theme2/src/themes/andromeda.rs | 3 + crates/theme2/src/themes/atelier.rs | 60 +++++++++++ crates/theme2/src/themes/ayu.rs | 9 ++ crates/theme2/src/themes/gruvbox.rs | 18 ++++ crates/theme2/src/themes/one.rs | 6 ++ crates/theme2/src/themes/rose_pine.rs | 9 ++ crates/theme2/src/themes/sandcastle.rs | 3 + crates/theme2/src/themes/solarized.rs | 6 ++ crates/theme2/src/themes/summercamp.rs | 3 + crates/theme_importer/src/zed1/converter.rs | 107 +++++++++----------- 11 files changed, 166 insertions(+), 60 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 9e1d8e641f0964319e123476fa608484ce6320ea..c897c0c2db6ec26e784fa6b7b23d3dd8f6c8b698 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -1724,7 +1724,7 @@ impl EditorElement { // Show the placeholder when the editor is empty if snapshot.is_empty() { let font_size = self.style.text.font_size.to_pixels(cx.rem_size()); - let placeholder_color = cx.theme().styles.colors.text_placeholder; + let placeholder_color = cx.theme().colors().text_placeholder; let placeholder_text = snapshot.placeholder_text(); let placeholder_lines = placeholder_text diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index 5affa63fb09d866ba2e92be3ad326016c0448495..699abec4912a3b78333ac9f9988d0c8e19af2865 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -27,6 +27,9 @@ pub fn andromeda() -> UserThemeFamily { element_selected: Some(rgba(0x383b4580).into()), text: Some(rgba(0xaca8aeff).into()), text_muted: Some(rgba(0x474a53ff).into()), + text_placeholder: Some(rgba(0x474a53ff).into()), + text_disabled: Some(rgba(0xf7f7f8ff).into()), + text_accent: Some(rgba(0x11a793ff).into()), status_bar_background: Some(rgba(0x262a33ff).into()), title_bar_background: Some(rgba(0x262a33ff).into()), toolbar_background: Some(rgba(0x1e2025ff).into()), diff --git a/crates/theme2/src/themes/atelier.rs b/crates/theme2/src/themes/atelier.rs index f1ec02cb75764e7f85763ecfeae4aaf35fa553db..1722521b032cf3b963c89fcc0c9713579fa826ae 100644 --- a/crates/theme2/src/themes/atelier.rs +++ b/crates/theme2/src/themes/atelier.rs @@ -28,6 +28,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x8b8a7880).into()), text: Some(rgba(0x61604fff).into()), text_muted: Some(rgba(0x878573ff).into()), + text_placeholder: Some(rgba(0x878573ff).into()), + text_disabled: Some(rgba(0x22221bff).into()), + text_accent: Some(rgba(0x38a166ff).into()), status_bar_background: Some(rgba(0xc5c4b9ff).into()), title_bar_background: Some(rgba(0xc5c4b9ff).into()), toolbar_background: Some(rgba(0xf4f3ecff).into()), @@ -385,6 +388,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x71696680).into()), text: Some(rgba(0xa79f9dff).into()), text_muted: Some(rgba(0x766e6bff).into()), + text_placeholder: Some(rgba(0x766e6bff).into()), + text_disabled: Some(rgba(0xf1efeeff).into()), + text_accent: Some(rgba(0x417ee6ff).into()), status_bar_background: Some(rgba(0x443c39ff).into()), title_bar_background: Some(rgba(0x443c39ff).into()), toolbar_background: Some(rgba(0x1b1918ff).into()), @@ -742,6 +748,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x7e8b8280).into()), text: Some(rgba(0x546259ff).into()), text_muted: Some(rgba(0x79877dff).into()), + text_placeholder: Some(rgba(0x79877dff).into()), + text_disabled: Some(rgba(0x171c19ff).into()), + text_accent: Some(rgba(0x488c90ff).into()), status_bar_background: Some(rgba(0xbcc5bfff).into()), title_bar_background: Some(rgba(0xbcc5bfff).into()), toolbar_background: Some(rgba(0xecf4eeff).into()), @@ -1099,6 +1108,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x605a6880).into()), text: Some(rgba(0x898591ff).into()), text_muted: Some(rgba(0x655f6dff).into()), + text_placeholder: Some(rgba(0x655f6dff).into()), + text_disabled: Some(rgba(0xefecf4ff).into()), + text_accent: Some(rgba(0x576ddaff).into()), status_bar_background: Some(rgba(0x3a353fff).into()), title_bar_background: Some(rgba(0x3a353fff).into()), toolbar_background: Some(rgba(0x19171cff).into()), @@ -1456,6 +1468,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x67665580).into()), text: Some(rgba(0x91907fff).into()), text_muted: Some(rgba(0x6c6b5aff).into()), + text_placeholder: Some(rgba(0x6c6b5aff).into()), + text_disabled: Some(rgba(0xf4f3ecff).into()), + text_accent: Some(rgba(0x37a166ff).into()), status_bar_background: Some(rgba(0x424136ff).into()), title_bar_background: Some(rgba(0x424136ff).into()), toolbar_background: Some(rgba(0x22221bff).into()), @@ -1813,6 +1828,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x666e8f80).into()), text: Some(rgba(0x959bb2ff).into()), text_muted: Some(rgba(0x6b7394ff).into()), + text_placeholder: Some(rgba(0x6b7394ff).into()), + text_disabled: Some(rgba(0xf5f7ffff).into()), + text_accent: Some(rgba(0x3e8fd0ff).into()), status_bar_background: Some(rgba(0x3e4769ff).into()), title_bar_background: Some(rgba(0x3e4769ff).into()), toolbar_background: Some(rgba(0x202746ff).into()), @@ -2170,6 +2188,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x8e94aa80).into()), text: Some(rgba(0x606889ff).into()), text_muted: Some(rgba(0x898fa5ff).into()), + text_placeholder: Some(rgba(0x898fa5ff).into()), + text_disabled: Some(rgba(0x202746ff).into()), + text_accent: Some(rgba(0x3f8fd0ff).into()), status_bar_background: Some(rgba(0xc2c6d9ff).into()), title_bar_background: Some(rgba(0xc2c6d9ff).into()), toolbar_background: Some(rgba(0xf5f7ffff).into()), @@ -2527,6 +2548,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x77746480).into()), text: Some(rgba(0xa4a08bff).into()), text_muted: Some(rgba(0x7c7968ff).into()), + text_placeholder: Some(rgba(0x7c7968ff).into()), + text_disabled: Some(rgba(0xfefbecff).into()), + text_accent: Some(rgba(0x6684e0ff).into()), status_bar_background: Some(rgba(0x45433bff).into()), title_bar_background: Some(rgba(0x45433bff).into()), toolbar_background: Some(rgba(0x20201dff).into()), @@ -2884,6 +2908,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x64776480).into()), text: Some(rgba(0x8ba48bff).into()), text_muted: Some(rgba(0x687c68ff).into()), + text_placeholder: Some(rgba(0x687c68ff).into()), + text_disabled: Some(rgba(0xf4fbf4ff).into()), + text_accent: Some(rgba(0x3e62f4ff).into()), status_bar_background: Some(rgba(0x3b453bff).into()), title_bar_background: Some(rgba(0x3b453bff).into()), toolbar_background: Some(rgba(0x131513ff).into()), @@ -3241,6 +3268,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x837e8b80).into()), text: Some(rgba(0x5a5462ff).into()), text_muted: Some(rgba(0x7e7987ff).into()), + text_placeholder: Some(rgba(0x7e7987ff).into()), + text_disabled: Some(rgba(0x19171cff).into()), + text_accent: Some(rgba(0x586ddaff).into()), status_bar_background: Some(rgba(0xbfbcc5ff).into()), title_bar_background: Some(rgba(0xbfbcc5ff).into()), toolbar_background: Some(rgba(0xefecf4ff).into()), @@ -3598,6 +3628,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x60585880).into()), text: Some(rgba(0x898383ff).into()), text_muted: Some(rgba(0x655d5dff).into()), + text_placeholder: Some(rgba(0x655d5dff).into()), + text_disabled: Some(rgba(0xf4ececff).into()), + text_accent: Some(rgba(0x7272caff).into()), status_bar_background: Some(rgba(0x3b3535ff).into()), title_bar_background: Some(rgba(0x3b3535ff).into()), toolbar_background: Some(rgba(0x1b1818ff).into()), @@ -3955,6 +3988,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x72647280).into()), text: Some(rgba(0xa99aa9ff).into()), text_muted: Some(rgba(0x776977ff).into()), + text_placeholder: Some(rgba(0x776977ff).into()), + text_disabled: Some(rgba(0xf7f3f7ff).into()), + text_accent: Some(rgba(0x526aebff).into()), status_bar_background: Some(rgba(0x433a43ff).into()), title_bar_background: Some(rgba(0x433a43ff).into()), toolbar_background: Some(rgba(0x1b181bff).into()), @@ -4312,6 +4348,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x57768580).into()), text: Some(rgba(0x7ca0b3ff).into()), text_muted: Some(rgba(0x5a7b8bff).into()), + text_placeholder: Some(rgba(0x5a7b8bff).into()), + text_disabled: Some(rgba(0xebf8ffff).into()), + text_accent: Some(rgba(0x277fadff).into()), status_bar_background: Some(rgba(0x33444dff).into()), title_bar_background: Some(rgba(0x33444dff).into()), toolbar_background: Some(rgba(0x161b1dff).into()), @@ -4669,6 +4708,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0xa1999680).into()), text: Some(rgba(0x6a6360ff).into()), text_muted: Some(rgba(0x9c9491ff).into()), + text_placeholder: Some(rgba(0x9c9491ff).into()), + text_disabled: Some(rgba(0x1b1918ff).into()), + text_accent: Some(rgba(0x417ee6ff).into()), status_bar_background: Some(rgba(0xcdc8c6ff).into()), title_bar_background: Some(rgba(0xcdc8c6ff).into()), toolbar_background: Some(rgba(0xf1efeeff).into()), @@ -5026,6 +5068,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x9e9a8580).into()), text: Some(rgba(0x706d5fff).into()), text_muted: Some(rgba(0x999580ff).into()), + text_placeholder: Some(rgba(0x999580ff).into()), + text_disabled: Some(rgba(0x20201dff).into()), + text_accent: Some(rgba(0x6784e0ff).into()), status_bar_background: Some(rgba(0xcecab4ff).into()), title_bar_background: Some(rgba(0xcecab4ff).into()), toolbar_background: Some(rgba(0xfefbecff).into()), @@ -5383,6 +5428,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x837c7c80).into()), text: Some(rgba(0x5a5252ff).into()), text_muted: Some(rgba(0x7e7777ff).into()), + text_placeholder: Some(rgba(0x7e7777ff).into()), + text_disabled: Some(rgba(0x1b1818ff).into()), + text_accent: Some(rgba(0x7372caff).into()), status_bar_background: Some(rgba(0xc1bbbbff).into()), title_bar_background: Some(rgba(0xc1bbbbff).into()), toolbar_background: Some(rgba(0xf4ececff).into()), @@ -5740,6 +5788,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x859e8580).into()), text: Some(rgba(0x5f705fff).into()), text_muted: Some(rgba(0x809980ff).into()), + text_placeholder: Some(rgba(0x809980ff).into()), + text_disabled: Some(rgba(0x131513ff).into()), + text_accent: Some(rgba(0x3f62f4ff).into()), status_bar_background: Some(rgba(0xb4ceb4ff).into()), title_bar_background: Some(rgba(0xb4ceb4ff).into()), toolbar_background: Some(rgba(0xf4fbf4ff).into()), @@ -6097,6 +6148,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x5a685f80).into()), text: Some(rgba(0x859188ff).into()), text_muted: Some(rgba(0x5f6d64ff).into()), + text_placeholder: Some(rgba(0x5f6d64ff).into()), + text_disabled: Some(rgba(0xecf4eeff).into()), + text_accent: Some(rgba(0x478c90ff).into()), status_bar_background: Some(rgba(0x353f39ff).into()), title_bar_background: Some(rgba(0x353f39ff).into()), toolbar_background: Some(rgba(0x171c19ff).into()), @@ -6454,6 +6508,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0xa394a380).into()), text: Some(rgba(0x6b5e6bff).into()), text_muted: Some(rgba(0x9e8f9eff).into()), + text_placeholder: Some(rgba(0x9e8f9eff).into()), + text_disabled: Some(rgba(0x1b181bff).into()), + text_accent: Some(rgba(0x526aebff).into()), status_bar_background: Some(rgba(0xc6b8c6ff).into()), title_bar_background: Some(rgba(0xc6b8c6ff).into()), toolbar_background: Some(rgba(0xf7f3f7ff).into()), @@ -6811,6 +6868,9 @@ pub fn atelier() -> UserThemeFamily { element_selected: Some(rgba(0x769aad80).into()), text: Some(rgba(0x526f7dff).into()), text_muted: Some(rgba(0x7195a8ff).into()), + text_placeholder: Some(rgba(0x7195a8ff).into()), + text_disabled: Some(rgba(0x161b1dff).into()), + text_accent: Some(rgba(0x277fadff).into()), status_bar_background: Some(rgba(0xa6cadcff).into()), title_bar_background: Some(rgba(0xa6cadcff).into()), toolbar_background: Some(rgba(0xebf8ffff).into()), diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index 4bd39894db4de57dce964279bac09d577bcdd256..eb6ac40bcedbb192fbc2f67efb54415692dcad4c 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -28,6 +28,9 @@ pub fn ayu() -> UserThemeFamily { element_selected: Some(rgba(0x50515280).into()), text: Some(rgba(0x8a8986ff).into()), text_muted: Some(rgba(0x58595aff).into()), + text_placeholder: Some(rgba(0x58595aff).into()), + text_disabled: Some(rgba(0xbfbdb6ff).into()), + text_accent: Some(rgba(0x5ac2feff).into()), status_bar_background: Some(rgba(0x313337ff).into()), title_bar_background: Some(rgba(0x313337ff).into()), toolbar_background: Some(rgba(0x0d1017ff).into()), @@ -364,6 +367,9 @@ pub fn ayu() -> UserThemeFamily { element_selected: Some(rgba(0xc0c2c480).into()), text: Some(rgba(0x8c8f93ff).into()), text_muted: Some(rgba(0xb9bbbdff).into()), + text_placeholder: Some(rgba(0xb9bbbdff).into()), + text_disabled: Some(rgba(0x5c6166ff).into()), + text_accent: Some(rgba(0x3b9ee5ff).into()), status_bar_background: Some(rgba(0xdcdddeff).into()), title_bar_background: Some(rgba(0xdcdddeff).into()), toolbar_background: Some(rgba(0xfcfcfcff).into()), @@ -700,6 +706,9 @@ pub fn ayu() -> UserThemeFamily { element_selected: Some(rgba(0x63656a80).into()), text: Some(rgba(0x9a9a98ff).into()), text_muted: Some(rgba(0x6b6d71ff).into()), + text_placeholder: Some(rgba(0x6b6d71ff).into()), + text_disabled: Some(rgba(0xcccac2ff).into()), + text_accent: Some(rgba(0x73cffeff).into()), status_bar_background: Some(rgba(0x464a52ff).into()), title_bar_background: Some(rgba(0x464a52ff).into()), toolbar_background: Some(rgba(0x242936ff).into()), diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index e0b2e44101ee13976e95a8d7b2ca9043ca39bc64..2dcf717c47561b05d88a60045379f32c481227d1 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -28,6 +28,9 @@ pub fn gruvbox() -> UserThemeFamily { element_selected: Some(rgba(0xb5a68e80).into()), text: Some(rgba(0x5f5650ff).into()), text_muted: Some(rgba(0xad9e87ff).into()), + text_placeholder: Some(rgba(0xad9e87ff).into()), + text_disabled: Some(rgba(0x282828ff).into()), + text_accent: Some(rgba(0x0b6678ff).into()), status_bar_background: Some(rgba(0xd9c8a4ff).into()), title_bar_background: Some(rgba(0xd9c8a4ff).into()), toolbar_background: Some(rgba(0xf9f5d7ff).into()), @@ -371,6 +374,9 @@ pub fn gruvbox() -> UserThemeFamily { element_selected: Some(rgba(0x6e635a80).into()), text: Some(rgba(0xc5b597ff).into()), text_muted: Some(rgba(0x776b61ff).into()), + text_placeholder: Some(rgba(0x776b61ff).into()), + text_disabled: Some(rgba(0xfbf1c7ff).into()), + text_accent: Some(rgba(0x83a598ff).into()), status_bar_background: Some(rgba(0x4c4642ff).into()), title_bar_background: Some(rgba(0x4c4642ff).into()), toolbar_background: Some(rgba(0x32302fff).into()), @@ -714,6 +720,9 @@ pub fn gruvbox() -> UserThemeFamily { element_selected: Some(rgba(0xb5a68e80).into()), text: Some(rgba(0x5f5650ff).into()), text_muted: Some(rgba(0xad9e87ff).into()), + text_placeholder: Some(rgba(0xad9e87ff).into()), + text_disabled: Some(rgba(0x282828ff).into()), + text_accent: Some(rgba(0x0b6678ff).into()), status_bar_background: Some(rgba(0xd9c8a4ff).into()), title_bar_background: Some(rgba(0xd9c8a4ff).into()), toolbar_background: Some(rgba(0xfbf1c7ff).into()), @@ -1057,6 +1066,9 @@ pub fn gruvbox() -> UserThemeFamily { element_selected: Some(rgba(0x6e635a80).into()), text: Some(rgba(0xc5b597ff).into()), text_muted: Some(rgba(0x776b61ff).into()), + text_placeholder: Some(rgba(0x776b61ff).into()), + text_disabled: Some(rgba(0xfbf1c7ff).into()), + text_accent: Some(rgba(0x83a598ff).into()), status_bar_background: Some(rgba(0x4c4642ff).into()), title_bar_background: Some(rgba(0x4c4642ff).into()), toolbar_background: Some(rgba(0x282828ff).into()), @@ -1400,6 +1412,9 @@ pub fn gruvbox() -> UserThemeFamily { element_selected: Some(rgba(0xb5a68e80).into()), text: Some(rgba(0x5f5650ff).into()), text_muted: Some(rgba(0xad9e87ff).into()), + text_placeholder: Some(rgba(0xad9e87ff).into()), + text_disabled: Some(rgba(0x282828ff).into()), + text_accent: Some(rgba(0x0b6678ff).into()), status_bar_background: Some(rgba(0xd9c8a4ff).into()), title_bar_background: Some(rgba(0xd9c8a4ff).into()), toolbar_background: Some(rgba(0xf2e5bcff).into()), @@ -1743,6 +1758,9 @@ pub fn gruvbox() -> UserThemeFamily { element_selected: Some(rgba(0x6e635a80).into()), text: Some(rgba(0xc5b597ff).into()), text_muted: Some(rgba(0x776b61ff).into()), + text_placeholder: Some(rgba(0x776b61ff).into()), + text_disabled: Some(rgba(0xfbf1c7ff).into()), + text_accent: Some(rgba(0x83a598ff).into()), status_bar_background: Some(rgba(0x4c4642ff).into()), title_bar_background: Some(rgba(0x4c4642ff).into()), toolbar_background: Some(rgba(0x1d2021ff).into()), diff --git a/crates/theme2/src/themes/one.rs b/crates/theme2/src/themes/one.rs index 089e3b3bcda383f276cd318dc495f0d7433cc05c..3a20146be1b19c37562a08b49fb63a65102f93db 100644 --- a/crates/theme2/src/themes/one.rs +++ b/crates/theme2/src/themes/one.rs @@ -28,6 +28,9 @@ pub fn one() -> UserThemeFamily { element_selected: Some(rgba(0xafafaf80).into()), text: Some(rgba(0x7f8188ff).into()), text_muted: Some(rgba(0xa7a7a8ff).into()), + text_placeholder: Some(rgba(0xa7a7a8ff).into()), + text_disabled: Some(rgba(0x383a41ff).into()), + text_accent: Some(rgba(0x5c79e2ff).into()), status_bar_background: Some(rgba(0xdcdcddff).into()), title_bar_background: Some(rgba(0xdcdcddff).into()), toolbar_background: Some(rgba(0xfafafaff).into()), @@ -371,6 +374,9 @@ pub fn one() -> UserThemeFamily { element_selected: Some(rgba(0x4f545e80).into()), text: Some(rgba(0x838994ff).into()), text_muted: Some(rgba(0x545862ff).into()), + text_placeholder: Some(rgba(0x545862ff).into()), + text_disabled: Some(rgba(0xc8ccd4ff).into()), + text_accent: Some(rgba(0x74ade8ff).into()), status_bar_background: Some(rgba(0x3b414dff).into()), title_bar_background: Some(rgba(0x3b414dff).into()), toolbar_background: Some(rgba(0x282c34ff).into()), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index abefb32f4e338baa5b369f3ecdf73b21429c9365..1dcf523a74304f6555aa38d55a8e97c0e894255b 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -28,6 +28,9 @@ pub fn rose_pine() -> UserThemeFamily { element_selected: Some(rgba(0xc1bac180).into()), text: Some(rgba(0x706c8cff).into()), text_muted: Some(rgba(0xb1abb5ff).into()), + text_placeholder: Some(rgba(0xb1abb5ff).into()), + text_disabled: Some(rgba(0x575279ff).into()), + text_accent: Some(rgba(0x57949fff).into()), status_bar_background: Some(rgba(0xdcd8d8ff).into()), title_bar_background: Some(rgba(0xdcd8d8ff).into()), toolbar_background: Some(rgba(0xfaf4edff).into()), @@ -378,6 +381,9 @@ pub fn rose_pine() -> UserThemeFamily { element_selected: Some(rgba(0x45415d80).into()), text: Some(rgba(0x85819eff).into()), text_muted: Some(rgba(0x3a3653ff).into()), + text_placeholder: Some(rgba(0x3a3653ff).into()), + text_disabled: Some(rgba(0xe0def4ff).into()), + text_accent: Some(rgba(0x9cced7ff).into()), status_bar_background: Some(rgba(0x38354eff).into()), title_bar_background: Some(rgba(0x38354eff).into()), toolbar_background: Some(rgba(0x232136ff).into()), @@ -728,6 +734,9 @@ pub fn rose_pine() -> UserThemeFamily { element_selected: Some(rgba(0x47445b80).into()), text: Some(rgba(0x75718eff).into()), text_muted: Some(rgba(0x3b384fff).into()), + text_placeholder: Some(rgba(0x3b384fff).into()), + text_disabled: Some(rgba(0xe0def4ff).into()), + text_accent: Some(rgba(0x9cced7ff).into()), status_bar_background: Some(rgba(0x292739ff).into()), title_bar_background: Some(rgba(0x292739ff).into()), toolbar_background: Some(rgba(0x191724ff).into()), diff --git a/crates/theme2/src/themes/sandcastle.rs b/crates/theme2/src/themes/sandcastle.rs index 2ee42660e3b59ef94b6e519032b6d124411cac36..c0bd53b2d6506d5b148245398f77a413314f4be8 100644 --- a/crates/theme2/src/themes/sandcastle.rs +++ b/crates/theme2/src/themes/sandcastle.rs @@ -27,6 +27,9 @@ pub fn sandcastle() -> UserThemeFamily { element_selected: Some(rgba(0x57535380).into()), text: Some(rgba(0xa69782ff).into()), text_muted: Some(rgba(0x645b54ff).into()), + text_placeholder: Some(rgba(0x645b54ff).into()), + text_disabled: Some(rgba(0xfdf4c1ff).into()), + text_accent: Some(rgba(0x528b8bff).into()), status_bar_background: Some(rgba(0x333944ff).into()), title_bar_background: Some(rgba(0x333944ff).into()), toolbar_background: Some(rgba(0x282c34ff).into()), diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index 4b8f60a61d67e8b5a2127b98541f87c3983eb2b4..e358537dfbaa418bd49501f0f23a7777e96c00d1 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -28,6 +28,9 @@ pub fn solarized() -> UserThemeFamily { element_selected: Some(rgba(0x7f919480).into()), text: Some(rgba(0x34555eff).into()), text_muted: Some(rgba(0x788b8fff).into()), + text_placeholder: Some(rgba(0x788b8fff).into()), + text_disabled: Some(rgba(0x002b36ff).into()), + text_accent: Some(rgba(0x298bd1ff).into()), status_bar_background: Some(rgba(0xcfd0c4ff).into()), title_bar_background: Some(rgba(0xcfd0c4ff).into()), toolbar_background: Some(rgba(0xfdf6e3ff).into()), @@ -364,6 +367,9 @@ pub fn solarized() -> UserThemeFamily { element_selected: Some(rgba(0x566d7480).into()), text: Some(rgba(0x93a1a1ff).into()), text_muted: Some(rgba(0x5f757dff).into()), + text_placeholder: Some(rgba(0x5f757dff).into()), + text_disabled: Some(rgba(0xfdf6e3ff).into()), + text_accent: Some(rgba(0x288bd1ff).into()), status_bar_background: Some(rgba(0x083743ff).into()), title_bar_background: Some(rgba(0x083743ff).into()), toolbar_background: Some(rgba(0x002b36ff).into()), diff --git a/crates/theme2/src/themes/summercamp.rs b/crates/theme2/src/themes/summercamp.rs index f4b5b6ed637e8d7df811f5ea16ba05e7ebce59f8..eab403fe79fcd53463dc3ac4e4714ebe24528c0a 100644 --- a/crates/theme2/src/themes/summercamp.rs +++ b/crates/theme2/src/themes/summercamp.rs @@ -27,6 +27,9 @@ pub fn summercamp() -> UserThemeFamily { element_selected: Some(rgba(0x39342780).into()), text: Some(rgba(0x736e55ff).into()), text_muted: Some(rgba(0x3d382aff).into()), + text_placeholder: Some(rgba(0x3d382aff).into()), + text_disabled: Some(rgba(0xf8f5deff).into()), + text_accent: Some(rgba(0x499befff).into()), status_bar_background: Some(rgba(0x2a261cff).into()), title_bar_background: Some(rgba(0x2a261cff).into()), toolbar_background: Some(rgba(0x1c1810ff).into()), diff --git a/crates/theme_importer/src/zed1/converter.rs b/crates/theme_importer/src/zed1/converter.rs index 0b932c83fb2a4f0d0cebe05a14ac0ad1065a8ad2..87318199cf61b220772e46264f6f75355a0ca3de 100644 --- a/crates/theme_importer/src/zed1/converter.rs +++ b/crates/theme_importer/src/zed1/converter.rs @@ -87,63 +87,52 @@ impl Zed1ThemeConverter { Some(zed1_color_to_hsla(color)) } + let picker = &self.theme.picker; + let title_bar = &self.theme.titlebar; + let status_bar = &self.theme.workspace.status_bar; + let project_panel = &self.theme.project_panel; let tab_bar = &self.theme.workspace.tab_bar; let active_tab = &self.theme.workspace.tab_bar.tab_style(true, true); let inactive_tab = &self.theme.workspace.tab_bar.tab_style(true, false); let toolbar = &self.theme.workspace.toolbar; + let editor = &self.theme.editor; let scrollbar = &self.theme.editor.scrollbar; + let terminal = &self.theme.terminal; - let zed1_titlebar_border = convert(self.theme.titlebar.container.border.color); + let title_bar_border = convert(title_bar.container.border.color); Ok(ThemeColorsRefinement { - border: zed1_titlebar_border, - border_variant: zed1_titlebar_border, + border: title_bar_border, + border_variant: title_bar_border, background: convert(self.theme.workspace.background), - elevated_surface_background: self - .theme - .picker - .container - .background_color - .map(zed1_color_to_hsla), - title_bar_background: self - .theme - .titlebar - .container - .background_color - .map(zed1_color_to_hsla), - status_bar_background: self - .theme - .workspace - .status_bar + elevated_surface_background: picker.container.background_color.map(zed1_color_to_hsla), + title_bar_background: title_bar.container.background_color.map(zed1_color_to_hsla), + status_bar_background: status_bar .container .background_color .map(zed1_color_to_hsla) - .or_else(|| { - self.theme - .titlebar - .container - .background_color - .map(zed1_color_to_hsla) - }), - panel_background: self - .theme - .project_panel + .or_else(|| title_bar.container.background_color.map(zed1_color_to_hsla)), + panel_background: project_panel .container .background_color .map(zed1_color_to_hsla), text: convert(self.theme.project_panel.entry.default_style().text.color), text_muted: convert(active_tab.description.text.color), - element_hover: self - .theme - .picker + text_accent: convert(status_bar.panel_buttons.button.active_state().icon_color), + text_disabled: convert(status_bar.panel_buttons.button.disabled_style().icon_color), + text_placeholder: picker + .empty_input_editor + .placeholder_text + .as_ref() + .map(|placeholder_text| placeholder_text.color) + .map(zed1_color_to_hsla), + element_hover: picker .item .hovered .as_ref() .and_then(|hovered| hovered.container.background_color) .map(zed1_color_to_hsla), - element_selected: self - .theme - .picker + element_selected: picker .item .active_state() .container @@ -159,13 +148,13 @@ impl Zed1ThemeConverter { .background_color .map(zed1_color_to_hsla), toolbar_background: toolbar.container.background_color.map(zed1_color_to_hsla), - editor_foreground: convert(self.theme.editor.text_color), - editor_background: convert(self.theme.editor.background), - editor_gutter_background: convert(self.theme.editor.gutter_background), - editor_line_number: convert(self.theme.editor.line_number), - editor_active_line_number: convert(self.theme.editor.line_number_active), - editor_wrap_guide: convert(self.theme.editor.wrap_guide), - editor_active_wrap_guide: convert(self.theme.editor.active_wrap_guide), + editor_foreground: convert(editor.text_color), + editor_background: convert(editor.background), + editor_gutter_background: convert(editor.gutter_background), + editor_line_number: convert(editor.line_number), + editor_active_line_number: convert(editor.line_number_active), + editor_wrap_guide: convert(editor.wrap_guide), + editor_active_wrap_guide: convert(editor.active_wrap_guide), scrollbar_track_background: scrollbar.track.background_color.map(zed1_color_to_hsla), scrollbar_track_border: convert(scrollbar.track.border.color), scrollbar_thumb_background: scrollbar.thumb.background_color.map(zed1_color_to_hsla), @@ -174,23 +163,23 @@ impl Zed1ThemeConverter { .thumb .background_color .map(zed1_color_to_hsla), - terminal_background: convert(self.theme.terminal.background), - terminal_ansi_bright_black: convert(self.theme.terminal.bright_black), - terminal_ansi_bright_red: convert(self.theme.terminal.bright_red), - terminal_ansi_bright_green: convert(self.theme.terminal.bright_green), - terminal_ansi_bright_yellow: convert(self.theme.terminal.bright_yellow), - terminal_ansi_bright_blue: convert(self.theme.terminal.bright_blue), - terminal_ansi_bright_magenta: convert(self.theme.terminal.bright_magenta), - terminal_ansi_bright_cyan: convert(self.theme.terminal.bright_cyan), - terminal_ansi_bright_white: convert(self.theme.terminal.bright_white), - terminal_ansi_black: convert(self.theme.terminal.black), - terminal_ansi_red: convert(self.theme.terminal.red), - terminal_ansi_green: convert(self.theme.terminal.green), - terminal_ansi_yellow: convert(self.theme.terminal.yellow), - terminal_ansi_blue: convert(self.theme.terminal.blue), - terminal_ansi_magenta: convert(self.theme.terminal.magenta), - terminal_ansi_cyan: convert(self.theme.terminal.cyan), - terminal_ansi_white: convert(self.theme.terminal.white), + terminal_background: convert(terminal.background), + terminal_ansi_bright_black: convert(terminal.bright_black), + terminal_ansi_bright_red: convert(terminal.bright_red), + terminal_ansi_bright_green: convert(terminal.bright_green), + terminal_ansi_bright_yellow: convert(terminal.bright_yellow), + terminal_ansi_bright_blue: convert(terminal.bright_blue), + terminal_ansi_bright_magenta: convert(terminal.bright_magenta), + terminal_ansi_bright_cyan: convert(terminal.bright_cyan), + terminal_ansi_bright_white: convert(terminal.bright_white), + terminal_ansi_black: convert(terminal.black), + terminal_ansi_red: convert(terminal.red), + terminal_ansi_green: convert(terminal.green), + terminal_ansi_yellow: convert(terminal.yellow), + terminal_ansi_blue: convert(terminal.blue), + terminal_ansi_magenta: convert(terminal.magenta), + terminal_ansi_cyan: convert(terminal.cyan), + terminal_ansi_white: convert(terminal.white), ..Default::default() }) } From ca7e5048177bf1fa8993d8684d6a9154321dff92 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Sat, 23 Dec 2023 00:49:51 +0100 Subject: [PATCH 304/644] titlebar: show "Share project" button only in local projects. (#3795) Fixes '"Share" button is shown even for remote projects'. Release Notes: - N/A --- crates/collab_ui2/src/collab_titlebar_item.rs | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 75c4cc5263895a499d6865dee7c005d99026f031..02c4446a9af41184f851795fcfcef0ca5e60518e 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -169,27 +169,31 @@ impl Render for CollabTitlebarItem { .pr_1() .when_some(room, |this, room| { let room = room.read(cx); - let is_shared = self.project.read(cx).is_shared(); + let project = self.project.read(cx); + let is_local = project.is_local(); + let is_shared = is_local && project.is_shared(); let is_muted = room.is_muted(cx); let is_deafened = room.is_deafened().unwrap_or(false); let is_screen_sharing = room.is_screen_sharing(); - this.child( - Button::new( - "toggle_sharing", - if is_shared { "Unshare" } else { "Share" }, + this.when(is_local, |this| { + this.child( + Button::new( + "toggle_sharing", + if is_shared { "Unshare" } else { "Share" }, + ) + .style(ButtonStyle::Subtle) + .on_click(cx.listener( + move |this, _, cx| { + if is_shared { + this.unshare_project(&Default::default(), cx); + } else { + this.share_project(&Default::default(), cx); + } + }, + )), ) - .style(ButtonStyle::Subtle) - .on_click(cx.listener( - move |this, _, cx| { - if is_shared { - this.unshare_project(&Default::default(), cx); - } else { - this.share_project(&Default::default(), cx); - } - }, - )), - ) + }) .child( IconButton::new("leave-call", ui::Icon::Exit) .style(ButtonStyle::Subtle) From c6f3f439c4128b3fff1569e27cb7bb6327aa5bf8 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 23 Dec 2023 01:55:40 +0200 Subject: [PATCH 305/644] Fix mouse listeners' z-index for editor --- crates/editor2/src/element.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 9e1d8e641f0964319e123476fa608484ce6320ea..f7feba9292230f3c05d37f8a6351262ef7827bfb 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -2840,17 +2840,13 @@ impl Element for EditorElement { } self.paint_text(text_bounds, &mut layout, cx); + cx.with_z_index(0, |cx| { + self.paint_mouse_listeners(bounds, gutter_bounds, text_bounds, &layout, cx); + }); if !layout.blocks.is_empty() { cx.with_z_index(0, |cx| { cx.with_element_id(Some("editor_blocks"), |cx| { self.paint_blocks(bounds, &mut layout, cx); - self.paint_mouse_listeners( - bounds, - gutter_bounds, - text_bounds, - &layout, - cx, - ); }); }) } From 3213a860a6e702d4fc4c48359a441caf48269a22 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 18:56:17 -0500 Subject: [PATCH 306/644] Use extra small label for tab descriptions (#3797) This PR adjusts the size of the tab descriptions to use the extra small label size. This makes it easier to distinguish between the filename and the description: Screenshot 2023-12-22 at 6 49 11 PM It's also more in line with how things look in Zed1. Release Notes: - N/A --- crates/editor2/src/items.rs | 6 ++++- crates/ui2/src/components/button/button.rs | 2 +- .../src/components/button/toggle_button.rs | 2 +- crates/ui2/src/components/label/label_like.rs | 8 +++--- crates/ui2/src/styled_ext.rs | 25 +++++++++++-------- crates/ui2/src/styles/typography.rs | 16 +++++++++--- 6 files changed, 39 insertions(+), 20 deletions(-) diff --git a/crates/editor2/src/items.rs b/crates/editor2/src/items.rs index e0374d3d7307ce0972a94d66993e0b9df05750a0..ddb5b25db2fd990a675b15165b8d7d19282e3b1d 100644 --- a/crates/editor2/src/items.rs +++ b/crates/editor2/src/items.rs @@ -603,7 +603,11 @@ impl Item for Editor { Color::Muted })) .when_some(description, |this, description| { - this.child(Label::new(description).color(Color::Muted)) + this.child( + Label::new(description) + .size(LabelSize::XSmall) + .color(Color::Muted), + ) }) .into_any_element() } diff --git a/crates/ui2/src/components/button/button.rs b/crates/ui2/src/components/button/button.rs index 406cd1f420be8b6ff2e2a81e92f47fd8fa0748b1..bc5d03d639ffe4ba4fb1d5c8c6886268b7660159 100644 --- a/crates/ui2/src/components/button/button.rs +++ b/crates/ui2/src/components/button/button.rs @@ -172,7 +172,7 @@ impl RenderOnce for Button { Label::new(label) .color(label_color) .size(self.label_size.unwrap_or_default()) - .line_height_style(LineHeightStyle::UILabel), + .line_height_style(LineHeightStyle::UiLabel), ) .when(!self.icon_position.is_some(), |this| { this.children(self.icon.map(|icon| { diff --git a/crates/ui2/src/components/button/toggle_button.rs b/crates/ui2/src/components/button/toggle_button.rs index 39a517111b9a1958afac86979f4adbbdd18c25bf..4a6ecdeb2fc6cea673e8f695a35e0b7ec7cfa517 100644 --- a/crates/ui2/src/components/button/toggle_button.rs +++ b/crates/ui2/src/components/button/toggle_button.rs @@ -122,7 +122,7 @@ impl RenderOnce for ToggleButton { .child( Label::new(self.label) .color(label_color) - .line_height_style(LineHeightStyle::UILabel), + .line_height_style(LineHeightStyle::UiLabel), ) } } diff --git a/crates/ui2/src/components/label/label_like.rs b/crates/ui2/src/components/label/label_like.rs index 72a48adea451f49cd10dd2e2bd224f16d4ae51a9..ebfbbecceb6d2468d3c7da98929d3cd4bd20f1ba 100644 --- a/crates/ui2/src/components/label/label_like.rs +++ b/crates/ui2/src/components/label/label_like.rs @@ -8,14 +8,15 @@ pub enum LabelSize { #[default] Default, Small, + XSmall, } #[derive(Default, PartialEq, Copy, Clone)] pub enum LineHeightStyle { #[default] TextLabel, - /// Sets the line height to 1 - UILabel, + /// Sets the line height to 1. + UiLabel, } pub trait LabelCommon { @@ -92,8 +93,9 @@ impl RenderOnce for LabelLike { .map(|this| match self.size { LabelSize::Default => this.text_ui(), LabelSize::Small => this.text_ui_sm(), + LabelSize::XSmall => this.text_ui_xs(), }) - .when(self.line_height_style == LineHeightStyle::UILabel, |this| { + .when(self.line_height_style == LineHeightStyle::UiLabel, |this| { this.line_height(relative(1.)) }) .text_color(self.color.color(cx)) diff --git a/crates/ui2/src/styled_ext.rs b/crates/ui2/src/styled_ext.rs index 3358968c727c26872a6140b83a68b81043634c52..7e761f8f2c7a156be20ecc6b0ee20a4b72f2974a 100644 --- a/crates/ui2/src/styled_ext.rs +++ b/crates/ui2/src/styled_ext.rs @@ -3,7 +3,7 @@ use settings::Settings; use theme::ThemeSettings; use crate::prelude::*; -use crate::{ElevationIndex, UITextSize}; +use crate::{ElevationIndex, UiTextSize}; fn elevated(this: E, cx: &mut WindowContext, index: ElevationIndex) -> E { this.bg(cx.theme().colors().elevated_surface_background) @@ -44,10 +44,8 @@ pub trait StyledExt: Styled + Sized { self.flex().flex_col() } - fn text_ui_size(self, size: UITextSize) -> Self { - let size = size.rems(); - - self.text_size(size) + fn text_ui_size(self, size: UiTextSize) -> Self { + self.text_size(size.rems()) } /// The default size for UI text. @@ -58,9 +56,7 @@ pub trait StyledExt: Styled + Sized { /// /// Use [`text_ui_sm`] for regular-sized text. fn text_ui(self) -> Self { - let size = UITextSize::default().rems(); - - self.text_size(size) + self.text_size(UiTextSize::default().rems()) } /// The small size for UI text. @@ -71,9 +67,18 @@ pub trait StyledExt: Styled + Sized { /// /// Use [`text_ui`] for regular-sized text. fn text_ui_sm(self) -> Self { - let size = UITextSize::Small.rems(); + self.text_size(UiTextSize::Small.rems()) + } - self.text_size(size) + /// The extra small size for UI text. + /// + /// `0.625rem` or `10px` at the default scale of `1rem` = `16px`. + /// + /// Note: The absolute size of this text will change based on a user's `ui_scale` setting. + /// + /// Use [`text_ui`] for regular-sized text. + fn text_ui_xs(self) -> Self { + self.text_size(UiTextSize::XSmall.rems()) } /// The font size for buffer text. diff --git a/crates/ui2/src/styles/typography.rs b/crates/ui2/src/styles/typography.rs index 18b2c4849af3687b6ea0468a3ccc77846637f67f..4819791b02c988bfccc1c59484b373e5d8249bfe 100644 --- a/crates/ui2/src/styles/typography.rs +++ b/crates/ui2/src/styles/typography.rs @@ -1,7 +1,7 @@ use gpui::{rems, Rems}; #[derive(Debug, Default, Clone)] -pub enum UITextSize { +pub enum UiTextSize { /// The default size for UI text. /// /// `0.825rem` or `14px` at the default scale of `1rem` = `16px`. @@ -15,13 +15,21 @@ pub enum UITextSize { /// /// Note: The absolute size of this text will change based on a user's `ui_scale` setting. Small, + + /// The extra small size for UI text. + /// + /// `0.625rem` or `10px` at the default scale of `1rem` = `16px`. + /// + /// Note: The absolute size of this text will change based on a user's `ui_scale` setting. + XSmall, } -impl UITextSize { +impl UiTextSize { pub fn rems(self) -> Rems { match self { - Self::Default => rems(0.875), - Self::Small => rems(0.75), + Self::Default => rems(14. / 16.), + Self::Small => rems(12. / 16.), + Self::XSmall => rems(10. / 16.), } } } From f03ee1ea244c86e83b4f10c4acddf69109556e64 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 19:18:04 -0500 Subject: [PATCH 307/644] Add spacing between tab bar buttons (#3799) This PR adds spacing between buttons in the tab bar. Release Notes: - N/A --- crates/workspace2/src/pane.rs | 41 ++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 7128288e7b1cfee4d2153cc53ad9b858188d1a8c..893c5222220339ad02d9c89a084159ba0b253465 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -377,6 +377,7 @@ impl Pane { can_split: true, render_tab_bar_buttons: Rc::new(move |pane, cx| { h_stack() + .gap_2() .child( IconButton::new("plus", Icon::Plus) .icon_size(IconSize::Small) @@ -1657,24 +1658,28 @@ impl Pane { TabBar::new("tab_bar") .track_scroll(self.tab_bar_scroll_handle.clone()) .start_child( - IconButton::new("navigate_backward", Icon::ArrowLeft) - .icon_size(IconSize::Small) - .on_click({ - let view = cx.view().clone(); - move |_, cx| view.update(cx, Self::navigate_backward) - }) - .disabled(!self.can_navigate_backward()) - .tooltip(|cx| Tooltip::for_action("Go Back", &GoBack, cx)), - ) - .start_child( - IconButton::new("navigate_forward", Icon::ArrowRight) - .icon_size(IconSize::Small) - .on_click({ - let view = cx.view().clone(); - move |_, cx| view.update(cx, Self::navigate_backward) - }) - .disabled(!self.can_navigate_forward()) - .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)), + h_stack() + .gap_2() + .child( + IconButton::new("navigate_backward", Icon::ArrowLeft) + .icon_size(IconSize::Small) + .on_click({ + let view = cx.view().clone(); + move |_, cx| view.update(cx, Self::navigate_backward) + }) + .disabled(!self.can_navigate_backward()) + .tooltip(|cx| Tooltip::for_action("Go Back", &GoBack, cx)), + ) + .child( + IconButton::new("navigate_forward", Icon::ArrowRight) + .icon_size(IconSize::Small) + .on_click({ + let view = cx.view().clone(); + move |_, cx| view.update(cx, Self::navigate_backward) + }) + .disabled(!self.can_navigate_forward()) + .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)), + ), ) .end_child({ let render_tab_buttons = self.render_tab_bar_buttons.clone(); From a1915ce6c437af87d1faf0124dd949d8dc08b4d0 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 23 Dec 2023 02:29:33 +0200 Subject: [PATCH 308/644] Add spacing to terminal tab bar buttons --- crates/terminal_view2/src/terminal_panel.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/terminal_view2/src/terminal_panel.rs b/crates/terminal_view2/src/terminal_panel.rs index c2fe5de0148c2b00fe1b89913d8ef9b57c1db2b8..044a9f3aa8d63eb96ac202711c6494c38dcd3c4b 100644 --- a/crates/terminal_view2/src/terminal_panel.rs +++ b/crates/terminal_view2/src/terminal_panel.rs @@ -76,6 +76,7 @@ impl TerminalPanel { pane.set_can_navigate(false, cx); pane.set_render_tab_bar_buttons(cx, move |pane, cx| { h_stack() + .gap_2() .child( IconButton::new("plus", Icon::Plus) .icon_size(IconSize::Small) From 0e145a843507a6c61bfc82538d244ab6a1b0cb51 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 19:32:07 -0500 Subject: [PATCH 309/644] Make current call controls in title bar smaller (#3800) This PR adjusts the sizes of the current call controls in the title bar to be smaller. This matches the size of the other title bar items that are always present. Release Notes: - N/A --- crates/collab_ui2/src/collab_titlebar_item.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 02c4446a9af41184f851795fcfcef0ca5e60518e..6255e2b833daf2028675fba197bc80d28a1fdea4 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -183,6 +183,7 @@ impl Render for CollabTitlebarItem { if is_shared { "Unshare" } else { "Share" }, ) .style(ButtonStyle::Subtle) + .label_size(LabelSize::Small) .on_click(cx.listener( move |this, _, cx| { if is_shared { @@ -197,6 +198,7 @@ impl Render for CollabTitlebarItem { .child( IconButton::new("leave-call", ui::Icon::Exit) .style(ButtonStyle::Subtle) + .icon_size(IconSize::Small) .on_click(move |_, cx| { ActiveCall::global(cx) .update(cx, |call, cx| call.hang_up(cx)) @@ -213,6 +215,7 @@ impl Render for CollabTitlebarItem { }, ) .style(ButtonStyle::Subtle) + .icon_size(IconSize::Small) .selected(is_muted) .on_click(move |_, cx| crate::toggle_mute(&Default::default(), cx)), ) @@ -226,6 +229,7 @@ impl Render for CollabTitlebarItem { }, ) .style(ButtonStyle::Subtle) + .icon_size(IconSize::Small) .selected(is_deafened) .tooltip(move |cx| { Tooltip::with_meta("Deafen Audio", None, "Mic will be muted", cx) @@ -235,6 +239,7 @@ impl Render for CollabTitlebarItem { .child( IconButton::new("screen-share", ui::Icon::Screen) .style(ButtonStyle::Subtle) + .icon_size(IconSize::Small) .selected(is_screen_sharing) .on_click(move |_, cx| { crate::toggle_screen_sharing(&Default::default(), cx) @@ -313,6 +318,7 @@ impl CollabTitlebarItem { Button::new("project_owner_trigger", host.github_login.clone()) .color(Color::Player(participant_index.0)) .style(ButtonStyle::Subtle) + .label_size(LabelSize::Small) .tooltip(move |cx| Tooltip::text("Toggle following", cx)), ), ) From d7b06620584ac782f689bea9344487330cadc623 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 22 Dec 2023 16:44:28 -0800 Subject: [PATCH 310/644] Maintain workspace's zoom state when opening/closing docks, activating panels --- crates/workspace2/src/dock.rs | 46 +++++++++++++++++++++-------- crates/workspace2/src/workspace2.rs | 12 ++------ 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index fbc8a1f8789460531d743def92ff40844f87f088..928e03a692dfd947fb9322eb3f8dd724bab307c9 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -192,21 +192,43 @@ pub struct PanelButtons { } impl Dock { - pub fn new(position: DockPosition, cx: &mut ViewContext<'_, Self>) -> Self { + pub fn new(position: DockPosition, cx: &mut ViewContext) -> View { let focus_handle = cx.focus_handle(); - let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| { - if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) { - active_entry.panel.focus_handle(cx).focus(cx) + + let dock = cx.build_view(|cx: &mut ViewContext| { + let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| { + if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) { + active_entry.panel.focus_handle(cx).focus(cx) + } + }); + Self { + position, + panel_entries: Default::default(), + active_panel_index: 0, + is_open: false, + focus_handle: focus_handle.clone(), + _focus_subscription: focus_subscription, } }); - Self { - position, - panel_entries: Default::default(), - active_panel_index: 0, - is_open: false, - focus_handle, - _focus_subscription: focus_subscription, - } + + cx.observe(&dock, move |workspace, dock, cx| { + if dock.read(cx).is_open() { + if let Some(panel) = dock.read(cx).active_panel() { + if panel.is_zoomed(cx) { + workspace.zoomed = Some(panel.to_any().downgrade()); + workspace.zoomed_position = Some(position); + return; + } + } + } + if workspace.zoomed_position == Some(position) { + workspace.zoomed = None; + workspace.zoomed_position = None; + } + }) + .detach(); + + dock } pub fn position(&self) -> DockPosition { diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index f4484c827ecdb87ee9cc188def2cb39124157eed..61083ad2698d99f421c890f8440c8f88806d3ad6 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -586,9 +586,9 @@ impl Workspace { cx.emit(Event::WorkspaceCreated(weak_handle.clone())); - let left_dock = cx.build_view(|cx| Dock::new(DockPosition::Left, cx)); - let bottom_dock = cx.build_view(|cx| Dock::new(DockPosition::Bottom, cx)); - let right_dock = cx.build_view(|cx| Dock::new(DockPosition::Right, cx)); + let left_dock = Dock::new(DockPosition::Left, cx); + let bottom_dock = Dock::new(DockPosition::Bottom, cx); + let right_dock = Dock::new(DockPosition::Right, cx); let left_dock_buttons = cx.build_view(|cx| PanelButtons::new(left_dock.clone(), cx)); let bottom_dock_buttons = cx.build_view(|cx| PanelButtons::new(bottom_dock.clone(), cx)); let right_dock_buttons = cx.build_view(|cx| PanelButtons::new(right_dock.clone(), cx)); @@ -1616,7 +1616,6 @@ impl Workspace { for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] { if let Some(panel_index) = dock.read(cx).panel_index_for_type::() { let mut focus_center = false; - let mut reveal_dock = false; let panel = dock.update(cx, |dock, cx| { dock.activate_panel(panel_index, cx); @@ -1625,12 +1624,7 @@ impl Workspace { if should_focus(&**panel, cx) { dock.set_open(true, cx); panel.focus_handle(cx).focus(cx); - reveal_dock = true; } else { - // todo!() - // if panel.is_zoomed(cx) { - // dock.set_open(false, cx); - // } focus_center = true; } } From 0746a10d9be20be72dc368b5112799e17347e83a Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 22 Dec 2023 19:56:06 -0500 Subject: [PATCH 311/644] Increase telemetry queue size --- crates/client/src/telemetry.rs | 2 +- crates/client2/src/telemetry.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs index 6d70de6138ce26028c3ff5576283e19abef8f2e0..5e97382d7045d8856a4580ae01712d1fe3da713e 100644 --- a/crates/client/src/telemetry.rs +++ b/crates/client/src/telemetry.rs @@ -119,7 +119,7 @@ pub enum ClickhouseEvent { const MAX_QUEUE_LEN: usize = 1; #[cfg(not(debug_assertions))] -const MAX_QUEUE_LEN: usize = 10; +const MAX_QUEUE_LEN: usize = 50; #[cfg(debug_assertions)] const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(1); diff --git a/crates/client2/src/telemetry.rs b/crates/client2/src/telemetry.rs index 71c4c33491e99bbb8361f5acbbacd0a59881a409..e1a7d3f41e9944214f179edce5f2cb69a431009e 100644 --- a/crates/client2/src/telemetry.rs +++ b/crates/client2/src/telemetry.rs @@ -118,7 +118,7 @@ pub enum ClickhouseEvent { const MAX_QUEUE_LEN: usize = 1; #[cfg(not(debug_assertions))] -const MAX_QUEUE_LEN: usize = 10; +const MAX_QUEUE_LEN: usize = 50; #[cfg(debug_assertions)] const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(1); From 1989094e6dc064d19ad83b1b5f07af14c6876915 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 22 Dec 2023 19:57:13 -0500 Subject: [PATCH 312/644] Increase queue flush debounce time --- crates/client/src/telemetry.rs | 2 +- crates/client2/src/telemetry.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs index 5e97382d7045d8856a4580ae01712d1fe3da713e..0118832fe03bdca1e4c08199fe369304b1ca879b 100644 --- a/crates/client/src/telemetry.rs +++ b/crates/client/src/telemetry.rs @@ -125,7 +125,7 @@ const MAX_QUEUE_LEN: usize = 50; const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(1); #[cfg(not(debug_assertions))] -const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(30); +const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(120); impl Telemetry { pub fn new(client: Arc, cx: &AppContext) -> Arc { diff --git a/crates/client2/src/telemetry.rs b/crates/client2/src/telemetry.rs index e1a7d3f41e9944214f179edce5f2cb69a431009e..e27bc3a49808946bc3027d64bcaab53e588df32f 100644 --- a/crates/client2/src/telemetry.rs +++ b/crates/client2/src/telemetry.rs @@ -124,7 +124,7 @@ const MAX_QUEUE_LEN: usize = 50; const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(1); #[cfg(not(debug_assertions))] -const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(30); +const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(120); impl Telemetry { pub fn new(client: Arc, cx: &mut AppContext) -> Arc { From b1870af386a7d048cb89e6ecef8b5b29d83e1800 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Fri, 22 Dec 2023 20:23:55 -0500 Subject: [PATCH 313/644] Add project open event Give the caller of report_app_event() the choice of whether to immediately flush the queue or not. --- crates/client/src/telemetry.rs | 4 ++-- crates/client2/src/telemetry.rs | 6 +++--- crates/workspace/src/workspace.rs | 6 +++++- crates/workspace2/src/workspace2.rs | 6 +++++- crates/zed/src/main.rs | 2 +- crates/zed2/src/main.rs | 2 +- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs index 0118832fe03bdca1e4c08199fe369304b1ca879b..49cb9843f030df4379a2ac0936d100a6c3c2807e 100644 --- a/crates/client/src/telemetry.rs +++ b/crates/client/src/telemetry.rs @@ -340,18 +340,18 @@ impl Telemetry { self.report_clickhouse_event(event, telemetry_settings, false) } - // app_events are called at app open and app close, so flush is set to immediately send pub fn report_app_event( self: &Arc, telemetry_settings: TelemetrySettings, operation: &'static str, + immediate_flush: bool, ) { let event = ClickhouseEvent::App { operation, milliseconds_since_first_event: self.milliseconds_since_first_event(), }; - self.report_clickhouse_event(event, telemetry_settings, true) + self.report_clickhouse_event(event, telemetry_settings, immediate_flush) } fn milliseconds_since_first_event(&self) -> i64 { diff --git a/crates/client2/src/telemetry.rs b/crates/client2/src/telemetry.rs index e27bc3a49808946bc3027d64bcaab53e588df32f..f02ff937e4b992058f80e46d5fb4335281f40a35 100644 --- a/crates/client2/src/telemetry.rs +++ b/crates/client2/src/telemetry.rs @@ -173,7 +173,7 @@ impl Telemetry { #[cfg(not(any(test, feature = "test-support")))] fn shutdown_telemetry(self: &Arc, cx: &mut AppContext) -> impl Future { let telemetry_settings = TelemetrySettings::get_global(cx).clone(); - self.report_app_event(telemetry_settings, "close"); + self.report_app_event(telemetry_settings, "close", true); Task::ready(()) } @@ -364,18 +364,18 @@ impl Telemetry { self.report_clickhouse_event(event, telemetry_settings, false) } - // app_events are called at app open and app close, so flush is set to immediately send pub fn report_app_event( self: &Arc, telemetry_settings: TelemetrySettings, operation: &'static str, + immediate_flush: bool, ) { let event = ClickhouseEvent::App { operation, milliseconds_since_first_event: self.milliseconds_since_first_event(), }; - self.report_clickhouse_event(event, telemetry_settings, true) + self.report_clickhouse_event(event, telemetry_settings, immediate_flush) } fn milliseconds_since_first_event(&self) -> i64 { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 455c27a57e1821f233a35a6eb6f9f3e223fa1bb0..ee2a8ab104a1bfdd7281b345e5fdb854f50507ab 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -14,7 +14,7 @@ use anyhow::{anyhow, Context, Result}; use call::ActiveCall; use client::{ proto::{self, PeerId}, - Client, Status, TypedEnvelope, UserStore, + Client, Status, TelemetrySettings, TypedEnvelope, UserStore, }; use collections::{hash_map, HashMap, HashSet}; use drag_and_drop::DragAndDrop; @@ -1462,6 +1462,10 @@ impl Workspace { } pub fn open(&mut self, _: &Open, cx: &mut ViewContext) -> Option>> { + let telemetry_settings = *settings::get::(cx); + self.client() + .telemetry() + .report_app_event(telemetry_settings, "open project", false); let mut paths = cx.prompt_for_paths(PathPromptOptions { files: true, directories: true, diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 61083ad2698d99f421c890f8440c8f88806d3ad6..0eb6425287f0ee6da9ceaf617078bc55392d32bf 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -15,7 +15,7 @@ use anyhow::{anyhow, Context as _, Result}; use call::ActiveCall; use client::{ proto::{self, PeerId}, - Client, Status, TypedEnvelope, UserStore, + Client, Status, TelemetrySettings, TypedEnvelope, UserStore, }; use collections::{hash_map, HashMap, HashSet}; use dock::{Dock, DockPosition, Panel, PanelButtons, PanelHandle}; @@ -1250,6 +1250,10 @@ impl Workspace { } pub fn open(&mut self, _: &Open, cx: &mut ViewContext) { + let telemetry_settings = TelemetrySettings::get_global(cx).clone(); + self.client() + .telemetry() + .report_app_event(telemetry_settings, "open project", false); let paths = cx.prompt_for_paths(PathPromptOptions { files: true, directories: true, diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 20b93ae6bb4f3ddf0368748fd949ddb5c6b83e63..04f468eb2f03a2ea9661005116a2d9796af6c5c9 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -174,7 +174,7 @@ fn main() { }; client .telemetry() - .report_app_event(telemetry_settings, event_operation); + .report_app_event(telemetry_settings, event_operation, true); let app_state = Arc::new(AppState { languages, diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index 93643648b8c78b13556d97e6de2f491b99642a67..a885a81f79e7e4c3fc02e1dfe2e13a5072dac668 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -184,7 +184,7 @@ fn main() { }; client .telemetry() - .report_app_event(telemetry_settings, event_operation); + .report_app_event(telemetry_settings, event_operation, true); let app_state = Arc::new(AppState { languages: languages.clone(), From e8a14b19715ba2ea06d6d84bbfba5080ffca33d6 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 21:10:53 -0500 Subject: [PATCH 314/644] Adjust color used for text --- crates/theme2/src/themes/andromeda.rs | 2 +- crates/theme2/src/themes/atelier.rs | 40 ++++++++++----------- crates/theme2/src/themes/ayu.rs | 6 ++-- crates/theme2/src/themes/gruvbox.rs | 12 +++---- crates/theme2/src/themes/one.rs | 4 +-- crates/theme2/src/themes/rose_pine.rs | 6 ++-- crates/theme2/src/themes/sandcastle.rs | 2 +- crates/theme2/src/themes/solarized.rs | 4 +-- crates/theme2/src/themes/summercamp.rs | 2 +- crates/theme_importer/src/zed1/converter.rs | 2 +- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index 699abec4912a3b78333ac9f9988d0c8e19af2865..2130653e57b18701de0e1fac6248a4fd92597a2f 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -25,7 +25,7 @@ pub fn andromeda() -> UserThemeFamily { panel_background: Some(rgba(0x21242bff).into()), element_hover: Some(rgba(0x2b2f3980).into()), element_selected: Some(rgba(0x383b4580).into()), - text: Some(rgba(0xaca8aeff).into()), + text: Some(rgba(0xf7f7f8ff).into()), text_muted: Some(rgba(0x474a53ff).into()), text_placeholder: Some(rgba(0x474a53ff).into()), text_disabled: Some(rgba(0xf7f7f8ff).into()), diff --git a/crates/theme2/src/themes/atelier.rs b/crates/theme2/src/themes/atelier.rs index 1722521b032cf3b963c89fcc0c9713579fa826ae..869fa44c0d7ac62a14922cadb6ec5d5f87f25f1a 100644 --- a/crates/theme2/src/themes/atelier.rs +++ b/crates/theme2/src/themes/atelier.rs @@ -26,7 +26,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xebeae3ff).into()), element_hover: Some(rgba(0x96958580).into()), element_selected: Some(rgba(0x8b8a7880).into()), - text: Some(rgba(0x61604fff).into()), + text: Some(rgba(0x22221bff).into()), text_muted: Some(rgba(0x878573ff).into()), text_placeholder: Some(rgba(0x878573ff).into()), text_disabled: Some(rgba(0x22221bff).into()), @@ -386,7 +386,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x27211eff).into()), element_hover: Some(rgba(0x665f5c80).into()), element_selected: Some(rgba(0x71696680).into()), - text: Some(rgba(0xa79f9dff).into()), + text: Some(rgba(0xf1efeeff).into()), text_muted: Some(rgba(0x766e6bff).into()), text_placeholder: Some(rgba(0x766e6bff).into()), text_disabled: Some(rgba(0xf1efeeff).into()), @@ -746,7 +746,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xe3ebe6ff).into()), element_hover: Some(rgba(0x8b968e80).into()), element_selected: Some(rgba(0x7e8b8280).into()), - text: Some(rgba(0x546259ff).into()), + text: Some(rgba(0x171c19ff).into()), text_muted: Some(rgba(0x79877dff).into()), text_placeholder: Some(rgba(0x79877dff).into()), text_disabled: Some(rgba(0x171c19ff).into()), @@ -1106,7 +1106,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x221f26ff).into()), element_hover: Some(rgba(0x56505e80).into()), element_selected: Some(rgba(0x605a6880).into()), - text: Some(rgba(0x898591ff).into()), + text: Some(rgba(0xefecf4ff).into()), text_muted: Some(rgba(0x655f6dff).into()), text_placeholder: Some(rgba(0x655f6dff).into()), text_disabled: Some(rgba(0xefecf4ff).into()), @@ -1466,7 +1466,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x2c2b23ff).into()), element_hover: Some(rgba(0x5d5c4c80).into()), element_selected: Some(rgba(0x67665580).into()), - text: Some(rgba(0x91907fff).into()), + text: Some(rgba(0xf4f3ecff).into()), text_muted: Some(rgba(0x6c6b5aff).into()), text_placeholder: Some(rgba(0x6c6b5aff).into()), text_disabled: Some(rgba(0xf4f3ecff).into()), @@ -1826,7 +1826,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x262f51ff).into()), element_hover: Some(rgba(0x5c648580).into()), element_selected: Some(rgba(0x666e8f80).into()), - text: Some(rgba(0x959bb2ff).into()), + text: Some(rgba(0xf5f7ffff).into()), text_muted: Some(rgba(0x6b7394ff).into()), text_placeholder: Some(rgba(0x6b7394ff).into()), text_disabled: Some(rgba(0xf5f7ffff).into()), @@ -2186,7 +2186,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xe5e8f5ff).into()), element_hover: Some(rgba(0x9a9fb680).into()), element_selected: Some(rgba(0x8e94aa80).into()), - text: Some(rgba(0x606889ff).into()), + text: Some(rgba(0x202746ff).into()), text_muted: Some(rgba(0x898fa5ff).into()), text_placeholder: Some(rgba(0x898fa5ff).into()), text_disabled: Some(rgba(0x202746ff).into()), @@ -2546,7 +2546,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x262622ff).into()), element_hover: Some(rgba(0x6c695c80).into()), element_selected: Some(rgba(0x77746480).into()), - text: Some(rgba(0xa4a08bff).into()), + text: Some(rgba(0xfefbecff).into()), text_muted: Some(rgba(0x7c7968ff).into()), text_placeholder: Some(rgba(0x7c7968ff).into()), text_disabled: Some(rgba(0xfefbecff).into()), @@ -2906,7 +2906,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x1f231fff).into()), element_hover: Some(rgba(0x5c6c5c80).into()), element_selected: Some(rgba(0x64776480).into()), - text: Some(rgba(0x8ba48bff).into()), + text: Some(rgba(0xf4fbf4ff).into()), text_muted: Some(rgba(0x687c68ff).into()), text_placeholder: Some(rgba(0x687c68ff).into()), text_disabled: Some(rgba(0xf4fbf4ff).into()), @@ -3266,7 +3266,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xe6e3ebff).into()), element_hover: Some(rgba(0x8f8b9680).into()), element_selected: Some(rgba(0x837e8b80).into()), - text: Some(rgba(0x5a5462ff).into()), + text: Some(rgba(0x19171cff).into()), text_muted: Some(rgba(0x7e7987ff).into()), text_placeholder: Some(rgba(0x7e7987ff).into()), text_disabled: Some(rgba(0x19171cff).into()), @@ -3626,7 +3626,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x252020ff).into()), element_hover: Some(rgba(0x564e4e80).into()), element_selected: Some(rgba(0x60585880).into()), - text: Some(rgba(0x898383ff).into()), + text: Some(rgba(0xf4ececff).into()), text_muted: Some(rgba(0x655d5dff).into()), text_placeholder: Some(rgba(0x655d5dff).into()), text_disabled: Some(rgba(0xf4ececff).into()), @@ -3986,7 +3986,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x252025ff).into()), element_hover: Some(rgba(0x675b6780).into()), element_selected: Some(rgba(0x72647280).into()), - text: Some(rgba(0xa99aa9ff).into()), + text: Some(rgba(0xf7f3f7ff).into()), text_muted: Some(rgba(0x776977ff).into()), text_placeholder: Some(rgba(0x776977ff).into()), text_disabled: Some(rgba(0xf7f3f7ff).into()), @@ -4346,7 +4346,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x1c2529ff).into()), element_hover: Some(rgba(0x4f6b7880).into()), element_selected: Some(rgba(0x57768580).into()), - text: Some(rgba(0x7ca0b3ff).into()), + text: Some(rgba(0xebf8ffff).into()), text_muted: Some(rgba(0x5a7b8bff).into()), text_placeholder: Some(rgba(0x5a7b8bff).into()), text_disabled: Some(rgba(0xebf8ffff).into()), @@ -4706,7 +4706,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xe9e6e4ff).into()), element_hover: Some(rgba(0xaaa3a180).into()), element_selected: Some(rgba(0xa1999680).into()), - text: Some(rgba(0x6a6360ff).into()), + text: Some(rgba(0x1b1918ff).into()), text_muted: Some(rgba(0x9c9491ff).into()), text_placeholder: Some(rgba(0x9c9491ff).into()), text_disabled: Some(rgba(0x1b1918ff).into()), @@ -5066,7 +5066,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xeeebd7ff).into()), element_hover: Some(rgba(0xa8a48e80).into()), element_selected: Some(rgba(0x9e9a8580).into()), - text: Some(rgba(0x706d5fff).into()), + text: Some(rgba(0x20201dff).into()), text_muted: Some(rgba(0x999580ff).into()), text_placeholder: Some(rgba(0x999580ff).into()), text_disabled: Some(rgba(0x20201dff).into()), @@ -5426,7 +5426,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xebe3e3ff).into()), element_hover: Some(rgba(0x8e898980).into()), element_selected: Some(rgba(0x837c7c80).into()), - text: Some(rgba(0x5a5252ff).into()), + text: Some(rgba(0x1b1818ff).into()), text_muted: Some(rgba(0x7e7777ff).into()), text_placeholder: Some(rgba(0x7e7777ff).into()), text_disabled: Some(rgba(0x1b1818ff).into()), @@ -5786,7 +5786,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xdaeedaff).into()), element_hover: Some(rgba(0x8ea88e80).into()), element_selected: Some(rgba(0x859e8580).into()), - text: Some(rgba(0x5f705fff).into()), + text: Some(rgba(0x131513ff).into()), text_muted: Some(rgba(0x809980ff).into()), text_placeholder: Some(rgba(0x809980ff).into()), text_disabled: Some(rgba(0x131513ff).into()), @@ -6146,7 +6146,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0x1f2621ff).into()), element_hover: Some(rgba(0x505e5580).into()), element_selected: Some(rgba(0x5a685f80).into()), - text: Some(rgba(0x859188ff).into()), + text: Some(rgba(0xecf4eeff).into()), text_muted: Some(rgba(0x5f6d64ff).into()), text_placeholder: Some(rgba(0x5f6d64ff).into()), text_disabled: Some(rgba(0xecf4eeff).into()), @@ -6506,7 +6506,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xe1d6e1ff).into()), element_hover: Some(rgba(0xad9dad80).into()), element_selected: Some(rgba(0xa394a380).into()), - text: Some(rgba(0x6b5e6bff).into()), + text: Some(rgba(0x1b181bff).into()), text_muted: Some(rgba(0x9e8f9eff).into()), text_placeholder: Some(rgba(0x9e8f9eff).into()), text_disabled: Some(rgba(0x1b181bff).into()), @@ -6866,7 +6866,7 @@ pub fn atelier() -> UserThemeFamily { panel_background: Some(rgba(0xcdeaf9ff).into()), element_hover: Some(rgba(0x80a4b680).into()), element_selected: Some(rgba(0x769aad80).into()), - text: Some(rgba(0x526f7dff).into()), + text: Some(rgba(0x161b1dff).into()), text_muted: Some(rgba(0x7195a8ff).into()), text_placeholder: Some(rgba(0x7195a8ff).into()), text_disabled: Some(rgba(0x161b1dff).into()), diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index eb6ac40bcedbb192fbc2f67efb54415692dcad4c..45b6cea310b5af8ae3614064adfa7e4241b9dc44 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -26,7 +26,7 @@ pub fn ayu() -> UserThemeFamily { panel_background: Some(rgba(0x1f2127ff).into()), element_hover: Some(rgba(0x3f404380).into()), element_selected: Some(rgba(0x50515280).into()), - text: Some(rgba(0x8a8986ff).into()), + text: Some(rgba(0xbfbdb6ff).into()), text_muted: Some(rgba(0x58595aff).into()), text_placeholder: Some(rgba(0x58595aff).into()), text_disabled: Some(rgba(0xbfbdb6ff).into()), @@ -365,7 +365,7 @@ pub fn ayu() -> UserThemeFamily { panel_background: Some(rgba(0xececedff).into()), element_hover: Some(rgba(0xcfd1d280).into()), element_selected: Some(rgba(0xc0c2c480).into()), - text: Some(rgba(0x8c8f93ff).into()), + text: Some(rgba(0x5c6166ff).into()), text_muted: Some(rgba(0xb9bbbdff).into()), text_placeholder: Some(rgba(0xb9bbbdff).into()), text_disabled: Some(rgba(0x5c6166ff).into()), @@ -704,7 +704,7 @@ pub fn ayu() -> UserThemeFamily { panel_background: Some(rgba(0x353944ff).into()), element_hover: Some(rgba(0x53565d80).into()), element_selected: Some(rgba(0x63656a80).into()), - text: Some(rgba(0x9a9a98ff).into()), + text: Some(rgba(0xcccac2ff).into()), text_muted: Some(rgba(0x6b6d71ff).into()), text_placeholder: Some(rgba(0x6b6d71ff).into()), text_disabled: Some(rgba(0xcccac2ff).into()), diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index 2dcf717c47561b05d88a60045379f32c481227d1..8b85ff285481da1ae6aeaf84e0c12229bf9a1cad 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -26,7 +26,7 @@ pub fn gruvbox() -> UserThemeFamily { panel_background: Some(rgba(0xecddb5ff).into()), element_hover: Some(rgba(0xc9b99a80).into()), element_selected: Some(rgba(0xb5a68e80).into()), - text: Some(rgba(0x5f5650ff).into()), + text: Some(rgba(0x282828ff).into()), text_muted: Some(rgba(0xad9e87ff).into()), text_placeholder: Some(rgba(0xad9e87ff).into()), text_disabled: Some(rgba(0x282828ff).into()), @@ -372,7 +372,7 @@ pub fn gruvbox() -> UserThemeFamily { panel_background: Some(rgba(0x3b3735ff).into()), element_hover: Some(rgba(0x5b534d80).into()), element_selected: Some(rgba(0x6e635a80).into()), - text: Some(rgba(0xc5b597ff).into()), + text: Some(rgba(0xfbf1c7ff).into()), text_muted: Some(rgba(0x776b61ff).into()), text_placeholder: Some(rgba(0x776b61ff).into()), text_disabled: Some(rgba(0xfbf1c7ff).into()), @@ -718,7 +718,7 @@ pub fn gruvbox() -> UserThemeFamily { panel_background: Some(rgba(0xecddb4ff).into()), element_hover: Some(rgba(0xc9b99a80).into()), element_selected: Some(rgba(0xb5a68e80).into()), - text: Some(rgba(0x5f5650ff).into()), + text: Some(rgba(0x282828ff).into()), text_muted: Some(rgba(0xad9e87ff).into()), text_placeholder: Some(rgba(0xad9e87ff).into()), text_disabled: Some(rgba(0x282828ff).into()), @@ -1064,7 +1064,7 @@ pub fn gruvbox() -> UserThemeFamily { panel_background: Some(rgba(0x3a3735ff).into()), element_hover: Some(rgba(0x5b534d80).into()), element_selected: Some(rgba(0x6e635a80).into()), - text: Some(rgba(0xc5b597ff).into()), + text: Some(rgba(0xfbf1c7ff).into()), text_muted: Some(rgba(0x776b61ff).into()), text_placeholder: Some(rgba(0x776b61ff).into()), text_disabled: Some(rgba(0xfbf1c7ff).into()), @@ -1410,7 +1410,7 @@ pub fn gruvbox() -> UserThemeFamily { panel_background: Some(rgba(0xecdcb3ff).into()), element_hover: Some(rgba(0xc9b99a80).into()), element_selected: Some(rgba(0xb5a68e80).into()), - text: Some(rgba(0x5f5650ff).into()), + text: Some(rgba(0x282828ff).into()), text_muted: Some(rgba(0xad9e87ff).into()), text_placeholder: Some(rgba(0xad9e87ff).into()), text_disabled: Some(rgba(0x282828ff).into()), @@ -1756,7 +1756,7 @@ pub fn gruvbox() -> UserThemeFamily { panel_background: Some(rgba(0x393634ff).into()), element_hover: Some(rgba(0x5b534d80).into()), element_selected: Some(rgba(0x6e635a80).into()), - text: Some(rgba(0xc5b597ff).into()), + text: Some(rgba(0xfbf1c7ff).into()), text_muted: Some(rgba(0x776b61ff).into()), text_placeholder: Some(rgba(0x776b61ff).into()), text_disabled: Some(rgba(0xfbf1c7ff).into()), diff --git a/crates/theme2/src/themes/one.rs b/crates/theme2/src/themes/one.rs index 3a20146be1b19c37562a08b49fb63a65102f93db..8de6c06de6876ae5154ccea9d94b30a0bf89c62e 100644 --- a/crates/theme2/src/themes/one.rs +++ b/crates/theme2/src/themes/one.rs @@ -26,7 +26,7 @@ pub fn one() -> UserThemeFamily { panel_background: Some(rgba(0xebebecff).into()), element_hover: Some(rgba(0xc9c9ca80).into()), element_selected: Some(rgba(0xafafaf80).into()), - text: Some(rgba(0x7f8188ff).into()), + text: Some(rgba(0x383a41ff).into()), text_muted: Some(rgba(0xa7a7a8ff).into()), text_placeholder: Some(rgba(0xa7a7a8ff).into()), text_disabled: Some(rgba(0x383a41ff).into()), @@ -372,7 +372,7 @@ pub fn one() -> UserThemeFamily { panel_background: Some(rgba(0x2f343eff).into()), element_hover: Some(rgba(0x464b5780).into()), element_selected: Some(rgba(0x4f545e80).into()), - text: Some(rgba(0x838994ff).into()), + text: Some(rgba(0xc8ccd4ff).into()), text_muted: Some(rgba(0x545862ff).into()), text_placeholder: Some(rgba(0x545862ff).into()), text_disabled: Some(rgba(0xc8ccd4ff).into()), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index 1dcf523a74304f6555aa38d55a8e97c0e894255b..5f8ed063a35ab28d74548def098c0ce1687369ca 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -26,7 +26,7 @@ pub fn rose_pine() -> UserThemeFamily { panel_background: Some(rgba(0xfef9f2ff).into()), element_hover: Some(rgba(0xdcd6d580).into()), element_selected: Some(rgba(0xc1bac180).into()), - text: Some(rgba(0x706c8cff).into()), + text: Some(rgba(0x575279ff).into()), text_muted: Some(rgba(0xb1abb5ff).into()), text_placeholder: Some(rgba(0xb1abb5ff).into()), text_disabled: Some(rgba(0x575279ff).into()), @@ -379,7 +379,7 @@ pub fn rose_pine() -> UserThemeFamily { panel_background: Some(rgba(0x28253cff).into()), element_hover: Some(rgba(0x504c6880).into()), element_selected: Some(rgba(0x45415d80).into()), - text: Some(rgba(0x85819eff).into()), + text: Some(rgba(0xe0def4ff).into()), text_muted: Some(rgba(0x3a3653ff).into()), text_placeholder: Some(rgba(0x3a3653ff).into()), text_disabled: Some(rgba(0xe0def4ff).into()), @@ -732,7 +732,7 @@ pub fn rose_pine() -> UserThemeFamily { panel_background: Some(rgba(0x1d1b2aff).into()), element_hover: Some(rgba(0x423f5580).into()), element_selected: Some(rgba(0x47445b80).into()), - text: Some(rgba(0x75718eff).into()), + text: Some(rgba(0xe0def4ff).into()), text_muted: Some(rgba(0x3b384fff).into()), text_placeholder: Some(rgba(0x3b384fff).into()), text_disabled: Some(rgba(0xe0def4ff).into()), diff --git a/crates/theme2/src/themes/sandcastle.rs b/crates/theme2/src/themes/sandcastle.rs index c0bd53b2d6506d5b148245398f77a413314f4be8..9b6828d82f5c9ae18873582b552e0b31c5e0b1bb 100644 --- a/crates/theme2/src/themes/sandcastle.rs +++ b/crates/theme2/src/themes/sandcastle.rs @@ -25,7 +25,7 @@ pub fn sandcastle() -> UserThemeFamily { panel_background: Some(rgba(0x2b3039ff).into()), element_hover: Some(rgba(0x3d435080).into()), element_selected: Some(rgba(0x57535380).into()), - text: Some(rgba(0xa69782ff).into()), + text: Some(rgba(0xfdf4c1ff).into()), text_muted: Some(rgba(0x645b54ff).into()), text_placeholder: Some(rgba(0x645b54ff).into()), text_disabled: Some(rgba(0xfdf4c1ff).into()), diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index e358537dfbaa418bd49501f0f23a7777e96c00d1..7aece1c6c47929e7551c14819c4af381fb05e056 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -26,7 +26,7 @@ pub fn solarized() -> UserThemeFamily { panel_background: Some(rgba(0xf3eddaff).into()), element_hover: Some(rgba(0x9faaa880).into()), element_selected: Some(rgba(0x7f919480).into()), - text: Some(rgba(0x34555eff).into()), + text: Some(rgba(0x002b36ff).into()), text_muted: Some(rgba(0x788b8fff).into()), text_placeholder: Some(rgba(0x788b8fff).into()), text_disabled: Some(rgba(0x002b36ff).into()), @@ -365,7 +365,7 @@ pub fn solarized() -> UserThemeFamily { panel_background: Some(rgba(0x04313cff).into()), element_hover: Some(rgba(0x2b4f5880).into()), element_selected: Some(rgba(0x566d7480).into()), - text: Some(rgba(0x93a1a1ff).into()), + text: Some(rgba(0xfdf6e3ff).into()), text_muted: Some(rgba(0x5f757dff).into()), text_placeholder: Some(rgba(0x5f757dff).into()), text_disabled: Some(rgba(0xfdf6e3ff).into()), diff --git a/crates/theme2/src/themes/summercamp.rs b/crates/theme2/src/themes/summercamp.rs index eab403fe79fcd53463dc3ac4e4714ebe24528c0a..6d36acd2edee5ba08c8873b704e141023081321a 100644 --- a/crates/theme2/src/themes/summercamp.rs +++ b/crates/theme2/src/themes/summercamp.rs @@ -25,7 +25,7 @@ pub fn summercamp() -> UserThemeFamily { panel_background: Some(rgba(0x231f16ff).into()), element_hover: Some(rgba(0x312d2180).into()), element_selected: Some(rgba(0x39342780).into()), - text: Some(rgba(0x736e55ff).into()), + text: Some(rgba(0xf8f5deff).into()), text_muted: Some(rgba(0x3d382aff).into()), text_placeholder: Some(rgba(0x3d382aff).into()), text_disabled: Some(rgba(0xf8f5deff).into()), diff --git a/crates/theme_importer/src/zed1/converter.rs b/crates/theme_importer/src/zed1/converter.rs index 87318199cf61b220772e46264f6f75355a0ca3de..2ce98a497bdb8a06e64d53d3015beca88be90bad 100644 --- a/crates/theme_importer/src/zed1/converter.rs +++ b/crates/theme_importer/src/zed1/converter.rs @@ -116,7 +116,7 @@ impl Zed1ThemeConverter { .container .background_color .map(zed1_color_to_hsla), - text: convert(self.theme.project_panel.entry.default_style().text.color), + text: convert(self.theme.collab_panel.channel_name.text.color), text_muted: convert(active_tab.description.text.color), text_accent: convert(status_bar.panel_buttons.button.active_state().icon_color), text_disabled: convert(status_bar.panel_buttons.button.disabled_style().icon_color), From 9cb613245e319d996f6918ed119bd4c2aef43c57 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 21:18:43 -0500 Subject: [PATCH 315/644] Adjust border colors --- crates/theme2/src/themes/andromeda.rs | 4 +- crates/theme2/src/themes/atelier.rs | 80 ++++++++++----------- crates/theme2/src/themes/ayu.rs | 12 ++-- crates/theme2/src/themes/gruvbox.rs | 24 +++---- crates/theme2/src/themes/one.rs | 8 +-- crates/theme2/src/themes/rose_pine.rs | 12 ++-- crates/theme2/src/themes/sandcastle.rs | 4 +- crates/theme2/src/themes/solarized.rs | 8 +-- crates/theme2/src/themes/summercamp.rs | 4 +- crates/theme_importer/src/zed1/converter.rs | 6 +- 10 files changed, 80 insertions(+), 82 deletions(-) diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index 2130653e57b18701de0e1fac6248a4fd92597a2f..a7cf529222375bb1ece74e412f070dc69937e731 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -18,8 +18,8 @@ pub fn andromeda() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x2b2f39ff).into()), - border_variant: Some(rgba(0x2b2f39ff).into()), + border: Some(rgba(0x252931ff).into()), + border_variant: Some(rgba(0x21232aff).into()), elevated_surface_background: Some(rgba(0x262a33ff).into()), background: Some(rgba(0x262a33ff).into()), panel_background: Some(rgba(0x21242bff).into()), diff --git a/crates/theme2/src/themes/atelier.rs b/crates/theme2/src/themes/atelier.rs index 869fa44c0d7ac62a14922cadb6ec5d5f87f25f1a..3a1f94c8880537445d779d3bdcec2e0e957233e3 100644 --- a/crates/theme2/src/themes/atelier.rs +++ b/crates/theme2/src/themes/atelier.rs @@ -19,8 +19,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x969585ff).into()), - border_variant: Some(rgba(0x969585ff).into()), + border: Some(rgba(0xd1d0c6ff).into()), + border_variant: Some(rgba(0xedece5ff).into()), elevated_surface_background: Some(rgba(0xc5c4b9ff).into()), background: Some(rgba(0xc5c4b9ff).into()), panel_background: Some(rgba(0xebeae3ff).into()), @@ -379,8 +379,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x665f5cff).into()), - border_variant: Some(rgba(0x665f5cff).into()), + border: Some(rgba(0x3b3431ff).into()), + border_variant: Some(rgba(0x251f1dff).into()), elevated_surface_background: Some(rgba(0x443c39ff).into()), background: Some(rgba(0x443c39ff).into()), panel_background: Some(rgba(0x27211eff).into()), @@ -739,8 +739,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x8b968eff).into()), - border_variant: Some(rgba(0x8b968eff).into()), + border: Some(rgba(0xc8d1cbff).into()), + border_variant: Some(rgba(0xe5ede7ff).into()), elevated_surface_background: Some(rgba(0xbcc5bfff).into()), background: Some(rgba(0xbcc5bfff).into()), panel_background: Some(rgba(0xe3ebe6ff).into()), @@ -1099,8 +1099,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x56505eff).into()), - border_variant: Some(rgba(0x56505eff).into()), + border: Some(rgba(0x332f38ff).into()), + border_variant: Some(rgba(0x201e24ff).into()), elevated_surface_background: Some(rgba(0x3a353fff).into()), background: Some(rgba(0x3a353fff).into()), panel_background: Some(rgba(0x221f26ff).into()), @@ -1459,8 +1459,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x5d5c4cff).into()), - border_variant: Some(rgba(0x5d5c4cff).into()), + border: Some(rgba(0x3c3b31ff).into()), + border_variant: Some(rgba(0x2a2922ff).into()), elevated_surface_background: Some(rgba(0x424136ff).into()), background: Some(rgba(0x424136ff).into()), panel_background: Some(rgba(0x2c2b23ff).into()), @@ -1819,8 +1819,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x5c6485ff).into()), - border_variant: Some(rgba(0x5c6485ff).into()), + border: Some(rgba(0x363f62ff).into()), + border_variant: Some(rgba(0x252d4fff).into()), elevated_surface_background: Some(rgba(0x3e4769ff).into()), background: Some(rgba(0x3e4769ff).into()), panel_background: Some(rgba(0x262f51ff).into()), @@ -2179,8 +2179,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x9a9fb6ff).into()), - border_variant: Some(rgba(0x9a9fb6ff).into()), + border: Some(rgba(0xccd0e1ff).into()), + border_variant: Some(rgba(0xe9ebf7ff).into()), elevated_surface_background: Some(rgba(0xc2c6d9ff).into()), background: Some(rgba(0xc2c6d9ff).into()), panel_background: Some(rgba(0xe5e8f5ff).into()), @@ -2539,8 +2539,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x6c695cff).into()), - border_variant: Some(rgba(0x6c695cff).into()), + border: Some(rgba(0x3b3933ff).into()), + border_variant: Some(rgba(0x252521ff).into()), elevated_surface_background: Some(rgba(0x45433bff).into()), background: Some(rgba(0x45433bff).into()), panel_background: Some(rgba(0x262622ff).into()), @@ -2899,8 +2899,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x5c6c5cff).into()), - border_variant: Some(rgba(0x5c6c5cff).into()), + border: Some(rgba(0x333b33ff).into()), + border_variant: Some(rgba(0x1d201dff).into()), elevated_surface_background: Some(rgba(0x3b453bff).into()), background: Some(rgba(0x3b453bff).into()), panel_background: Some(rgba(0x1f231fff).into()), @@ -3259,8 +3259,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x8f8b96ff).into()), - border_variant: Some(rgba(0x8f8b96ff).into()), + border: Some(rgba(0xcbc8d1ff).into()), + border_variant: Some(rgba(0xe8e5edff).into()), elevated_surface_background: Some(rgba(0xbfbcc5ff).into()), background: Some(rgba(0xbfbcc5ff).into()), panel_background: Some(rgba(0xe6e3ebff).into()), @@ -3619,8 +3619,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x564e4eff).into()), - border_variant: Some(rgba(0x564e4eff).into()), + border: Some(rgba(0x352f2fff).into()), + border_variant: Some(rgba(0x231f1fff).into()), elevated_surface_background: Some(rgba(0x3b3535ff).into()), background: Some(rgba(0x3b3535ff).into()), panel_background: Some(rgba(0x252020ff).into()), @@ -3979,8 +3979,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x675b67ff).into()), - border_variant: Some(rgba(0x675b67ff).into()), + border: Some(rgba(0x393239ff).into()), + border_variant: Some(rgba(0x231e23ff).into()), elevated_surface_background: Some(rgba(0x433a43ff).into()), background: Some(rgba(0x433a43ff).into()), panel_background: Some(rgba(0x252025ff).into()), @@ -4339,8 +4339,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x4f6b78ff).into()), - border_variant: Some(rgba(0x4f6b78ff).into()), + border: Some(rgba(0x2c3b42ff).into()), + border_variant: Some(rgba(0x1b2327ff).into()), elevated_surface_background: Some(rgba(0x33444dff).into()), background: Some(rgba(0x33444dff).into()), panel_background: Some(rgba(0x1c2529ff).into()), @@ -4699,8 +4699,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xaaa3a1ff).into()), - border_variant: Some(rgba(0xaaa3a1ff).into()), + border: Some(rgba(0xd6d1cfff).into()), + border_variant: Some(rgba(0xebe8e6ff).into()), elevated_surface_background: Some(rgba(0xcdc8c6ff).into()), background: Some(rgba(0xcdc8c6ff).into()), panel_background: Some(rgba(0xe9e6e4ff).into()), @@ -5059,8 +5059,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xa8a48eff).into()), - border_variant: Some(rgba(0xa8a48eff).into()), + border: Some(rgba(0xd7d3beff).into()), + border_variant: Some(rgba(0xf2eedcff).into()), elevated_surface_background: Some(rgba(0xcecab4ff).into()), background: Some(rgba(0xcecab4ff).into()), panel_background: Some(rgba(0xeeebd7ff).into()), @@ -5419,8 +5419,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x8e8989ff).into()), - border_variant: Some(rgba(0x8e8989ff).into()), + border: Some(rgba(0xcfc7c7ff).into()), + border_variant: Some(rgba(0xede5e5ff).into()), elevated_surface_background: Some(rgba(0xc1bbbbff).into()), background: Some(rgba(0xc1bbbbff).into()), panel_background: Some(rgba(0xebe3e3ff).into()), @@ -5779,8 +5779,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x8ea88eff).into()), - border_variant: Some(rgba(0x8ea88eff).into()), + border: Some(rgba(0xbed7beff).into()), + border_variant: Some(rgba(0xdff0dfff).into()), elevated_surface_background: Some(rgba(0xb4ceb4ff).into()), background: Some(rgba(0xb4ceb4ff).into()), panel_background: Some(rgba(0xdaeedaff).into()), @@ -6139,8 +6139,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x505e55ff).into()), - border_variant: Some(rgba(0x505e55ff).into()), + border: Some(rgba(0x2f3832ff).into()), + border_variant: Some(rgba(0x1e2420ff).into()), elevated_surface_background: Some(rgba(0x353f39ff).into()), background: Some(rgba(0x353f39ff).into()), panel_background: Some(rgba(0x1f2621ff).into()), @@ -6499,8 +6499,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xad9dadff).into()), - border_variant: Some(rgba(0xad9dadff).into()), + border: Some(rgba(0xcdbecdff).into()), + border_variant: Some(rgba(0xe5dce5ff).into()), elevated_surface_background: Some(rgba(0xc6b8c6ff).into()), background: Some(rgba(0xc6b8c6ff).into()), panel_background: Some(rgba(0xe1d6e1ff).into()), @@ -6859,8 +6859,8 @@ pub fn atelier() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x80a4b6ff).into()), - border_variant: Some(rgba(0x80a4b6ff).into()), + border: Some(rgba(0xb0d3e5ff).into()), + border_variant: Some(rgba(0xd3edfaff).into()), elevated_surface_background: Some(rgba(0xa6cadcff).into()), background: Some(rgba(0xa6cadcff).into()), panel_background: Some(rgba(0xcdeaf9ff).into()), diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index 45b6cea310b5af8ae3614064adfa7e4241b9dc44..deab32b8124920fc89a04f5b44da73c346437e51 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -19,8 +19,8 @@ pub fn ayu() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x3f4043ff).into()), - border_variant: Some(rgba(0x3f4043ff).into()), + border: Some(rgba(0x2d2f34ff).into()), + border_variant: Some(rgba(0x1b1e24ff).into()), elevated_surface_background: Some(rgba(0x313337ff).into()), background: Some(rgba(0x313337ff).into()), panel_background: Some(rgba(0x1f2127ff).into()), @@ -358,8 +358,8 @@ pub fn ayu() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xcfd1d2ff).into()), - border_variant: Some(rgba(0xcfd1d2ff).into()), + border: Some(rgba(0xdfe0e1ff).into()), + border_variant: Some(rgba(0xefeff0ff).into()), elevated_surface_background: Some(rgba(0xdcdddeff).into()), background: Some(rgba(0xdcdddeff).into()), panel_background: Some(rgba(0xececedff).into()), @@ -697,8 +697,8 @@ pub fn ayu() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x53565dff).into()), - border_variant: Some(rgba(0x53565dff).into()), + border: Some(rgba(0x43464fff).into()), + border_variant: Some(rgba(0x323641ff).into()), elevated_surface_background: Some(rgba(0x464a52ff).into()), background: Some(rgba(0x464a52ff).into()), panel_background: Some(rgba(0x353944ff).into()), diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index 8b85ff285481da1ae6aeaf84e0c12229bf9a1cad..8512706fd4fd3d8c249fc94f4708880a896052fa 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -19,8 +19,8 @@ pub fn gruvbox() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xc9b99aff).into()), - border_variant: Some(rgba(0xc9b99aff).into()), + border: Some(rgba(0xddcca7ff).into()), + border_variant: Some(rgba(0xefe2bcff).into()), elevated_surface_background: Some(rgba(0xd9c8a4ff).into()), background: Some(rgba(0xd9c8a4ff).into()), panel_background: Some(rgba(0xecddb5ff).into()), @@ -365,8 +365,8 @@ pub fn gruvbox() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x5b534dff).into()), - border_variant: Some(rgba(0x5b534dff).into()), + border: Some(rgba(0x494340ff).into()), + border_variant: Some(rgba(0x393634ff).into()), elevated_surface_background: Some(rgba(0x4c4642ff).into()), background: Some(rgba(0x4c4642ff).into()), panel_background: Some(rgba(0x3b3735ff).into()), @@ -711,8 +711,8 @@ pub fn gruvbox() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xc9b99aff).into()), - border_variant: Some(rgba(0xc9b99aff).into()), + border: Some(rgba(0xddcca7ff).into()), + border_variant: Some(rgba(0xefe1b8ff).into()), elevated_surface_background: Some(rgba(0xd9c8a4ff).into()), background: Some(rgba(0xd9c8a4ff).into()), panel_background: Some(rgba(0xecddb4ff).into()), @@ -1057,8 +1057,8 @@ pub fn gruvbox() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x5b534dff).into()), - border_variant: Some(rgba(0x5b534dff).into()), + border: Some(rgba(0x494340ff).into()), + border_variant: Some(rgba(0x373432ff).into()), elevated_surface_background: Some(rgba(0x4c4642ff).into()), background: Some(rgba(0x4c4642ff).into()), panel_background: Some(rgba(0x3a3735ff).into()), @@ -1403,8 +1403,8 @@ pub fn gruvbox() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xc9b99aff).into()), - border_variant: Some(rgba(0xc9b99aff).into()), + border: Some(rgba(0xddcca7ff).into()), + border_variant: Some(rgba(0xeddeb5ff).into()), elevated_surface_background: Some(rgba(0xd9c8a4ff).into()), background: Some(rgba(0xd9c8a4ff).into()), panel_background: Some(rgba(0xecdcb3ff).into()), @@ -1749,8 +1749,8 @@ pub fn gruvbox() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x5b534dff).into()), - border_variant: Some(rgba(0x5b534dff).into()), + border: Some(rgba(0x494340ff).into()), + border_variant: Some(rgba(0x343130ff).into()), elevated_surface_background: Some(rgba(0x4c4642ff).into()), background: Some(rgba(0x4c4642ff).into()), panel_background: Some(rgba(0x393634ff).into()), diff --git a/crates/theme2/src/themes/one.rs b/crates/theme2/src/themes/one.rs index 8de6c06de6876ae5154ccea9d94b30a0bf89c62e..dcd90bf1afed088f984a0ed8ade8fd00c82f3bf8 100644 --- a/crates/theme2/src/themes/one.rs +++ b/crates/theme2/src/themes/one.rs @@ -19,8 +19,8 @@ pub fn one() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xc9c9caff).into()), - border_variant: Some(rgba(0xc9c9caff).into()), + border: Some(rgba(0xdfdfe0ff).into()), + border_variant: Some(rgba(0xeeeeeeff).into()), elevated_surface_background: Some(rgba(0xdcdcddff).into()), background: Some(rgba(0xdcdcddff).into()), panel_background: Some(rgba(0xebebecff).into()), @@ -365,8 +365,8 @@ pub fn one() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x464b57ff).into()), - border_variant: Some(rgba(0x464b57ff).into()), + border: Some(rgba(0x363c46ff).into()), + border_variant: Some(rgba(0x2e333cff).into()), elevated_surface_background: Some(rgba(0x3b414dff).into()), background: Some(rgba(0x3b414dff).into()), panel_background: Some(rgba(0x2f343eff).into()), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index 5f8ed063a35ab28d74548def098c0ce1687369ca..a08618ca6a85657f0c1b9d51918e4b4121f06175 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -19,8 +19,8 @@ pub fn rose_pine() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0xdcd6d5ff).into()), - border_variant: Some(rgba(0xdcd6d5ff).into()), + border: Some(rgba(0xe5e0dfff).into()), + border_variant: Some(rgba(0xfdf8f1ff).into()), elevated_surface_background: Some(rgba(0xdcd8d8ff).into()), background: Some(rgba(0xdcd8d8ff).into()), panel_background: Some(rgba(0xfef9f2ff).into()), @@ -372,8 +372,8 @@ pub fn rose_pine() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x504c68ff).into()), - border_variant: Some(rgba(0x504c68ff).into()), + border: Some(rgba(0x322f48ff).into()), + border_variant: Some(rgba(0x27243bff).into()), elevated_surface_background: Some(rgba(0x38354eff).into()), background: Some(rgba(0x38354eff).into()), panel_background: Some(rgba(0x28253cff).into()), @@ -725,8 +725,8 @@ pub fn rose_pine() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x423f55ff).into()), - border_variant: Some(rgba(0x423f55ff).into()), + border: Some(rgba(0x232132ff).into()), + border_variant: Some(rgba(0x1c1a29ff).into()), elevated_surface_background: Some(rgba(0x292739ff).into()), background: Some(rgba(0x292739ff).into()), panel_background: Some(rgba(0x1d1b2aff).into()), diff --git a/crates/theme2/src/themes/sandcastle.rs b/crates/theme2/src/themes/sandcastle.rs index 9b6828d82f5c9ae18873582b552e0b31c5e0b1bb..38b6e046654481f6bc1d363bf9a1cd02131480d9 100644 --- a/crates/theme2/src/themes/sandcastle.rs +++ b/crates/theme2/src/themes/sandcastle.rs @@ -18,8 +18,8 @@ pub fn sandcastle() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x3d4350ff).into()), - border_variant: Some(rgba(0x3d4350ff).into()), + border: Some(rgba(0x313741ff).into()), + border_variant: Some(rgba(0x2a2f38ff).into()), elevated_surface_background: Some(rgba(0x333944ff).into()), background: Some(rgba(0x333944ff).into()), panel_background: Some(rgba(0x2b3039ff).into()), diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index 7aece1c6c47929e7551c14819c4af381fb05e056..a09ca0e0cc1a933d913bfb00ae5b22732c3a2db0 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -19,8 +19,8 @@ pub fn solarized() -> UserThemeFamily { appearance: Appearance::Light, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x9faaa8ff).into()), - border_variant: Some(rgba(0x9faaa8ff).into()), + border: Some(rgba(0xdcdacbff).into()), + border_variant: Some(rgba(0xf5eedbff).into()), elevated_surface_background: Some(rgba(0xcfd0c4ff).into()), background: Some(rgba(0xcfd0c4ff).into()), panel_background: Some(rgba(0xf3eddaff).into()), @@ -358,8 +358,8 @@ pub fn solarized() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x2b4f58ff).into()), - border_variant: Some(rgba(0x2b4f58ff).into()), + border: Some(rgba(0x063541ff).into()), + border_variant: Some(rgba(0x032f3bff).into()), elevated_surface_background: Some(rgba(0x083743ff).into()), background: Some(rgba(0x083743ff).into()), panel_background: Some(rgba(0x04313cff).into()), diff --git a/crates/theme2/src/themes/summercamp.rs b/crates/theme2/src/themes/summercamp.rs index 6d36acd2edee5ba08c8873b704e141023081321a..c27d8369c3bca15aabf9742c1b17ea5879ef4707 100644 --- a/crates/theme2/src/themes/summercamp.rs +++ b/crates/theme2/src/themes/summercamp.rs @@ -18,8 +18,8 @@ pub fn summercamp() -> UserThemeFamily { appearance: Appearance::Dark, styles: UserThemeStylesRefinement { colors: ThemeColorsRefinement { - border: Some(rgba(0x312d21ff).into()), - border_variant: Some(rgba(0x312d21ff).into()), + border: Some(rgba(0x29251bff).into()), + border_variant: Some(rgba(0x221e15ff).into()), elevated_surface_background: Some(rgba(0x2a261cff).into()), background: Some(rgba(0x2a261cff).into()), panel_background: Some(rgba(0x231f16ff).into()), diff --git a/crates/theme_importer/src/zed1/converter.rs b/crates/theme_importer/src/zed1/converter.rs index 2ce98a497bdb8a06e64d53d3015beca88be90bad..6543f216355ac3139f5b5dca2eee0861bc019fec 100644 --- a/crates/theme_importer/src/zed1/converter.rs +++ b/crates/theme_importer/src/zed1/converter.rs @@ -99,11 +99,9 @@ impl Zed1ThemeConverter { let scrollbar = &self.theme.editor.scrollbar; let terminal = &self.theme.terminal; - let title_bar_border = convert(title_bar.container.border.color); - Ok(ThemeColorsRefinement { - border: title_bar_border, - border_variant: title_bar_border, + border: convert(active_tab.container.border.color), + border_variant: convert(toolbar.container.border.color), background: convert(self.theme.workspace.background), elevated_surface_background: picker.container.background_color.map(zed1_color_to_hsla), title_bar_background: title_bar.container.background_color.map(zed1_color_to_hsla), From bdb89d470034fe41d4d6afda57375c3781dd8375 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 21:25:31 -0500 Subject: [PATCH 316/644] Render tab bar tools as muted --- crates/workspace2/src/pane.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 893c5222220339ad02d9c89a084159ba0b253465..bcf36dfe18e4d93d611d1403e68d0155979675d2 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -381,6 +381,7 @@ impl Pane { .child( IconButton::new("plus", Icon::Plus) .icon_size(IconSize::Small) + .icon_color(Color::Muted) .on_click(cx.listener(|pane, _, cx| { let menu = ContextMenu::build(cx, |menu, _| { menu.action("New File", NewFile.boxed_clone()) @@ -402,6 +403,7 @@ impl Pane { .child( IconButton::new("split", Icon::Split) .icon_size(IconSize::Small) + .icon_color(Color::Muted) .on_click(cx.listener(|pane, _, cx| { let menu = ContextMenu::build(cx, |menu, _| { menu.action("Split Right", SplitRight.boxed_clone()) @@ -422,6 +424,7 @@ impl Pane { let zoomed = pane.is_zoomed(); IconButton::new("toggle_zoom", Icon::Maximize) .icon_size(IconSize::Small) + .icon_color(Color::Muted) .selected(zoomed) .selected_icon(Icon::Minimize) .on_click(cx.listener(|pane, _, cx| { From 04d26353d281097b68556808812181c45927f1f5 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 21:25:45 -0500 Subject: [PATCH 317/644] Adjust muted text colors --- crates/theme2/src/themes/andromeda.rs | 2 +- crates/theme2/src/themes/atelier.rs | 40 ++++++++++----------- crates/theme2/src/themes/ayu.rs | 6 ++-- crates/theme2/src/themes/gruvbox.rs | 12 +++---- crates/theme2/src/themes/one.rs | 4 +-- crates/theme2/src/themes/rose_pine.rs | 6 ++-- crates/theme2/src/themes/sandcastle.rs | 2 +- crates/theme2/src/themes/solarized.rs | 4 +-- crates/theme2/src/themes/summercamp.rs | 2 +- crates/theme_importer/src/zed1/converter.rs | 2 +- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index a7cf529222375bb1ece74e412f070dc69937e731..fd61f9b482192048538a13ba6c110e85bcd8b389 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -26,7 +26,7 @@ pub fn andromeda() -> UserThemeFamily { element_hover: Some(rgba(0x2b2f3980).into()), element_selected: Some(rgba(0x383b4580).into()), text: Some(rgba(0xf7f7f8ff).into()), - text_muted: Some(rgba(0x474a53ff).into()), + text_muted: Some(rgba(0xaca8aeff).into()), text_placeholder: Some(rgba(0x474a53ff).into()), text_disabled: Some(rgba(0xf7f7f8ff).into()), text_accent: Some(rgba(0x11a793ff).into()), diff --git a/crates/theme2/src/themes/atelier.rs b/crates/theme2/src/themes/atelier.rs index 3a1f94c8880537445d779d3bdcec2e0e957233e3..6c942d5b4c65b7187ea115f8133c98d3d83b5c28 100644 --- a/crates/theme2/src/themes/atelier.rs +++ b/crates/theme2/src/themes/atelier.rs @@ -27,7 +27,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x96958580).into()), element_selected: Some(rgba(0x8b8a7880).into()), text: Some(rgba(0x22221bff).into()), - text_muted: Some(rgba(0x878573ff).into()), + text_muted: Some(rgba(0x61604fff).into()), text_placeholder: Some(rgba(0x878573ff).into()), text_disabled: Some(rgba(0x22221bff).into()), text_accent: Some(rgba(0x38a166ff).into()), @@ -387,7 +387,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x665f5c80).into()), element_selected: Some(rgba(0x71696680).into()), text: Some(rgba(0xf1efeeff).into()), - text_muted: Some(rgba(0x766e6bff).into()), + text_muted: Some(rgba(0xa79f9dff).into()), text_placeholder: Some(rgba(0x766e6bff).into()), text_disabled: Some(rgba(0xf1efeeff).into()), text_accent: Some(rgba(0x417ee6ff).into()), @@ -747,7 +747,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x8b968e80).into()), element_selected: Some(rgba(0x7e8b8280).into()), text: Some(rgba(0x171c19ff).into()), - text_muted: Some(rgba(0x79877dff).into()), + text_muted: Some(rgba(0x546259ff).into()), text_placeholder: Some(rgba(0x79877dff).into()), text_disabled: Some(rgba(0x171c19ff).into()), text_accent: Some(rgba(0x488c90ff).into()), @@ -1107,7 +1107,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x56505e80).into()), element_selected: Some(rgba(0x605a6880).into()), text: Some(rgba(0xefecf4ff).into()), - text_muted: Some(rgba(0x655f6dff).into()), + text_muted: Some(rgba(0x898591ff).into()), text_placeholder: Some(rgba(0x655f6dff).into()), text_disabled: Some(rgba(0xefecf4ff).into()), text_accent: Some(rgba(0x576ddaff).into()), @@ -1467,7 +1467,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x5d5c4c80).into()), element_selected: Some(rgba(0x67665580).into()), text: Some(rgba(0xf4f3ecff).into()), - text_muted: Some(rgba(0x6c6b5aff).into()), + text_muted: Some(rgba(0x91907fff).into()), text_placeholder: Some(rgba(0x6c6b5aff).into()), text_disabled: Some(rgba(0xf4f3ecff).into()), text_accent: Some(rgba(0x37a166ff).into()), @@ -1827,7 +1827,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x5c648580).into()), element_selected: Some(rgba(0x666e8f80).into()), text: Some(rgba(0xf5f7ffff).into()), - text_muted: Some(rgba(0x6b7394ff).into()), + text_muted: Some(rgba(0x959bb2ff).into()), text_placeholder: Some(rgba(0x6b7394ff).into()), text_disabled: Some(rgba(0xf5f7ffff).into()), text_accent: Some(rgba(0x3e8fd0ff).into()), @@ -2187,7 +2187,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x9a9fb680).into()), element_selected: Some(rgba(0x8e94aa80).into()), text: Some(rgba(0x202746ff).into()), - text_muted: Some(rgba(0x898fa5ff).into()), + text_muted: Some(rgba(0x606889ff).into()), text_placeholder: Some(rgba(0x898fa5ff).into()), text_disabled: Some(rgba(0x202746ff).into()), text_accent: Some(rgba(0x3f8fd0ff).into()), @@ -2547,7 +2547,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x6c695c80).into()), element_selected: Some(rgba(0x77746480).into()), text: Some(rgba(0xfefbecff).into()), - text_muted: Some(rgba(0x7c7968ff).into()), + text_muted: Some(rgba(0xa4a08bff).into()), text_placeholder: Some(rgba(0x7c7968ff).into()), text_disabled: Some(rgba(0xfefbecff).into()), text_accent: Some(rgba(0x6684e0ff).into()), @@ -2907,7 +2907,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x5c6c5c80).into()), element_selected: Some(rgba(0x64776480).into()), text: Some(rgba(0xf4fbf4ff).into()), - text_muted: Some(rgba(0x687c68ff).into()), + text_muted: Some(rgba(0x8ba48bff).into()), text_placeholder: Some(rgba(0x687c68ff).into()), text_disabled: Some(rgba(0xf4fbf4ff).into()), text_accent: Some(rgba(0x3e62f4ff).into()), @@ -3267,7 +3267,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x8f8b9680).into()), element_selected: Some(rgba(0x837e8b80).into()), text: Some(rgba(0x19171cff).into()), - text_muted: Some(rgba(0x7e7987ff).into()), + text_muted: Some(rgba(0x5a5462ff).into()), text_placeholder: Some(rgba(0x7e7987ff).into()), text_disabled: Some(rgba(0x19171cff).into()), text_accent: Some(rgba(0x586ddaff).into()), @@ -3627,7 +3627,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x564e4e80).into()), element_selected: Some(rgba(0x60585880).into()), text: Some(rgba(0xf4ececff).into()), - text_muted: Some(rgba(0x655d5dff).into()), + text_muted: Some(rgba(0x898383ff).into()), text_placeholder: Some(rgba(0x655d5dff).into()), text_disabled: Some(rgba(0xf4ececff).into()), text_accent: Some(rgba(0x7272caff).into()), @@ -3987,7 +3987,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x675b6780).into()), element_selected: Some(rgba(0x72647280).into()), text: Some(rgba(0xf7f3f7ff).into()), - text_muted: Some(rgba(0x776977ff).into()), + text_muted: Some(rgba(0xa99aa9ff).into()), text_placeholder: Some(rgba(0x776977ff).into()), text_disabled: Some(rgba(0xf7f3f7ff).into()), text_accent: Some(rgba(0x526aebff).into()), @@ -4347,7 +4347,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x4f6b7880).into()), element_selected: Some(rgba(0x57768580).into()), text: Some(rgba(0xebf8ffff).into()), - text_muted: Some(rgba(0x5a7b8bff).into()), + text_muted: Some(rgba(0x7ca0b3ff).into()), text_placeholder: Some(rgba(0x5a7b8bff).into()), text_disabled: Some(rgba(0xebf8ffff).into()), text_accent: Some(rgba(0x277fadff).into()), @@ -4707,7 +4707,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0xaaa3a180).into()), element_selected: Some(rgba(0xa1999680).into()), text: Some(rgba(0x1b1918ff).into()), - text_muted: Some(rgba(0x9c9491ff).into()), + text_muted: Some(rgba(0x6a6360ff).into()), text_placeholder: Some(rgba(0x9c9491ff).into()), text_disabled: Some(rgba(0x1b1918ff).into()), text_accent: Some(rgba(0x417ee6ff).into()), @@ -5067,7 +5067,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0xa8a48e80).into()), element_selected: Some(rgba(0x9e9a8580).into()), text: Some(rgba(0x20201dff).into()), - text_muted: Some(rgba(0x999580ff).into()), + text_muted: Some(rgba(0x706d5fff).into()), text_placeholder: Some(rgba(0x999580ff).into()), text_disabled: Some(rgba(0x20201dff).into()), text_accent: Some(rgba(0x6784e0ff).into()), @@ -5427,7 +5427,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x8e898980).into()), element_selected: Some(rgba(0x837c7c80).into()), text: Some(rgba(0x1b1818ff).into()), - text_muted: Some(rgba(0x7e7777ff).into()), + text_muted: Some(rgba(0x5a5252ff).into()), text_placeholder: Some(rgba(0x7e7777ff).into()), text_disabled: Some(rgba(0x1b1818ff).into()), text_accent: Some(rgba(0x7372caff).into()), @@ -5787,7 +5787,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x8ea88e80).into()), element_selected: Some(rgba(0x859e8580).into()), text: Some(rgba(0x131513ff).into()), - text_muted: Some(rgba(0x809980ff).into()), + text_muted: Some(rgba(0x5f705fff).into()), text_placeholder: Some(rgba(0x809980ff).into()), text_disabled: Some(rgba(0x131513ff).into()), text_accent: Some(rgba(0x3f62f4ff).into()), @@ -6147,7 +6147,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x505e5580).into()), element_selected: Some(rgba(0x5a685f80).into()), text: Some(rgba(0xecf4eeff).into()), - text_muted: Some(rgba(0x5f6d64ff).into()), + text_muted: Some(rgba(0x859188ff).into()), text_placeholder: Some(rgba(0x5f6d64ff).into()), text_disabled: Some(rgba(0xecf4eeff).into()), text_accent: Some(rgba(0x478c90ff).into()), @@ -6507,7 +6507,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0xad9dad80).into()), element_selected: Some(rgba(0xa394a380).into()), text: Some(rgba(0x1b181bff).into()), - text_muted: Some(rgba(0x9e8f9eff).into()), + text_muted: Some(rgba(0x6b5e6bff).into()), text_placeholder: Some(rgba(0x9e8f9eff).into()), text_disabled: Some(rgba(0x1b181bff).into()), text_accent: Some(rgba(0x526aebff).into()), @@ -6867,7 +6867,7 @@ pub fn atelier() -> UserThemeFamily { element_hover: Some(rgba(0x80a4b680).into()), element_selected: Some(rgba(0x769aad80).into()), text: Some(rgba(0x161b1dff).into()), - text_muted: Some(rgba(0x7195a8ff).into()), + text_muted: Some(rgba(0x526f7dff).into()), text_placeholder: Some(rgba(0x7195a8ff).into()), text_disabled: Some(rgba(0x161b1dff).into()), text_accent: Some(rgba(0x277fadff).into()), diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index deab32b8124920fc89a04f5b44da73c346437e51..bc2fe60b040a2ca939ea8a4d09ffbe54c1b98259 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -27,7 +27,7 @@ pub fn ayu() -> UserThemeFamily { element_hover: Some(rgba(0x3f404380).into()), element_selected: Some(rgba(0x50515280).into()), text: Some(rgba(0xbfbdb6ff).into()), - text_muted: Some(rgba(0x58595aff).into()), + text_muted: Some(rgba(0x8a8986ff).into()), text_placeholder: Some(rgba(0x58595aff).into()), text_disabled: Some(rgba(0xbfbdb6ff).into()), text_accent: Some(rgba(0x5ac2feff).into()), @@ -366,7 +366,7 @@ pub fn ayu() -> UserThemeFamily { element_hover: Some(rgba(0xcfd1d280).into()), element_selected: Some(rgba(0xc0c2c480).into()), text: Some(rgba(0x5c6166ff).into()), - text_muted: Some(rgba(0xb9bbbdff).into()), + text_muted: Some(rgba(0x8c8f93ff).into()), text_placeholder: Some(rgba(0xb9bbbdff).into()), text_disabled: Some(rgba(0x5c6166ff).into()), text_accent: Some(rgba(0x3b9ee5ff).into()), @@ -705,7 +705,7 @@ pub fn ayu() -> UserThemeFamily { element_hover: Some(rgba(0x53565d80).into()), element_selected: Some(rgba(0x63656a80).into()), text: Some(rgba(0xcccac2ff).into()), - text_muted: Some(rgba(0x6b6d71ff).into()), + text_muted: Some(rgba(0x9a9a98ff).into()), text_placeholder: Some(rgba(0x6b6d71ff).into()), text_disabled: Some(rgba(0xcccac2ff).into()), text_accent: Some(rgba(0x73cffeff).into()), diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index 8512706fd4fd3d8c249fc94f4708880a896052fa..3db69b5a5463bc1cef83f3967d54ce27feec8295 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -27,7 +27,7 @@ pub fn gruvbox() -> UserThemeFamily { element_hover: Some(rgba(0xc9b99a80).into()), element_selected: Some(rgba(0xb5a68e80).into()), text: Some(rgba(0x282828ff).into()), - text_muted: Some(rgba(0xad9e87ff).into()), + text_muted: Some(rgba(0x5f5650ff).into()), text_placeholder: Some(rgba(0xad9e87ff).into()), text_disabled: Some(rgba(0x282828ff).into()), text_accent: Some(rgba(0x0b6678ff).into()), @@ -373,7 +373,7 @@ pub fn gruvbox() -> UserThemeFamily { element_hover: Some(rgba(0x5b534d80).into()), element_selected: Some(rgba(0x6e635a80).into()), text: Some(rgba(0xfbf1c7ff).into()), - text_muted: Some(rgba(0x776b61ff).into()), + text_muted: Some(rgba(0xc5b597ff).into()), text_placeholder: Some(rgba(0x776b61ff).into()), text_disabled: Some(rgba(0xfbf1c7ff).into()), text_accent: Some(rgba(0x83a598ff).into()), @@ -719,7 +719,7 @@ pub fn gruvbox() -> UserThemeFamily { element_hover: Some(rgba(0xc9b99a80).into()), element_selected: Some(rgba(0xb5a68e80).into()), text: Some(rgba(0x282828ff).into()), - text_muted: Some(rgba(0xad9e87ff).into()), + text_muted: Some(rgba(0x5f5650ff).into()), text_placeholder: Some(rgba(0xad9e87ff).into()), text_disabled: Some(rgba(0x282828ff).into()), text_accent: Some(rgba(0x0b6678ff).into()), @@ -1065,7 +1065,7 @@ pub fn gruvbox() -> UserThemeFamily { element_hover: Some(rgba(0x5b534d80).into()), element_selected: Some(rgba(0x6e635a80).into()), text: Some(rgba(0xfbf1c7ff).into()), - text_muted: Some(rgba(0x776b61ff).into()), + text_muted: Some(rgba(0xc5b597ff).into()), text_placeholder: Some(rgba(0x776b61ff).into()), text_disabled: Some(rgba(0xfbf1c7ff).into()), text_accent: Some(rgba(0x83a598ff).into()), @@ -1411,7 +1411,7 @@ pub fn gruvbox() -> UserThemeFamily { element_hover: Some(rgba(0xc9b99a80).into()), element_selected: Some(rgba(0xb5a68e80).into()), text: Some(rgba(0x282828ff).into()), - text_muted: Some(rgba(0xad9e87ff).into()), + text_muted: Some(rgba(0x5f5650ff).into()), text_placeholder: Some(rgba(0xad9e87ff).into()), text_disabled: Some(rgba(0x282828ff).into()), text_accent: Some(rgba(0x0b6678ff).into()), @@ -1757,7 +1757,7 @@ pub fn gruvbox() -> UserThemeFamily { element_hover: Some(rgba(0x5b534d80).into()), element_selected: Some(rgba(0x6e635a80).into()), text: Some(rgba(0xfbf1c7ff).into()), - text_muted: Some(rgba(0x776b61ff).into()), + text_muted: Some(rgba(0xc5b597ff).into()), text_placeholder: Some(rgba(0x776b61ff).into()), text_disabled: Some(rgba(0xfbf1c7ff).into()), text_accent: Some(rgba(0x83a598ff).into()), diff --git a/crates/theme2/src/themes/one.rs b/crates/theme2/src/themes/one.rs index dcd90bf1afed088f984a0ed8ade8fd00c82f3bf8..7ea2bbea87b6fcc58344a440dba955b37b3a13be 100644 --- a/crates/theme2/src/themes/one.rs +++ b/crates/theme2/src/themes/one.rs @@ -27,7 +27,7 @@ pub fn one() -> UserThemeFamily { element_hover: Some(rgba(0xc9c9ca80).into()), element_selected: Some(rgba(0xafafaf80).into()), text: Some(rgba(0x383a41ff).into()), - text_muted: Some(rgba(0xa7a7a8ff).into()), + text_muted: Some(rgba(0x7f8188ff).into()), text_placeholder: Some(rgba(0xa7a7a8ff).into()), text_disabled: Some(rgba(0x383a41ff).into()), text_accent: Some(rgba(0x5c79e2ff).into()), @@ -373,7 +373,7 @@ pub fn one() -> UserThemeFamily { element_hover: Some(rgba(0x464b5780).into()), element_selected: Some(rgba(0x4f545e80).into()), text: Some(rgba(0xc8ccd4ff).into()), - text_muted: Some(rgba(0x545862ff).into()), + text_muted: Some(rgba(0x838994ff).into()), text_placeholder: Some(rgba(0x545862ff).into()), text_disabled: Some(rgba(0xc8ccd4ff).into()), text_accent: Some(rgba(0x74ade8ff).into()), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index a08618ca6a85657f0c1b9d51918e4b4121f06175..e63e8f2ad879a9dcfdac906f34124d229cf2db8a 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -27,7 +27,7 @@ pub fn rose_pine() -> UserThemeFamily { element_hover: Some(rgba(0xdcd6d580).into()), element_selected: Some(rgba(0xc1bac180).into()), text: Some(rgba(0x575279ff).into()), - text_muted: Some(rgba(0xb1abb5ff).into()), + text_muted: Some(rgba(0x706c8cff).into()), text_placeholder: Some(rgba(0xb1abb5ff).into()), text_disabled: Some(rgba(0x575279ff).into()), text_accent: Some(rgba(0x57949fff).into()), @@ -380,7 +380,7 @@ pub fn rose_pine() -> UserThemeFamily { element_hover: Some(rgba(0x504c6880).into()), element_selected: Some(rgba(0x45415d80).into()), text: Some(rgba(0xe0def4ff).into()), - text_muted: Some(rgba(0x3a3653ff).into()), + text_muted: Some(rgba(0x85819eff).into()), text_placeholder: Some(rgba(0x3a3653ff).into()), text_disabled: Some(rgba(0xe0def4ff).into()), text_accent: Some(rgba(0x9cced7ff).into()), @@ -733,7 +733,7 @@ pub fn rose_pine() -> UserThemeFamily { element_hover: Some(rgba(0x423f5580).into()), element_selected: Some(rgba(0x47445b80).into()), text: Some(rgba(0xe0def4ff).into()), - text_muted: Some(rgba(0x3b384fff).into()), + text_muted: Some(rgba(0x75718eff).into()), text_placeholder: Some(rgba(0x3b384fff).into()), text_disabled: Some(rgba(0xe0def4ff).into()), text_accent: Some(rgba(0x9cced7ff).into()), diff --git a/crates/theme2/src/themes/sandcastle.rs b/crates/theme2/src/themes/sandcastle.rs index 38b6e046654481f6bc1d363bf9a1cd02131480d9..3e66ce97c1d0fb34defea641f669a69dafd1d923 100644 --- a/crates/theme2/src/themes/sandcastle.rs +++ b/crates/theme2/src/themes/sandcastle.rs @@ -26,7 +26,7 @@ pub fn sandcastle() -> UserThemeFamily { element_hover: Some(rgba(0x3d435080).into()), element_selected: Some(rgba(0x57535380).into()), text: Some(rgba(0xfdf4c1ff).into()), - text_muted: Some(rgba(0x645b54ff).into()), + text_muted: Some(rgba(0xa69782ff).into()), text_placeholder: Some(rgba(0x645b54ff).into()), text_disabled: Some(rgba(0xfdf4c1ff).into()), text_accent: Some(rgba(0x528b8bff).into()), diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index a09ca0e0cc1a933d913bfb00ae5b22732c3a2db0..61c3fc8539473ca55ebdd2127cb80c605a3151e0 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -27,7 +27,7 @@ pub fn solarized() -> UserThemeFamily { element_hover: Some(rgba(0x9faaa880).into()), element_selected: Some(rgba(0x7f919480).into()), text: Some(rgba(0x002b36ff).into()), - text_muted: Some(rgba(0x788b8fff).into()), + text_muted: Some(rgba(0x34555eff).into()), text_placeholder: Some(rgba(0x788b8fff).into()), text_disabled: Some(rgba(0x002b36ff).into()), text_accent: Some(rgba(0x298bd1ff).into()), @@ -366,7 +366,7 @@ pub fn solarized() -> UserThemeFamily { element_hover: Some(rgba(0x2b4f5880).into()), element_selected: Some(rgba(0x566d7480).into()), text: Some(rgba(0xfdf6e3ff).into()), - text_muted: Some(rgba(0x5f757dff).into()), + text_muted: Some(rgba(0x93a1a1ff).into()), text_placeholder: Some(rgba(0x5f757dff).into()), text_disabled: Some(rgba(0xfdf6e3ff).into()), text_accent: Some(rgba(0x288bd1ff).into()), diff --git a/crates/theme2/src/themes/summercamp.rs b/crates/theme2/src/themes/summercamp.rs index c27d8369c3bca15aabf9742c1b17ea5879ef4707..3540d824d2c5e01293260bbe1c60a9b00d8706ce 100644 --- a/crates/theme2/src/themes/summercamp.rs +++ b/crates/theme2/src/themes/summercamp.rs @@ -26,7 +26,7 @@ pub fn summercamp() -> UserThemeFamily { element_hover: Some(rgba(0x312d2180).into()), element_selected: Some(rgba(0x39342780).into()), text: Some(rgba(0xf8f5deff).into()), - text_muted: Some(rgba(0x3d382aff).into()), + text_muted: Some(rgba(0x736e55ff).into()), text_placeholder: Some(rgba(0x3d382aff).into()), text_disabled: Some(rgba(0xf8f5deff).into()), text_accent: Some(rgba(0x499befff).into()), diff --git a/crates/theme_importer/src/zed1/converter.rs b/crates/theme_importer/src/zed1/converter.rs index 6543f216355ac3139f5b5dca2eee0861bc019fec..d2f156246e6e15595c2a650d17103c67076c433a 100644 --- a/crates/theme_importer/src/zed1/converter.rs +++ b/crates/theme_importer/src/zed1/converter.rs @@ -115,7 +115,7 @@ impl Zed1ThemeConverter { .background_color .map(zed1_color_to_hsla), text: convert(self.theme.collab_panel.channel_name.text.color), - text_muted: convert(active_tab.description.text.color), + text_muted: convert(tab_bar.pane_button.default_style().color), text_accent: convert(status_bar.panel_buttons.button.active_state().icon_color), text_disabled: convert(status_bar.panel_buttons.button.disabled_style().icon_color), text_placeholder: picker From 446c947ad1a20fd6916421aed72f7b91dd789845 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 21:33:57 -0500 Subject: [PATCH 318/644] Render breadcrumb using muted colors --- crates/breadcrumbs2/src/breadcrumbs.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/breadcrumbs2/src/breadcrumbs.rs b/crates/breadcrumbs2/src/breadcrumbs.rs index 3b8ce1c6c5a34096a985d5ace4ff62f744ad870c..e579c8ded05d6532a2dcb1006da69f821044b667 100644 --- a/crates/breadcrumbs2/src/breadcrumbs.rs +++ b/crates/breadcrumbs2/src/breadcrumbs.rs @@ -53,12 +53,15 @@ impl Render for Breadcrumbs { }; let highlighted_segments = segments.into_iter().map(|segment| { + let mut text_style = cx.text_style(); + text_style.color = Color::Muted.color(cx); + StyledText::new(segment.text) - .with_highlights(&cx.text_style(), segment.highlights.unwrap_or_default()) + .with_highlights(&text_style, segment.highlights.unwrap_or_default()) .into_any() }); let breadcrumbs = Itertools::intersperse_with(highlighted_segments, || { - Label::new("›").into_any_element() + Label::new("›").color(Color::Muted).into_any_element() }); let editor = active_item From 14ed4a431644c8233f934d2b8f6d71f8332365a9 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 21:36:20 -0500 Subject: [PATCH 319/644] Render project panel entries as muted, unless selected --- crates/project_panel2/src/project_panel.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index 2966c55f79b84ddbad7dcea046541f795bc0a18b..21a114c43c925dacdcfbe86da5b0af3f11960522 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -1372,7 +1372,11 @@ impl ProjectPanel { GitFileStatus::Modified => Color::Modified, GitFileStatus::Conflict => Color::Conflict, }) - .unwrap_or(Color::Default); + .unwrap_or(if is_selected { + Color::Default + } else { + Color::Muted + }); let file_name = details.filename.clone(); let icon = details.icon.clone(); From e5148b4a1bdb296921c88979b252601ce01307b9 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 22:28:41 -0500 Subject: [PATCH 320/644] Assign player colors from the theme (#3805) This PR updates the `theme_importer` to pull in the player colors so that we can assign them based on the current theme. Release Notes: - N/A --- crates/theme2/src/registry.rs | 18 +- crates/theme2/src/styles/players.rs | 5 +- crates/theme2/src/themes/andromeda.rs | 47 +- crates/theme2/src/themes/atelier.rs | 845 +++++++++++++++++- crates/theme2/src/themes/ayu.rs | 131 ++- crates/theme2/src/themes/gruvbox.rs | 257 +++++- crates/theme2/src/themes/one.rs | 89 +- crates/theme2/src/themes/rose_pine.rs | 131 ++- crates/theme2/src/themes/sandcastle.rs | 47 +- crates/theme2/src/themes/solarized.rs | 89 +- crates/theme2/src/themes/summercamp.rs | 47 +- crates/theme2/src/user_theme.rs | 6 +- crates/theme_importer/src/main.rs | 5 +- crates/theme_importer/src/theme_printer.rs | 10 + crates/theme_importer/src/vscode/converter.rs | 1 + crates/theme_importer/src/zed1/converter.rs | 32 +- 16 files changed, 1730 insertions(+), 30 deletions(-) diff --git a/crates/theme2/src/registry.rs b/crates/theme2/src/registry.rs index ac94d93bcd3784483f8cd88f14ba94a05ad6750b..015814e3b2e025267e1391d99a5e9aa4f670c31c 100644 --- a/crates/theme2/src/registry.rs +++ b/crates/theme2/src/registry.rs @@ -49,9 +49,20 @@ impl ThemeRegistry { }; theme_colors.refine(&user_theme.styles.colors); - let mut status_colors = StatusColors::dark(); + let mut status_colors = match user_theme.appearance { + Appearance::Light => StatusColors::light(), + Appearance::Dark => StatusColors::dark(), + }; status_colors.refine(&user_theme.styles.status); + let mut player_colors = match user_theme.appearance { + Appearance::Light => PlayerColors::light(), + Appearance::Dark => PlayerColors::dark(), + }; + if let Some(player_colors_from_theme) = user_theme.styles.player { + player_colors = player_colors_from_theme; + } + let mut syntax_colors = match user_theme.appearance { Appearance::Light => SyntaxTheme::light(), Appearance::Dark => SyntaxTheme::dark(), @@ -82,10 +93,7 @@ impl ThemeRegistry { system: SystemColors::default(), colors: theme_colors, status: status_colors, - player: match user_theme.appearance { - Appearance::Light => PlayerColors::light(), - Appearance::Dark => PlayerColors::dark(), - }, + player: player_colors, syntax: Arc::new(syntax_colors), accents: Vec::new(), }, diff --git a/crates/theme2/src/styles/players.rs b/crates/theme2/src/styles/players.rs index e8bce8e578200cc05802a4c2d44fb3edace32c6b..9f9b837e47b8c7e2ccf8b0d870214c382bb9cf28 100644 --- a/crates/theme2/src/styles/players.rs +++ b/crates/theme2/src/styles/players.rs @@ -1,8 +1,9 @@ use gpui::Hsla; +use serde_derive::Deserialize; use crate::{amber, blue, jade, lime, orange, pink, purple, red}; -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Clone, Copy, Deserialize, Default)] pub struct PlayerColor { pub cursor: Hsla, pub background: Hsla, @@ -15,7 +16,7 @@ pub struct PlayerColor { /// /// The rest of the default colors crisscross back and forth on the /// color wheel so that the colors are as distinct as possible. -#[derive(Clone)] +#[derive(Clone, Deserialize)] pub struct PlayerColors(pub Vec); impl Default for PlayerColors { diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index fd61f9b482192048538a13ba6c110e85bcd8b389..67c18f88adf2d6150065c3108bc1b6f6df058bdf 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -5,8 +5,9 @@ use gpui::rgba; #[allow(unused)] use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, + UserThemeStylesRefinement, }; pub fn andromeda() -> UserThemeFamily { @@ -75,6 +76,48 @@ pub fn andromeda() -> UserThemeFamily { warning: Some(rgba(0xfee56dff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x11a793ff).into(), + background: rgba(0x11a793ff).into(), + selection: rgba(0x11a7933d).into(), + }, + PlayerColor { + cursor: rgba(0xc74decff).into(), + background: rgba(0xc74decff).into(), + selection: rgba(0xc74dec3d).into(), + }, + PlayerColor { + cursor: rgba(0xf29c14ff).into(), + background: rgba(0xf29c14ff).into(), + selection: rgba(0xf29c143d).into(), + }, + PlayerColor { + cursor: rgba(0x8a3fa6ff).into(), + background: rgba(0x8a3fa6ff).into(), + selection: rgba(0x8a3fa63d).into(), + }, + PlayerColor { + cursor: rgba(0x09e7c6ff).into(), + background: rgba(0x09e7c6ff).into(), + selection: rgba(0x09e7c63d).into(), + }, + PlayerColor { + cursor: rgba(0xf82872ff).into(), + background: rgba(0xf82872ff).into(), + selection: rgba(0xf828723d).into(), + }, + PlayerColor { + cursor: rgba(0xfee56dff).into(), + background: rgba(0xfee56dff).into(), + selection: rgba(0xfee56d3d).into(), + }, + PlayerColor { + cursor: rgba(0x96df72ff).into(), + background: rgba(0x96df72ff).into(), + selection: rgba(0x96df723d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( diff --git a/crates/theme2/src/themes/atelier.rs b/crates/theme2/src/themes/atelier.rs index 6c942d5b4c65b7187ea115f8133c98d3d83b5c28..d6681aa6b194fa2bb0227ea59f460e57155fdfde 100644 --- a/crates/theme2/src/themes/atelier.rs +++ b/crates/theme2/src/themes/atelier.rs @@ -5,8 +5,9 @@ use gpui::rgba; #[allow(unused)] use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, + UserThemeStylesRefinement, }; pub fn atelier() -> UserThemeFamily { @@ -76,6 +77,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xa59810ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x38a166ff).into(), + background: rgba(0x38a166ff).into(), + selection: rgba(0x38a1663d).into(), + }, + PlayerColor { + cursor: rgba(0x9d6c7cff).into(), + background: rgba(0x9d6c7cff).into(), + selection: rgba(0x9d6c7c3d).into(), + }, + PlayerColor { + cursor: rgba(0xae7315ff).into(), + background: rgba(0xae7315ff).into(), + selection: rgba(0xae73153d).into(), + }, + PlayerColor { + cursor: rgba(0x609182ff).into(), + background: rgba(0x609182ff).into(), + selection: rgba(0x6091823d).into(), + }, + PlayerColor { + cursor: rgba(0x5c9d49ff).into(), + background: rgba(0x5c9d49ff).into(), + selection: rgba(0x5c9d493d).into(), + }, + PlayerColor { + cursor: rgba(0xba6337ff).into(), + background: rgba(0xba6337ff).into(), + selection: rgba(0xba63373d).into(), + }, + PlayerColor { + cursor: rgba(0xa59810ff).into(), + background: rgba(0xa59810ff).into(), + selection: rgba(0xa598103d).into(), + }, + PlayerColor { + cursor: rgba(0x7d9728ff).into(), + background: rgba(0x7d9728ff).into(), + selection: rgba(0x7d97283d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -436,6 +479,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xc38419ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x417ee6ff).into(), + background: rgba(0x417ee6ff).into(), + selection: rgba(0x417ee63d).into(), + }, + PlayerColor { + cursor: rgba(0xc340f2ff).into(), + background: rgba(0xc340f2ff).into(), + selection: rgba(0xc340f23d).into(), + }, + PlayerColor { + cursor: rgba(0xdf5321ff).into(), + background: rgba(0xdf5321ff).into(), + selection: rgba(0xdf53213d).into(), + }, + PlayerColor { + cursor: rgba(0x6666e9ff).into(), + background: rgba(0x6666e9ff).into(), + selection: rgba(0x6666e93d).into(), + }, + PlayerColor { + cursor: rgba(0x3e97b8ff).into(), + background: rgba(0x3e97b8ff).into(), + selection: rgba(0x3e97b83d).into(), + }, + PlayerColor { + cursor: rgba(0xf22d40ff).into(), + background: rgba(0xf22d40ff).into(), + selection: rgba(0xf22d403d).into(), + }, + PlayerColor { + cursor: rgba(0xc38419ff).into(), + background: rgba(0xc38419ff).into(), + selection: rgba(0xc384193d).into(), + }, + PlayerColor { + cursor: rgba(0x7b9727ff).into(), + background: rgba(0x7b9727ff).into(), + selection: rgba(0x7b97273d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -796,6 +881,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xa07e3cff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x488c90ff).into(), + background: rgba(0x488c90ff).into(), + selection: rgba(0x488c903d).into(), + }, + PlayerColor { + cursor: rgba(0x867469ff).into(), + background: rgba(0x867469ff).into(), + selection: rgba(0x8674693d).into(), + }, + PlayerColor { + cursor: rgba(0x9f713dff).into(), + background: rgba(0x9f713dff).into(), + selection: rgba(0x9f713d3d).into(), + }, + PlayerColor { + cursor: rgba(0x56859bff).into(), + background: rgba(0x56859bff).into(), + selection: rgba(0x56859b3d).into(), + }, + PlayerColor { + cursor: rgba(0x1f9aa0ff).into(), + background: rgba(0x1f9aa0ff).into(), + selection: rgba(0x1f9aa03d).into(), + }, + PlayerColor { + cursor: rgba(0xb1623aff).into(), + background: rgba(0xb1623aff).into(), + selection: rgba(0xb1623a3d).into(), + }, + PlayerColor { + cursor: rgba(0xa07e3cff).into(), + background: rgba(0xa07e3cff).into(), + selection: rgba(0xa07e3c3d).into(), + }, + PlayerColor { + cursor: rgba(0x499963ff).into(), + background: rgba(0x499963ff).into(), + selection: rgba(0x4999633d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -1156,6 +1283,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xa06e3bff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x576ddaff).into(), + background: rgba(0x576ddaff).into(), + selection: rgba(0x576dda3d).into(), + }, + PlayerColor { + cursor: rgba(0xbf41bfff).into(), + background: rgba(0xbf41bfff).into(), + selection: rgba(0xbf41bf3d).into(), + }, + PlayerColor { + cursor: rgba(0xaa573cff).into(), + background: rgba(0xaa573cff).into(), + selection: rgba(0xaa573c3d).into(), + }, + PlayerColor { + cursor: rgba(0x955ae6ff).into(), + background: rgba(0x955ae6ff).into(), + selection: rgba(0x955ae63d).into(), + }, + PlayerColor { + cursor: rgba(0x3a8bc6ff).into(), + background: rgba(0x3a8bc6ff).into(), + selection: rgba(0x3a8bc63d).into(), + }, + PlayerColor { + cursor: rgba(0xbe4678ff).into(), + background: rgba(0xbe4678ff).into(), + selection: rgba(0xbe46783d).into(), + }, + PlayerColor { + cursor: rgba(0xa06e3bff).into(), + background: rgba(0xa06e3bff).into(), + selection: rgba(0xa06e3b3d).into(), + }, + PlayerColor { + cursor: rgba(0x2c9292ff).into(), + background: rgba(0x2c9292ff).into(), + selection: rgba(0x2c92923d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -1516,6 +1685,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xa59810ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x37a166ff).into(), + background: rgba(0x37a166ff).into(), + selection: rgba(0x37a1663d).into(), + }, + PlayerColor { + cursor: rgba(0x9d6c7cff).into(), + background: rgba(0x9d6c7cff).into(), + selection: rgba(0x9d6c7c3d).into(), + }, + PlayerColor { + cursor: rgba(0xae7315ff).into(), + background: rgba(0xae7315ff).into(), + selection: rgba(0xae73153d).into(), + }, + PlayerColor { + cursor: rgba(0x5f9182ff).into(), + background: rgba(0x5f9182ff).into(), + selection: rgba(0x5f91823d).into(), + }, + PlayerColor { + cursor: rgba(0x5b9d48ff).into(), + background: rgba(0x5b9d48ff).into(), + selection: rgba(0x5b9d483d).into(), + }, + PlayerColor { + cursor: rgba(0xba6237ff).into(), + background: rgba(0xba6237ff).into(), + selection: rgba(0xba62373d).into(), + }, + PlayerColor { + cursor: rgba(0xa59810ff).into(), + background: rgba(0xa59810ff).into(), + selection: rgba(0xa598103d).into(), + }, + PlayerColor { + cursor: rgba(0x7d9727ff).into(), + background: rgba(0x7d9727ff).into(), + selection: rgba(0x7d97273d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -1876,6 +2087,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xc08b31ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x3e8fd0ff).into(), + background: rgba(0x3e8fd0ff).into(), + selection: rgba(0x3e8fd03d).into(), + }, + PlayerColor { + cursor: rgba(0x9c637aff).into(), + background: rgba(0x9c637aff).into(), + selection: rgba(0x9c637a3d).into(), + }, + PlayerColor { + cursor: rgba(0xc76b2aff).into(), + background: rgba(0xc76b2aff).into(), + selection: rgba(0xc76b2a3d).into(), + }, + PlayerColor { + cursor: rgba(0x6679ccff).into(), + background: rgba(0x6679ccff).into(), + selection: rgba(0x6679cc3d).into(), + }, + PlayerColor { + cursor: rgba(0x25a2c9ff).into(), + background: rgba(0x25a2c9ff).into(), + selection: rgba(0x25a2c93d).into(), + }, + PlayerColor { + cursor: rgba(0xc94923ff).into(), + background: rgba(0xc94923ff).into(), + selection: rgba(0xc949233d).into(), + }, + PlayerColor { + cursor: rgba(0xc08b31ff).into(), + background: rgba(0xc08b31ff).into(), + selection: rgba(0xc08b313d).into(), + }, + PlayerColor { + cursor: rgba(0xac973aff).into(), + background: rgba(0xac973aff).into(), + selection: rgba(0xac973a3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -2236,6 +2489,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xc08b31ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x3f8fd0ff).into(), + background: rgba(0x3f8fd0ff).into(), + selection: rgba(0x3f8fd03d).into(), + }, + PlayerColor { + cursor: rgba(0x9c637aff).into(), + background: rgba(0x9c637aff).into(), + selection: rgba(0x9c637a3d).into(), + }, + PlayerColor { + cursor: rgba(0xc76b2aff).into(), + background: rgba(0xc76b2aff).into(), + selection: rgba(0xc76b2a3d).into(), + }, + PlayerColor { + cursor: rgba(0x6779ccff).into(), + background: rgba(0x6779ccff).into(), + selection: rgba(0x6779cc3d).into(), + }, + PlayerColor { + cursor: rgba(0x25a2c9ff).into(), + background: rgba(0x25a2c9ff).into(), + selection: rgba(0x25a2c93d).into(), + }, + PlayerColor { + cursor: rgba(0xc94a23ff).into(), + background: rgba(0xc94a23ff).into(), + selection: rgba(0xc94a233d).into(), + }, + PlayerColor { + cursor: rgba(0xc08b31ff).into(), + background: rgba(0xc08b31ff).into(), + selection: rgba(0xc08b313d).into(), + }, + PlayerColor { + cursor: rgba(0xac973aff).into(), + background: rgba(0xac973aff).into(), + selection: rgba(0xac973a3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -2596,6 +2891,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xae9515ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x6684e0ff).into(), + background: rgba(0x6684e0ff).into(), + selection: rgba(0x6684e03d).into(), + }, + PlayerColor { + cursor: rgba(0xd43652ff).into(), + background: rgba(0xd43652ff).into(), + selection: rgba(0xd436523d).into(), + }, + PlayerColor { + cursor: rgba(0xb65612ff).into(), + background: rgba(0xb65612ff).into(), + selection: rgba(0xb656123d).into(), + }, + PlayerColor { + cursor: rgba(0xb854d3ff).into(), + background: rgba(0xb854d3ff).into(), + selection: rgba(0xb854d33d).into(), + }, + PlayerColor { + cursor: rgba(0x21ad83ff).into(), + background: rgba(0x21ad83ff).into(), + selection: rgba(0x21ad833d).into(), + }, + PlayerColor { + cursor: rgba(0xd73837ff).into(), + background: rgba(0xd73837ff).into(), + selection: rgba(0xd738373d).into(), + }, + PlayerColor { + cursor: rgba(0xae9515ff).into(), + background: rgba(0xae9515ff).into(), + selection: rgba(0xae95153d).into(), + }, + PlayerColor { + cursor: rgba(0x60ac3aff).into(), + background: rgba(0x60ac3aff).into(), + selection: rgba(0x60ac3a3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -2956,6 +3293,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0x98981cff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x3e62f4ff).into(), + background: rgba(0x3e62f4ff).into(), + selection: rgba(0x3e62f43d).into(), + }, + PlayerColor { + cursor: rgba(0xe61cc3ff).into(), + background: rgba(0xe61cc3ff).into(), + selection: rgba(0xe61cc33d).into(), + }, + PlayerColor { + cursor: rgba(0x87711eff).into(), + background: rgba(0x87711eff).into(), + selection: rgba(0x87711e3d).into(), + }, + PlayerColor { + cursor: rgba(0xad2dedff).into(), + background: rgba(0xad2dedff).into(), + selection: rgba(0xad2ded3d).into(), + }, + PlayerColor { + cursor: rgba(0x1c99b3ff).into(), + background: rgba(0x1c99b3ff).into(), + selection: rgba(0x1c99b33d).into(), + }, + PlayerColor { + cursor: rgba(0xe61c3cff).into(), + background: rgba(0xe61c3cff).into(), + selection: rgba(0xe61c3c3d).into(), + }, + PlayerColor { + cursor: rgba(0x98981cff).into(), + background: rgba(0x98981cff).into(), + selection: rgba(0x98981c3d).into(), + }, + PlayerColor { + cursor: rgba(0x2ba32aff).into(), + background: rgba(0x2ba32aff).into(), + selection: rgba(0x2ba32a3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -3316,6 +3695,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xa06e3cff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x586ddaff).into(), + background: rgba(0x586ddaff).into(), + selection: rgba(0x586dda3d).into(), + }, + PlayerColor { + cursor: rgba(0xbf41bfff).into(), + background: rgba(0xbf41bfff).into(), + selection: rgba(0xbf41bf3d).into(), + }, + PlayerColor { + cursor: rgba(0xaa583dff).into(), + background: rgba(0xaa583dff).into(), + selection: rgba(0xaa583d3d).into(), + }, + PlayerColor { + cursor: rgba(0x955be6ff).into(), + background: rgba(0x955be6ff).into(), + selection: rgba(0x955be63d).into(), + }, + PlayerColor { + cursor: rgba(0x3b8bc6ff).into(), + background: rgba(0x3b8bc6ff).into(), + selection: rgba(0x3b8bc63d).into(), + }, + PlayerColor { + cursor: rgba(0xbe4778ff).into(), + background: rgba(0xbe4778ff).into(), + selection: rgba(0xbe47783d).into(), + }, + PlayerColor { + cursor: rgba(0xa06e3cff).into(), + background: rgba(0xa06e3cff).into(), + selection: rgba(0xa06e3c3d).into(), + }, + PlayerColor { + cursor: rgba(0x2c9292ff).into(), + background: rgba(0x2c9292ff).into(), + selection: rgba(0x2c92923d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -3676,6 +4097,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xa06e3bff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x7272caff).into(), + background: rgba(0x7272caff).into(), + selection: rgba(0x7272ca3d).into(), + }, + PlayerColor { + cursor: rgba(0xbd5187ff).into(), + background: rgba(0xbd5187ff).into(), + selection: rgba(0xbd51873d).into(), + }, + PlayerColor { + cursor: rgba(0xb45a3cff).into(), + background: rgba(0xb45a3cff).into(), + selection: rgba(0xb45a3c3d).into(), + }, + PlayerColor { + cursor: rgba(0x8464c4ff).into(), + background: rgba(0x8464c4ff).into(), + selection: rgba(0x8464c43d).into(), + }, + PlayerColor { + cursor: rgba(0x5485b6ff).into(), + background: rgba(0x5485b6ff).into(), + selection: rgba(0x5485b63d).into(), + }, + PlayerColor { + cursor: rgba(0xca4949ff).into(), + background: rgba(0xca4949ff).into(), + selection: rgba(0xca49493d).into(), + }, + PlayerColor { + cursor: rgba(0xa06e3bff).into(), + background: rgba(0xa06e3bff).into(), + selection: rgba(0xa06e3b3d).into(), + }, + PlayerColor { + cursor: rgba(0x4b8b8bff).into(), + background: rgba(0x4b8b8bff).into(), + selection: rgba(0x4b8b8b3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -4036,6 +4499,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xbb8a36ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x526aebff).into(), + background: rgba(0x526aebff).into(), + selection: rgba(0x526aeb3d).into(), + }, + PlayerColor { + cursor: rgba(0xcc34ccff).into(), + background: rgba(0xcc34ccff).into(), + selection: rgba(0xcc34cc3d).into(), + }, + PlayerColor { + cursor: rgba(0xa65927ff).into(), + background: rgba(0xa65927ff).into(), + selection: rgba(0xa659273d).into(), + }, + PlayerColor { + cursor: rgba(0x7b59c0ff).into(), + background: rgba(0x7b59c0ff).into(), + selection: rgba(0x7b59c03d).into(), + }, + PlayerColor { + cursor: rgba(0x189393ff).into(), + background: rgba(0x189393ff).into(), + selection: rgba(0x1893933d).into(), + }, + PlayerColor { + cursor: rgba(0xca402cff).into(), + background: rgba(0xca402cff).into(), + selection: rgba(0xca402c3d).into(), + }, + PlayerColor { + cursor: rgba(0xbb8a36ff).into(), + background: rgba(0xbb8a36ff).into(), + selection: rgba(0xbb8a363d).into(), + }, + PlayerColor { + cursor: rgba(0x918b3bff).into(), + background: rgba(0x918b3bff).into(), + selection: rgba(0x918b3b3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -4396,6 +4901,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0x8a8a11ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x277fadff).into(), + background: rgba(0x277fadff).into(), + selection: rgba(0x277fad3d).into(), + }, + PlayerColor { + cursor: rgba(0xb72ed2ff).into(), + background: rgba(0xb72ed2ff).into(), + selection: rgba(0xb72ed23d).into(), + }, + PlayerColor { + cursor: rgba(0x935c26ff).into(), + background: rgba(0x935c26ff).into(), + selection: rgba(0x935c263d).into(), + }, + PlayerColor { + cursor: rgba(0x6b6bb8ff).into(), + background: rgba(0x6b6bb8ff).into(), + selection: rgba(0x6b6bb83d).into(), + }, + PlayerColor { + cursor: rgba(0x2e8f6fff).into(), + background: rgba(0x2e8f6fff).into(), + selection: rgba(0x2e8f6f3d).into(), + }, + PlayerColor { + cursor: rgba(0xd22e72ff).into(), + background: rgba(0xd22e72ff).into(), + selection: rgba(0xd22e723d).into(), + }, + PlayerColor { + cursor: rgba(0x8a8a11ff).into(), + background: rgba(0x8a8a11ff).into(), + selection: rgba(0x8a8a113d).into(), + }, + PlayerColor { + cursor: rgba(0x568c3bff).into(), + background: rgba(0x568c3bff).into(), + selection: rgba(0x568c3b3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -4756,6 +5303,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xc3841aff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x417ee6ff).into(), + background: rgba(0x417ee6ff).into(), + selection: rgba(0x417ee63d).into(), + }, + PlayerColor { + cursor: rgba(0xc340f2ff).into(), + background: rgba(0xc340f2ff).into(), + selection: rgba(0xc340f23d).into(), + }, + PlayerColor { + cursor: rgba(0xdf5421ff).into(), + background: rgba(0xdf5421ff).into(), + selection: rgba(0xdf54213d).into(), + }, + PlayerColor { + cursor: rgba(0x6766e9ff).into(), + background: rgba(0x6766e9ff).into(), + selection: rgba(0x6766e93d).into(), + }, + PlayerColor { + cursor: rgba(0x3f97b8ff).into(), + background: rgba(0x3f97b8ff).into(), + selection: rgba(0x3f97b83d).into(), + }, + PlayerColor { + cursor: rgba(0xf22e41ff).into(), + background: rgba(0xf22e41ff).into(), + selection: rgba(0xf22e413d).into(), + }, + PlayerColor { + cursor: rgba(0xc3841aff).into(), + background: rgba(0xc3841aff).into(), + selection: rgba(0xc3841a3d).into(), + }, + PlayerColor { + cursor: rgba(0x7b9728ff).into(), + background: rgba(0x7b9728ff).into(), + selection: rgba(0x7b97283d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -5116,6 +5705,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xae9515ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x6784e0ff).into(), + background: rgba(0x6784e0ff).into(), + selection: rgba(0x6784e03d).into(), + }, + PlayerColor { + cursor: rgba(0xd43753ff).into(), + background: rgba(0xd43753ff).into(), + selection: rgba(0xd437533d).into(), + }, + PlayerColor { + cursor: rgba(0xb65713ff).into(), + background: rgba(0xb65713ff).into(), + selection: rgba(0xb657133d).into(), + }, + PlayerColor { + cursor: rgba(0xb855d3ff).into(), + background: rgba(0xb855d3ff).into(), + selection: rgba(0xb855d33d).into(), + }, + PlayerColor { + cursor: rgba(0x22ad83ff).into(), + background: rgba(0x22ad83ff).into(), + selection: rgba(0x22ad833d).into(), + }, + PlayerColor { + cursor: rgba(0xd73838ff).into(), + background: rgba(0xd73838ff).into(), + selection: rgba(0xd738383d).into(), + }, + PlayerColor { + cursor: rgba(0xae9515ff).into(), + background: rgba(0xae9515ff).into(), + selection: rgba(0xae95153d).into(), + }, + PlayerColor { + cursor: rgba(0x61ac3aff).into(), + background: rgba(0x61ac3aff).into(), + selection: rgba(0x61ac3a3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -5476,6 +6107,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xa06e3cff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x7372caff).into(), + background: rgba(0x7372caff).into(), + selection: rgba(0x7372ca3d).into(), + }, + PlayerColor { + cursor: rgba(0xbd5287ff).into(), + background: rgba(0xbd5287ff).into(), + selection: rgba(0xbd52873d).into(), + }, + PlayerColor { + cursor: rgba(0xb45b3dff).into(), + background: rgba(0xb45b3dff).into(), + selection: rgba(0xb45b3d3d).into(), + }, + PlayerColor { + cursor: rgba(0x8464c4ff).into(), + background: rgba(0x8464c4ff).into(), + selection: rgba(0x8464c43d).into(), + }, + PlayerColor { + cursor: rgba(0x5585b6ff).into(), + background: rgba(0x5585b6ff).into(), + selection: rgba(0x5585b63d).into(), + }, + PlayerColor { + cursor: rgba(0xca4a4aff).into(), + background: rgba(0xca4a4aff).into(), + selection: rgba(0xca4a4a3d).into(), + }, + PlayerColor { + cursor: rgba(0xa06e3cff).into(), + background: rgba(0xa06e3cff).into(), + selection: rgba(0xa06e3c3d).into(), + }, + PlayerColor { + cursor: rgba(0x4c8b8bff).into(), + background: rgba(0x4c8b8bff).into(), + selection: rgba(0x4c8b8b3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -5836,6 +6509,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0x98981dff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x3f62f4ff).into(), + background: rgba(0x3f62f4ff).into(), + selection: rgba(0x3f62f43d).into(), + }, + PlayerColor { + cursor: rgba(0xe61dc3ff).into(), + background: rgba(0xe61dc3ff).into(), + selection: rgba(0xe61dc33d).into(), + }, + PlayerColor { + cursor: rgba(0x87711fff).into(), + background: rgba(0x87711fff).into(), + selection: rgba(0x87711f3d).into(), + }, + PlayerColor { + cursor: rgba(0xad2dedff).into(), + background: rgba(0xad2dedff).into(), + selection: rgba(0xad2ded3d).into(), + }, + PlayerColor { + cursor: rgba(0x1d99b3ff).into(), + background: rgba(0x1d99b3ff).into(), + selection: rgba(0x1d99b33d).into(), + }, + PlayerColor { + cursor: rgba(0xe61c3dff).into(), + background: rgba(0xe61c3dff).into(), + selection: rgba(0xe61c3d3d).into(), + }, + PlayerColor { + cursor: rgba(0x98981dff).into(), + background: rgba(0x98981dff).into(), + selection: rgba(0x98981d3d).into(), + }, + PlayerColor { + cursor: rgba(0x2ba32bff).into(), + background: rgba(0x2ba32bff).into(), + selection: rgba(0x2ba32b3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -6196,6 +6911,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xa07e3bff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x478c90ff).into(), + background: rgba(0x478c90ff).into(), + selection: rgba(0x478c903d).into(), + }, + PlayerColor { + cursor: rgba(0x867469ff).into(), + background: rgba(0x867469ff).into(), + selection: rgba(0x8674693d).into(), + }, + PlayerColor { + cursor: rgba(0x9f713cff).into(), + background: rgba(0x9f713cff).into(), + selection: rgba(0x9f713c3d).into(), + }, + PlayerColor { + cursor: rgba(0x55859bff).into(), + background: rgba(0x55859bff).into(), + selection: rgba(0x55859b3d).into(), + }, + PlayerColor { + cursor: rgba(0x1e9aa0ff).into(), + background: rgba(0x1e9aa0ff).into(), + selection: rgba(0x1e9aa03d).into(), + }, + PlayerColor { + cursor: rgba(0xb16139ff).into(), + background: rgba(0xb16139ff).into(), + selection: rgba(0xb161393d).into(), + }, + PlayerColor { + cursor: rgba(0xa07e3bff).into(), + background: rgba(0xa07e3bff).into(), + selection: rgba(0xa07e3b3d).into(), + }, + PlayerColor { + cursor: rgba(0x489963ff).into(), + background: rgba(0x489963ff).into(), + selection: rgba(0x4899633d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -6556,6 +7313,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0xbb8a36ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x526aebff).into(), + background: rgba(0x526aebff).into(), + selection: rgba(0x526aeb3d).into(), + }, + PlayerColor { + cursor: rgba(0xcc35ccff).into(), + background: rgba(0xcc35ccff).into(), + selection: rgba(0xcc35cc3d).into(), + }, + PlayerColor { + cursor: rgba(0xa65a27ff).into(), + background: rgba(0xa65a27ff).into(), + selection: rgba(0xa65a273d).into(), + }, + PlayerColor { + cursor: rgba(0x7b5ac0ff).into(), + background: rgba(0x7b5ac0ff).into(), + selection: rgba(0x7b5ac03d).into(), + }, + PlayerColor { + cursor: rgba(0x199393ff).into(), + background: rgba(0x199393ff).into(), + selection: rgba(0x1993933d).into(), + }, + PlayerColor { + cursor: rgba(0xca412cff).into(), + background: rgba(0xca412cff).into(), + selection: rgba(0xca412c3d).into(), + }, + PlayerColor { + cursor: rgba(0xbb8a36ff).into(), + background: rgba(0xbb8a36ff).into(), + selection: rgba(0xbb8a363d).into(), + }, + PlayerColor { + cursor: rgba(0x918b3cff).into(), + background: rgba(0x918b3cff).into(), + selection: rgba(0x918b3c3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -6916,6 +7715,48 @@ pub fn atelier() -> UserThemeFamily { warning: Some(rgba(0x8a8a11ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x277fadff).into(), + background: rgba(0x277fadff).into(), + selection: rgba(0x277fad3d).into(), + }, + PlayerColor { + cursor: rgba(0xb72fd2ff).into(), + background: rgba(0xb72fd2ff).into(), + selection: rgba(0xb72fd23d).into(), + }, + PlayerColor { + cursor: rgba(0x935d26ff).into(), + background: rgba(0x935d26ff).into(), + selection: rgba(0x935d263d).into(), + }, + PlayerColor { + cursor: rgba(0x6c6bb8ff).into(), + background: rgba(0x6c6bb8ff).into(), + selection: rgba(0x6c6bb83d).into(), + }, + PlayerColor { + cursor: rgba(0x2f8f6fff).into(), + background: rgba(0x2f8f6fff).into(), + selection: rgba(0x2f8f6f3d).into(), + }, + PlayerColor { + cursor: rgba(0xd22f72ff).into(), + background: rgba(0xd22f72ff).into(), + selection: rgba(0xd22f723d).into(), + }, + PlayerColor { + cursor: rgba(0x8a8a11ff).into(), + background: rgba(0x8a8a11ff).into(), + selection: rgba(0x8a8a113d).into(), + }, + PlayerColor { + cursor: rgba(0x578c3cff).into(), + background: rgba(0x578c3cff).into(), + selection: rgba(0x578c3c3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index bc2fe60b040a2ca939ea8a4d09ffbe54c1b98259..4ea839eaa955ed558437cc8909c10f534df84289 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -5,8 +5,9 @@ use gpui::rgba; #[allow(unused)] use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, + UserThemeStylesRefinement, }; pub fn ayu() -> UserThemeFamily { @@ -76,6 +77,48 @@ pub fn ayu() -> UserThemeFamily { warning: Some(rgba(0xfeb454ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x5ac2feff).into(), + background: rgba(0x5ac2feff).into(), + selection: rgba(0x5ac2fe3d).into(), + }, + PlayerColor { + cursor: rgba(0x3abae5ff).into(), + background: rgba(0x3abae5ff).into(), + selection: rgba(0x3abae53d).into(), + }, + PlayerColor { + cursor: rgba(0xfe8f40ff).into(), + background: rgba(0xfe8f40ff).into(), + selection: rgba(0xfe8f403d).into(), + }, + PlayerColor { + cursor: rgba(0xd2a6feff).into(), + background: rgba(0xd2a6feff).into(), + selection: rgba(0xd2a6fe3d).into(), + }, + PlayerColor { + cursor: rgba(0x95e5cbff).into(), + background: rgba(0x95e5cbff).into(), + selection: rgba(0x95e5cb3d).into(), + }, + PlayerColor { + cursor: rgba(0xef7178ff).into(), + background: rgba(0xef7178ff).into(), + selection: rgba(0xef71783d).into(), + }, + PlayerColor { + cursor: rgba(0xfeb454ff).into(), + background: rgba(0xfeb454ff).into(), + selection: rgba(0xfeb4543d).into(), + }, + PlayerColor { + cursor: rgba(0xaad84cff).into(), + background: rgba(0xaad84cff).into(), + selection: rgba(0xaad84c3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -415,6 +458,48 @@ pub fn ayu() -> UserThemeFamily { warning: Some(rgba(0xf1ae4aff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x3b9ee5ff).into(), + background: rgba(0x3b9ee5ff).into(), + selection: rgba(0x3b9ee53d).into(), + }, + PlayerColor { + cursor: rgba(0x56b4d3ff).into(), + background: rgba(0x56b4d3ff).into(), + selection: rgba(0x56b4d33d).into(), + }, + PlayerColor { + cursor: rgba(0xf98d3fff).into(), + background: rgba(0xf98d3fff).into(), + selection: rgba(0xf98d3f3d).into(), + }, + PlayerColor { + cursor: rgba(0xa37accff).into(), + background: rgba(0xa37accff).into(), + selection: rgba(0xa37acc3d).into(), + }, + PlayerColor { + cursor: rgba(0x4dbf99ff).into(), + background: rgba(0x4dbf99ff).into(), + selection: rgba(0x4dbf993d).into(), + }, + PlayerColor { + cursor: rgba(0xef7271ff).into(), + background: rgba(0xef7271ff).into(), + selection: rgba(0xef72713d).into(), + }, + PlayerColor { + cursor: rgba(0xf1ae4aff).into(), + background: rgba(0xf1ae4aff).into(), + selection: rgba(0xf1ae4a3d).into(), + }, + PlayerColor { + cursor: rgba(0x86b305ff).into(), + background: rgba(0x86b305ff).into(), + selection: rgba(0x86b3053d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -754,6 +839,48 @@ pub fn ayu() -> UserThemeFamily { warning: Some(rgba(0xfed073ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x73cffeff).into(), + background: rgba(0x73cffeff).into(), + selection: rgba(0x73cffe3d).into(), + }, + PlayerColor { + cursor: rgba(0x5ccee5ff).into(), + background: rgba(0x5ccee5ff).into(), + selection: rgba(0x5ccee53d).into(), + }, + PlayerColor { + cursor: rgba(0xfead66ff).into(), + background: rgba(0xfead66ff).into(), + selection: rgba(0xfead663d).into(), + }, + PlayerColor { + cursor: rgba(0xdebffeff).into(), + background: rgba(0xdebffeff).into(), + selection: rgba(0xdebffe3d).into(), + }, + PlayerColor { + cursor: rgba(0x95e5cbff).into(), + background: rgba(0x95e5cbff).into(), + selection: rgba(0x95e5cb3d).into(), + }, + PlayerColor { + cursor: rgba(0xf18779ff).into(), + background: rgba(0xf18779ff).into(), + selection: rgba(0xf187793d).into(), + }, + PlayerColor { + cursor: rgba(0xfed073ff).into(), + background: rgba(0xfed073ff).into(), + selection: rgba(0xfed0733d).into(), + }, + PlayerColor { + cursor: rgba(0xd5fe80ff).into(), + background: rgba(0xd5fe80ff).into(), + selection: rgba(0xd5fe803d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index 3db69b5a5463bc1cef83f3967d54ce27feec8295..096afc7ee3487a9e88140bfeff7595e3124a7266 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -5,8 +5,9 @@ use gpui::rgba; #[allow(unused)] use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, + UserThemeStylesRefinement, }; pub fn gruvbox() -> UserThemeFamily { @@ -76,6 +77,48 @@ pub fn gruvbox() -> UserThemeFamily { warning: Some(rgba(0xb57616ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x0b6678ff).into(), + background: rgba(0x0b6678ff).into(), + selection: rgba(0x0b66783d).into(), + }, + PlayerColor { + cursor: rgba(0x7c6f64ff).into(), + background: rgba(0x7c6f64ff).into(), + selection: rgba(0x7c6f643d).into(), + }, + PlayerColor { + cursor: rgba(0xaf3b05ff).into(), + background: rgba(0xaf3b05ff).into(), + selection: rgba(0xaf3b053d).into(), + }, + PlayerColor { + cursor: rgba(0x8f4071ff).into(), + background: rgba(0x8f4071ff).into(), + selection: rgba(0x8f40713d).into(), + }, + PlayerColor { + cursor: rgba(0x437b59ff).into(), + background: rgba(0x437b59ff).into(), + selection: rgba(0x437b593d).into(), + }, + PlayerColor { + cursor: rgba(0x9d0408ff).into(), + background: rgba(0x9d0408ff).into(), + selection: rgba(0x9d04083d).into(), + }, + PlayerColor { + cursor: rgba(0xb57616ff).into(), + background: rgba(0xb57616ff).into(), + selection: rgba(0xb576163d).into(), + }, + PlayerColor { + cursor: rgba(0x797410ff).into(), + background: rgba(0x797410ff).into(), + selection: rgba(0x7974103d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -422,6 +465,48 @@ pub fn gruvbox() -> UserThemeFamily { warning: Some(rgba(0xf9bd30ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x83a598ff).into(), + background: rgba(0x83a598ff).into(), + selection: rgba(0x83a5983d).into(), + }, + PlayerColor { + cursor: rgba(0xa89984ff).into(), + background: rgba(0xa89984ff).into(), + selection: rgba(0xa899843d).into(), + }, + PlayerColor { + cursor: rgba(0xfd801bff).into(), + background: rgba(0xfd801bff).into(), + selection: rgba(0xfd801b3d).into(), + }, + PlayerColor { + cursor: rgba(0xd3869bff).into(), + background: rgba(0xd3869bff).into(), + selection: rgba(0xd3869b3d).into(), + }, + PlayerColor { + cursor: rgba(0x8ec07cff).into(), + background: rgba(0x8ec07cff).into(), + selection: rgba(0x8ec07c3d).into(), + }, + PlayerColor { + cursor: rgba(0xfb4a35ff).into(), + background: rgba(0xfb4a35ff).into(), + selection: rgba(0xfb4a353d).into(), + }, + PlayerColor { + cursor: rgba(0xf9bd30ff).into(), + background: rgba(0xf9bd30ff).into(), + selection: rgba(0xf9bd303d).into(), + }, + PlayerColor { + cursor: rgba(0xb8bb27ff).into(), + background: rgba(0xb8bb27ff).into(), + selection: rgba(0xb8bb273d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -768,6 +853,48 @@ pub fn gruvbox() -> UserThemeFamily { warning: Some(rgba(0xb57616ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x0b6678ff).into(), + background: rgba(0x0b6678ff).into(), + selection: rgba(0x0b66783d).into(), + }, + PlayerColor { + cursor: rgba(0x7c6f64ff).into(), + background: rgba(0x7c6f64ff).into(), + selection: rgba(0x7c6f643d).into(), + }, + PlayerColor { + cursor: rgba(0xaf3b05ff).into(), + background: rgba(0xaf3b05ff).into(), + selection: rgba(0xaf3b053d).into(), + }, + PlayerColor { + cursor: rgba(0x8f4071ff).into(), + background: rgba(0x8f4071ff).into(), + selection: rgba(0x8f40713d).into(), + }, + PlayerColor { + cursor: rgba(0x437b59ff).into(), + background: rgba(0x437b59ff).into(), + selection: rgba(0x437b593d).into(), + }, + PlayerColor { + cursor: rgba(0x9d0408ff).into(), + background: rgba(0x9d0408ff).into(), + selection: rgba(0x9d04083d).into(), + }, + PlayerColor { + cursor: rgba(0xb57616ff).into(), + background: rgba(0xb57616ff).into(), + selection: rgba(0xb576163d).into(), + }, + PlayerColor { + cursor: rgba(0x797410ff).into(), + background: rgba(0x797410ff).into(), + selection: rgba(0x7974103d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -1114,6 +1241,48 @@ pub fn gruvbox() -> UserThemeFamily { warning: Some(rgba(0xf9bd30ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x83a598ff).into(), + background: rgba(0x83a598ff).into(), + selection: rgba(0x83a5983d).into(), + }, + PlayerColor { + cursor: rgba(0xa89984ff).into(), + background: rgba(0xa89984ff).into(), + selection: rgba(0xa899843d).into(), + }, + PlayerColor { + cursor: rgba(0xfd801bff).into(), + background: rgba(0xfd801bff).into(), + selection: rgba(0xfd801b3d).into(), + }, + PlayerColor { + cursor: rgba(0xd3869bff).into(), + background: rgba(0xd3869bff).into(), + selection: rgba(0xd3869b3d).into(), + }, + PlayerColor { + cursor: rgba(0x8ec07cff).into(), + background: rgba(0x8ec07cff).into(), + selection: rgba(0x8ec07c3d).into(), + }, + PlayerColor { + cursor: rgba(0xfb4a35ff).into(), + background: rgba(0xfb4a35ff).into(), + selection: rgba(0xfb4a353d).into(), + }, + PlayerColor { + cursor: rgba(0xf9bd30ff).into(), + background: rgba(0xf9bd30ff).into(), + selection: rgba(0xf9bd303d).into(), + }, + PlayerColor { + cursor: rgba(0xb8bb27ff).into(), + background: rgba(0xb8bb27ff).into(), + selection: rgba(0xb8bb273d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -1460,6 +1629,48 @@ pub fn gruvbox() -> UserThemeFamily { warning: Some(rgba(0xb57616ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x0b6678ff).into(), + background: rgba(0x0b6678ff).into(), + selection: rgba(0x0b66783d).into(), + }, + PlayerColor { + cursor: rgba(0x7c6f64ff).into(), + background: rgba(0x7c6f64ff).into(), + selection: rgba(0x7c6f643d).into(), + }, + PlayerColor { + cursor: rgba(0xaf3b05ff).into(), + background: rgba(0xaf3b05ff).into(), + selection: rgba(0xaf3b053d).into(), + }, + PlayerColor { + cursor: rgba(0x8f4071ff).into(), + background: rgba(0x8f4071ff).into(), + selection: rgba(0x8f40713d).into(), + }, + PlayerColor { + cursor: rgba(0x437b59ff).into(), + background: rgba(0x437b59ff).into(), + selection: rgba(0x437b593d).into(), + }, + PlayerColor { + cursor: rgba(0x9d0408ff).into(), + background: rgba(0x9d0408ff).into(), + selection: rgba(0x9d04083d).into(), + }, + PlayerColor { + cursor: rgba(0xb57616ff).into(), + background: rgba(0xb57616ff).into(), + selection: rgba(0xb576163d).into(), + }, + PlayerColor { + cursor: rgba(0x797410ff).into(), + background: rgba(0x797410ff).into(), + selection: rgba(0x7974103d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -1806,6 +2017,48 @@ pub fn gruvbox() -> UserThemeFamily { warning: Some(rgba(0xf9bd30ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x83a598ff).into(), + background: rgba(0x83a598ff).into(), + selection: rgba(0x83a5983d).into(), + }, + PlayerColor { + cursor: rgba(0xa89984ff).into(), + background: rgba(0xa89984ff).into(), + selection: rgba(0xa899843d).into(), + }, + PlayerColor { + cursor: rgba(0xfd801bff).into(), + background: rgba(0xfd801bff).into(), + selection: rgba(0xfd801b3d).into(), + }, + PlayerColor { + cursor: rgba(0xd3869bff).into(), + background: rgba(0xd3869bff).into(), + selection: rgba(0xd3869b3d).into(), + }, + PlayerColor { + cursor: rgba(0x8ec07cff).into(), + background: rgba(0x8ec07cff).into(), + selection: rgba(0x8ec07c3d).into(), + }, + PlayerColor { + cursor: rgba(0xfb4a35ff).into(), + background: rgba(0xfb4a35ff).into(), + selection: rgba(0xfb4a353d).into(), + }, + PlayerColor { + cursor: rgba(0xf9bd30ff).into(), + background: rgba(0xf9bd30ff).into(), + selection: rgba(0xf9bd303d).into(), + }, + PlayerColor { + cursor: rgba(0xb8bb27ff).into(), + background: rgba(0xb8bb27ff).into(), + selection: rgba(0xb8bb273d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( diff --git a/crates/theme2/src/themes/one.rs b/crates/theme2/src/themes/one.rs index 7ea2bbea87b6fcc58344a440dba955b37b3a13be..f4d53404fb05e1d7f3bf3b0db8c08a7807a00177 100644 --- a/crates/theme2/src/themes/one.rs +++ b/crates/theme2/src/themes/one.rs @@ -5,8 +5,9 @@ use gpui::rgba; #[allow(unused)] use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, + UserThemeStylesRefinement, }; pub fn one() -> UserThemeFamily { @@ -76,6 +77,48 @@ pub fn one() -> UserThemeFamily { warning: Some(rgba(0xdec184ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x5c79e2ff).into(), + background: rgba(0x5c79e2ff).into(), + selection: rgba(0x5c79e23d).into(), + }, + PlayerColor { + cursor: rgba(0x994fa6ff).into(), + background: rgba(0x994fa6ff).into(), + selection: rgba(0x994fa63d).into(), + }, + PlayerColor { + cursor: rgba(0xad6f27ff).into(), + background: rgba(0xad6f27ff).into(), + selection: rgba(0xad6f273d).into(), + }, + PlayerColor { + cursor: rgba(0xa44aabff).into(), + background: rgba(0xa44aabff).into(), + selection: rgba(0xa44aab3d).into(), + }, + PlayerColor { + cursor: rgba(0x3b82b7ff).into(), + background: rgba(0x3b82b7ff).into(), + selection: rgba(0x3b82b73d).into(), + }, + PlayerColor { + cursor: rgba(0xd36151ff).into(), + background: rgba(0xd36151ff).into(), + selection: rgba(0xd361513d).into(), + }, + PlayerColor { + cursor: rgba(0xdec184ff).into(), + background: rgba(0xdec184ff).into(), + selection: rgba(0xdec1843d).into(), + }, + PlayerColor { + cursor: rgba(0x669f59ff).into(), + background: rgba(0x669f59ff).into(), + selection: rgba(0x669f593d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -422,6 +465,48 @@ pub fn one() -> UserThemeFamily { warning: Some(rgba(0xdec184ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x74ade8ff).into(), + background: rgba(0x74ade8ff).into(), + selection: rgba(0x74ade83d).into(), + }, + PlayerColor { + cursor: rgba(0xbe5046ff).into(), + background: rgba(0xbe5046ff).into(), + selection: rgba(0xbe50463d).into(), + }, + PlayerColor { + cursor: rgba(0xc0966bff).into(), + background: rgba(0xc0966bff).into(), + selection: rgba(0xc0966b3d).into(), + }, + PlayerColor { + cursor: rgba(0xb478cfff).into(), + background: rgba(0xb478cfff).into(), + selection: rgba(0xb478cf3d).into(), + }, + PlayerColor { + cursor: rgba(0x6fb4c0ff).into(), + background: rgba(0x6fb4c0ff).into(), + selection: rgba(0x6fb4c03d).into(), + }, + PlayerColor { + cursor: rgba(0xd07277ff).into(), + background: rgba(0xd07277ff).into(), + selection: rgba(0xd072773d).into(), + }, + PlayerColor { + cursor: rgba(0xdec184ff).into(), + background: rgba(0xdec184ff).into(), + selection: rgba(0xdec1843d).into(), + }, + PlayerColor { + cursor: rgba(0xa1c181ff).into(), + background: rgba(0xa1c181ff).into(), + selection: rgba(0xa1c1813d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index e63e8f2ad879a9dcfdac906f34124d229cf2db8a..cc14268a0fe05540dab0d8cc88326dc2e4a3b508 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -5,8 +5,9 @@ use gpui::rgba; #[allow(unused)] use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, + UserThemeStylesRefinement, }; pub fn rose_pine() -> UserThemeFamily { @@ -76,6 +77,48 @@ pub fn rose_pine() -> UserThemeFamily { warning: Some(rgba(0xe99d35ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x57949fff).into(), + background: rgba(0x57949fff).into(), + selection: rgba(0x57949f3d).into(), + }, + PlayerColor { + cursor: rgba(0x7c697fff).into(), + background: rgba(0x7c697fff).into(), + selection: rgba(0x7c697f3d).into(), + }, + PlayerColor { + cursor: rgba(0x907aa9ff).into(), + background: rgba(0x907aa9ff).into(), + selection: rgba(0x907aa93d).into(), + }, + PlayerColor { + cursor: rgba(0x907aa9ff).into(), + background: rgba(0x907aa9ff).into(), + selection: rgba(0x907aa93d).into(), + }, + PlayerColor { + cursor: rgba(0x2a6983ff).into(), + background: rgba(0x2a6983ff).into(), + selection: rgba(0x2a69833d).into(), + }, + PlayerColor { + cursor: rgba(0xb4647aff).into(), + background: rgba(0xb4647aff).into(), + selection: rgba(0xb4647a3d).into(), + }, + PlayerColor { + cursor: rgba(0xe99d35ff).into(), + background: rgba(0xe99d35ff).into(), + selection: rgba(0xe99d353d).into(), + }, + PlayerColor { + cursor: rgba(0x3eaa8eff).into(), + background: rgba(0x3eaa8eff).into(), + selection: rgba(0x3eaa8e3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -429,6 +472,48 @@ pub fn rose_pine() -> UserThemeFamily { warning: Some(rgba(0xf5c177ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x9cced7ff).into(), + background: rgba(0x9cced7ff).into(), + selection: rgba(0x9cced73d).into(), + }, + PlayerColor { + cursor: rgba(0xa784a1ff).into(), + background: rgba(0xa784a1ff).into(), + selection: rgba(0xa784a13d).into(), + }, + PlayerColor { + cursor: rgba(0xc4a7e6ff).into(), + background: rgba(0xc4a7e6ff).into(), + selection: rgba(0xc4a7e63d).into(), + }, + PlayerColor { + cursor: rgba(0xc4a7e6ff).into(), + background: rgba(0xc4a7e6ff).into(), + selection: rgba(0xc4a7e63d).into(), + }, + PlayerColor { + cursor: rgba(0x3f8fb0ff).into(), + background: rgba(0x3f8fb0ff).into(), + selection: rgba(0x3f8fb03d).into(), + }, + PlayerColor { + cursor: rgba(0xea6f92ff).into(), + background: rgba(0xea6f92ff).into(), + selection: rgba(0xea6f923d).into(), + }, + PlayerColor { + cursor: rgba(0xf5c177ff).into(), + background: rgba(0xf5c177ff).into(), + selection: rgba(0xf5c1773d).into(), + }, + PlayerColor { + cursor: rgba(0x5dc2a3ff).into(), + background: rgba(0x5dc2a3ff).into(), + selection: rgba(0x5dc2a33d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -782,6 +867,48 @@ pub fn rose_pine() -> UserThemeFamily { warning: Some(rgba(0xf5c177ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x9cced7ff).into(), + background: rgba(0x9cced7ff).into(), + selection: rgba(0x9cced73d).into(), + }, + PlayerColor { + cursor: rgba(0x9d7691ff).into(), + background: rgba(0x9d7691ff).into(), + selection: rgba(0x9d76913d).into(), + }, + PlayerColor { + cursor: rgba(0xc4a7e6ff).into(), + background: rgba(0xc4a7e6ff).into(), + selection: rgba(0xc4a7e63d).into(), + }, + PlayerColor { + cursor: rgba(0xc4a7e6ff).into(), + background: rgba(0xc4a7e6ff).into(), + selection: rgba(0xc4a7e63d).into(), + }, + PlayerColor { + cursor: rgba(0x32748fff).into(), + background: rgba(0x32748fff).into(), + selection: rgba(0x32748f3d).into(), + }, + PlayerColor { + cursor: rgba(0xea6f92ff).into(), + background: rgba(0xea6f92ff).into(), + selection: rgba(0xea6f923d).into(), + }, + PlayerColor { + cursor: rgba(0xf5c177ff).into(), + background: rgba(0xf5c177ff).into(), + selection: rgba(0xf5c1773d).into(), + }, + PlayerColor { + cursor: rgba(0x5dc2a3ff).into(), + background: rgba(0x5dc2a3ff).into(), + selection: rgba(0x5dc2a33d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( diff --git a/crates/theme2/src/themes/sandcastle.rs b/crates/theme2/src/themes/sandcastle.rs index 3e66ce97c1d0fb34defea641f669a69dafd1d923..ddcd06bec5e2a14568d654d2bfb75a15cb0e0ad3 100644 --- a/crates/theme2/src/themes/sandcastle.rs +++ b/crates/theme2/src/themes/sandcastle.rs @@ -5,8 +5,9 @@ use gpui::rgba; #[allow(unused)] use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, + UserThemeStylesRefinement, }; pub fn sandcastle() -> UserThemeFamily { @@ -75,6 +76,48 @@ pub fn sandcastle() -> UserThemeFamily { warning: Some(rgba(0xa07e3bff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x528b8bff).into(), + background: rgba(0x528b8bff).into(), + selection: rgba(0x528b8b3d).into(), + }, + PlayerColor { + cursor: rgba(0xa87323ff).into(), + background: rgba(0xa87323ff).into(), + selection: rgba(0xa873233d).into(), + }, + PlayerColor { + cursor: rgba(0xa07e3bff).into(), + background: rgba(0xa07e3bff).into(), + selection: rgba(0xa07e3b3d).into(), + }, + PlayerColor { + cursor: rgba(0xd75f5fff).into(), + background: rgba(0xd75f5fff).into(), + selection: rgba(0xd75f5f3d).into(), + }, + PlayerColor { + cursor: rgba(0x83a598ff).into(), + background: rgba(0x83a598ff).into(), + selection: rgba(0x83a5983d).into(), + }, + PlayerColor { + cursor: rgba(0xb4637aff).into(), + background: rgba(0xb4637aff).into(), + selection: rgba(0xb4637a3d).into(), + }, + PlayerColor { + cursor: rgba(0xa07e3bff).into(), + background: rgba(0xa07e3bff).into(), + selection: rgba(0xa07e3b3d).into(), + }, + PlayerColor { + cursor: rgba(0x83a598ff).into(), + background: rgba(0x83a598ff).into(), + selection: rgba(0x83a5983d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index 61c3fc8539473ca55ebdd2127cb80c605a3151e0..7bf383e854ded6de475e4e2432002793b83bd620 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -5,8 +5,9 @@ use gpui::rgba; #[allow(unused)] use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, + UserThemeStylesRefinement, }; pub fn solarized() -> UserThemeFamily { @@ -76,6 +77,48 @@ pub fn solarized() -> UserThemeFamily { warning: Some(rgba(0xb58904ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x298bd1ff).into(), + background: rgba(0x298bd1ff).into(), + selection: rgba(0x298bd13d).into(), + }, + PlayerColor { + cursor: rgba(0xd33882ff).into(), + background: rgba(0xd33882ff).into(), + selection: rgba(0xd338823d).into(), + }, + PlayerColor { + cursor: rgba(0xcb4c18ff).into(), + background: rgba(0xcb4c18ff).into(), + selection: rgba(0xcb4c183d).into(), + }, + PlayerColor { + cursor: rgba(0x6d71c4ff).into(), + background: rgba(0x6d71c4ff).into(), + selection: rgba(0x6d71c43d).into(), + }, + PlayerColor { + cursor: rgba(0x2ca198ff).into(), + background: rgba(0x2ca198ff).into(), + selection: rgba(0x2ca1983d).into(), + }, + PlayerColor { + cursor: rgba(0xdc3330ff).into(), + background: rgba(0xdc3330ff).into(), + selection: rgba(0xdc33303d).into(), + }, + PlayerColor { + cursor: rgba(0xb58904ff).into(), + background: rgba(0xb58904ff).into(), + selection: rgba(0xb589043d).into(), + }, + PlayerColor { + cursor: rgba(0x859904ff).into(), + background: rgba(0x859904ff).into(), + selection: rgba(0x8599043d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( @@ -415,6 +458,48 @@ pub fn solarized() -> UserThemeFamily { warning: Some(rgba(0xb58903ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x288bd1ff).into(), + background: rgba(0x288bd1ff).into(), + selection: rgba(0x288bd13d).into(), + }, + PlayerColor { + cursor: rgba(0xd33782ff).into(), + background: rgba(0xd33782ff).into(), + selection: rgba(0xd337823d).into(), + }, + PlayerColor { + cursor: rgba(0xcb4b17ff).into(), + background: rgba(0xcb4b17ff).into(), + selection: rgba(0xcb4b173d).into(), + }, + PlayerColor { + cursor: rgba(0x6c71c4ff).into(), + background: rgba(0x6c71c4ff).into(), + selection: rgba(0x6c71c43d).into(), + }, + PlayerColor { + cursor: rgba(0x2ca198ff).into(), + background: rgba(0x2ca198ff).into(), + selection: rgba(0x2ca1983d).into(), + }, + PlayerColor { + cursor: rgba(0xdc3330ff).into(), + background: rgba(0xdc3330ff).into(), + selection: rgba(0xdc33303d).into(), + }, + PlayerColor { + cursor: rgba(0xb58903ff).into(), + background: rgba(0xb58903ff).into(), + selection: rgba(0xb589033d).into(), + }, + PlayerColor { + cursor: rgba(0x859904ff).into(), + background: rgba(0x859904ff).into(), + selection: rgba(0x8599043d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( diff --git a/crates/theme2/src/themes/summercamp.rs b/crates/theme2/src/themes/summercamp.rs index 3540d824d2c5e01293260bbe1c60a9b00d8706ce..64f51231ae35b69028170d855be10bec43388708 100644 --- a/crates/theme2/src/themes/summercamp.rs +++ b/crates/theme2/src/themes/summercamp.rs @@ -5,8 +5,9 @@ use gpui::rgba; #[allow(unused)] use crate::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, + UserThemeStylesRefinement, }; pub fn summercamp() -> UserThemeFamily { @@ -75,6 +76,48 @@ pub fn summercamp() -> UserThemeFamily { warning: Some(rgba(0xf1fe29ff).into()), ..Default::default() }, + player: Some(PlayerColors(vec![ + PlayerColor { + cursor: rgba(0x499befff).into(), + background: rgba(0x499befff).into(), + selection: rgba(0x499bef3d).into(), + }, + PlayerColor { + cursor: rgba(0xf59be6ff).into(), + background: rgba(0xf59be6ff).into(), + selection: rgba(0xf59be63d).into(), + }, + PlayerColor { + cursor: rgba(0xfaa11dff).into(), + background: rgba(0xfaa11dff).into(), + selection: rgba(0xfaa11d3d).into(), + }, + PlayerColor { + cursor: rgba(0xfe8080ff).into(), + background: rgba(0xfe8080ff).into(), + selection: rgba(0xfe80803d).into(), + }, + PlayerColor { + cursor: rgba(0x5beabcff).into(), + background: rgba(0x5beabcff).into(), + selection: rgba(0x5beabc3d).into(), + }, + PlayerColor { + cursor: rgba(0xe35142ff).into(), + background: rgba(0xe35142ff).into(), + selection: rgba(0xe351423d).into(), + }, + PlayerColor { + cursor: rgba(0xf1fe29ff).into(), + background: rgba(0xf1fe29ff).into(), + selection: rgba(0xf1fe293d).into(), + }, + PlayerColor { + cursor: rgba(0x5dea5aff).into(), + background: rgba(0x5dea5aff).into(), + selection: rgba(0x5dea5a3d).into(), + }, + ])), syntax: Some(UserSyntaxTheme { highlights: vec![ ( diff --git a/crates/theme2/src/user_theme.rs b/crates/theme2/src/user_theme.rs index e42b7b290532ce66a26e707a95955a1d538a1d4e..d34f066c3b0f13208cd8930efee3e5859f65fdf0 100644 --- a/crates/theme2/src/user_theme.rs +++ b/crates/theme2/src/user_theme.rs @@ -1,4 +1,7 @@ -use crate::{Appearance, StatusColors, StatusColorsRefinement, ThemeColors, ThemeColorsRefinement}; +use crate::{ + Appearance, PlayerColors, StatusColors, StatusColorsRefinement, ThemeColors, + ThemeColorsRefinement, +}; use gpui::{FontStyle, FontWeight, Hsla}; use refineable::Refineable; use serde::Deserialize; @@ -24,6 +27,7 @@ pub struct UserThemeStyles { pub colors: ThemeColors, #[refineable] pub status: StatusColors, + pub player: PlayerColors, pub syntax: UserSyntaxTheme, } diff --git a/crates/theme_importer/src/main.rs b/crates/theme_importer/src/main.rs index 4072a59df8d6f4a8816dd769e795b0931788fea3..19644c98165c2a111edcea06c18d0e09f3b295bb 100644 --- a/crates/theme_importer/src/main.rs +++ b/crates/theme_importer/src/main.rs @@ -316,8 +316,9 @@ fn main() -> Result<()> { #[allow(unused)] use crate::{{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserHighlightStyle, UserSyntaxTheme, - UserTheme, UserThemeFamily, UserThemeStylesRefinement, UserFontWeight, UserFontStyle + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement, + UserFontWeight, UserFontStyle }}; pub fn {theme_family_slug}() -> UserThemeFamily {{ diff --git a/crates/theme_importer/src/theme_printer.rs b/crates/theme_importer/src/theme_printer.rs index 2116b5b6704814fedfd65faa5da72d2963c9cb62..54f99e3b4ccb539ab007eb28002e40bfcfcdf942 100644 --- a/crates/theme_importer/src/theme_printer.rs +++ b/crates/theme_importer/src/theme_printer.rs @@ -107,6 +107,16 @@ impl<'a> Debug for UserThemeStylesRefinementPrinter<'a> { f.debug_struct("UserThemeStylesRefinement") .field("colors", &ThemeColorsRefinementPrinter(&self.0.colors)) .field("status", &StatusColorsRefinementPrinter(&self.0.status)) + .field( + "player", + &OptionPrinter( + &self + .0 + .player + .as_ref() + .map(|player_colors| PlayerColorsPrinter(player_colors)), + ), + ) .field( "syntax", &OptionPrinter( diff --git a/crates/theme_importer/src/vscode/converter.rs b/crates/theme_importer/src/vscode/converter.rs index 41534d0d0e29553ef4568bd03193f020afa2dc94..13297a91aa79650c089c5df3f2f8af0ee7ca88fb 100644 --- a/crates/theme_importer/src/vscode/converter.rs +++ b/crates/theme_importer/src/vscode/converter.rs @@ -61,6 +61,7 @@ impl VsCodeThemeConverter { styles: UserThemeStylesRefinement { colors: theme_colors_refinements, status: status_color_refinements, + player: None, syntax: Some(syntax_theme), }, }) diff --git a/crates/theme_importer/src/zed1/converter.rs b/crates/theme_importer/src/zed1/converter.rs index d2f156246e6e15595c2a650d17103c67076c433a..385ad43350dee1200e790abf9fe64bd2288d266d 100644 --- a/crates/theme_importer/src/zed1/converter.rs +++ b/crates/theme_importer/src/zed1/converter.rs @@ -3,8 +3,9 @@ use gpui::{Hsla, Rgba}; use gpui1::color::Color as Zed1Color; use gpui1::fonts::HighlightStyle as Zed1HighlightStyle; use theme::{ - Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserFontStyle, UserFontWeight, - UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeStylesRefinement, + Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, ThemeColorsRefinement, + UserFontStyle, UserFontWeight, UserHighlightStyle, UserSyntaxTheme, UserTheme, + UserThemeStylesRefinement, }; use theme1::Theme as Zed1Theme; @@ -50,6 +51,7 @@ impl Zed1ThemeConverter { let status_colors_refinement = self.convert_status_colors()?; let theme_colors_refinement = self.convert_theme_colors()?; + let player_colors = self.convert_player_colors()?; let syntax_theme = self.convert_syntax_theme()?; Ok(UserTheme { @@ -58,6 +60,7 @@ impl Zed1ThemeConverter { styles: UserThemeStylesRefinement { colors: theme_colors_refinement, status: status_colors_refinement, + player: Some(player_colors), syntax: Some(syntax_theme), }, }) @@ -82,6 +85,31 @@ impl Zed1ThemeConverter { }) } + fn convert_player_colors(&self) -> Result { + let player_one = self.theme.editor.selection; + + let mut player_colors = vec![PlayerColor { + cursor: zed1_color_to_hsla(player_one.cursor), + selection: zed1_color_to_hsla(player_one.selection), + background: zed1_color_to_hsla(player_one.cursor), + }]; + + for index in 1..8 { + let player = self + .theme + .editor + .selection_style_for_room_participant(index); + + player_colors.push(PlayerColor { + cursor: zed1_color_to_hsla(player.cursor), + selection: zed1_color_to_hsla(player.selection), + background: zed1_color_to_hsla(player.cursor), + }); + } + + Ok(PlayerColors(player_colors)) + } + fn convert_theme_colors(&self) -> Result { fn convert(color: Zed1Color) -> Option { Some(zed1_color_to_hsla(color)) From 698460ea897723bf23253e6e6411f70168844258 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 22 Dec 2023 23:06:30 -0500 Subject: [PATCH 321/644] Style inlay hints (#3806) This PR styles the inlay hints after the changes to the themes. Release Notes: - N/A --- crates/editor2/src/editor.rs | 4 ---- crates/theme2/src/themes/andromeda.rs | 1 + crates/theme2/src/themes/atelier.rs | 20 ++++++++++++++++++++ crates/theme2/src/themes/ayu.rs | 3 +++ crates/theme2/src/themes/gruvbox.rs | 6 ++++++ crates/theme2/src/themes/one.rs | 2 ++ crates/theme2/src/themes/rose_pine.rs | 3 +++ crates/theme2/src/themes/sandcastle.rs | 1 + crates/theme2/src/themes/solarized.rs | 2 ++ crates/theme2/src/themes/summercamp.rs | 1 + crates/theme_importer/src/zed1/converter.rs | 2 ++ 11 files changed, 41 insertions(+), 4 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 943ddf47bdad7dedc6b5d1f55a1828d80b99097b..d3ee41b11f92512a88c6b6dc334256aacc8625aa 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -7676,12 +7676,10 @@ impl Editor { inlays_style: HighlightStyle { color: Some(cx.theme().status().hint), font_weight: Some(FontWeight::BOLD), - fade_out: Some(0.6), ..HighlightStyle::default() }, suggestions_style: HighlightStyle { color: Some(cx.theme().status().predictive), - fade_out: Some(0.6), ..HighlightStyle::default() }, }, @@ -9348,12 +9346,10 @@ impl Render for Editor { inlays_style: HighlightStyle { color: Some(cx.theme().status().hint), font_weight: Some(FontWeight::BOLD), - fade_out: Some(0.6), ..HighlightStyle::default() }, suggestions_style: HighlightStyle { color: Some(cx.theme().status().predictive), - fade_out: Some(0.6), ..HighlightStyle::default() }, }, diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index 67c18f88adf2d6150065c3108bc1b6f6df058bdf..0a9b977d21eacd782f7461b11c5bca654d775093 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -71,6 +71,7 @@ pub fn andromeda() -> UserThemeFamily { created: Some(rgba(0x96df72ff).into()), deleted: Some(rgba(0xcd1d5aff).into()), error: Some(rgba(0xf82872ff).into()), + hint: Some(rgba(0x618399ff).into()), modified: Some(rgba(0xfee56dff).into()), success: Some(rgba(0xf7f7f8ff).into()), warning: Some(rgba(0xfee56dff).into()), diff --git a/crates/theme2/src/themes/atelier.rs b/crates/theme2/src/themes/atelier.rs index d6681aa6b194fa2bb0227ea59f460e57155fdfde..e5c2e49d5bda7e7781eb0abc9901e6e40a968a2f 100644 --- a/crates/theme2/src/themes/atelier.rs +++ b/crates/theme2/src/themes/atelier.rs @@ -72,6 +72,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x98ab54ff).into()), deleted: Some(rgba(0xba6337ff).into()), error: Some(rgba(0xba6337ff).into()), + hint: Some(rgba(0x768962ff).into()), modified: Some(rgba(0xa59810ff).into()), success: Some(rgba(0x22221bff).into()), warning: Some(rgba(0xa59810ff).into()), @@ -474,6 +475,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x7b9727ff).into()), deleted: Some(rgba(0xc82234ff).into()), error: Some(rgba(0xf22d40ff).into()), + hint: Some(rgba(0xa87187ff).into()), modified: Some(rgba(0xc38419ff).into()), success: Some(rgba(0xf1efeeff).into()), warning: Some(rgba(0xc38419ff).into()), @@ -876,6 +878,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x6fae80ff).into()), deleted: Some(rgba(0xb1623aff).into()), error: Some(rgba(0xb1623aff).into()), + hint: Some(rgba(0x66847cff).into()), modified: Some(rgba(0xa07e3cff).into()), success: Some(rgba(0x171c19ff).into()), warning: Some(rgba(0xa07e3cff).into()), @@ -1278,6 +1281,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x2c9292ff).into()), deleted: Some(rgba(0x953a5fff).into()), error: Some(rgba(0xbe4678ff).into()), + hint: Some(rgba(0x716998ff).into()), modified: Some(rgba(0xa06e3bff).into()), success: Some(rgba(0xefecf4ff).into()), warning: Some(rgba(0xa06e3bff).into()), @@ -1680,6 +1684,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x7d9727ff).into()), deleted: Some(rgba(0x934e2dff).into()), error: Some(rgba(0xba6237ff).into()), + hint: Some(rgba(0x70825bff).into()), modified: Some(rgba(0xa59810ff).into()), success: Some(rgba(0xf4f3ecff).into()), warning: Some(rgba(0xa59810ff).into()), @@ -2082,6 +2087,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0xac973aff).into()), deleted: Some(rgba(0xa33a1eff).into()), error: Some(rgba(0xc94923ff).into()), + hint: Some(rgba(0x6d82a6ff).into()), modified: Some(rgba(0xc08b31ff).into()), success: Some(rgba(0xf5f7ffff).into()), warning: Some(rgba(0xc08b31ff).into()), @@ -2484,6 +2490,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0xbfab61ff).into()), deleted: Some(rgba(0xc94a23ff).into()), error: Some(rgba(0xc94a23ff).into()), + hint: Some(rgba(0x7087b2ff).into()), modified: Some(rgba(0xc08b31ff).into()), success: Some(rgba(0x202746ff).into()), warning: Some(rgba(0xc08b31ff).into()), @@ -2886,6 +2893,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x60ac3aff).into()), deleted: Some(rgba(0xaf2c2eff).into()), error: Some(rgba(0xd73837ff).into()), + hint: Some(rgba(0xb17272ff).into()), modified: Some(rgba(0xae9515ff).into()), success: Some(rgba(0xfefbecff).into()), warning: Some(rgba(0xae9515ff).into()), @@ -3288,6 +3296,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x2ba32aff).into()), deleted: Some(rgba(0xbd1331ff).into()), error: Some(rgba(0xe61c3cff).into()), + hint: Some(rgba(0x008b9fff).into()), modified: Some(rgba(0x98981cff).into()), success: Some(rgba(0xf4fbf4ff).into()), warning: Some(rgba(0x98981cff).into()), @@ -3690,6 +3699,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x5fa8a7ff).into()), deleted: Some(rgba(0xbe4778ff).into()), error: Some(rgba(0xbe4778ff).into()), + hint: Some(rgba(0x786e9dff).into()), modified: Some(rgba(0xa06e3cff).into()), success: Some(rgba(0x19171cff).into()), warning: Some(rgba(0xa06e3cff).into()), @@ -4092,6 +4102,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x4b8b8bff).into()), deleted: Some(rgba(0xa23b3bff).into()), error: Some(rgba(0xca4949ff).into()), + hint: Some(rgba(0x8a647aff).into()), modified: Some(rgba(0xa06e3bff).into()), success: Some(rgba(0xf4ececff).into()), warning: Some(rgba(0xa06e3bff).into()), @@ -4494,6 +4505,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x918b3bff).into()), deleted: Some(rgba(0xa43424ff).into()), error: Some(rgba(0xca402cff).into()), + hint: Some(rgba(0x8d70a8ff).into()), modified: Some(rgba(0xbb8a36ff).into()), success: Some(rgba(0xf7f3f7ff).into()), warning: Some(rgba(0xbb8a36ff).into()), @@ -4896,6 +4908,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x568c3bff).into()), deleted: Some(rgba(0xa9275aff).into()), error: Some(rgba(0xd22e72ff).into()), + hint: Some(rgba(0x52809aff).into()), modified: Some(rgba(0x8a8a11ff).into()), success: Some(rgba(0xebf8ffff).into()), warning: Some(rgba(0x8a8a11ff).into()), @@ -5298,6 +5311,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x97ab54ff).into()), deleted: Some(rgba(0xf22e41ff).into()), error: Some(rgba(0xf22e41ff).into()), + hint: Some(rgba(0xa67287ff).into()), modified: Some(rgba(0xc3841aff).into()), success: Some(rgba(0x1b1918ff).into()), warning: Some(rgba(0xc3841aff).into()), @@ -5700,6 +5714,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x83bd62ff).into()), deleted: Some(rgba(0xd73838ff).into()), error: Some(rgba(0xd73838ff).into()), + hint: Some(rgba(0xb37979ff).into()), modified: Some(rgba(0xae9515ff).into()), success: Some(rgba(0x20201dff).into()), warning: Some(rgba(0xae9515ff).into()), @@ -6102,6 +6117,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x70a2a1ff).into()), deleted: Some(rgba(0xca4a4aff).into()), error: Some(rgba(0xca4a4aff).into()), + hint: Some(rgba(0x916a80ff).into()), modified: Some(rgba(0xa06e3cff).into()), success: Some(rgba(0x1b1818ff).into()), warning: Some(rgba(0xa06e3cff).into()), @@ -6504,6 +6520,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x61b656ff).into()), deleted: Some(rgba(0xe61c3dff).into()), error: Some(rgba(0xe61c3dff).into()), + hint: Some(rgba(0x008fa1ff).into()), modified: Some(rgba(0x98981dff).into()), success: Some(rgba(0x131513ff).into()), warning: Some(rgba(0x98981dff).into()), @@ -6906,6 +6923,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x489963ff).into()), deleted: Some(rgba(0x8b4d2fff).into()), error: Some(rgba(0xb16139ff).into()), + hint: Some(rgba(0x607e76ff).into()), modified: Some(rgba(0xa07e3bff).into()), success: Some(rgba(0xecf4eeff).into()), warning: Some(rgba(0xa07e3bff).into()), @@ -7308,6 +7326,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0xa8a161ff).into()), deleted: Some(rgba(0xca412cff).into()), error: Some(rgba(0xca412cff).into()), + hint: Some(rgba(0x8c70a6ff).into()), modified: Some(rgba(0xbb8a36ff).into()), success: Some(rgba(0x1b181bff).into()), warning: Some(rgba(0xbb8a36ff).into()), @@ -7710,6 +7729,7 @@ pub fn atelier() -> UserThemeFamily { created: Some(rgba(0x78a361ff).into()), deleted: Some(rgba(0xd22f72ff).into()), error: Some(rgba(0xd22f72ff).into()), + hint: Some(rgba(0x5a87a0ff).into()), modified: Some(rgba(0x8a8a11ff).into()), success: Some(rgba(0x161b1dff).into()), warning: Some(rgba(0x8a8a11ff).into()), diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index 4ea839eaa955ed558437cc8909c10f534df84289..7c0eb701081f002ec5c1bd54ed11fc45e08bee2a 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -72,6 +72,7 @@ pub fn ayu() -> UserThemeFamily { created: Some(rgba(0xaad84cff).into()), deleted: Some(rgba(0xc3595fff).into()), error: Some(rgba(0xef7178ff).into()), + hint: Some(rgba(0x638c81ff).into()), modified: Some(rgba(0xfeb454ff).into()), success: Some(rgba(0xbfbdb6ff).into()), warning: Some(rgba(0xfeb454ff).into()), @@ -453,6 +454,7 @@ pub fn ayu() -> UserThemeFamily { created: Some(rgba(0xa1c24bff).into()), deleted: Some(rgba(0xef7271ff).into()), error: Some(rgba(0xef7271ff).into()), + hint: Some(rgba(0x8ca7c2ff).into()), modified: Some(rgba(0xf1ae4aff).into()), success: Some(rgba(0x5c6166ff).into()), warning: Some(rgba(0xf1ae4aff).into()), @@ -834,6 +836,7 @@ pub fn ayu() -> UserThemeFamily { created: Some(rgba(0xd5fe80ff).into()), deleted: Some(rgba(0xc46a60ff).into()), error: Some(rgba(0xf18779ff).into()), + hint: Some(rgba(0x7399a3ff).into()), modified: Some(rgba(0xfed073ff).into()), success: Some(rgba(0xcccac2ff).into()), warning: Some(rgba(0xfed073ff).into()), diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index 096afc7ee3487a9e88140bfeff7595e3124a7266..8cc13fb1771a080a8addcf67ef0cbf0b74530948 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -72,6 +72,7 @@ pub fn gruvbox() -> UserThemeFamily { created: Some(rgba(0x958e43ff).into()), deleted: Some(rgba(0x9d0408ff).into()), error: Some(rgba(0x9d0408ff).into()), + hint: Some(rgba(0x677562ff).into()), modified: Some(rgba(0xb57616ff).into()), success: Some(rgba(0x282828ff).into()), warning: Some(rgba(0xb57616ff).into()), @@ -460,6 +461,7 @@ pub fn gruvbox() -> UserThemeFamily { created: Some(rgba(0xb8bb27ff).into()), deleted: Some(rgba(0xd0382bff).into()), error: Some(rgba(0xfb4a35ff).into()), + hint: Some(rgba(0x8d957eff).into()), modified: Some(rgba(0xf9bd30ff).into()), success: Some(rgba(0xfbf1c7ff).into()), warning: Some(rgba(0xf9bd30ff).into()), @@ -848,6 +850,7 @@ pub fn gruvbox() -> UserThemeFamily { created: Some(rgba(0x958e43ff).into()), deleted: Some(rgba(0x9d0408ff).into()), error: Some(rgba(0x9d0408ff).into()), + hint: Some(rgba(0x677562ff).into()), modified: Some(rgba(0xb57616ff).into()), success: Some(rgba(0x282828ff).into()), warning: Some(rgba(0xb57616ff).into()), @@ -1236,6 +1239,7 @@ pub fn gruvbox() -> UserThemeFamily { created: Some(rgba(0xb8bb27ff).into()), deleted: Some(rgba(0xd0382bff).into()), error: Some(rgba(0xfb4a35ff).into()), + hint: Some(rgba(0x8d957eff).into()), modified: Some(rgba(0xf9bd30ff).into()), success: Some(rgba(0xfbf1c7ff).into()), warning: Some(rgba(0xf9bd30ff).into()), @@ -1624,6 +1628,7 @@ pub fn gruvbox() -> UserThemeFamily { created: Some(rgba(0x958e43ff).into()), deleted: Some(rgba(0x9d0408ff).into()), error: Some(rgba(0x9d0408ff).into()), + hint: Some(rgba(0x677562ff).into()), modified: Some(rgba(0xb57616ff).into()), success: Some(rgba(0x282828ff).into()), warning: Some(rgba(0xb57616ff).into()), @@ -2012,6 +2017,7 @@ pub fn gruvbox() -> UserThemeFamily { created: Some(rgba(0xb8bb27ff).into()), deleted: Some(rgba(0xd0382bff).into()), error: Some(rgba(0xfb4a35ff).into()), + hint: Some(rgba(0x8d957eff).into()), modified: Some(rgba(0xf9bd30ff).into()), success: Some(rgba(0xfbf1c7ff).into()), warning: Some(rgba(0xf9bd30ff).into()), diff --git a/crates/theme2/src/themes/one.rs b/crates/theme2/src/themes/one.rs index f4d53404fb05e1d7f3bf3b0db8c08a7807a00177..e62ccbefdd61e212984bdea40a166967cae026e6 100644 --- a/crates/theme2/src/themes/one.rs +++ b/crates/theme2/src/themes/one.rs @@ -72,6 +72,7 @@ pub fn one() -> UserThemeFamily { created: Some(rgba(0x84b278ff).into()), deleted: Some(rgba(0xd36151ff).into()), error: Some(rgba(0xd36151ff).into()), + hint: Some(rgba(0x9295beff).into()), modified: Some(rgba(0xdec184ff).into()), success: Some(rgba(0x383a41ff).into()), warning: Some(rgba(0xdec184ff).into()), @@ -460,6 +461,7 @@ pub fn one() -> UserThemeFamily { created: Some(rgba(0xa1c181ff).into()), deleted: Some(rgba(0xa45a5eff).into()), error: Some(rgba(0xd07277ff).into()), + hint: Some(rgba(0x5b708aff).into()), modified: Some(rgba(0xdec184ff).into()), success: Some(rgba(0xc8ccd4ff).into()), warning: Some(rgba(0xdec184ff).into()), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index cc14268a0fe05540dab0d8cc88326dc2e4a3b508..318767cb2bc943f5db0524254e98d48402675576 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -72,6 +72,7 @@ pub fn rose_pine() -> UserThemeFamily { created: Some(rgba(0x6bbca3ff).into()), deleted: Some(rgba(0xb4647aff).into()), error: Some(rgba(0xb4647aff).into()), + hint: Some(rgba(0x7a92aaff).into()), modified: Some(rgba(0xe99d35ff).into()), success: Some(rgba(0x575279ff).into()), warning: Some(rgba(0xe99d35ff).into()), @@ -467,6 +468,7 @@ pub fn rose_pine() -> UserThemeFamily { created: Some(rgba(0x5dc2a3ff).into()), deleted: Some(rgba(0xbe5773ff).into()), error: Some(rgba(0xea6f92ff).into()), + hint: Some(rgba(0x728aa2ff).into()), modified: Some(rgba(0xf5c177ff).into()), success: Some(rgba(0xe0def4ff).into()), warning: Some(rgba(0xf5c177ff).into()), @@ -862,6 +864,7 @@ pub fn rose_pine() -> UserThemeFamily { created: Some(rgba(0x5dc2a3ff).into()), deleted: Some(rgba(0xbe5773ff).into()), error: Some(rgba(0xea6f92ff).into()), + hint: Some(rgba(0x5e768cff).into()), modified: Some(rgba(0xf5c177ff).into()), success: Some(rgba(0xe0def4ff).into()), warning: Some(rgba(0xf5c177ff).into()), diff --git a/crates/theme2/src/themes/sandcastle.rs b/crates/theme2/src/themes/sandcastle.rs index ddcd06bec5e2a14568d654d2bfb75a15cb0e0ad3..5aa03988746c8e710657ea89352168ea49f9428b 100644 --- a/crates/theme2/src/themes/sandcastle.rs +++ b/crates/theme2/src/themes/sandcastle.rs @@ -71,6 +71,7 @@ pub fn sandcastle() -> UserThemeFamily { created: Some(rgba(0x83a598ff).into()), deleted: Some(rgba(0x8d4f61ff).into()), error: Some(rgba(0xb4637aff).into()), + hint: Some(rgba(0x727d68ff).into()), modified: Some(rgba(0xa07e3bff).into()), success: Some(rgba(0xfdf4c1ff).into()), warning: Some(rgba(0xa07e3bff).into()), diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index 7bf383e854ded6de475e4e2432002793b83bd620..c71ce54a2f027a32e1bf2424ea4422e893c4265d 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -72,6 +72,7 @@ pub fn solarized() -> UserThemeFamily { created: Some(rgba(0xa0ad46ff).into()), deleted: Some(rgba(0xdc3330ff).into()), error: Some(rgba(0xdc3330ff).into()), + hint: Some(rgba(0x5889a3ff).into()), modified: Some(rgba(0xb58904ff).into()), success: Some(rgba(0x002b36ff).into()), warning: Some(rgba(0xb58904ff).into()), @@ -453,6 +454,7 @@ pub fn solarized() -> UserThemeFamily { created: Some(rgba(0x859904ff).into()), deleted: Some(rgba(0xb52727ff).into()), error: Some(rgba(0xdc3330ff).into()), + hint: Some(rgba(0x4f8297ff).into()), modified: Some(rgba(0xb58903ff).into()), success: Some(rgba(0xfdf6e3ff).into()), warning: Some(rgba(0xb58903ff).into()), diff --git a/crates/theme2/src/themes/summercamp.rs b/crates/theme2/src/themes/summercamp.rs index 64f51231ae35b69028170d855be10bec43388708..a849988f7b2ca4855c0b0e5b38fc91707f7763b2 100644 --- a/crates/theme2/src/themes/summercamp.rs +++ b/crates/theme2/src/themes/summercamp.rs @@ -71,6 +71,7 @@ pub fn summercamp() -> UserThemeFamily { created: Some(rgba(0x5dea5aff).into()), deleted: Some(rgba(0xb93f36ff).into()), error: Some(rgba(0xe35142ff).into()), + hint: Some(rgba(0x246e61ff).into()), modified: Some(rgba(0xf1fe29ff).into()), success: Some(rgba(0xf8f5deff).into()), warning: Some(rgba(0xf1fe29ff).into()), diff --git a/crates/theme_importer/src/zed1/converter.rs b/crates/theme_importer/src/zed1/converter.rs index 385ad43350dee1200e790abf9fe64bd2288d266d..a12d96054ca83738069540c5883d8bea069ad667 100644 --- a/crates/theme_importer/src/zed1/converter.rs +++ b/crates/theme_importer/src/zed1/converter.rs @@ -71,6 +71,7 @@ impl Zed1ThemeConverter { Some(zed1_color_to_hsla(color)) } + let editor = &self.theme.editor; let diff_style = &self.theme.editor.diff; let diagnostic_summary = &self.theme.workspace.status_bar.diagnostic_summary; @@ -81,6 +82,7 @@ impl Zed1ThemeConverter { success: convert(diagnostic_summary.icon_color_ok), warning: convert(diagnostic_summary.icon_color_warning), error: convert(diagnostic_summary.icon_color_error), + hint: editor.hint.color.map(zed1_color_to_hsla), ..Default::default() }) } From e839dc5ee62d2b86c18c0666c47b5fbb9127d62f Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 23 Dec 2023 21:53:08 +0200 Subject: [PATCH 322/644] Hide pane tab bar for 0 items, hide its end buttons for no focus --- crates/workspace2/src/pane.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index bcf36dfe18e4d93d611d1403e68d0155979675d2..ecbebcfa36e00053fd91b342698dcdc0bebf36a5 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -1684,9 +1684,11 @@ impl Pane { .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)), ), ) - .end_child({ - let render_tab_buttons = self.render_tab_bar_buttons.clone(); - render_tab_buttons(self, cx) + .when(self.has_focus(cx), |tab_bar| { + tab_bar.end_child({ + let render_tab_buttons = self.render_tab_bar_buttons.clone(); + render_tab_buttons(self, cx) + }) }) .children( self.items @@ -1937,7 +1939,9 @@ impl Render for Pane { }) }), ) - .child(self.render_tab_bar(cx)) + .when(self.active_item().is_some(), |pane| { + pane.child(self.render_tab_bar(cx)) + }) .child({ let has_worktrees = self.project.read(cx).worktrees().next().is_some(); // main content From a249375f991eaaef2a2ea9d84d66112bacc602ae Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 23 Dec 2023 22:10:11 +0200 Subject: [PATCH 323/644] Do not show nav history buttons in terminal pane --- crates/terminal_view2/src/terminal_panel.rs | 1 + crates/workspace2/src/pane.rs | 56 ++++++++++++--------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/crates/terminal_view2/src/terminal_panel.rs b/crates/terminal_view2/src/terminal_panel.rs index 044a9f3aa8d63eb96ac202711c6494c38dcd3c4b..dd0c7d39995e539b542492b4b01ff52d60d7e82d 100644 --- a/crates/terminal_view2/src/terminal_panel.rs +++ b/crates/terminal_view2/src/terminal_panel.rs @@ -74,6 +74,7 @@ impl TerminalPanel { ); pane.set_can_split(false, cx); pane.set_can_navigate(false, cx); + pane.display_nav_history_buttons(false); pane.set_render_tab_bar_buttons(cx, move |pane, cx| { h_stack() .gap_2() diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index ecbebcfa36e00053fd91b342698dcdc0bebf36a5..bdb95deb564ee5d555a8a8fc6b4483565f709b64 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -187,6 +187,7 @@ pub struct Pane { render_tab_bar_buttons: Rc) -> AnyElement>, _subscriptions: Vec, tab_bar_scroll_handle: ScrollHandle, + display_nav_history_buttons: bool, } pub struct ItemNavHistory { @@ -439,6 +440,7 @@ impl Pane { }) .into_any_element() }), + display_nav_history_buttons: true, _subscriptions: subscriptions, } } @@ -1660,30 +1662,32 @@ impl Pane { fn render_tab_bar(&mut self, cx: &mut ViewContext<'_, Pane>) -> impl IntoElement { TabBar::new("tab_bar") .track_scroll(self.tab_bar_scroll_handle.clone()) - .start_child( - h_stack() - .gap_2() - .child( - IconButton::new("navigate_backward", Icon::ArrowLeft) - .icon_size(IconSize::Small) - .on_click({ - let view = cx.view().clone(); - move |_, cx| view.update(cx, Self::navigate_backward) - }) - .disabled(!self.can_navigate_backward()) - .tooltip(|cx| Tooltip::for_action("Go Back", &GoBack, cx)), - ) - .child( - IconButton::new("navigate_forward", Icon::ArrowRight) - .icon_size(IconSize::Small) - .on_click({ - let view = cx.view().clone(); - move |_, cx| view.update(cx, Self::navigate_backward) - }) - .disabled(!self.can_navigate_forward()) - .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)), - ), - ) + .when(self.display_nav_history_buttons, |tab_bar| { + tab_bar.start_child( + h_stack() + .gap_2() + .child( + IconButton::new("navigate_backward", Icon::ArrowLeft) + .icon_size(IconSize::Small) + .on_click({ + let view = cx.view().clone(); + move |_, cx| view.update(cx, Self::navigate_backward) + }) + .disabled(!self.can_navigate_backward()) + .tooltip(|cx| Tooltip::for_action("Go Back", &GoBack, cx)), + ) + .child( + IconButton::new("navigate_forward", Icon::ArrowRight) + .icon_size(IconSize::Small) + .on_click({ + let view = cx.view().clone(); + move |_, cx| view.update(cx, Self::navigate_backward) + }) + .disabled(!self.can_navigate_forward()) + .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)), + ), + ) + }) .when(self.has_focus(cx), |tab_bar| { tab_bar.end_child({ let render_tab_buttons = self.render_tab_bar_buttons.clone(); @@ -1851,6 +1855,10 @@ impl Pane { }) .log_err(); } + + pub fn display_nav_history_buttons(&mut self, display: bool) { + self.display_nav_history_buttons = display; + } } impl FocusableView for Pane { From 1096eeff3a428b41139cffbfb320ebe4f6fe1840 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 23 Dec 2023 22:33:52 +0200 Subject: [PATCH 324/644] Add a horizontal separator between history and query file finder matches --- crates/file_finder2/src/file_finder.rs | 9 +++++++++ crates/picker2/src/picker2.rs | 8 ++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/crates/file_finder2/src/file_finder.rs b/crates/file_finder2/src/file_finder.rs index 7410ed765886843026d60779bb1f413548352d7a..8ca7d46f2965b7452b86415d5817a8c67d6bc0c1 100644 --- a/crates/file_finder2/src/file_finder.rs +++ b/crates/file_finder2/src/file_finder.rs @@ -544,6 +544,15 @@ impl PickerDelegate for FileFinderDelegate { cx.notify(); } + fn separators_after_indices(&self) -> Vec { + let history_items = self.matches.history.len(); + if history_items == 0 { + Vec::new() + } else { + vec![history_items - 1] + } + } + fn update_matches( &mut self, raw_query: String, diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 8585d9e73bdb7b362516ba6e81e57d7789c79b90..3abdf953b3469e2e932d2a5f441c90caa44d8f3a 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -5,7 +5,7 @@ use gpui::{ UniformListScrollHandle, View, ViewContext, WindowContext, }; use std::{cmp, sync::Arc}; -use ui::{prelude::*, v_stack, Color, Divider, Label, ListItem, ListItemSpacing}; +use ui::{prelude::*, v_stack, Color, Divider, Label, ListItem, ListItemSpacing, ListSeparator}; use workspace::ModalView; pub struct Picker { @@ -26,6 +26,9 @@ pub trait PickerDelegate: Sized + 'static { type ListItem: IntoElement; fn match_count(&self) -> usize; fn selected_index(&self) -> usize; + fn separators_after_indices(&self) -> Vec { + Vec::new() + } fn set_selected_index(&mut self, ix: usize, cx: &mut ViewContext>); fn placeholder_text(&self) -> Arc; @@ -266,6 +269,7 @@ impl Render for Picker { "candidates", self.delegate.match_count(), { + let separators_after_indices = self.delegate.separators_after_indices(); let selected_index = self.delegate.selected_index(); move |picker, visible_range, cx| { visible_range @@ -285,7 +289,7 @@ impl Render for Picker { ix, ix == selected_index, cx, - )) + )).when(separators_after_indices.contains(&ix), |picker| picker.child(ListSeparator)) }) .collect() } From 58c5720c3289ee5634e55670d3d80367f5298e0b Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Sat, 23 Dec 2023 17:23:50 -0500 Subject: [PATCH 325/644] Remove telemetry debounce time in zed 2 --- crates/client2/src/telemetry.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/crates/client2/src/telemetry.rs b/crates/client2/src/telemetry.rs index f02ff937e4b992058f80e46d5fb4335281f40a35..9587bd9a0b861a8aa7c602dfc1cf90865d712bad 100644 --- a/crates/client2/src/telemetry.rs +++ b/crates/client2/src/telemetry.rs @@ -28,7 +28,6 @@ struct TelemetryState { app_metadata: AppMetadata, architecture: &'static str, clickhouse_events_queue: Vec, - flush_clickhouse_events_task: Option>, log_file: Option, is_staff: Option, first_event_datetime: Option>, @@ -120,12 +119,6 @@ const MAX_QUEUE_LEN: usize = 1; #[cfg(not(debug_assertions))] const MAX_QUEUE_LEN: usize = 50; -#[cfg(debug_assertions)] -const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(1); - -#[cfg(not(debug_assertions))] -const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(120); - impl Telemetry { pub fn new(client: Arc, cx: &mut AppContext) -> Arc { let release_channel = if cx.has_global::() { @@ -146,7 +139,6 @@ impl Telemetry { metrics_id: None, session_id: None, clickhouse_events_queue: Default::default(), - flush_clickhouse_events_task: Default::default(), log_file: None, is_staff: None, first_event_datetime: None, @@ -412,13 +404,6 @@ impl Telemetry { if immediate_flush || state.clickhouse_events_queue.len() >= MAX_QUEUE_LEN { drop(state); self.flush_clickhouse_events(); - } else { - let this = self.clone(); - let executor = self.executor.clone(); - state.flush_clickhouse_events_task = Some(self.executor.spawn(async move { - executor.timer(DEBOUNCE_INTERVAL).await; - this.flush_clickhouse_events(); - })); } } } @@ -439,7 +424,6 @@ impl Telemetry { let mut state = self.state.lock(); state.first_event_datetime = None; let mut events = mem::take(&mut state.clickhouse_events_queue); - state.flush_clickhouse_events_task.take(); drop(state); let this = self.clone(); From 81ed86128821fbaa6a0aca5a82957766cff9811d Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Sat, 23 Dec 2023 22:26:00 -0500 Subject: [PATCH 326/644] Migrate from device_id to installation_id key --- crates/zed/src/main.rs | 26 ++++++++++++++++++-------- crates/zed2/src/main.rs | 26 ++++++++++++++++++-------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 04f468eb2f03a2ea9661005116a2d9796af6c5c9..da8ff80c316f522b593a7ee44b301a673f315c29 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -327,19 +327,29 @@ async fn authenticate(client: Arc, cx: &AsyncAppContext) -> Result<()> { } async fn installation_id() -> Result<(String, bool)> { - let legacy_key_name = "device_id"; - - if let Ok(Some(installation_id)) = KEY_VALUE_STORE.read_kvp(legacy_key_name) { - Ok((installation_id, true)) - } else { - let installation_id = Uuid::new_v4().to_string(); + let legacy_key_name = "device_id".to_string(); + let key_name = "installation_id".to_string(); + // Migrate legacy key to new key + if let Ok(Some(installation_id)) = KEY_VALUE_STORE.read_kvp(&legacy_key_name) { KEY_VALUE_STORE - .write_kvp(legacy_key_name.to_string(), installation_id.clone()) + .write_kvp(key_name, installation_id.clone()) .await?; + KEY_VALUE_STORE.delete_kvp(legacy_key_name).await?; + return Ok((installation_id, true)); + } - Ok((installation_id, false)) + if let Ok(Some(installation_id)) = KEY_VALUE_STORE.read_kvp(&key_name) { + return Ok((installation_id, true)); } + + let installation_id = Uuid::new_v4().to_string(); + + KEY_VALUE_STORE + .write_kvp(key_name, installation_id.clone()) + .await?; + + Ok((installation_id, false)) } async fn restore_or_create_workspace(app_state: &Arc, mut cx: AsyncAppContext) { diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index a885a81f79e7e4c3fc02e1dfe2e13a5072dac668..a24fb7377d93fe1f0106d5998a1a22329a9c06a9 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -387,19 +387,29 @@ async fn authenticate(client: Arc, cx: &AsyncAppContext) -> Result<()> { } async fn installation_id() -> Result<(String, bool)> { - let legacy_key_name = "device_id"; - - if let Ok(Some(installation_id)) = KEY_VALUE_STORE.read_kvp(legacy_key_name) { - Ok((installation_id, true)) - } else { - let installation_id = Uuid::new_v4().to_string(); + let legacy_key_name = "device_id".to_string(); + let key_name = "installation_id".to_string(); + // Migrate legacy key to new key + if let Ok(Some(installation_id)) = KEY_VALUE_STORE.read_kvp(&legacy_key_name) { KEY_VALUE_STORE - .write_kvp(legacy_key_name.to_string(), installation_id.clone()) + .write_kvp(key_name, installation_id.clone()) .await?; + KEY_VALUE_STORE.delete_kvp(legacy_key_name).await?; + return Ok((installation_id, true)); + } - Ok((installation_id, false)) + if let Ok(Some(installation_id)) = KEY_VALUE_STORE.read_kvp(&key_name) { + return Ok((installation_id, true)); } + + let installation_id = Uuid::new_v4().to_string(); + + KEY_VALUE_STORE + .write_kvp(key_name, installation_id.clone()) + .await?; + + Ok((installation_id, false)) } async fn restore_or_create_workspace(app_state: &Arc, mut cx: AsyncAppContext) { From 88d05fd8140fbb4c0fcd65457497827a8c5c6cf1 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Mon, 25 Dec 2023 03:36:54 -0500 Subject: [PATCH 327/644] Wire up journal --- crates/journal2/src/journal2.rs | 18 +++++++++++------- crates/zed2/src/main.rs | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/crates/journal2/src/journal2.rs b/crates/journal2/src/journal2.rs index 20d520e36e427808a09d631cb95451318fefb51c..95ef17a358e8c14c91cfb0af4eab98acba3d2f48 100644 --- a/crates/journal2/src/journal2.rs +++ b/crates/journal2/src/journal2.rs @@ -1,6 +1,6 @@ use anyhow::Result; use chrono::{Datelike, Local, NaiveTime, Timelike}; -use gpui::AppContext; +use gpui::{actions, AppContext, ViewContext}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use settings2::Settings; @@ -9,11 +9,9 @@ use std::{ path::{Path, PathBuf}, sync::Arc, }; -use workspace2::AppState; -// use zed::AppState; +use workspace2::{AppState, Workspace}; -// todo!(); -// actions!(journal, [NewJournalEntry]); +actions!(journal, [NewJournalEntry]); #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct JournalSettings { @@ -55,8 +53,14 @@ impl settings2::Settings for JournalSettings { pub fn init(_: Arc, cx: &mut AppContext) { JournalSettings::register(cx); - // todo!() - // cx.add_global_action(move |_: &NewJournalEntry, cx| new_journal_entry(app_state.clone(), cx)); + cx.observe_new_views( + |workspace: &mut Workspace, _cx: &mut ViewContext| { + workspace.register_action(|workspace, _: &NewJournalEntry, cx| { + new_journal_entry(workspace.app_state().clone(), cx); + }); + }, + ) + .detach(); } pub fn new_journal_entry(app_state: Arc, cx: &mut AppContext) { diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index a24fb7377d93fe1f0106d5998a1a22329a9c06a9..06eb4320141cd5531efd383237877cd28582b642 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -215,7 +215,7 @@ fn main() { vim::init(cx); terminal_view::init(cx); - // journal2::init(app_state.clone(), cx); + journal::init(app_state.clone(), cx); language_selector::init(cx); theme_selector::init(cx); language_tools::init(cx); From ada1da48ca512784902f4001def74c13bb8b29a3 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Mon, 25 Dec 2023 03:47:03 -0500 Subject: [PATCH 328/644] Remove already-implemented comment --- crates/zed2/src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index 06eb4320141cd5531efd383237877cd28582b642..a248e4537bcf111e46933f24df32b0171b9d8720 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -209,7 +209,6 @@ fn main() { project_symbols::init(cx); project_panel::init(Assets, cx); channel::init(&client, user_store.clone(), cx); - // diagnostics::init(cx); search::init(cx); semantic_index::init(fs.clone(), http.clone(), languages.clone(), cx); vim::init(cx); From 8f3ea6ccb3e498912b3d03395de5603c1b3f1ad0 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Mon, 25 Dec 2023 03:47:28 -0500 Subject: [PATCH 329/644] Remove silencing of warnings and fix warnings --- crates/zed2/src/main.rs | 5 +---- crates/zed2/src/open_listener.rs | 11 +++++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index a248e4537bcf111e46933f24df32b0171b9d8720..f1fd168ffd832bcd2533dbb6e03c5fa13b571f85 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -1,6 +1,3 @@ -#![allow(unused_variables, dead_code, unused_mut)] -// todo!() this is to make transition easier. - // Allow binary to be called Zed for a nice application menu when running executable directly #![allow(non_snake_case)] @@ -411,7 +408,7 @@ async fn installation_id() -> Result<(String, bool)> { Ok((installation_id, false)) } -async fn restore_or_create_workspace(app_state: &Arc, mut cx: AsyncAppContext) { +async fn restore_or_create_workspace(app_state: &Arc, cx: AsyncAppContext) { async_maybe!({ if let Some(location) = workspace::last_opened_workspace_paths().await { cx.update(|cx| workspace::open_paths(location.paths().as_ref(), app_state, None, cx))? diff --git a/crates/zed2/src/open_listener.rs b/crates/zed2/src/open_listener.rs index b45254f7174c600f27ff552fef8ae7c2a2be7446..6db020a785788d1fe0d05cd2a4d10d937f2b5ac4 100644 --- a/crates/zed2/src/open_listener.rs +++ b/crates/zed2/src/open_listener.rs @@ -251,12 +251,11 @@ pub async fn handle_cli_connection( let wait = async move { if paths.is_empty() { let (done_tx, done_rx) = oneshot::channel(); - let _subscription = - workspace.update(&mut cx, |workspace, cx| { - cx.on_release(move |_, _, _| { - let _ = done_tx.send(()); - }) - }); + let _subscription = workspace.update(&mut cx, |_, cx| { + cx.on_release(move |_, _, _| { + let _ = done_tx.send(()); + }) + }); let _ = done_rx.await; } else { let _ = futures::future::try_join_all(item_release_futures) From 904358263caf3563b1e7ec2567f3ab6ea2f7c646 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 25 Dec 2023 12:23:44 +0100 Subject: [PATCH 330/644] Remove #[allow(unused)] annotations in zed2 crates (#3798) Release Notes: - N/A --- crates/copilot_button2/src/copilot_button.rs | 56 ++-- crates/editor2/src/blink_manager.rs | 3 +- crates/editor2/src/display_map.rs | 11 +- crates/editor2/src/display_map/block_map.rs | 2 +- crates/editor2/src/display_map/wrap_map.rs | 8 +- crates/editor2/src/editor.rs | 94 +++---- crates/editor2/src/editor_tests.rs | 264 +++++++++--------- crates/editor2/src/element.rs | 57 ++-- crates/editor2/src/hover_popover.rs | 10 +- crates/editor2/src/inlay_hint_cache.rs | 117 ++++---- crates/editor2/src/items.rs | 44 +-- crates/editor2/src/link_go_to_definition.rs | 2 +- crates/editor2/src/mouse_context_menu.rs | 8 +- crates/editor2/src/movement.rs | 4 +- crates/editor2/src/rust_analyzer_ext.rs | 4 +- crates/editor2/src/scroll.rs | 2 +- crates/editor2/src/scroll/actions.rs | 2 +- crates/editor2/src/scroll/autoscroll.rs | 12 +- .../editor2/src/test/editor_test_context.rs | 3 +- crates/workspace2/src/persistence.rs | 2 +- crates/zed2/src/open_listener.rs | 11 +- crates/zed2/src/zed2.rs | 13 +- 22 files changed, 358 insertions(+), 371 deletions(-) diff --git a/crates/copilot_button2/src/copilot_button.rs b/crates/copilot_button2/src/copilot_button.rs index d3a1c1e58c0e6e0113cc965017aecf0a3c3cdca9..2c8427732e7043da64aa16b6e72547678f4d82df 100644 --- a/crates/copilot_button2/src/copilot_button.rs +++ b/crates/copilot_button2/src/copilot_button.rs @@ -1,11 +1,10 @@ -#![allow(unused)] use anyhow::Result; use copilot::{Copilot, SignOut, Status}; use editor::{scroll::autoscroll::Autoscroll, Editor}; use fs::Fs; use gpui::{ - div, Action, AnchorCorner, AppContext, AsyncAppContext, AsyncWindowContext, Div, Entity, - ParentElement, Render, Subscription, View, ViewContext, WeakView, WindowContext, + div, Action, AnchorCorner, AppContext, AsyncWindowContext, Div, Entity, ParentElement, Render, + Subscription, View, ViewContext, WeakView, WindowContext, }; use language::{ language_settings::{self, all_language_settings, AllLanguageSettings}, @@ -17,10 +16,7 @@ use util::{paths, ResultExt}; use workspace::{ create_and_open_local_file, item::ItemHandle, - ui::{ - popover_menu, ButtonCommon, Clickable, ContextMenu, Icon, IconButton, IconSize, - PopoverMenu, Tooltip, - }, + ui::{popover_menu, ButtonCommon, Clickable, ContextMenu, Icon, IconButton, IconSize, Tooltip}, StatusItemView, Toast, Workspace, }; use zed_actions::OpenBrowser; @@ -71,27 +67,31 @@ impl Render for CopilotButton { return div().child( IconButton::new("copilot-error", icon) .icon_size(IconSize::Small) - .on_click(cx.listener(move |this, _, cx| { + .on_click(cx.listener(move |_, _, cx| { if let Some(workspace) = cx.window_handle().downcast::() { - workspace.update(cx, |workspace, cx| { - workspace.show_toast( - Toast::new( - COPILOT_ERROR_TOAST_ID, - format!("Copilot can't be started: {}", e), - ) - .on_click( - "Reinstall Copilot", - |cx| { - if let Some(copilot) = Copilot::global(cx) { - copilot - .update(cx, |copilot, cx| copilot.reinstall(cx)) - .detach(); - } - }, - ), - cx, - ); - }); + workspace + .update(cx, |workspace, cx| { + workspace.show_toast( + Toast::new( + COPILOT_ERROR_TOAST_ID, + format!("Copilot can't be started: {}", e), + ) + .on_click( + "Reinstall Copilot", + |cx| { + if let Some(copilot) = Copilot::global(cx) { + copilot + .update(cx, |copilot, cx| { + copilot.reinstall(cx) + }) + .detach(); + } + }, + ), + cx, + ); + }) + .ok(); } })) .tooltip(|cx| Tooltip::text("GitHub Copilot", cx)), @@ -134,7 +134,7 @@ impl CopilotButton { pub fn build_copilot_start_menu(&mut self, cx: &mut ViewContext) -> View { let fs = self.fs.clone(); - ContextMenu::build(cx, |menu, cx| { + ContextMenu::build(cx, |menu, _| { menu.entry("Sign In", None, initiate_sign_in).entry( "Disable Copilot", None, diff --git a/crates/editor2/src/blink_manager.rs b/crates/editor2/src/blink_manager.rs index 0fc748f48abbcaf66e47f9ab86dcfd4855a20e3d..e3a8ce6293c67a57af4a4a2403e074cfd9765344 100644 --- a/crates/editor2/src/blink_manager.rs +++ b/crates/editor2/src/blink_manager.rs @@ -67,7 +67,8 @@ impl BlinkManager { cx.spawn(|this, mut cx| async move { Timer::after(interval).await; if let Some(this) = this.upgrade() { - this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx)); + this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx)) + .ok(); } }) .detach(); diff --git a/crates/editor2/src/display_map.rs b/crates/editor2/src/display_map.rs index 60975a7a5caec6552b3154e528b9629e9beb094c..6298c80d2f05c1e9fddaa2149be1553e2ea14f8f 100644 --- a/crates/editor2/src/display_map.rs +++ b/crates/editor2/src/display_map.rs @@ -12,10 +12,7 @@ use crate::{ pub use block_map::{BlockMap, BlockPoint}; use collections::{BTreeMap, HashMap, HashSet}; use fold_map::FoldMap; -use gpui::{ - Font, FontId, HighlightStyle, Hsla, LineLayout, Model, ModelContext, Pixels, ShapedLine, - TextRun, UnderlineStyle, WrappedLine, -}; +use gpui::{Font, HighlightStyle, Hsla, LineLayout, Model, ModelContext, Pixels, UnderlineStyle}; use inlay_map::InlayMap; use language::{ language_settings::language_settings, OffsetUtf16, Point, Subscription as BufferSubscription, @@ -24,7 +21,7 @@ use lsp::DiagnosticSeverity; use std::{any::TypeId, borrow::Cow, fmt::Debug, num::NonZeroU32, ops::Range, sync::Arc}; use sum_tree::{Bias, TreeMap}; use tab_map::TabMap; -use theme::{StatusColors, SyntaxTheme, Theme}; + use wrap_map::WrapMap; pub use block_map::{ @@ -1018,7 +1015,7 @@ pub mod tests { .map(|i| i.parse().expect("invalid `OPERATIONS` variable")) .unwrap_or(10); - let test_platform = &cx.test_platform; + let _test_platform = &cx.test_platform; let mut tab_size = rng.gen_range(1..=4); let buffer_start_excerpt_header_height = rng.gen_range(1..=5); let excerpt_header_height = rng.gen_range(1..=5); @@ -1280,7 +1277,7 @@ pub mod tests { let editor = cx.editor.clone(); let window = cx.window.clone(); - cx.update_window(window, |_, cx| { + _ = cx.update_window(window, |_, cx| { let text_layout_details = editor.update(cx, |editor, cx| editor.text_layout_details(cx)); diff --git a/crates/editor2/src/display_map/block_map.rs b/crates/editor2/src/display_map/block_map.rs index cc0095bca94f30f6d65866c640092cb384d2cce3..6eb0d05bfe84c4b487bb65bfc97ee49bcaff1736 100644 --- a/crates/editor2/src/display_map/block_map.rs +++ b/crates/editor2/src/display_map/block_map.rs @@ -1185,7 +1185,7 @@ mod tests { fn test_blocks_on_wrapped_lines(cx: &mut gpui::TestAppContext) { cx.update(|cx| init_test(cx)); - let font_id = cx.text_system().font_id(&font("Helvetica")).unwrap(); + let _font_id = cx.text_system().font_id(&font("Helvetica")).unwrap(); let text = "one two three\nfour five six\nseven eight"; diff --git a/crates/editor2/src/display_map/wrap_map.rs b/crates/editor2/src/display_map/wrap_map.rs index 6a47a435a3c445d87b811c790bb4d83a1523983a..4ef6a13c69ed81b8e4a6c6a23bd19d0b94391642 100644 --- a/crates/editor2/src/display_map/wrap_map.rs +++ b/crates/editor2/src/display_map/wrap_map.rs @@ -197,7 +197,8 @@ impl WrapMap { this.background_task = None; this.flush_edits(cx); cx.notify(); - }); + }) + .ok(); })); } } @@ -277,7 +278,8 @@ impl WrapMap { this.background_task = None; this.flush_edits(cx); cx.notify(); - }); + }) + .ok(); })); } } @@ -1057,7 +1059,7 @@ mod tests { }; let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap(); let font = font("Helvetica"); - let font_id = text_system.font_id(&font).unwrap(); + let _font_id = text_system.font_id(&font).unwrap(); let font_size = px(14.0); log::info!("Tab size: {}", tab_size); diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index d3ee41b11f92512a88c6b6dc334256aacc8625aa..c9fb2fa181f4a1d9d06cfcb21e95c7bbd2c4c34a 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -1,4 +1,3 @@ -#![allow(unused)] mod blink_manager; pub mod display_map; mod editor_settings; @@ -42,11 +41,10 @@ use git::diff_hunk_to_display; use gpui::{ actions, div, impl_actions, point, prelude::*, px, relative, rems, size, uniform_list, Action, AnyElement, AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context, - DispatchPhase, Div, ElementId, EventEmitter, FocusHandle, FocusableView, FontFeatures, - FontStyle, FontWeight, HighlightStyle, Hsla, InputHandler, InteractiveText, KeyContext, Model, - MouseButton, ParentElement, Pixels, Render, RenderOnce, SharedString, Styled, StyledText, - Subscription, Task, TextRun, TextStyle, UniformListScrollHandle, View, ViewContext, - VisualContext, WeakView, WhiteSpace, WindowContext, + DispatchPhase, ElementId, EventEmitter, FocusHandle, FocusableView, FontStyle, FontWeight, + HighlightStyle, Hsla, InputHandler, InteractiveText, KeyContext, Model, MouseButton, + ParentElement, Pixels, Render, SharedString, Styled, StyledText, Subscription, Task, TextStyle, + UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WhiteSpace, WindowContext, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; use hover_popover::{hide_hover, HoverState}; @@ -61,7 +59,7 @@ use language::{ LanguageRegistry, LanguageServerName, OffsetRangeExt, Point, Selection, SelectionGoal, TransactionId, }; -use lazy_static::lazy_static; + use link_go_to_definition::{GoToDefinitionLink, InlayHighlight, LinkGoToDefinitionState}; use lsp::{DiagnosticSeverity, LanguageServerId}; use mouse_context_menu::MouseContextMenu; @@ -72,7 +70,7 @@ pub use multi_buffer::{ ToPoint, }; use ordered_float::OrderedFloat; -use parking_lot::{Mutex, RwLock}; +use parking_lot::RwLock; use project::{FormatTrigger, Location, Project, ProjectPath, ProjectTransaction}; use rand::prelude::*; use rpc::proto::{self, *}; @@ -99,19 +97,11 @@ use std::{ pub use sum_tree::Bias; use sum_tree::TreeMap; use text::{OffsetUtf16, Rope}; -use theme::{ - ActiveTheme, DiagnosticStyle, PlayerColor, SyntaxTheme, Theme, ThemeColors, ThemeSettings, -}; -use ui::{ - h_stack, v_stack, ButtonSize, ButtonStyle, HighlightedLabel, Icon, IconButton, Popover, Tooltip, -}; +use theme::{ActiveTheme, DiagnosticStyle, PlayerColor, SyntaxTheme, ThemeColors, ThemeSettings}; +use ui::{h_stack, ButtonSize, ButtonStyle, Icon, IconButton, Popover, Tooltip}; use ui::{prelude::*, IconSize}; use util::{post_inc, RangeExt, ResultExt, TryFutureExt}; -use workspace::{ - item::{Item, ItemEvent, ItemHandle}, - searchable::SearchEvent, - ItemNavHistory, Pane, SplitDirection, ViewId, Workspace, -}; +use workspace::{searchable::SearchEvent, ItemNavHistory, Pane, SplitDirection, ViewId, Workspace}; const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500); const MAX_LINE_LEN: usize = 1024; @@ -439,7 +429,7 @@ pub fn init(cx: &mut AppContext) { workspace::register_followable_item::(cx); workspace::register_deserializable_item::(cx); cx.observe_new_views( - |workspace: &mut Workspace, cx: &mut ViewContext| { + |workspace: &mut Workspace, _cx: &mut ViewContext| { workspace.register_action(Editor::new_file); workspace.register_action(Editor::new_file_in_direction); }, @@ -1216,7 +1206,7 @@ impl CompletionsMenu { cx.view().clone(), "completions", matches.len(), - move |editor, range, cx| { + move |_editor, range, cx| { let start_ix = range.start; let completions_guard = completions.read(); @@ -1271,7 +1261,7 @@ impl CompletionsMenu { }) .on_mouse_down( MouseButton::Left, - cx.listener(move |editor, event, cx| { + cx.listener(move |editor, _event, cx| { cx.stop_propagation(); editor .confirm_completion( @@ -1414,7 +1404,7 @@ impl CodeActionsMenu { fn render( &self, mut cursor_position: DisplayPoint, - style: &EditorStyle, + _style: &EditorStyle, max_height: Pixels, cx: &mut ViewContext, ) -> (DisplayPoint, AnyElement) { @@ -1425,7 +1415,7 @@ impl CodeActionsMenu { cx.view().clone(), "code_actions_menu", self.actions.len(), - move |this, range, cx| { + move |_this, range, cx| { actions[range.clone()] .iter() .enumerate() @@ -3418,9 +3408,11 @@ impl Editor { Some(cx.spawn(|editor, mut cx| async move { if let Some(transaction) = on_type_formatting.await? { if push_to_client_history { - buffer.update(&mut cx, |buffer, _| { - buffer.push_transaction(transaction, Instant::now()); - }); + buffer + .update(&mut cx, |buffer, _| { + buffer.push_transaction(transaction, Instant::now()); + }) + .ok(); } editor.update(&mut cx, |editor, cx| { editor.refresh_document_highlights(cx); @@ -4226,7 +4218,7 @@ impl Editor { pub fn render_code_actions_indicator( &self, - style: &EditorStyle, + _style: &EditorStyle, is_active: bool, cx: &mut ViewContext, ) -> Option { @@ -4236,7 +4228,7 @@ impl Editor { .icon_size(IconSize::Small) .icon_color(Color::Muted) .selected(is_active) - .on_click(cx.listener(|editor, e, cx| { + .on_click(cx.listener(|editor, _e, cx| { editor.toggle_code_actions( &ToggleCodeActions { deployed_from_indicator: true, @@ -4253,10 +4245,10 @@ impl Editor { pub fn render_fold_indicators( &self, fold_data: Vec>, - style: &EditorStyle, + _style: &EditorStyle, gutter_hovered: bool, - line_height: Pixels, - gutter_margin: Pixels, + _line_height: Pixels, + _gutter_margin: Pixels, cx: &mut ViewContext, ) -> Vec> { fold_data @@ -4267,7 +4259,7 @@ impl Editor { .map(|(fold_status, buffer_row, active)| { (active || gutter_hovered || fold_status == FoldStatus::Folded).then(|| { IconButton::new(ix as usize, ui::Icon::ChevronDown) - .on_click(cx.listener(move |editor, e, cx| match fold_status { + .on_click(cx.listener(move |editor, _e, cx| match fold_status { FoldStatus::Folded => { editor.unfold_at(&UnfoldAt { buffer_row }, cx); } @@ -7379,11 +7371,13 @@ impl Editor { .filter_map(|location| location.transpose()) .collect::>() .context("location tasks")?; - workspace.update(&mut cx, |workspace, cx| { - Self::open_locations_in_multibuffer( - workspace, locations, replica_id, title, split, cx, - ) - }); + workspace + .update(&mut cx, |workspace, cx| { + Self::open_locations_in_multibuffer( + workspace, locations, replica_id, title, split, cx, + ) + }) + .ok(); anyhow::Ok(()) }) @@ -7832,15 +7826,17 @@ impl Editor { transaction = format.log_err().fuse() => transaction, }; - buffer.update(&mut cx, |buffer, cx| { - if let Some(transaction) = transaction { - if !buffer.is_singleton() { - buffer.push_transaction(&transaction.0, cx); + buffer + .update(&mut cx, |buffer, cx| { + if let Some(transaction) = transaction { + if !buffer.is_singleton() { + buffer.push_transaction(&transaction.0, cx); + } } - } - cx.notify(); - }); + cx.notify(); + }) + .ok(); Ok(()) }) @@ -9119,7 +9115,7 @@ impl Editor { let listener = Arc::new(listener); self.editor_actions.push(Box::new(move |cx| { - let view = cx.view().clone(); + let _view = cx.view().clone(); let cx = cx.window_context(); let listener = listener.clone(); cx.on_action(TypeId::of::(), move |action, phase, cx| { @@ -9289,7 +9285,7 @@ pub enum EditorEvent { impl EventEmitter for Editor {} impl FocusableView for Editor { - fn focus_handle(&self, cx: &AppContext) -> FocusHandle { + fn focus_handle(&self, _cx: &AppContext) -> FocusHandle { self.focus_handle.clone() } } @@ -9329,7 +9325,7 @@ impl Render for Editor { let background = match self.mode { EditorMode::SingleLine => cx.theme().system().transparent, - EditorMode::AutoHeight { max_lines } => cx.theme().system().transparent, + EditorMode::AutoHeight { max_lines: _ } => cx.theme().system().transparent, EditorMode::Full => cx.theme().colors().editor_background, }; @@ -9719,7 +9715,7 @@ impl InvalidationRegion for SnippetState { } } -pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> RenderBlock { +pub fn diagnostic_block_renderer(diagnostic: Diagnostic, _is_valid: bool) -> RenderBlock { let (text_without_backticks, code_ranges) = highlight_diagnostic_message(&diagnostic); Arc::new(move |cx: &mut BlockContext| { diff --git a/crates/editor2/src/editor_tests.rs b/crates/editor2/src/editor_tests.rs index 2548fc40a4afc2262a533536a6230c650183b1f0..563913bbe199e1402d175417f2356476e33376b2 100644 --- a/crates/editor2/src/editor_tests.rs +++ b/crates/editor2/src/editor_tests.rs @@ -12,7 +12,7 @@ use futures::StreamExt; use gpui::{ div, serde_json::{self, json}, - Div, Flatten, TestAppContext, VisualTestContext, WindowBounds, WindowOptions, + TestAppContext, VisualTestContext, WindowBounds, WindowOptions, }; use indoc::indoc; use language::{ @@ -77,7 +77,7 @@ fn test_edit_events(cx: &mut TestAppContext) { assert_eq!(mem::take(&mut *events.borrow_mut()), []); // Mutating editor 1 will emit an `Edited` event only for that editor. - editor1.update(cx, |editor, cx| editor.insert("X", cx)); + _ = editor1.update(cx, |editor, cx| editor.insert("X", cx)); assert_eq!( mem::take(&mut *events.borrow_mut()), [ @@ -88,7 +88,7 @@ fn test_edit_events(cx: &mut TestAppContext) { ); // Mutating editor 2 will emit an `Edited` event only for that editor. - editor2.update(cx, |editor, cx| editor.delete(&Delete, cx)); + _ = editor2.update(cx, |editor, cx| editor.delete(&Delete, cx)); assert_eq!( mem::take(&mut *events.borrow_mut()), [ @@ -99,7 +99,7 @@ fn test_edit_events(cx: &mut TestAppContext) { ); // Undoing on editor 1 will emit an `Edited` event only for that editor. - editor1.update(cx, |editor, cx| editor.undo(&Undo, cx)); + _ = editor1.update(cx, |editor, cx| editor.undo(&Undo, cx)); assert_eq!( mem::take(&mut *events.borrow_mut()), [ @@ -110,7 +110,7 @@ fn test_edit_events(cx: &mut TestAppContext) { ); // Redoing on editor 1 will emit an `Edited` event only for that editor. - editor1.update(cx, |editor, cx| editor.redo(&Redo, cx)); + _ = editor1.update(cx, |editor, cx| editor.redo(&Redo, cx)); assert_eq!( mem::take(&mut *events.borrow_mut()), [ @@ -121,7 +121,7 @@ fn test_edit_events(cx: &mut TestAppContext) { ); // Undoing on editor 2 will emit an `Edited` event only for that editor. - editor2.update(cx, |editor, cx| editor.undo(&Undo, cx)); + _ = editor2.update(cx, |editor, cx| editor.undo(&Undo, cx)); assert_eq!( mem::take(&mut *events.borrow_mut()), [ @@ -132,7 +132,7 @@ fn test_edit_events(cx: &mut TestAppContext) { ); // Redoing on editor 2 will emit an `Edited` event only for that editor. - editor2.update(cx, |editor, cx| editor.redo(&Redo, cx)); + _ = editor2.update(cx, |editor, cx| editor.redo(&Redo, cx)); assert_eq!( mem::take(&mut *events.borrow_mut()), [ @@ -143,7 +143,7 @@ fn test_edit_events(cx: &mut TestAppContext) { ); // No event is emitted when the mutation is a no-op. - editor2.update(cx, |editor, cx| { + _ = editor2.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges([0..0])); editor.backspace(&Backspace, cx); @@ -161,7 +161,7 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) { let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); let editor = cx.add_window(|cx| build_editor(buffer.clone(), cx)); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.start_transaction_at(now, cx); editor.change_selections(None, cx, |s| s.select_ranges([2..4])); @@ -181,7 +181,7 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) { editor.change_selections(None, cx, |s| s.select_ranges([2..2])); // Simulate an edit in another editor - buffer.update(cx, |buffer, cx| { + _ = buffer.update(cx, |buffer, cx| { buffer.start_transaction_at(now, cx); buffer.edit([(0..1, "a")], None, cx); buffer.edit([(1..1, "b")], None, cx); @@ -334,7 +334,7 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) { build_editor(buffer, cx) }); - editor.update(cx, |view, cx| { + _ = editor.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); }); assert_eq!( @@ -344,7 +344,7 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) { [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)] ); - editor.update(cx, |view, cx| { + _ = editor.update(cx, |view, cx| { view.update_selection( DisplayPoint::new(3, 3), 0, @@ -360,7 +360,7 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) { [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); - editor.update(cx, |view, cx| { + _ = editor.update(cx, |view, cx| { view.update_selection( DisplayPoint::new(1, 1), 0, @@ -376,7 +376,7 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) { [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)] ); - editor.update(cx, |view, cx| { + _ = editor.update(cx, |view, cx| { view.end_selection(cx); view.update_selection( DisplayPoint::new(3, 3), @@ -393,7 +393,7 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) { [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)] ); - editor.update(cx, |view, cx| { + _ = editor.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(3, 3), true, 1, cx); view.update_selection( DisplayPoint::new(0, 0), @@ -413,7 +413,7 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) { ] ); - editor.update(cx, |view, cx| { + _ = editor.update(cx, |view, cx| { view.end_selection(cx); }); @@ -434,7 +434,7 @@ fn test_canceling_pending_selection(cx: &mut TestAppContext) { build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx); assert_eq!( view.selections.display_ranges(cx), @@ -442,7 +442,7 @@ fn test_canceling_pending_selection(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.update_selection( DisplayPoint::new(3, 3), 0, @@ -455,7 +455,7 @@ fn test_canceling_pending_selection(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.cancel(&Cancel, cx); view.update_selection( DisplayPoint::new(1, 1), @@ -490,7 +490,7 @@ fn test_clone(cx: &mut TestAppContext) { build_editor(buffer, cx) }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone())); editor.fold_ranges( [ @@ -557,7 +557,7 @@ async fn test_navigation_history(cx: &mut TestAppContext) { .update(cx, |workspace, _| workspace.active_pane().clone()) .unwrap(); - workspace.update(cx, |v, cx| { + _ = workspace.update(cx, |_v, cx| { cx.build_view(|cx| { let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx); let mut editor = build_editor(buffer.clone(), cx); @@ -671,7 +671,7 @@ fn test_cancel(cx: &mut TestAppContext) { build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.begin_selection(DisplayPoint::new(3, 4), false, 1, cx); view.update_selection( DisplayPoint::new(1, 1), @@ -698,7 +698,7 @@ fn test_cancel(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.cancel(&Cancel, cx); assert_eq!( view.selections.display_ranges(cx), @@ -706,7 +706,7 @@ fn test_cancel(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.cancel(&Cancel, cx); assert_eq!( view.selections.display_ranges(cx), @@ -744,7 +744,7 @@ fn test_fold_action(cx: &mut TestAppContext) { build_editor(buffer.clone(), cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(8, 0)..DisplayPoint::new(12, 0)]); }); @@ -812,7 +812,7 @@ fn test_move_cursor(cx: &mut TestAppContext) { let buffer = cx.update(|cx| MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx)); let view = cx.add_window(|cx| build_editor(buffer.clone(), cx)); - buffer.update(cx, |buffer, cx| { + _ = buffer.update(cx, |buffer, cx| { buffer.edit( vec![ (Point::new(1, 0)..Point::new(1, 0), "\t"), @@ -822,7 +822,7 @@ fn test_move_cursor(cx: &mut TestAppContext) { cx, ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { assert_eq!( view.selections.display_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] @@ -893,7 +893,7 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) { assert_eq!('ⓐ'.len_utf8(), 3); assert_eq!('α'.len_utf8(), 2); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.fold_ranges( vec![ Point::new(0, 6)..Point::new(0, 12), @@ -1006,7 +1006,7 @@ fn test_move_cursor_different_line_lengths(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx); build_editor(buffer.clone(), cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([empty_range(0, "ⓐⓑⓒⓓⓔ".len())]); }); @@ -1056,7 +1056,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\n def", cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), @@ -1065,7 +1065,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { }); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx); assert_eq!( view.selections.display_ranges(cx), @@ -1076,7 +1076,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx); assert_eq!( view.selections.display_ranges(cx), @@ -1087,7 +1087,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx); assert_eq!( view.selections.display_ranges(cx), @@ -1098,7 +1098,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.move_to_end_of_line(&MoveToEndOfLine, cx); assert_eq!( view.selections.display_ranges(cx), @@ -1110,7 +1110,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { }); // Moving to the end of line again is a no-op. - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.move_to_end_of_line(&MoveToEndOfLine, cx); assert_eq!( view.selections.display_ranges(cx), @@ -1121,7 +1121,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.move_left(&MoveLeft, cx); view.select_to_beginning_of_line( &SelectToBeginningOfLine { @@ -1138,7 +1138,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_to_beginning_of_line( &SelectToBeginningOfLine { stop_at_soft_wraps: true, @@ -1154,7 +1154,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_to_beginning_of_line( &SelectToBeginningOfLine { stop_at_soft_wraps: true, @@ -1170,7 +1170,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_to_end_of_line( &SelectToEndOfLine { stop_at_soft_wraps: true, @@ -1186,7 +1186,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.delete_to_end_of_line(&DeleteToEndOfLine, cx); assert_eq!(view.display_text(cx), "ab\n de"); assert_eq!( @@ -1198,7 +1198,7 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.delete_to_beginning_of_line(&DeleteToBeginningOfLine, cx); assert_eq!(view.display_text(cx), "\n"); assert_eq!( @@ -1219,7 +1219,7 @@ fn test_prev_next_word_boundary(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("use std::str::{foo, bar}\n\n {baz.qux()}", cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 11)..DisplayPoint::new(0, 11), @@ -1273,7 +1273,7 @@ fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut TestAppContext) { build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.set_wrap_width(Some(140.0.into()), cx); assert_eq!( view.display_text(cx), @@ -1714,7 +1714,7 @@ fn test_delete_to_word_boundary(cx: &mut TestAppContext) { build_editor(buffer.clone(), cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ // an empty selection - the preceding word fragment is deleted @@ -1727,7 +1727,7 @@ fn test_delete_to_word_boundary(cx: &mut TestAppContext) { assert_eq!(view.buffer.read(cx).read(cx).text(), "e two te four"); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ // an empty selection - the following word fragment is deleted @@ -1750,7 +1750,7 @@ fn test_newline(cx: &mut TestAppContext) { build_editor(buffer.clone(), cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -1793,7 +1793,7 @@ fn test_newline_with_old_selections(cx: &mut TestAppContext) { editor }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { // Edit the buffer directly, deleting ranges surrounding the editor's selections editor.buffer.update(cx, |buffer, cx| { buffer.edit( @@ -2003,7 +2003,7 @@ fn test_insert_with_old_selections(cx: &mut TestAppContext) { editor }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { // Edit the buffer directly, deleting ranges surrounding the editor's selections editor.buffer.update(cx, |buffer, cx| { buffer.edit([(2..5, ""), (10..13, ""), (18..21, "")], None, cx); @@ -2514,7 +2514,7 @@ fn test_delete_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), @@ -2537,7 +2537,7 @@ fn test_delete_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)]) }); @@ -2946,7 +2946,7 @@ fn test_duplicate_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), @@ -2972,7 +2972,7 @@ fn test_duplicate_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\ndef\nghi\n", cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 1)..DisplayPoint::new(1, 1), @@ -2999,7 +2999,7 @@ fn test_move_line_up_down(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.fold_ranges( vec![ Point::new(0, 2)..Point::new(1, 2), @@ -3038,7 +3038,7 @@ fn test_move_line_up_down(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.move_line_down(&MoveLineDown, cx); assert_eq!( view.display_text(cx), @@ -3055,7 +3055,7 @@ fn test_move_line_up_down(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.move_line_down(&MoveLineDown, cx); assert_eq!( view.display_text(cx), @@ -3072,7 +3072,7 @@ fn test_move_line_up_down(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.move_line_up(&MoveLineUp, cx); assert_eq!( view.display_text(cx), @@ -3098,7 +3098,7 @@ fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&sample_text(10, 5, 'a'), cx); build_editor(buffer, cx) }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let snapshot = editor.buffer.read(cx).snapshot(cx); editor.insert_blocks( [BlockProperties { @@ -3420,7 +3420,7 @@ fn test_select_all(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple("abc\nde\nfgh", cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_all(&SelectAll, cx); assert_eq!( view.selections.display_ranges(cx), @@ -3437,7 +3437,7 @@ fn test_select_line(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&sample_text(6, 5, 'a'), cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), @@ -3456,7 +3456,7 @@ fn test_select_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_line(&SelectLine, cx); assert_eq!( view.selections.display_ranges(cx), @@ -3467,7 +3467,7 @@ fn test_select_line(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_line(&SelectLine, cx); assert_eq!( view.selections.display_ranges(cx), @@ -3484,7 +3484,7 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) { let buffer = MultiBuffer::build_simple(&sample_text(9, 5, 'a'), cx); build_editor(buffer, cx) }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.fold_ranges( vec![ Point::new(0, 2)..Point::new(1, 2), @@ -3505,7 +3505,7 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) { assert_eq!(view.display_text(cx), "aa⋯bbb\nccc⋯eeee\nfffff\nggggg\n⋯i"); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.split_selection_into_lines(&SplitSelectionIntoLines, cx); assert_eq!( view.display_text(cx), @@ -3522,7 +3522,7 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) { ); }); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([DisplayPoint::new(5, 0)..DisplayPoint::new(0, 1)]) }); @@ -3916,7 +3916,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { view.condition::(&cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25), @@ -3935,7 +3935,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { ] ); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( @@ -3946,7 +3946,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { ] ); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( @@ -3955,7 +3955,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { ); // Trying to expand the selected syntax node one more time has no effect. - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx); }); assert_eq!( @@ -3963,7 +3963,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)] ); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( @@ -3974,7 +3974,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { ] ); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( @@ -3986,7 +3986,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { ] ); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( @@ -3999,7 +3999,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { ); // Trying to shrink the selected syntax node one more time has no effect. - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx); }); assert_eq!( @@ -4013,7 +4013,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) { // Ensure that we keep expanding the selection if the larger selection starts or ends within // a fold. - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.fold_ranges( vec![ Point::new(0, 21)..Point::new(0, 24), @@ -4082,7 +4082,7 @@ async fn test_autoindent_selections(cx: &mut gpui::TestAppContext) { .condition::(cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx)) .await; - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges([5..5, 8..8, 9..9])); editor.newline(&Newline, cx); assert_eq!(editor.text(cx), "fn a(\n \n) {\n \n}\n"); @@ -4646,7 +4646,7 @@ async fn test_surround_with_pair(cx: &mut gpui::TestAppContext) { view.condition::(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1), @@ -4797,7 +4797,7 @@ async fn test_delete_autoclose_pair(cx: &mut gpui::TestAppContext) { .condition::(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| { s.select_ranges([ Point::new(0, 1)..Point::new(0, 1), @@ -4883,9 +4883,9 @@ async fn test_snippets(cx: &mut gpui::TestAppContext) { ); let buffer = cx.update(|cx| MultiBuffer::build_simple(&text, cx)); - let (editor, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx)); + let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx)); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let snippet = Snippet::parse("f(${1:one}, ${2:two}, ${1:three})$0").unwrap(); editor @@ -5003,7 +5003,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) { fs.insert_file("/file.rs", Default::default()).await; let project = Project::test(fs, ["/file.rs".as_ref()], cx).await; - project.update(cx, |project, _| project.languages().add(Arc::new(language))); + _ = project.update(cx, |project, _| project.languages().add(Arc::new(language))); let buffer = project .update(cx, |project, cx| project.open_local_buffer("/file.rs", cx)) .await @@ -5014,7 +5014,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) { let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx)); - editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); + _ = editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); assert!(cx.read(|cx| editor.is_dirty(cx))); let save = editor @@ -5035,7 +5035,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) { .next() .await; cx.executor().start_waiting(); - let x = save.await; + let _x = save.await; assert_eq!( editor.update(cx, |editor, cx| editor.text(cx)), @@ -5043,7 +5043,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) { ); assert!(!cx.read(|cx| editor.is_dirty(cx))); - editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); + _ = editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); assert!(cx.read(|cx| editor.is_dirty(cx))); // Ensure we can still save even if formatting hangs. @@ -5122,7 +5122,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) { fs.insert_file("/file.rs", Default::default()).await; let project = Project::test(fs, ["/file.rs".as_ref()], cx).await; - project.update(cx, |project, _| project.languages().add(Arc::new(language))); + _ = project.update(cx, |project, _| project.languages().add(Arc::new(language))); let buffer = project .update(cx, |project, cx| project.open_local_buffer("/file.rs", cx)) .await @@ -5133,7 +5133,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) { let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx)); - editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); + _ = editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); assert!(cx.read(|cx| editor.is_dirty(cx))); let save = editor @@ -5161,7 +5161,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) { ); assert!(!cx.read(|cx| editor.is_dirty(cx))); - editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); + _ = editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); assert!(cx.read(|cx| editor.is_dirty(cx))); // Ensure we can still save even if formatting hangs. @@ -5247,7 +5247,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) { fs.insert_file("/file.rs", Default::default()).await; let project = Project::test(fs, ["/file.rs".as_ref()], cx).await; - project.update(cx, |project, _| { + _ = project.update(cx, |project, _| { project.languages().add(Arc::new(language)); }); let buffer = project @@ -5260,7 +5260,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) { let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx)); - editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); + _ = editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); let format = editor .update(cx, |editor, cx| { @@ -5288,7 +5288,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) { "one, two\nthree\n" ); - editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); + _ = editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx)); // Ensure we don't lock if formatting hangs. fake_server.handle_request::(move |params, _| async move { assert_eq!( @@ -5627,7 +5627,7 @@ async fn test_completion(cx: &mut gpui::TestAppContext) { handle_resolve_completion_request(&mut cx, None).await; apply_additional_edits.await.unwrap(); - cx.update(|cx| { + _ = cx.update(|cx| { cx.update_global::(|settings, cx| { settings.update_user_settings::(cx, |settings| { settings.show_completions_on_input = Some(false); @@ -6046,7 +6046,7 @@ fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) { }); let (view, cx) = cx.add_window_view(|cx| build_editor(multibuffer, cx)); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { assert_eq!(view.text(cx), "aaaa\nbbbb"); view.change_selections(None, cx, |s| { s.select_ranges([ @@ -6116,7 +6116,7 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) { }); let (view, cx) = cx.add_window_view(|cx| build_editor(multibuffer, cx)); - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { let (expected_text, selection_ranges) = marked_text_ranges( indoc! {" aaaa @@ -6210,7 +6210,7 @@ fn test_refresh_selections(cx: &mut TestAppContext) { }); // Refreshing selections is a no-op when excerpts haven't changed. - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.refresh()); assert_eq!( editor.selections.ranges(cx), @@ -6221,10 +6221,10 @@ fn test_refresh_selections(cx: &mut TestAppContext) { ); }); - multibuffer.update(cx, |multibuffer, cx| { + _ = multibuffer.update(cx, |multibuffer, cx| { multibuffer.remove_excerpts([excerpt1_id.unwrap()], cx); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { // Removing an excerpt causes the first selection to become degenerate. assert_eq!( editor.selections.ranges(cx), @@ -6289,10 +6289,10 @@ fn test_refresh_selections_while_selecting_with_mouse(cx: &mut TestAppContext) { editor }); - multibuffer.update(cx, |multibuffer, cx| { + _ = multibuffer.update(cx, |multibuffer, cx| { multibuffer.remove_excerpts([excerpt1_id.unwrap()], cx); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( editor.selections.ranges(cx), [Point::new(0, 0)..Point::new(0, 0)] @@ -6356,7 +6356,7 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) { view.condition::(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; - view.update(cx, |view, cx| { + _ = view.update(cx, |view, cx| { view.change_selections(None, cx, |s| { s.select_display_ranges([ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3), @@ -6393,7 +6393,7 @@ fn test_highlighted_ranges(cx: &mut TestAppContext) { build_editor(buffer.clone(), cx) }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { struct Type1; struct Type2; @@ -6498,7 +6498,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) { let is_still_following = Rc::new(RefCell::new(true)); let follower_edit_event_count = Rc::new(RefCell::new(0)); let pending_update = Rc::new(RefCell::new(None)); - follower.update(cx, { + _ = follower.update(cx, { let update = pending_update.clone(); let is_still_following = is_still_following.clone(); let follower_edit_event_count = follower_edit_event_count.clone(); @@ -6515,7 +6515,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) { cx.subscribe( &follower.root_view(cx).unwrap(), - move |_, _, event: &EditorEvent, cx| { + move |_, _, event: &EditorEvent, _cx| { if matches!(Editor::to_follow_event(event), Some(FollowEvent::Unfollow)) { *is_still_following.borrow_mut() = false; } @@ -6530,7 +6530,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) { }); // Update the selections only - leader.update(cx, |leader, cx| { + _ = leader.update(cx, |leader, cx| { leader.change_selections(None, cx, |s| s.select_ranges([1..1])); }); follower @@ -6540,14 +6540,14 @@ async fn test_following(cx: &mut gpui::TestAppContext) { .unwrap() .await .unwrap(); - follower.update(cx, |follower, cx| { + _ = follower.update(cx, |follower, cx| { assert_eq!(follower.selections.ranges(cx), vec![1..1]); }); assert_eq!(*is_still_following.borrow(), true); assert_eq!(*follower_edit_event_count.borrow(), 0); // Update the scroll position only - leader.update(cx, |leader, cx| { + _ = leader.update(cx, |leader, cx| { leader.set_scroll_position(gpui::Point::new(1.5, 3.5), cx); }); follower @@ -6568,7 +6568,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) { // Update the selections and scroll position. The follower's scroll position is updated // via autoscroll, not via the leader's exact scroll position. - leader.update(cx, |leader, cx| { + _ = leader.update(cx, |leader, cx| { leader.change_selections(None, cx, |s| s.select_ranges([0..0])); leader.request_autoscroll(Autoscroll::newest(), cx); leader.set_scroll_position(gpui::Point::new(1.5, 3.5), cx); @@ -6580,14 +6580,14 @@ async fn test_following(cx: &mut gpui::TestAppContext) { .unwrap() .await .unwrap(); - follower.update(cx, |follower, cx| { + _ = follower.update(cx, |follower, cx| { assert_eq!(follower.scroll_position(cx), gpui::Point::new(1.5, 0.0)); assert_eq!(follower.selections.ranges(cx), vec![0..0]); }); assert_eq!(*is_still_following.borrow(), true); // Creating a pending selection that precedes another selection - leader.update(cx, |leader, cx| { + _ = leader.update(cx, |leader, cx| { leader.change_selections(None, cx, |s| s.select_ranges([1..1])); leader.begin_selection(DisplayPoint::new(0, 0), true, 1, cx); }); @@ -6598,13 +6598,13 @@ async fn test_following(cx: &mut gpui::TestAppContext) { .unwrap() .await .unwrap(); - follower.update(cx, |follower, cx| { + _ = follower.update(cx, |follower, cx| { assert_eq!(follower.selections.ranges(cx), vec![0..0, 1..1]); }); assert_eq!(*is_still_following.borrow(), true); // Extend the pending selection so that it surrounds another selection - leader.update(cx, |leader, cx| { + _ = leader.update(cx, |leader, cx| { leader.extend_selection(DisplayPoint::new(0, 2), 1, cx); }); follower @@ -6614,12 +6614,12 @@ async fn test_following(cx: &mut gpui::TestAppContext) { .unwrap() .await .unwrap(); - follower.update(cx, |follower, cx| { + _ = follower.update(cx, |follower, cx| { assert_eq!(follower.selections.ranges(cx), vec![0..2]); }); // Scrolling locally breaks the follow - follower.update(cx, |follower, cx| { + _ = follower.update(cx, |follower, cx| { let top_anchor = follower.buffer().read(cx).read(cx).anchor_after(0); follower.set_scroll_anchor( ScrollAnchor { @@ -6695,7 +6695,7 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) { }); // Insert some excerpts. - leader.update(cx, |leader, cx| { + _ = leader.update(cx, |leader, cx| { leader.buffer.update(cx, |multibuffer, cx| { let excerpt_ids = multibuffer.push_excerpts( buffer_1.clone(), @@ -6771,7 +6771,7 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) { ); // Remove some excerpts. - leader.update(cx, |leader, cx| { + _ = leader.update(cx, |leader, cx| { leader.buffer.update(cx, |multibuffer, cx| { let excerpt_ids = multibuffer.excerpt_ids(); multibuffer.remove_excerpts([excerpt_ids[1], excerpt_ids[2]], cx); @@ -6814,8 +6814,8 @@ async fn go_to_prev_overlapping_diagnostic( } "}); - cx.update(|cx| { - project.update(cx, |project, cx| { + _ = cx.update(|cx| { + _ = project.update(cx, |project, cx| { project .update_diagnostics( LanguageServerId(0), @@ -7113,7 +7113,7 @@ async fn test_copilot(executor: BackgroundExecutor, cx: &mut gpui::TestAppContex init_test(cx, |_| {}); let (copilot, copilot_lsp) = Copilot::fake(cx); - cx.update(|cx| cx.set_global(copilot)); + _ = cx.update(|cx| cx.set_global(copilot)); let mut cx = EditorLspTestContext::new_rust( lsp::ServerCapabilities { completion_provider: Some(lsp::CompletionOptions { @@ -7366,7 +7366,7 @@ async fn test_copilot_completion_invalidation( init_test(cx, |_| {}); let (copilot, copilot_lsp) = Copilot::fake(cx); - cx.update(|cx| cx.set_global(copilot)); + _ = cx.update(|cx| cx.set_global(copilot)); let mut cx = EditorLspTestContext::new_rust( lsp::ServerCapabilities { completion_provider: Some(lsp::CompletionOptions { @@ -7430,7 +7430,7 @@ async fn test_copilot_multibuffer(executor: BackgroundExecutor, cx: &mut gpui::T init_test(cx, |_| {}); let (copilot, copilot_lsp) = Copilot::fake(cx); - cx.update(|cx| cx.set_global(copilot)); + _ = cx.update(|cx| cx.set_global(copilot)); let buffer_1 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "a = 1\nb = 2\n")); let buffer_2 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "c = 3\nd = 4\n")); @@ -7465,7 +7465,7 @@ async fn test_copilot_multibuffer(executor: BackgroundExecutor, cx: &mut gpui::T }], vec![], ); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { // Ensure copilot suggestions are shown for the first excerpt. editor.change_selections(None, cx, |s| { s.select_ranges([Point::new(1, 5)..Point::new(1, 5)]) @@ -7473,7 +7473,7 @@ async fn test_copilot_multibuffer(executor: BackgroundExecutor, cx: &mut gpui::T editor.next_copilot_suggestion(&Default::default(), cx); }); executor.advance_clock(COPILOT_DEBOUNCE_TIMEOUT); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert!(editor.has_active_copilot_suggestion(cx)); assert_eq!( editor.display_text(cx), @@ -7491,7 +7491,7 @@ async fn test_copilot_multibuffer(executor: BackgroundExecutor, cx: &mut gpui::T }], vec![], ); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { // Move to another excerpt, ensuring the suggestion gets cleared. editor.change_selections(None, cx, |s| { s.select_ranges([Point::new(4, 5)..Point::new(4, 5)]) @@ -7515,7 +7515,7 @@ async fn test_copilot_multibuffer(executor: BackgroundExecutor, cx: &mut gpui::T // Ensure the new suggestion is displayed when the debounce timeout expires. executor.advance_clock(COPILOT_DEBOUNCE_TIMEOUT); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert!(editor.has_active_copilot_suggestion(cx)); assert_eq!( editor.display_text(cx), @@ -7535,7 +7535,7 @@ async fn test_copilot_disabled_globs(executor: BackgroundExecutor, cx: &mut gpui }); let (copilot, copilot_lsp) = Copilot::fake(cx); - cx.update(|cx| cx.set_global(copilot)); + _ = cx.update(|cx| cx.set_global(copilot)); let fs = FakeFs::new(cx.executor()); fs.insert_tree( @@ -7594,7 +7594,7 @@ async fn test_copilot_disabled_globs(executor: BackgroundExecutor, cx: &mut gpui }) }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |selections| { selections.select_ranges([Point::new(0, 0)..Point::new(0, 0)]) }); @@ -7604,7 +7604,7 @@ async fn test_copilot_disabled_globs(executor: BackgroundExecutor, cx: &mut gpui executor.advance_clock(COPILOT_DEBOUNCE_TIMEOUT); assert!(copilot_requests.try_next().is_err()); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| { s.select_ranges([Point::new(2, 0)..Point::new(2, 0)]) }); @@ -7659,7 +7659,7 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) { ) .await; let project = Project::test(fs, ["/a".as_ref()], cx).await; - project.update(cx, |project, _| project.languages().add(Arc::new(language))); + _ = project.update(cx, |project, _| project.languages().add(Arc::new(language))); let workspace = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let cx = &mut VisualTestContext::from_window(*workspace, cx); @@ -7717,7 +7717,7 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) { cx.executor().run_until_parked(); - buffer.update(cx, |buffer, _| { + _ = buffer.update(cx, |buffer, _| { assert_eq!( buffer.text(), "fn main() { let a = {5}; }", @@ -7770,7 +7770,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut gpui::Test ) .await; let project = Project::test(fs, ["/a".as_ref()], cx).await; - project.update(cx, |project, _| project.languages().add(Arc::new(language))); + _ = project.update(cx, |project, _| project.languages().add(Arc::new(language))); let _window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx)); let _buffer = project .update(cx, |project, cx| { @@ -8082,7 +8082,7 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) { let project = Project::test(fs, ["/file.rs".as_ref()], cx).await; let prettier_format_suffix = project::TEST_PRETTIER_FORMAT_SUFFIX; - project.update(cx, |project, _| { + _ = project.update(cx, |project, _| { project.languages().add(Arc::new(language)); }); let buffer = project @@ -8093,7 +8093,7 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) { let buffer_text = "one\ntwo\nthree\n"; let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx)); - editor.update(cx, |editor, cx| editor.set_text(buffer_text, cx)); + _ = editor.update(cx, |editor, cx| editor.set_text(buffer_text, cx)); editor .update(cx, |editor, cx| { @@ -8244,7 +8244,7 @@ pub(crate) fn update_test_language_settings( cx: &mut TestAppContext, f: impl Fn(&mut AllLanguageSettingsContent), ) { - cx.update(|cx| { + _ = cx.update(|cx| { cx.update_global(|store: &mut SettingsStore, cx| { store.update_user_settings::(cx, f); }); @@ -8255,7 +8255,7 @@ pub(crate) fn update_test_project_settings( cx: &mut TestAppContext, f: impl Fn(&mut ProjectSettings), ) { - cx.update(|cx| { + _ = cx.update(|cx| { cx.update_global(|store: &mut SettingsStore, cx| { store.update_user_settings::(cx, f); }); @@ -8263,7 +8263,7 @@ pub(crate) fn update_test_project_settings( } pub(crate) fn init_test(cx: &mut TestAppContext, f: fn(&mut AllLanguageSettingsContent)) { - cx.update(|cx| { + _ = cx.update(|cx| { let store = SettingsStore::test(cx); cx.set_global(store); theme::init(theme::LoadThemes::JustBase, cx); diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 568adce5566c4456366dd5ad4b6682f4a4905037..eb9f4106ea43d57e5339511ad52b8255c6e35882 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -16,24 +16,23 @@ use crate::{ mouse_context_menu, scroll::scroll_amount::ScrollAmount, CursorShape, DisplayPoint, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, - HalfPageDown, HalfPageUp, LineDown, LineUp, MoveDown, OpenExcerpts, PageDown, PageUp, Point, - SelectPhase, Selection, SoftWrap, ToPoint, MAX_LINE_LEN, + HalfPageDown, HalfPageUp, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point, SelectPhase, + Selection, SoftWrap, ToPoint, MAX_LINE_LEN, }; use anyhow::Result; use collections::{BTreeMap, HashMap}; use git::diff::DiffHunkStatus; use gpui::{ div, fill, outline, overlay, point, px, quad, relative, size, transparent_black, Action, - AnchorCorner, AnyElement, AsyncWindowContext, AvailableSpace, BorrowWindow, Bounds, - ContentMask, Corners, CursorStyle, DispatchPhase, Edges, Element, ElementId, - ElementInputHandler, Entity, EntityId, Hsla, InteractiveBounds, InteractiveElement, - IntoElement, LineLayout, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, - MouseUpEvent, ParentElement, Pixels, RenderOnce, ScrollWheelEvent, ShapedLine, SharedString, - Size, StackingOrder, StatefulInteractiveElement, Style, Styled, TextRun, TextStyle, View, - ViewContext, WeakView, WindowContext, WrappedLine, + AnchorCorner, AnyElement, AvailableSpace, BorrowWindow, Bounds, ContentMask, Corners, + CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Hsla, InteractiveBounds, + InteractiveElement, IntoElement, ModifiersChangedEvent, MouseButton, MouseDownEvent, + MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, ScrollWheelEvent, ShapedLine, + SharedString, Size, StackingOrder, StatefulInteractiveElement, Style, Styled, TextRun, + TextStyle, View, ViewContext, WindowContext, }; use itertools::Itertools; -use language::{language_settings::ShowWhitespaceSetting, Language}; +use language::language_settings::ShowWhitespaceSetting; use multi_buffer::Anchor; use project::{ project_settings::{GitGutterSetting, ProjectSettings}, @@ -52,15 +51,11 @@ use std::{ }; use sum_tree::Bias; use theme::{ActiveTheme, PlayerColor}; -use ui::{ - h_stack, ButtonLike, ButtonStyle, Disclosure, IconButton, IconElement, IconSize, Label, Tooltip, -}; -use ui::{prelude::*, Icon}; +use ui::prelude::*; +use ui::{h_stack, ButtonLike, ButtonStyle, IconButton, Label, Tooltip}; use util::ResultExt; use workspace::item::Item; -enum FoldMarkers {} - struct SelectionLayout { head: DisplayPoint, cursor_shape: CursorShape, @@ -732,7 +727,7 @@ impl EditorElement { ix as f32 * line_height - (scroll_top % line_height), ); - line.paint(line_origin, line_height, cx); + line.paint(line_origin, line_height, cx).log_err(); } } @@ -2687,11 +2682,13 @@ impl LineWithInvisibles { let line_height = layout.position_map.line_height; let line_y = line_height * row as f32 - layout.position_map.scroll_position.y; - self.line.paint( - content_origin + gpui::point(-layout.position_map.scroll_position.x, line_y), - line_height, - cx, - ); + self.line + .paint( + content_origin + gpui::point(-layout.position_map.scroll_position.x, line_y), + line_height, + cx, + ) + .log_err(); self.draw_invisibles( &selection_ranges, @@ -2746,7 +2743,7 @@ impl LineWithInvisibles { continue; } } - invisible_symbol.paint(origin, line_height, cx); + invisible_symbol.paint(origin, line_height, cx).log_err(); } } } @@ -3090,7 +3087,9 @@ impl Cursor { cx.paint_quad(cursor); if let Some(block_text) = &self.block_text { - block_text.paint(self.origin + origin, self.line_height, cx); + block_text + .paint(self.origin + origin, self.line_height, cx) + .log_err(); } } @@ -3251,7 +3250,7 @@ mod tests { editor_tests::{init_test, update_test_language_settings}, Editor, MultiBuffer, }; - use gpui::{EmptyView, TestAppContext}; + use gpui::TestAppContext; use language::language_settings; use log::info; use std::{num::NonZeroU32, sync::Arc}; @@ -3432,7 +3431,7 @@ mod tests { let editor = window.root(cx).unwrap(); let style = cx.update(|cx| editor.read(cx).style().unwrap().clone()); let mut element = EditorElement::new(&editor, style); - let state = window.update(cx, |editor, cx| { + let _state = window.update(cx, |editor, cx| { editor.cursor_shape = CursorShape::Block; editor.change_selections(None, cx, |s| { s.select_display_ranges([ @@ -3504,7 +3503,7 @@ mod tests { .unwrap(); let mut element = EditorElement::new(&editor, style); - let mut state = cx + let state = cx .update_window(window.into(), |_, cx| { element.compute_layout( Bounds { @@ -3768,17 +3767,15 @@ fn compute_auto_height_layout( .width; let mut snapshot = editor.snapshot(cx); - let gutter_padding; let gutter_width; let gutter_margin; if snapshot.show_gutter { let descent = cx.text_system().descent(font_id, font_size); let gutter_padding_factor = 3.5; - gutter_padding = (em_width * gutter_padding_factor).round(); + let gutter_padding = (em_width * gutter_padding_factor).round(); gutter_width = max_line_number_width + gutter_padding * 2.0; gutter_margin = -descent; } else { - gutter_padding = Pixels::ZERO; gutter_width = Pixels::ZERO; gutter_margin = Pixels::ZERO; }; diff --git a/crates/editor2/src/hover_popover.rs b/crates/editor2/src/hover_popover.rs index 3a53a1bd1d6cca3e48dc3267b65b1d8d9527ac4f..ca2fc4e9b2a2aa054703bb271d1f8af18bd151b3 100644 --- a/crates/editor2/src/hover_popover.rs +++ b/crates/editor2/src/hover_popover.rs @@ -6,12 +6,12 @@ use crate::{ }; use futures::FutureExt; use gpui::{ - actions, div, px, AnyElement, AppContext, CursorStyle, InteractiveElement, IntoElement, Model, - MouseButton, ParentElement, Pixels, SharedString, Size, StatefulInteractiveElement, Styled, - Task, ViewContext, WeakView, + actions, div, px, AnyElement, CursorStyle, InteractiveElement, IntoElement, Model, MouseButton, + ParentElement, Pixels, SharedString, Size, StatefulInteractiveElement, Styled, Task, + ViewContext, WeakView, }; use language::{markdown, Bias, DiagnosticEntry, Language, LanguageRegistry, ParsedMarkdown}; -use lsp::DiagnosticSeverity; + use project::{HoverBlock, HoverBlockKind, InlayHintLabelPart, Project}; use settings::Settings; use std::{ops::Range, sync::Arc, time::Duration}; @@ -869,7 +869,7 @@ mod tests { let editor = cx.add_window(|cx| Editor::single_line(cx)); editor - .update(cx, |editor, cx| { + .update(cx, |editor, _cx| { let style = editor.style.clone().unwrap(); struct Row { diff --git a/crates/editor2/src/inlay_hint_cache.rs b/crates/editor2/src/inlay_hint_cache.rs index aab985ff9030988481796b0a4181189662f749c9..aac9e54cf3bf1906e3fc277d03ea5c40eb4abfac 100644 --- a/crates/editor2/src/inlay_hint_cache.rs +++ b/crates/editor2/src/inlay_hint_cache.rs @@ -1203,7 +1203,7 @@ pub mod tests { ExcerptRange, }; use futures::StreamExt; - use gpui::{Context, TestAppContext, View, WindowHandle}; + use gpui::{Context, TestAppContext, WindowHandle}; use itertools::Itertools; use language::{ language_settings::AllLanguageSettingsContent, FakeLspAdapter, Language, LanguageConfig, @@ -1214,7 +1214,6 @@ pub mod tests { use serde_json::json; use settings::SettingsStore; use text::{Point, ToPoint}; - use workspace::Workspace; use crate::editor_tests::update_test_language_settings; @@ -1273,7 +1272,7 @@ pub mod tests { cx.executor().run_until_parked(); let mut edits_made = 1; - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["0".to_string()]; assert_eq!( expected_hints, @@ -1292,13 +1291,13 @@ pub mod tests { ); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges([13..13])); editor.handle_input("some change", cx); edits_made += 1; }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["0".to_string(), "1".to_string()]; assert_eq!( expected_hints, @@ -1323,7 +1322,7 @@ pub mod tests { .expect("inlay refresh request failed"); edits_made += 1; cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["0".to_string(), "1".to_string(), "2".to_string()]; assert_eq!( expected_hints, @@ -1383,7 +1382,7 @@ pub mod tests { cx.executor().run_until_parked(); let mut edits_made = 1; - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["0".to_string()]; assert_eq!( expected_hints, @@ -1414,7 +1413,7 @@ pub mod tests { }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["0".to_string()]; assert_eq!( expected_hints, @@ -1438,7 +1437,7 @@ pub mod tests { cx.executor().run_until_parked(); edits_made += 1; - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["1".to_string()]; assert_eq!( expected_hints, @@ -1543,7 +1542,7 @@ pub mod tests { .next() .await; cx.executor().run_until_parked(); - rs_editor.update(cx, |editor, cx| { + _ = rs_editor.update(cx, |editor, cx| { let expected_hints = vec!["0".to_string()]; assert_eq!( expected_hints, @@ -1594,7 +1593,7 @@ pub mod tests { .next() .await; cx.executor().run_until_parked(); - md_editor.update(cx, |editor, cx| { + _ = md_editor.update(cx, |editor, cx| { let expected_hints = vec!["0".to_string()]; assert_eq!( expected_hints, @@ -1605,12 +1604,12 @@ pub mod tests { assert_eq!(editor.inlay_hint_cache().version, 1); }); - rs_editor.update(cx, |editor, cx| { + _ = rs_editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges([13..13])); editor.handle_input("some rs change", cx); }); cx.executor().run_until_parked(); - rs_editor.update(cx, |editor, cx| { + _ = rs_editor.update(cx, |editor, cx| { let expected_hints = vec!["1".to_string()]; assert_eq!( expected_hints, @@ -1624,7 +1623,7 @@ pub mod tests { "Every time hint cache changes, cache version should be incremented" ); }); - md_editor.update(cx, |editor, cx| { + _ = md_editor.update(cx, |editor, cx| { let expected_hints = vec!["0".to_string()]; assert_eq!( expected_hints, @@ -1635,12 +1634,12 @@ pub mod tests { assert_eq!(editor.inlay_hint_cache().version, 1); }); - md_editor.update(cx, |editor, cx| { + _ = md_editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges([13..13])); editor.handle_input("some md change", cx); }); cx.executor().run_until_parked(); - md_editor.update(cx, |editor, cx| { + _ = md_editor.update(cx, |editor, cx| { let expected_hints = vec!["1".to_string()]; assert_eq!( expected_hints, @@ -1650,7 +1649,7 @@ pub mod tests { assert_eq!(expected_hints, visible_hint_labels(editor, cx)); assert_eq!(editor.inlay_hint_cache().version, 2); }); - rs_editor.update(cx, |editor, cx| { + _ = rs_editor.update(cx, |editor, cx| { let expected_hints = vec!["1".to_string()]; assert_eq!( expected_hints, @@ -1725,7 +1724,7 @@ pub mod tests { cx.executor().run_until_parked(); let mut edits_made = 1; - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( lsp_request_count.load(Ordering::Relaxed), 1, @@ -1760,7 +1759,7 @@ pub mod tests { .await .expect("inlay refresh request failed"); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( lsp_request_count.load(Ordering::Relaxed), 2, @@ -1832,7 +1831,7 @@ pub mod tests { }) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( lsp_request_count.load(Ordering::Relaxed), 2, @@ -1876,7 +1875,7 @@ pub mod tests { }) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( lsp_request_count.load(Ordering::Relaxed), 2, @@ -1906,7 +1905,7 @@ pub mod tests { .await .expect("inlay refresh request failed"); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( lsp_request_count.load(Ordering::Relaxed), 2, @@ -1932,7 +1931,7 @@ pub mod tests { }) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( lsp_request_count.load(Ordering::Relaxed), 3, @@ -1968,7 +1967,7 @@ pub mod tests { .await .expect("inlay refresh request failed"); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( lsp_request_count.load(Ordering::Relaxed), 4, @@ -2035,7 +2034,7 @@ pub mod tests { "initial change #2", "initial change #3", ] { - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges([13..13])); editor.handle_input(change_after_opening, cx); }); @@ -2044,7 +2043,7 @@ pub mod tests { cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let current_text = editor.text(cx); for change in &expected_changes { assert!( @@ -2079,7 +2078,7 @@ pub mod tests { expected_changes.push(async_later_change); let task_editor = editor.clone(); edits.push(cx.spawn(|mut cx| async move { - task_editor.update(&mut cx, |editor, cx| { + _ = task_editor.update(&mut cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges([13..13])); editor.handle_input(async_later_change, cx); }); @@ -2088,7 +2087,7 @@ pub mod tests { let _ = future::join_all(edits).await; cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let current_text = editor.text(cx); for change in &expected_changes { assert!( @@ -2246,7 +2245,7 @@ pub mod tests { lsp::Position::new(initial_visible_range.end.row * 2, 2); let mut expected_invisible_query_start = lsp_initial_visible_range.end; expected_invisible_query_start.character += 1; - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let ranges = lsp_request_ranges.lock().drain(..).collect::>(); assert_eq!(ranges.len(), 2, "When scroll is at the edge of a big document, its visible part and the same range further should be queried in order, but got: {ranges:?}"); @@ -2273,7 +2272,7 @@ pub mod tests { ); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.scroll_screen(&ScrollAmount::Page(1.0), cx); editor.scroll_screen(&ScrollAmount::Page(1.0), cx); }); @@ -2343,7 +2342,7 @@ pub mod tests { }) .unwrap(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(Some(Autoscroll::center()), cx, |s| { s.select_ranges([selection_in_cached_range..selection_in_cached_range]) }); @@ -2352,7 +2351,7 @@ pub mod tests { INVISIBLE_RANGES_HINTS_REQUEST_DELAY_MILLIS + 100, )); cx.executor().run_until_parked(); - editor.update(cx, |_, _| { + _ = editor.update(cx, |_, _| { let ranges = lsp_request_ranges .lock() .drain(..) @@ -2362,14 +2361,14 @@ pub mod tests { assert_eq!(lsp_request_count.load(Ordering::Acquire), 4); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.handle_input("++++more text++++", cx); }); cx.executor().advance_clock(Duration::from_millis( INVISIBLE_RANGES_HINTS_REQUEST_DELAY_MILLIS + 100, )); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let mut ranges = lsp_request_ranges.lock().drain(..).collect::>(); ranges.sort_by_key(|r| r.start); @@ -2597,7 +2596,7 @@ pub mod tests { .await; cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec![ "main hint #0".to_string(), "main hint #1".to_string(), @@ -2615,7 +2614,7 @@ pub mod tests { assert_eq!(editor.inlay_hint_cache().version, expected_hints.len(), "Every visible excerpt hints should bump the verison"); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(Some(Autoscroll::Next), cx, |s| { s.select_ranges([Point::new(4, 0)..Point::new(4, 0)]) }); @@ -2627,7 +2626,7 @@ pub mod tests { }); }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec![ "main hint #0".to_string(), "main hint #1".to_string(), @@ -2646,7 +2645,7 @@ pub mod tests { "Due to every excerpt having one hint, we update cache per new excerpt scrolled"); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(Some(Autoscroll::Next), cx, |s| { s.select_ranges([Point::new(100, 0)..Point::new(100, 0)]) }); @@ -2677,13 +2676,13 @@ pub mod tests { expected_hints.len() }).unwrap(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(Some(Autoscroll::Next), cx, |s| { s.select_ranges([Point::new(4, 0)..Point::new(4, 0)]) }); }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec![ "main hint #0".to_string(), "main hint #1".to_string(), @@ -2705,7 +2704,7 @@ pub mod tests { }); editor_edited.store(true, Ordering::Release); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| { // TODO if this gets set to hint boundary (e.g. 56) we sometimes get an extra cache version bump, why? s.select_ranges([Point::new(57, 0)..Point::new(57, 0)]) @@ -2713,7 +2712,7 @@ pub mod tests { editor.handle_input("++++more text++++", cx); }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec![ "main hint(edited) #0".to_string(), "main hint(edited) #1".to_string(), @@ -2895,7 +2894,7 @@ pub mod tests { .await; cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( vec!["main hint #0".to_string(), "other hint #0".to_string()], cached_hint_labels(editor), @@ -2912,13 +2911,13 @@ pub mod tests { ); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.buffer().update(cx, |multibuffer, cx| { multibuffer.remove_excerpts(buffer_2_excerpts, cx) }) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert_eq!( vec!["main hint #0".to_string()], cached_hint_labels(editor), @@ -2944,7 +2943,7 @@ pub mod tests { }) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["main hint #0".to_string()]; assert_eq!( expected_hints, @@ -3041,13 +3040,13 @@ pub mod tests { .await; cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| { s.select_ranges([Point::new(10, 0)..Point::new(10, 0)]) }) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["1".to_string()]; assert_eq!(expected_hints, cached_hint_labels(editor)); assert_eq!(expected_hints, visible_hint_labels(editor, cx)); @@ -3068,7 +3067,7 @@ pub mod tests { let (file_with_hints, editor, fake_server) = prepare_test_objects(cx).await; - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.toggle_inlay_hints(&crate::ToggleInlayHints, cx) }); cx.executor().start_waiting(); @@ -3099,7 +3098,7 @@ pub mod tests { .next() .await; cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["1".to_string()]; assert_eq!( expected_hints, @@ -3114,11 +3113,11 @@ pub mod tests { ); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.toggle_inlay_hints(&crate::ToggleInlayHints, cx) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert!( cached_hint_labels(editor).is_empty(), "Should clear hints after 2nd toggle" @@ -3136,7 +3135,7 @@ pub mod tests { }) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["2".to_string()]; assert_eq!( expected_hints, @@ -3147,11 +3146,11 @@ pub mod tests { assert_eq!(editor.inlay_hint_cache().version, 3); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.toggle_inlay_hints(&crate::ToggleInlayHints, cx) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert!( cached_hint_labels(editor).is_empty(), "Should clear hints after enabling in settings and a 3rd toggle" @@ -3160,11 +3159,11 @@ pub mod tests { assert_eq!(editor.inlay_hint_cache().version, 4); }); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { editor.toggle_inlay_hints(&crate::ToggleInlayHints, cx) }); cx.executor().run_until_parked(); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { let expected_hints = vec!["3".to_string()]; assert_eq!( expected_hints, @@ -3223,7 +3222,7 @@ pub mod tests { .await; let project = Project::test(fs, ["/a".as_ref()], cx).await; - project.update(cx, |project, _| project.languages().add(Arc::new(language))); + _ = project.update(cx, |project, _| project.languages().add(Arc::new(language))); let buffer = project .update(cx, |project, cx| { project.open_local_buffer("/a/main.rs", cx) @@ -3235,7 +3234,7 @@ pub mod tests { let fake_server = fake_servers.next().await.unwrap(); let editor = cx.add_window(|cx| Editor::for_buffer(buffer, Some(project), cx)); - editor.update(cx, |editor, cx| { + _ = editor.update(cx, |editor, cx| { assert!(cached_hint_labels(editor).is_empty()); assert!(visible_hint_labels(editor, cx).is_empty()); assert_eq!(editor.inlay_hint_cache().version, 0); diff --git a/crates/editor2/src/items.rs b/crates/editor2/src/items.rs index ddb5b25db2fd990a675b15165b8d7d19282e3b1d..b10b891d0dbf1e3aa77e8c2a36d0a87add9a53d6 100644 --- a/crates/editor2/src/items.rs +++ b/crates/editor2/src/items.rs @@ -1,17 +1,15 @@ use crate::{ editor_settings::SeedQuerySetting, link_go_to_definition::hide_link_definition, - movement::surrounding_word, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor, - EditorEvent, EditorSettings, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, - NavigationData, ToPoint as _, + persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor, EditorEvent, EditorSettings, + ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _, }; use anyhow::{anyhow, Context as _, Result}; use collections::HashSet; use futures::future::try_join_all; use gpui::{ - div, point, AnyElement, AppContext, AsyncAppContext, AsyncWindowContext, Context, Div, Entity, - EntityId, EventEmitter, FocusHandle, IntoElement, Model, ParentElement, Pixels, Render, - SharedString, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, - WindowContext, + div, point, AnyElement, AppContext, AsyncWindowContext, Context, Div, Entity, EntityId, + EventEmitter, IntoElement, Model, ParentElement, Pixels, Render, SharedString, Styled, + Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext, }; use language::{ proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, CharKind, OffsetRangeExt, @@ -20,7 +18,7 @@ use language::{ use project::{search::SearchQuery, FormatTrigger, Item as _, Project, ProjectPath}; use rpc::proto::{self, update_view, PeerId}; use settings::Settings; -use smallvec::SmallVec; + use std::fmt::Write; use std::{ borrow::Cow, @@ -581,7 +579,7 @@ impl Item for Editor { } fn tab_content(&self, detail: Option, selected: bool, cx: &WindowContext) -> AnyElement { - let theme = cx.theme(); + let _theme = cx.theme(); let description = detail.and_then(|detail| { let path = path_for_buffer(&self.buffer, detail, false, cx)?; @@ -697,12 +695,14 @@ impl Item for Editor { })? .await?; for buffer in clean_buffers { - buffer.update(&mut cx, |buffer, cx| { - let version = buffer.saved_version().clone(); - let fingerprint = buffer.saved_version_fingerprint(); - let mtime = buffer.saved_mtime(); - buffer.did_save(version, fingerprint, mtime, cx); - }); + buffer + .update(&mut cx, |buffer, cx| { + let version = buffer.saved_version().clone(); + let fingerprint = buffer.saved_version_fingerprint(); + let mtime = buffer.saved_mtime(); + buffer.did_save(version, fingerprint, mtime, cx); + }) + .ok(); } } @@ -742,13 +742,15 @@ impl Item for Editor { this.update(&mut cx, |editor, cx| { editor.request_autoscroll(Autoscroll::fit(), cx) })?; - buffer.update(&mut cx, |buffer, cx| { - if let Some(transaction) = transaction { - if !buffer.is_singleton() { - buffer.push_transaction(&transaction.0, cx); + buffer + .update(&mut cx, |buffer, cx| { + if let Some(transaction) = transaction { + if !buffer.is_singleton() { + buffer.push_transaction(&transaction.0, cx); + } } - } - }); + }) + .ok(); Ok(()) }) } diff --git a/crates/editor2/src/link_go_to_definition.rs b/crates/editor2/src/link_go_to_definition.rs index ef171277975eda27ef352012079fb872d16178f0..42f502daeda6a308070763bb4bb9936f74aef210 100644 --- a/crates/editor2/src/link_go_to_definition.rs +++ b/crates/editor2/src/link_go_to_definition.rs @@ -618,7 +618,7 @@ mod tests { test::editor_lsp_test_context::EditorLspTestContext, }; use futures::StreamExt; - use gpui::{Modifiers, ModifiersChangedEvent, View}; + use gpui::{Modifiers, ModifiersChangedEvent}; use indoc::indoc; use language::language_settings::InlayHintSettings; use lsp::request::{GotoDefinition, GotoTypeDefinition}; diff --git a/crates/editor2/src/mouse_context_menu.rs b/crates/editor2/src/mouse_context_menu.rs index e6c0fc1111473541a285eaf6d4d41bf87c9952af..24f3b22a5c5648ae5ac2c8befc4989e0404a42a0 100644 --- a/crates/editor2/src/mouse_context_menu.rs +++ b/crates/editor2/src/mouse_context_menu.rs @@ -36,7 +36,7 @@ pub fn deploy_context_menu( s.set_pending_display_range(point..point, SelectMode::Character); }); - let context_menu = ui::ContextMenu::build(cx, |menu, cx| { + let context_menu = ui::ContextMenu::build(cx, |menu, _cx| { menu.action("Rename Symbol", Box::new(Rename)) .action("Go to Definition", Box::new(GoToDefinition)) .action("Go to Type Definition", Box::new(GoToTypeDefinition)) @@ -53,7 +53,7 @@ pub fn deploy_context_menu( let context_menu_focus = context_menu.focus_handle(cx); cx.focus(&context_menu_focus); - let _subscription = cx.subscribe(&context_menu, move |this, _, event: &DismissEvent, cx| { + let _subscription = cx.subscribe(&context_menu, move |this, _, _event: &DismissEvent, cx| { this.mouse_context_menu.take(); if context_menu_focus.contains_focused(cx) { this.focus(cx); @@ -97,7 +97,7 @@ mod tests { do_wˇork(); } "}); - cx.editor(|editor, app| assert!(editor.mouse_context_menu.is_none())); + cx.editor(|editor, _app| assert!(editor.mouse_context_menu.is_none())); cx.update_editor(|editor, cx| deploy_context_menu(editor, Default::default(), point, cx)); cx.assert_editor_state(indoc! {" @@ -105,6 +105,6 @@ mod tests { do_wˇork(); } "}); - cx.editor(|editor, app| assert!(editor.mouse_context_menu.is_some())); + cx.editor(|editor, _app| assert!(editor.mouse_context_menu.is_some())); } } diff --git a/crates/editor2/src/movement.rs b/crates/editor2/src/movement.rs index ab25bb8499aa323178d3573ad563797f1ec0a712..81905869686fd550500cad0b8212717dfec0865f 100644 --- a/crates/editor2/src/movement.rs +++ b/crates/editor2/src/movement.rs @@ -2,7 +2,7 @@ use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint}; use crate::{char_kind, CharKind, EditorStyle, ToOffset, ToPoint}; use gpui::{px, Pixels, TextSystem}; use language::Point; -use serde::de::IntoDeserializer; + use std::{ops::Range, sync::Arc}; #[derive(Debug, PartialEq)] @@ -757,7 +757,7 @@ mod tests { let mut cx = EditorTestContext::new(cx).await; let editor = cx.editor.clone(); let window = cx.window.clone(); - cx.update_window(window, |_, cx| { + _ = cx.update_window(window, |_, cx| { let text_layout_details = editor.update(cx, |editor, cx| editor.text_layout_details(cx)); diff --git a/crates/editor2/src/rust_analyzer_ext.rs b/crates/editor2/src/rust_analyzer_ext.rs index 0ebf242504098451e34a4d6b7163940055815431..a4e68ff8375b55c3ef65671444c5b4d461f2ee78 100644 --- a/crates/editor2/src/rust_analyzer_ext.rs +++ b/crates/editor2/src/rust_analyzer_ext.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use anyhow::Context as _; -use gpui::{Context, Model, View, ViewContext, VisualContext, WindowContext}; +use gpui::{Context, View, ViewContext, VisualContext, WindowContext}; use language::Language; use multi_buffer::MultiBuffer; use project::lsp_ext_command::ExpandMacro; @@ -91,7 +91,7 @@ pub fn expand_macro_recursively( cx, ) }); - cx.spawn(|editor, mut cx| async move { + cx.spawn(|_editor, mut cx| async move { let macro_expansion = expand_macro_task.await.context("expand macro")?; if macro_expansion.is_empty() { log::info!("Empty macro expansion for position {position:?}"); diff --git a/crates/editor2/src/scroll.rs b/crates/editor2/src/scroll.rs index 208dcc0dd3c9c75755176961386ffceb35892c6b..0798870f76cb37131b86295b57e5f3f01ad22705 100644 --- a/crates/editor2/src/scroll.rs +++ b/crates/editor2/src/scroll.rs @@ -9,7 +9,7 @@ use crate::{ Anchor, DisplayPoint, Editor, EditorEvent, EditorMode, InlayHintRefreshReason, MultiBufferSnapshot, ToPoint, }; -use gpui::{point, px, AppContext, Entity, Pixels, Styled, Task, ViewContext}; +use gpui::{point, px, AppContext, Entity, Pixels, Task, ViewContext}; use language::{Bias, Point}; use std::{ cmp::Ordering, diff --git a/crates/editor2/src/scroll/actions.rs b/crates/editor2/src/scroll/actions.rs index 9a1e54f5e48bc301bd29756b92e20885f2466117..21a4258f6f186700128e081b1ab5d36c3a5938c7 100644 --- a/crates/editor2/src/scroll/actions.rs +++ b/crates/editor2/src/scroll/actions.rs @@ -3,7 +3,7 @@ use crate::{ Autoscroll, Bias, Editor, EditorMode, NextScreen, ScrollAnchor, ScrollCursorBottom, ScrollCursorCenter, ScrollCursorTop, }; -use gpui::{actions, AppContext, Point, ViewContext}; +use gpui::{Point, ViewContext}; impl Editor { pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext) { diff --git a/crates/editor2/src/scroll/autoscroll.rs b/crates/editor2/src/scroll/autoscroll.rs index 9315d5c0997fd649e8c0f16cc5425cca1803a8f4..ba70739942c429e6b5eb11139a395b98db38475a 100644 --- a/crates/editor2/src/scroll/autoscroll.rs +++ b/crates/editor2/src/scroll/autoscroll.rs @@ -61,7 +61,7 @@ impl Editor { display_map.max_point().row() as f32 }; if scroll_position.y > max_scroll_top { - scroll_position.y = (max_scroll_top); + scroll_position.y = max_scroll_top; self.set_scroll_position(scroll_position, cx); } @@ -143,24 +143,24 @@ impl Editor { let needs_scroll_down = target_bottom >= end_row; if needs_scroll_up && !needs_scroll_down { - scroll_position.y = (target_top); + scroll_position.y = target_top; self.set_scroll_position_internal(scroll_position, local, true, cx); } if !needs_scroll_up && needs_scroll_down { - scroll_position.y = (target_bottom - visible_lines); + scroll_position.y = target_bottom - visible_lines; self.set_scroll_position_internal(scroll_position, local, true, cx); } } AutoscrollStrategy::Center => { - scroll_position.y = ((target_top - margin).max(0.0)); + scroll_position.y = (target_top - margin).max(0.0); self.set_scroll_position_internal(scroll_position, local, true, cx); } AutoscrollStrategy::Top => { - scroll_position.y = ((target_top).max(0.0)); + scroll_position.y = (target_top).max(0.0); self.set_scroll_position_internal(scroll_position, local, true, cx); } AutoscrollStrategy::Bottom => { - scroll_position.y = ((target_bottom - visible_lines).max(0.0)); + scroll_position.y = (target_bottom - visible_lines).max(0.0); self.set_scroll_position_internal(scroll_position, local, true, cx); } } diff --git a/crates/editor2/src/test/editor_test_context.rs b/crates/editor2/src/test/editor_test_context.rs index 0b6fb69d71b27089f6bce4a00d4492fbd8161629..bd5acb99459c131d316a5376688f3d4bcb81da93 100644 --- a/crates/editor2/src/test/editor_test_context.rs +++ b/crates/editor2/src/test/editor_test_context.rs @@ -4,8 +4,7 @@ use crate::{ use collections::BTreeMap; use futures::Future; use gpui::{ - AnyWindowHandle, AppContext, ForegroundExecutor, Keystroke, ModelContext, View, ViewContext, - VisualTestContext, WindowHandle, + AnyWindowHandle, AppContext, Keystroke, ModelContext, View, ViewContext, VisualTestContext, }; use indoc::indoc; use itertools::Itertools; diff --git a/crates/workspace2/src/persistence.rs b/crates/workspace2/src/persistence.rs index 1abb06dccfa712c97b626dafd1e8c1feb251ddb6..5358ee3f4c656e732a29c061593c6ff55eee7aed 100644 --- a/crates/workspace2/src/persistence.rs +++ b/crates/workspace2/src/persistence.rs @@ -1,4 +1,4 @@ -#![allow(dead_code)] +//#![allow(dead_code)] pub mod model; diff --git a/crates/zed2/src/open_listener.rs b/crates/zed2/src/open_listener.rs index b45254f7174c600f27ff552fef8ae7c2a2be7446..6db020a785788d1fe0d05cd2a4d10d937f2b5ac4 100644 --- a/crates/zed2/src/open_listener.rs +++ b/crates/zed2/src/open_listener.rs @@ -251,12 +251,11 @@ pub async fn handle_cli_connection( let wait = async move { if paths.is_empty() { let (done_tx, done_rx) = oneshot::channel(); - let _subscription = - workspace.update(&mut cx, |workspace, cx| { - cx.on_release(move |_, _, _| { - let _ = done_tx.send(()); - }) - }); + let _subscription = workspace.update(&mut cx, |_, cx| { + cx.on_release(move |_, _, _| { + let _ = done_tx.send(()); + }) + }); let _ = done_rx.await; } else { let _ = futures::future::try_join_all(item_release_futures) diff --git a/crates/zed2/src/zed2.rs b/crates/zed2/src/zed2.rs index aa21a3e9955defc8cb623b163851ecd8156dc5c5..4abc81cf37313824d6fd955894cbefed716c987d 100644 --- a/crates/zed2/src/zed2.rs +++ b/crates/zed2/src/zed2.rs @@ -1,6 +1,3 @@ -#![allow(unused_variables, unused_mut)] -//todo!() - mod app_menus; mod assets; pub mod languages; @@ -37,9 +34,8 @@ use util::{ use uuid::Uuid; use workspace::Pane; use workspace::{ - create_and_open_local_file, dock::PanelHandle, - notifications::simple_message_notification::MessageNotification, open_new, AppState, NewFile, - NewWindow, Workspace, WorkspaceSettings, + create_and_open_local_file, notifications::simple_message_notification::MessageNotification, + open_new, AppState, NewFile, NewWindow, Workspace, WorkspaceSettings, }; use zed_actions::{OpenBrowser, OpenSettings, OpenZedURL, Quit}; @@ -184,7 +180,6 @@ pub fn initialize_workspace(app_state: Arc, cx: &mut AppContext) { )?; workspace_handle.update(&mut cx, |workspace, cx| { - let project_panel_position = project_panel.position(cx); workspace.add_panel(project_panel, cx); workspace.add_panel(terminal_panel, cx); workspace.add_panel(assistant_panel, cx); @@ -473,7 +468,7 @@ fn quit(_: &mut Workspace, _: &Quit, cx: &mut gpui::ViewContext) { }) .log_err(); - if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) { + if let (true, Some(_)) = (should_confirm, workspace_windows.first().copied()) { let answer = cx .update(|_, cx| { cx.prompt( @@ -484,7 +479,7 @@ fn quit(_: &mut Workspace, _: &Quit, cx: &mut gpui::ViewContext) { }) .log_err(); - if let Some(mut answer) = answer { + if let Some(answer) = answer { let answer = answer.await.ok(); if answer != Some(0) { return Ok(()); From 12fe64b1774a7650440be1da3f3ceae96041f8f8 Mon Sep 17 00:00:00 2001 From: "Joseph T. Lyons" Date: Mon, 25 Dec 2023 07:02:19 -0500 Subject: [PATCH 331/644] Fix more warnings --- crates/zed2/src/main.rs | 89 +++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index f1fd168ffd832bcd2533dbb6e03c5fa13b571f85..8ddce12f998fde74d8270719f8caafb721973da5 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -250,7 +250,7 @@ fn main() { cx: &mut AppContext, ) { let task = workspace::open_paths(&paths, &app_state, None, cx); - cx.spawn(|cx| async move { + cx.spawn(|_| async move { if let Some((_window, results)) = task.await.log_err() { for result in results { if let Some(Err(e)) = result { @@ -311,53 +311,48 @@ fn main() { } let app_state = app_state.clone(); - let closure_client = client.clone(); - cx.spawn(move |mut cx| { - let client = closure_client.clone(); - async move { - while let Some(request) = open_rx.next().await { - match request { - OpenRequest::Paths { paths } => { - cx.update(|cx| open_paths_and_log_errs(&paths, &app_state, cx)) - .ok(); - } - OpenRequest::CliConnection { connection } => { - let app_state = app_state.clone(); - cx.spawn(move |cx| { - handle_cli_connection(connection, app_state.clone(), cx) - }) - .detach(); - } - OpenRequest::JoinChannel { channel_id } => { - let app_state = app_state.clone(); - cx.update(|mut cx| { - cx.spawn(|cx| async move { - cx.update(|cx| { - workspace::join_channel(channel_id, app_state, None, cx) - })? - .await?; - anyhow::Ok(()) - }) - .detach_and_log_err(&mut cx); + cx.spawn(move |cx| async move { + while let Some(request) = open_rx.next().await { + match request { + OpenRequest::Paths { paths } => { + cx.update(|cx| open_paths_and_log_errs(&paths, &app_state, cx)) + .ok(); + } + OpenRequest::CliConnection { connection } => { + let app_state = app_state.clone(); + cx.spawn(move |cx| { + handle_cli_connection(connection, app_state.clone(), cx) + }) + .detach(); + } + OpenRequest::JoinChannel { channel_id } => { + let app_state = app_state.clone(); + cx.update(|mut cx| { + cx.spawn(|cx| async move { + cx.update(|cx| { + workspace::join_channel(channel_id, app_state, None, cx) + })? + .await?; + anyhow::Ok(()) }) + .detach_and_log_err(&mut cx); + }) + .log_err(); + } + OpenRequest::OpenChannelNotes { channel_id } => { + let app_state = app_state.clone(); + let open_notes_task = cx.spawn(|mut cx| async move { + let workspace_window = + workspace::get_any_active_workspace(app_state, cx.clone()).await?; + let _ = workspace_window + .update(&mut cx, |_, cx| { + ChannelView::open(channel_id, cx.view().clone(), cx) + })? + .await?; + anyhow::Ok(()) + }); + cx.update(|cx| open_notes_task.detach_and_log_err(cx)) .log_err(); - } - OpenRequest::OpenChannelNotes { channel_id } => { - let app_state = app_state.clone(); - let open_notes_task = cx.spawn(|mut cx| async move { - let workspace_window = - workspace::get_any_active_workspace(app_state, cx.clone()) - .await?; - let _ = workspace_window - .update(&mut cx, |_, cx| { - ChannelView::open(channel_id, cx.view().clone(), cx) - })? - .await?; - anyhow::Ok(()) - }); - cx.update(|cx| open_notes_task.detach_and_log_err(cx)) - .log_err(); - } } } } @@ -773,7 +768,7 @@ async fn watch_languages(fs: Arc, languages: Arc) fn watch_file_types(fs: Arc, cx: &mut AppContext) { use std::time::Duration; - cx.spawn(|mut cx| async move { + cx.spawn(|cx| async move { let mut events = fs .watch( "assets/icons/file_icons/file_types.json".as_ref(), From ee57658abe86a55b2f267cb4c853a90d500bef17 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 25 Dec 2023 13:30:27 +0100 Subject: [PATCH 332/644] Fix up superfluous mod declaration --- crates/zed2/src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index 8ddce12f998fde74d8270719f8caafb721973da5..2fbb9c101d8202501bd96a602a28195c3199b3d6 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -53,8 +53,6 @@ use zed2::{ OpenListener, OpenRequest, }; -mod open_listener; - fn main() { menu::init(); zed_actions::init(); From 16626592dba30f9572e8957221ef5eff33673f86 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 26 Dec 2023 01:23:08 +0100 Subject: [PATCH 333/644] Remove allow unused from gpui2, vim2 tests and terminal_view2 (#3813) Release Notes: - N/A --- crates/gpui2/src/color.rs | 2 -- crates/terminal_view2/src/terminal_element.rs | 14 +++----------- crates/terminal_view2/src/terminal_view.rs | 15 ++++----------- .../test/neovim_backed_binding_test_context.rs | 3 --- .../vim2/src/test/neovim_backed_test_context.rs | 5 +---- crates/vim2/src/test/vim_test_context.rs | 3 --- 6 files changed, 8 insertions(+), 34 deletions(-) diff --git a/crates/gpui2/src/color.rs b/crates/gpui2/src/color.rs index 44a0e917be279999c327d112eddad59cc55d8dcc..d5514d900ffa69046ff6cb6e5ba5b287cecbb38c 100644 --- a/crates/gpui2/src/color.rs +++ b/crates/gpui2/src/color.rs @@ -1,5 +1,3 @@ -#![allow(dead_code)] - use anyhow::bail; use serde::de::{self, Deserialize, Deserializer, Visitor}; use std::fmt; diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index eb7348b9357cfe2c2c44c3405ceb2665318a7a7a..fc87ac45bd9b21591195f51c2a659f48bbcf68a9 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -248,14 +248,8 @@ impl TerminalElement { { let cell_text = cell.c.to_string(); if !is_blank(&cell) { - let cell_style = TerminalElement::cell_style( - &cell, - fg, - theme, - text_style, - text_system, - hyperlink, - ); + let cell_style = + TerminalElement::cell_style(&cell, fg, theme, text_style, hyperlink); let layout_cell = text_system .shape_line( @@ -315,7 +309,6 @@ impl TerminalElement { // bg: terminal::alacritty_terminal::ansi::Color, colors: &Theme, text_style: &TextStyle, - text_system: &TextSystem, hyperlink: Option<(HighlightStyle, &RangeInclusive)>, ) -> TextRun { let flags = indexed.cell.flags; @@ -392,7 +385,6 @@ impl TerminalElement { let font_size = font_size.map_or(buffer_font_size, |size| theme::adjusted_font_size(size, cx)); - let settings = ThemeSettings::get_global(cx); let theme = cx.theme().clone(); let link_style = HighlightStyle { @@ -898,7 +890,7 @@ impl PlatformInputHandler for TerminalInputHandler { None } - fn text_for_range(&mut self, range_utf16: std::ops::Range) -> Option { + fn text_for_range(&mut self, _: std::ops::Range) -> Option { None } diff --git a/crates/terminal_view2/src/terminal_view.rs b/crates/terminal_view2/src/terminal_view.rs index f82a43959bc1a4dbd04c0e6b2962b6ebb46071ff..6d18d6f8f95f3b1bb201217d5379a609e593ee00 100644 --- a/crates/terminal_view2/src/terminal_view.rs +++ b/crates/terminal_view2/src/terminal_view.rs @@ -1,6 +1,3 @@ -#![allow(unused_variables)] -//todo!(remove) - mod persistence; pub mod terminal_element; pub mod terminal_panel; @@ -68,11 +65,9 @@ pub fn init(cx: &mut AppContext) { register_deserializable_item::(cx); - cx.observe_new_views( - |workspace: &mut Workspace, cx: &mut ViewContext| { - workspace.register_action(TerminalView::deploy); - }, - ) + cx.observe_new_views(|workspace: &mut Workspace, _| { + workspace.register_action(TerminalView::deploy); + }) .detach(); } @@ -141,7 +136,6 @@ impl TerminalView { workspace_id: WorkspaceId, cx: &mut ViewContext, ) -> Self { - let view_id = cx.entity_id(); cx.observe(&terminal, |_, _, cx| cx.notify()).detach(); cx.subscribe(&terminal, move |this, _, event, cx| match event { Event::Wakeup => { @@ -308,7 +302,7 @@ impl TerminalView { position: gpui::Point, cx: &mut ViewContext, ) { - let context_menu = ContextMenu::build(cx, |menu, cx| { + let context_menu = ContextMenu::build(cx, |menu, _| { menu.action("Clear", Box::new(Clear)) .action("Close", Box::new(CloseActiveItem { save_intent: None })) }); @@ -628,7 +622,6 @@ impl Render for TerminalView { fn render(&mut self, cx: &mut ViewContext) -> Self::Element { let terminal_handle = self.terminal.clone(); - let self_id = cx.entity_id(); let focused = self.focus_handle.is_focused(cx); div() diff --git a/crates/vim2/src/test/neovim_backed_binding_test_context.rs b/crates/vim2/src/test/neovim_backed_binding_test_context.rs index 3b97cb2b16e34fad79a137ccd3c4b7cc6066141e..15fce99aad3f4ea0e03129342a4bca48fba4166f 100644 --- a/crates/vim2/src/test/neovim_backed_binding_test_context.rs +++ b/crates/vim2/src/test/neovim_backed_binding_test_context.rs @@ -1,6 +1,3 @@ -#![allow(unused)] -// todo!() - use std::ops::{Deref, DerefMut}; use crate::state::Mode; diff --git a/crates/vim2/src/test/neovim_backed_test_context.rs b/crates/vim2/src/test/neovim_backed_test_context.rs index 21455de55293faea2e39812a9df35f506f04dde6..7380537655b1e2765003aeaec37d7918c2607bfb 100644 --- a/crates/vim2/src/test/neovim_backed_test_context.rs +++ b/crates/vim2/src/test/neovim_backed_test_context.rs @@ -1,8 +1,5 @@ -#![allow(unused)] -// todo!() - use editor::{scroll::VERTICAL_SCROLL_MARGIN, test::editor_test_context::ContextHandle}; -use gpui::{point, px, rems, size, Context}; +use gpui::{px, size, Context}; use indoc::indoc; use settings::SettingsStore; use std::{ diff --git a/crates/vim2/src/test/vim_test_context.rs b/crates/vim2/src/test/vim_test_context.rs index 395696448037c8baf8c807ac06cab07c94f1597c..47afc20785aa81d7b1db6c8fd3dce40f35d6c970 100644 --- a/crates/vim2/src/test/vim_test_context.rs +++ b/crates/vim2/src/test/vim_test_context.rs @@ -1,6 +1,3 @@ -#![allow(unused)] -// todo!() - use std::ops::{Deref, DerefMut}; use editor::test::{ From af6f4678900f3eb6f5732ada8ae5e03db2a44a0b Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 26 Dec 2023 13:49:00 +0200 Subject: [PATCH 334/644] Avoid trailing separators in file finder --- crates/file_finder2/src/file_finder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/file_finder2/src/file_finder.rs b/crates/file_finder2/src/file_finder.rs index 8ca7d46f2965b7452b86415d5817a8c67d6bc0c1..69deba6d2c0da701db779d7f5cc76e9fe5792448 100644 --- a/crates/file_finder2/src/file_finder.rs +++ b/crates/file_finder2/src/file_finder.rs @@ -546,7 +546,7 @@ impl PickerDelegate for FileFinderDelegate { fn separators_after_indices(&self) -> Vec { let history_items = self.matches.history.len(); - if history_items == 0 { + if history_items == 0 || self.matches.search.is_empty() { Vec::new() } else { vec![history_items - 1] From f27c63bb5424f2633e4c5ff71b1a08bb34d68cc4 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 26 Dec 2023 14:09:29 +0200 Subject: [PATCH 335/644] Fix color-related terminal todo! --- crates/project2/src/terminals.rs | 1 - crates/project2/src/worktree.rs | 1 - crates/terminal2/src/terminal2.rs | 113 ++++++++++++++++-- crates/terminal_view2/src/terminal_element.rs | 111 ++--------------- 4 files changed, 110 insertions(+), 116 deletions(-) diff --git a/crates/project2/src/terminals.rs b/crates/project2/src/terminals.rs index 1bf69aa8b5abae490e8c1b4ca9f08a0da01fc3bb..a816c0ddb2a464a9fcc6c0cc206257acc5b6822a 100644 --- a/crates/project2/src/terminals.rs +++ b/crates/project2/src/terminals.rs @@ -37,7 +37,6 @@ impl Project { Some(settings.blinking.clone()), settings.alternate_scroll, window, - |_, _| todo!("color_for_index"), ) .map(|builder| { let terminal_handle = cx.build_model(|cx| builder.subscribe(cx)); diff --git a/crates/project2/src/worktree.rs b/crates/project2/src/worktree.rs index a5cb322cb5f52beb71c1b4200f58f098c2f6d88a..22b3cd8c653054f9ec0b5b09e0945441e4ecf607 100644 --- a/crates/project2/src/worktree.rs +++ b/crates/project2/src/worktree.rs @@ -2184,7 +2184,6 @@ impl LocalSnapshot { ignore_stack } - #[allow(dead_code)] // todo!("remove this when we use it") #[cfg(test)] pub(crate) fn expanded_entries(&self) -> impl Iterator { self.entries_by_path diff --git a/crates/terminal2/src/terminal2.rs b/crates/terminal2/src/terminal2.rs index 9d3c00d81f95a019671a74c54fb6704a03a25e9d..b15bd7c6d659cc7794b770934e95775c0ae41507 100644 --- a/crates/terminal2/src/terminal2.rs +++ b/crates/terminal2/src/terminal2.rs @@ -35,6 +35,7 @@ use procinfo::LocalProcessInfo; use serde::{Deserialize, Serialize}; use settings::Settings; use terminal_settings::{AlternateScroll, Shell, TerminalBlink, TerminalSettings}; +use theme::{ActiveTheme, Theme}; use util::truncate_and_trailoff; use std::{ @@ -50,9 +51,9 @@ use std::{ use thiserror::Error; use gpui::{ - actions, px, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter, Hsla, Keystroke, - ModelContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, - Point, ScrollWheelEvent, Size, Task, TouchPhase, + actions, black, px, red, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter, + Hsla, Keystroke, ModelContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, + MouseUpEvent, Pixels, Point, Rgba, ScrollWheelEvent, Size, Task, TouchPhase, }; use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str}; @@ -299,7 +300,6 @@ impl TerminalBuilder { blink_settings: Option, alternate_scroll: AlternateScroll, window: AnyWindowHandle, - color_for_index: impl Fn(usize, &mut AppContext) -> Hsla + Send + Sync + 'static, ) -> Result { let pty_config = { let alac_shell = match shell.clone() { @@ -405,7 +405,6 @@ impl TerminalBuilder { selection_phase: SelectionPhase::Ended, cmd_pressed: false, hovered_word: false, - color_for_index: Box::new(color_for_index), }; Ok(TerminalBuilder { @@ -562,8 +561,6 @@ pub struct Terminal { selection_phase: SelectionPhase, cmd_pressed: bool, hovered_word: bool, - // An implementation of the 8 bit ANSI color palette - color_for_index: Box Hsla + Send + Sync + 'static>, } impl Terminal { @@ -646,8 +643,9 @@ impl Terminal { ) { match event { InternalEvent::ColorRequest(index, format) => { - let color = term.colors()[*index] - .unwrap_or_else(|| to_alac_rgb((self.color_for_index)(*index, cx))); + let color = term.colors()[*index].unwrap_or_else(|| { + to_alac_rgb(get_color_at_index(*index, cx.theme().as_ref())) + }); self.write_to_pty(format(color)) } InternalEvent::Resize(mut new_size) => { @@ -1418,6 +1416,90 @@ fn content_index_for_mouse(pos: Point, size: &TerminalSize) -> usize { clamped_row * size.columns() + clamped_col } +///Converts an 8 bit ANSI color to it's GPUI equivalent. +///Accepts usize for compatibility with the alacritty::Colors interface, +///Other than that use case, should only be called with values in the [0,255] range +pub fn get_color_at_index(index: usize, theme: &Theme) -> Hsla { + let colors = theme.colors(); + + match index { + //0-15 are the same as the named colors above + 0 => colors.terminal_ansi_black, + 1 => colors.terminal_ansi_red, + 2 => colors.terminal_ansi_green, + 3 => colors.terminal_ansi_yellow, + 4 => colors.terminal_ansi_blue, + 5 => colors.terminal_ansi_magenta, + 6 => colors.terminal_ansi_cyan, + 7 => colors.terminal_ansi_white, + 8 => colors.terminal_ansi_bright_black, + 9 => colors.terminal_ansi_bright_red, + 10 => colors.terminal_ansi_bright_green, + 11 => colors.terminal_ansi_bright_yellow, + 12 => colors.terminal_ansi_bright_blue, + 13 => colors.terminal_ansi_bright_magenta, + 14 => colors.terminal_ansi_bright_cyan, + 15 => colors.terminal_ansi_bright_white, + //16-231 are mapped to their RGB colors on a 0-5 range per channel + 16..=231 => { + let (r, g, b) = rgb_for_index(&(index as u8)); //Split the index into it's ANSI-RGB components + let step = (u8::MAX as f32 / 5.).floor() as u8; //Split the RGB range into 5 chunks, with floor so no overflow + rgba_color(r * step, g * step, b * step) //Map the ANSI-RGB components to an RGB color + } + //232-255 are a 24 step grayscale from black to white + 232..=255 => { + let i = index as u8 - 232; //Align index to 0..24 + let step = (u8::MAX as f32 / 24.).floor() as u8; //Split the RGB grayscale values into 24 chunks + rgba_color(i * step, i * step, i * step) //Map the ANSI-grayscale components to the RGB-grayscale + } + //For compatibility with the alacritty::Colors interface + 256 => colors.text, + 257 => colors.background, + 258 => theme.players().local().cursor, + + // todo!(more colors) + 259 => red(), //style.dim_black, + 260 => red(), //style.dim_red, + 261 => red(), //style.dim_green, + 262 => red(), //style.dim_yellow, + 263 => red(), //style.dim_blue, + 264 => red(), //style.dim_magenta, + 265 => red(), //style.dim_cyan, + 266 => red(), //style.dim_white, + 267 => red(), //style.bright_foreground, + 268 => colors.terminal_ansi_black, //'Dim Background', non-standard color + + _ => black(), + } +} + +///Generates the rgb channels in [0, 5] for a given index into the 6x6x6 ANSI color cube +///See: [8 bit ansi color](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit). +/// +///Wikipedia gives a formula for calculating the index for a given color: +/// +///index = 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5) +/// +///This function does the reverse, calculating the r, g, and b components from a given index. +fn rgb_for_index(i: &u8) -> (u8, u8, u8) { + debug_assert!((&16..=&231).contains(&i)); + let i = i - 16; + let r = (i - (i % 36)) / 36; + let g = ((i % 36) - (i % 6)) / 6; + let b = (i % 36) % 6; + (r, g, b) +} + +pub fn rgba_color(r: u8, g: u8, b: u8) -> Hsla { + Rgba { + r: (r as f32 / 255.) as f32, + g: (g as f32 / 255.) as f32, + b: (b as f32 / 255.) as f32, + a: 1., + } + .into() +} + #[cfg(test)] mod tests { use alacritty_terminal::{ @@ -1427,7 +1509,18 @@ mod tests { use gpui::{point, size, Pixels}; use rand::{distributions::Alphanumeric, rngs::ThreadRng, thread_rng, Rng}; - use crate::{content_index_for_mouse, IndexedCell, TerminalContent, TerminalSize}; + use crate::{ + content_index_for_mouse, rgb_for_index, IndexedCell, TerminalContent, TerminalSize, + }; + + #[test] + fn test_rgb_for_index() { + //Test every possible value in the color cube + for i in 16..=231 { + let (r, g, b) = rgb_for_index(&(i as u8)); + assert_eq!(i, 16 + 36 * r + 6 * g + b); + } + } #[test] fn test_mouse_to_cell_test() { diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index fc87ac45bd9b21591195f51c2a659f48bbcf68a9..dcadc04e211c89aff672ee29b83f22a79898b5a6 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -1,12 +1,11 @@ use editor::{Cursor, HighlightedRange, HighlightedRangeLine}; use gpui::{ - black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace, + div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace, BorrowWindow, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, Interactivity, IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, - Pixels, PlatformInputHandler, Point, Rgba, ShapedLine, StatefulInteractiveElement, - StyleRefinement, Styled, TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, - WindowContext, + Pixels, PlatformInputHandler, Point, ShapedLine, StatefulInteractiveElement, StyleRefinement, + Styled, TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext, }; use itertools::Itertools; use language::CursorShape; @@ -1048,108 +1047,12 @@ fn convert_color(fg: &terminal::alacritty_terminal::ansi::Color, theme: &Theme) NamedColor::DimForeground => red(), }, //'True' colors - terminal::alacritty_terminal::ansi::Color::Spec(rgb) => rgba_color(rgb.r, rgb.g, rgb.b), + terminal::alacritty_terminal::ansi::Color::Spec(rgb) => { + terminal::rgba_color(rgb.r, rgb.g, rgb.b) + } //8 bit, indexed colors terminal::alacritty_terminal::ansi::Color::Indexed(i) => { - get_color_at_index(&(*i as usize), theme) - } - } -} - -///Converts an 8 bit ANSI color to it's GPUI equivalent. -///Accepts usize for compatibility with the alacritty::Colors interface, -///Other than that use case, should only be called with values in the [0,255] range -pub fn get_color_at_index(index: &usize, theme: &Theme) -> Hsla { - let colors = theme.colors(); - - match index { - //0-15 are the same as the named colors above - 0 => colors.terminal_ansi_black, - 1 => colors.terminal_ansi_red, - 2 => colors.terminal_ansi_green, - 3 => colors.terminal_ansi_yellow, - 4 => colors.terminal_ansi_blue, - 5 => colors.terminal_ansi_magenta, - 6 => colors.terminal_ansi_cyan, - 7 => colors.terminal_ansi_white, - 8 => colors.terminal_ansi_bright_black, - 9 => colors.terminal_ansi_bright_red, - 10 => colors.terminal_ansi_bright_green, - 11 => colors.terminal_ansi_bright_yellow, - 12 => colors.terminal_ansi_bright_blue, - 13 => colors.terminal_ansi_bright_magenta, - 14 => colors.terminal_ansi_bright_cyan, - 15 => colors.terminal_ansi_bright_white, - //16-231 are mapped to their RGB colors on a 0-5 range per channel - 16..=231 => { - let (r, g, b) = rgb_for_index(&(*index as u8)); //Split the index into it's ANSI-RGB components - let step = (u8::MAX as f32 / 5.).floor() as u8; //Split the RGB range into 5 chunks, with floor so no overflow - rgba_color(r * step, g * step, b * step) //Map the ANSI-RGB components to an RGB color - } - //232-255 are a 24 step grayscale from black to white - 232..=255 => { - let i = *index as u8 - 232; //Align index to 0..24 - let step = (u8::MAX as f32 / 24.).floor() as u8; //Split the RGB grayscale values into 24 chunks - rgba_color(i * step, i * step, i * step) //Map the ANSI-grayscale components to the RGB-grayscale - } - //For compatibility with the alacritty::Colors interface - 256 => colors.text, - 257 => colors.background, - 258 => theme.players().local().cursor, - - // todo!(more colors) - 259 => red(), //style.dim_black, - 260 => red(), //style.dim_red, - 261 => red(), //style.dim_green, - 262 => red(), //style.dim_yellow, - 263 => red(), //style.dim_blue, - 264 => red(), //style.dim_magenta, - 265 => red(), //style.dim_cyan, - 266 => red(), //style.dim_white, - 267 => red(), //style.bright_foreground, - 268 => colors.terminal_ansi_black, //'Dim Background', non-standard color - - _ => black(), - } -} - -///Generates the rgb channels in [0, 5] for a given index into the 6x6x6 ANSI color cube -///See: [8 bit ansi color](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit). -/// -///Wikipedia gives a formula for calculating the index for a given color: -/// -///index = 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5) -/// -///This function does the reverse, calculating the r, g, and b components from a given index. -fn rgb_for_index(i: &u8) -> (u8, u8, u8) { - debug_assert!((&16..=&231).contains(&i)); - let i = i - 16; - let r = (i - (i % 36)) / 36; - let g = ((i % 36) - (i % 6)) / 6; - let b = (i % 36) % 6; - (r, g, b) -} - -fn rgba_color(r: u8, g: u8, b: u8) -> Hsla { - Rgba { - r: (r as f32 / 255.) as f32, - g: (g as f32 / 255.) as f32, - b: (b as f32 / 255.) as f32, - a: 1., - } - .into() -} - -#[cfg(test)] -mod tests { - use crate::terminal_element::rgb_for_index; - - #[test] - fn test_rgb_for_index() { - //Test every possible value in the color cube - for i in 16..=231 { - let (r, g, b) = rgb_for_index(&(i as u8)); - assert_eq!(i, 16 + 36 * r + 6 * g + b); + terminal::get_color_at_index(*i as usize, theme) } } } From 937f237c8ffd31ac9cc53b6b4f998aa1ab9e97d1 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 26 Dec 2023 14:58:29 +0200 Subject: [PATCH 336/644] Add breadcrumbs to the multibuffer editor The breadcrumbs are not being open on the fisrt time, for some reason. --- crates/breadcrumbs2/src/breadcrumbs.rs | 58 ++++++++------------------ 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/crates/breadcrumbs2/src/breadcrumbs.rs b/crates/breadcrumbs2/src/breadcrumbs.rs index e579c8ded05d6532a2dcb1006da69f821044b667..da7182ec2c7394512e0ffafef2fcdf0c5cb7936f 100644 --- a/crates/breadcrumbs2/src/breadcrumbs.rs +++ b/crates/breadcrumbs2/src/breadcrumbs.rs @@ -11,10 +11,6 @@ use workspace::{ ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, }; -pub enum Event { - UpdateLocation, -} - pub struct Breadcrumbs { pane_focused: bool, active_item: Option>, @@ -31,7 +27,6 @@ impl Breadcrumbs { } } -impl EventEmitter for Breadcrumbs {} impl EventEmitter for Breadcrumbs {} impl Render for Breadcrumbs { @@ -39,15 +34,9 @@ impl Render for Breadcrumbs { fn render(&mut self, cx: &mut ViewContext) -> Self::Element { let element = h_stack().text_ui(); - - let Some(active_item) = &self - .active_item - .as_ref() - .filter(|item| item.downcast::().is_some()) - else { + let Some(active_item) = self.active_item.as_ref() else { return element; }; - let Some(segments) = active_item.breadcrumbs(cx.theme(), cx) else { return element; }; @@ -64,21 +53,24 @@ impl Render for Breadcrumbs { Label::new("›").color(Color::Muted).into_any_element() }); - let editor = active_item + let breadcrumbs_stack = h_stack().gap_1().children(breadcrumbs); + match active_item .downcast::() - .map(|editor| editor.downgrade()); - - element.child( - ButtonLike::new("toggle outline view") - .style(ButtonStyle::Subtle) - .child(h_stack().gap_1().children(breadcrumbs)) - .on_click(move |_, cx| { - if let Some(editor) = editor.as_ref().and_then(|editor| editor.upgrade()) { - outline::toggle(editor, &outline::Toggle, cx) - } - }) - .tooltip(|cx| Tooltip::for_action("Show symbol outline", &outline::Toggle, cx)), - ) + .map(|editor| editor.downgrade()) + { + Some(editor) => element.child( + ButtonLike::new("toggle outline view") + .child(breadcrumbs_stack) + .style(ButtonStyle::Subtle) + .on_click(move |_, cx| { + if let Some(editor) = editor.upgrade() { + outline::toggle(editor, &outline::Toggle, cx) + } + }) + .tooltip(|cx| Tooltip::for_action("Show symbol outline", &outline::Toggle, cx)), + ), + None => element.child(breadcrumbs_stack), + } } } @@ -97,7 +89,6 @@ impl ToolbarItemView for Breadcrumbs { Box::new(move |event, cx| { if let ItemEvent::UpdateBreadcrumbs = event { this.update(cx, |_, cx| { - cx.emit(Event::UpdateLocation); cx.notify(); }) .ok(); @@ -111,19 +102,6 @@ impl ToolbarItemView for Breadcrumbs { } } - // fn location_for_event( - // &self, - // _: &Event, - // current_location: ToolbarItemLocation, - // cx: &AppContext, - // ) -> ToolbarItemLocation { - // if let Some(active_item) = self.active_item.as_ref() { - // active_item.breadcrumb_location(cx) - // } else { - // current_location - // } - // } - fn pane_focus_update(&mut self, pane_focused: bool, _: &mut ViewContext) { self.pane_focused = pane_focused; } From 5cfd4b06b956616b559b1b1a125385948ab40bb2 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 27 Dec 2023 10:46:25 -0700 Subject: [PATCH 337/644] Use correct terminal background color --- crates/terminal_view2/src/terminal_element.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index dcadc04e211c89aff672ee29b83f22a79898b5a6..55da76383a0ed24afafc9d22aed9e567587b6e06 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -438,7 +438,7 @@ impl TerminalElement { let search_matches = self.terminal.read(cx).matches.clone(); - let background_color = theme.colors().background; + let background_color = theme.colors().terminal_background; let last_hovered_word = self.terminal.update(cx, |terminal, cx| { terminal.set_size(dimensions); From ddd6f0806b4fdb14d1c74737bfc5bc0afc55eae2 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 27 Dec 2023 11:08:43 -0700 Subject: [PATCH 338/644] Render cursor text with the terminal's background color --- crates/terminal_view2/src/terminal_element.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index 55da76383a0ed24afafc9d22aed9e567587b6e06..e5dd8472fe8b11fd32b8536db389baecb4911eae 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -287,8 +287,8 @@ impl TerminalElement { text_fragment.width }; - //Cursor should always surround as much of the text as possible, - //hence when on pixel boundaries round the origin down and the width up + // Cursor should always surround as much of the text as possible, + // hence when on pixel boundaries round the origin down and the width up Some(( point( (cursor_point.col() as f32 * size.cell_width()).floor(), @@ -301,7 +301,7 @@ impl TerminalElement { } } - ///Convert the Alacritty cell styles to GPUI text styles and background color + /// Convert the Alacritty cell styles to GPUI text styles and background color fn cell_style( indexed: &IndexedCell, fg: terminal::alacritty_terminal::ansi::Color, @@ -498,13 +498,6 @@ impl TerminalElement { let cursor_point = DisplayCursor::from(cursor.point, *display_offset); let cursor_text = { let str_trxt = cursor_char.to_string(); - - let color = if self.focused { - theme.players().local().background - } else { - theme.players().local().cursor - }; - let len = str_trxt.len(); cx.text_system() .shape_line( @@ -513,7 +506,7 @@ impl TerminalElement { &[TextRun { len, font: text_style.font(), - color, + color: theme.colors().terminal_background, background_color: None, underline: Default::default(), }], From a2b0f14dc166f279cba3cdad63f1fbbd50292a8f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 27 Dec 2023 11:23:12 -0700 Subject: [PATCH 339/644] Rename size to dimensions for consistency --- crates/terminal_view2/src/terminal_element.rs | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index e5dd8472fe8b11fd32b8536db389baecb4911eae..cb46f742f66135c2148fd6073ef010889bc1d8cd 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -34,7 +34,7 @@ pub struct LayoutState { relative_highlighted_ranges: Vec<(RangeInclusive, Hsla)>, cursor: Option, background_color: Hsla, - size: TerminalSize, + dimensions: TerminalSize, mode: TermMode, display_offset: usize, hyperlink_tooltip: Option, @@ -86,12 +86,12 @@ impl LayoutCell { let point = self.point; Point::new( - (origin.x + point.column as f32 * layout.size.cell_width).floor(), - origin.y + point.line as f32 * layout.size.line_height, + (origin.x + point.column as f32 * layout.dimensions.cell_width).floor(), + origin.y + point.line as f32 * layout.dimensions.line_height, ) }; - self.text.paint(pos, layout.size.line_height, cx).ok(); + self.text.paint(pos, layout.dimensions.line_height, cx).ok(); } } @@ -123,13 +123,13 @@ impl LayoutRect { let position = { let alac_point = self.point; point( - (origin.x + alac_point.column as f32 * layout.size.cell_width).floor(), - origin.y + alac_point.line as f32 * layout.size.line_height, + (origin.x + alac_point.column as f32 * layout.dimensions.cell_width).floor(), + origin.y + alac_point.line as f32 * layout.dimensions.line_height, ) }; let size = point( - (layout.size.cell_width * self.num_of_cells as f32).ceil(), - layout.size.line_height, + (layout.dimensions.cell_width * self.num_of_cells as f32).ceil(), + layout.dimensions.line_height, ) .into(); @@ -545,7 +545,7 @@ impl TerminalElement { cells, cursor, background_color, - size: dimensions, + dimensions, rects, relative_highlighted_ranges, mode: *mode, @@ -808,11 +808,11 @@ impl Element for TerminalElement { { let hr = HighlightedRange { start_y, //Need to change this - line_height: layout.size.line_height, + line_height: layout.dimensions.line_height, lines: highlighted_range_lines, color: color.clone(), //Copied from editor. TODO: move to theme or something - corner_radius: 0.15 * layout.size.line_height, + corner_radius: 0.15 * layout.dimensions.line_height, }; hr.paint(bounds, cx); } @@ -969,21 +969,24 @@ fn to_highlighted_range_lines( AlacPoint::new(range.end().line + layout.display_offset, range.end().column); // Step 2. Clamp range to viewport, and return None if it doesn't overlap - if unclamped_end.line.0 < 0 || unclamped_start.line.0 > layout.size.num_lines() as i32 { + if unclamped_end.line.0 < 0 || unclamped_start.line.0 > layout.dimensions.num_lines() as i32 { return None; } let clamped_start_line = unclamped_start.line.0.max(0) as usize; - let clamped_end_line = unclamped_end.line.0.min(layout.size.num_lines() as i32) as usize; + let clamped_end_line = unclamped_end + .line + .0 + .min(layout.dimensions.num_lines() as i32) as usize; //Convert the start of the range to pixels - let start_y = origin.y + clamped_start_line as f32 * layout.size.line_height; + let start_y = origin.y + clamped_start_line as f32 * layout.dimensions.line_height; // Step 3. Expand ranges that cross lines into a collection of single-line ranges. // (also convert to pixels) let mut highlighted_range_lines = Vec::new(); for line in clamped_start_line..=clamped_end_line { let mut line_start = 0; - let mut line_end = layout.size.columns(); + let mut line_end = layout.dimensions.columns(); if line == clamped_start_line { line_start = unclamped_start.column.0 as usize; @@ -993,8 +996,8 @@ fn to_highlighted_range_lines( } highlighted_range_lines.push(HighlightedRangeLine { - start_x: origin.x + line_start as f32 * layout.size.cell_width, - end_x: origin.x + line_end as f32 * layout.size.cell_width, + start_x: origin.x + line_start as f32 * layout.dimensions.cell_width, + end_x: origin.x + line_end as f32 * layout.dimensions.cell_width, }); } From 02f7e681a77628f18939f1418ea89c22801caf88 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 27 Dec 2023 11:58:26 -0700 Subject: [PATCH 340/644] Import elevated surface color from hover popover --- crates/theme2/src/themes/andromeda.rs | 2 +- crates/theme2/src/themes/atelier.rs | 40 ++++++++++----------- crates/theme2/src/themes/ayu.rs | 6 ++-- crates/theme2/src/themes/gruvbox.rs | 12 +++---- crates/theme2/src/themes/one.rs | 4 +-- crates/theme2/src/themes/rose_pine.rs | 6 ++-- crates/theme2/src/themes/sandcastle.rs | 2 +- crates/theme2/src/themes/solarized.rs | 4 +-- crates/theme2/src/themes/summercamp.rs | 2 +- crates/theme_importer/src/zed1/converter.rs | 6 +++- 10 files changed, 44 insertions(+), 40 deletions(-) diff --git a/crates/theme2/src/themes/andromeda.rs b/crates/theme2/src/themes/andromeda.rs index 0a9b977d21eacd782f7461b11c5bca654d775093..2e5b2578a0c758442c57f455c4c92b5aa7ef4840 100644 --- a/crates/theme2/src/themes/andromeda.rs +++ b/crates/theme2/src/themes/andromeda.rs @@ -21,7 +21,7 @@ pub fn andromeda() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x252931ff).into()), border_variant: Some(rgba(0x21232aff).into()), - elevated_surface_background: Some(rgba(0x262a33ff).into()), + elevated_surface_background: Some(rgba(0x21242bff).into()), background: Some(rgba(0x262a33ff).into()), panel_background: Some(rgba(0x21242bff).into()), element_hover: Some(rgba(0x2b2f3980).into()), diff --git a/crates/theme2/src/themes/atelier.rs b/crates/theme2/src/themes/atelier.rs index e5c2e49d5bda7e7781eb0abc9901e6e40a968a2f..1d069dd2be839ce867ad2bc133f531c48e30e010 100644 --- a/crates/theme2/src/themes/atelier.rs +++ b/crates/theme2/src/themes/atelier.rs @@ -22,7 +22,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xd1d0c6ff).into()), border_variant: Some(rgba(0xedece5ff).into()), - elevated_surface_background: Some(rgba(0xc5c4b9ff).into()), + elevated_surface_background: Some(rgba(0xebeae3ff).into()), background: Some(rgba(0xc5c4b9ff).into()), panel_background: Some(rgba(0xebeae3ff).into()), element_hover: Some(rgba(0x96958580).into()), @@ -425,7 +425,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x3b3431ff).into()), border_variant: Some(rgba(0x251f1dff).into()), - elevated_surface_background: Some(rgba(0x443c39ff).into()), + elevated_surface_background: Some(rgba(0x27211eff).into()), background: Some(rgba(0x443c39ff).into()), panel_background: Some(rgba(0x27211eff).into()), element_hover: Some(rgba(0x665f5c80).into()), @@ -828,7 +828,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xc8d1cbff).into()), border_variant: Some(rgba(0xe5ede7ff).into()), - elevated_surface_background: Some(rgba(0xbcc5bfff).into()), + elevated_surface_background: Some(rgba(0xe3ebe6ff).into()), background: Some(rgba(0xbcc5bfff).into()), panel_background: Some(rgba(0xe3ebe6ff).into()), element_hover: Some(rgba(0x8b968e80).into()), @@ -1231,7 +1231,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x332f38ff).into()), border_variant: Some(rgba(0x201e24ff).into()), - elevated_surface_background: Some(rgba(0x3a353fff).into()), + elevated_surface_background: Some(rgba(0x221f26ff).into()), background: Some(rgba(0x3a353fff).into()), panel_background: Some(rgba(0x221f26ff).into()), element_hover: Some(rgba(0x56505e80).into()), @@ -1634,7 +1634,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x3c3b31ff).into()), border_variant: Some(rgba(0x2a2922ff).into()), - elevated_surface_background: Some(rgba(0x424136ff).into()), + elevated_surface_background: Some(rgba(0x2c2b23ff).into()), background: Some(rgba(0x424136ff).into()), panel_background: Some(rgba(0x2c2b23ff).into()), element_hover: Some(rgba(0x5d5c4c80).into()), @@ -2037,7 +2037,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x363f62ff).into()), border_variant: Some(rgba(0x252d4fff).into()), - elevated_surface_background: Some(rgba(0x3e4769ff).into()), + elevated_surface_background: Some(rgba(0x262f51ff).into()), background: Some(rgba(0x3e4769ff).into()), panel_background: Some(rgba(0x262f51ff).into()), element_hover: Some(rgba(0x5c648580).into()), @@ -2440,7 +2440,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xccd0e1ff).into()), border_variant: Some(rgba(0xe9ebf7ff).into()), - elevated_surface_background: Some(rgba(0xc2c6d9ff).into()), + elevated_surface_background: Some(rgba(0xe5e8f5ff).into()), background: Some(rgba(0xc2c6d9ff).into()), panel_background: Some(rgba(0xe5e8f5ff).into()), element_hover: Some(rgba(0x9a9fb680).into()), @@ -2843,7 +2843,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x3b3933ff).into()), border_variant: Some(rgba(0x252521ff).into()), - elevated_surface_background: Some(rgba(0x45433bff).into()), + elevated_surface_background: Some(rgba(0x262622ff).into()), background: Some(rgba(0x45433bff).into()), panel_background: Some(rgba(0x262622ff).into()), element_hover: Some(rgba(0x6c695c80).into()), @@ -3246,7 +3246,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x333b33ff).into()), border_variant: Some(rgba(0x1d201dff).into()), - elevated_surface_background: Some(rgba(0x3b453bff).into()), + elevated_surface_background: Some(rgba(0x1f231fff).into()), background: Some(rgba(0x3b453bff).into()), panel_background: Some(rgba(0x1f231fff).into()), element_hover: Some(rgba(0x5c6c5c80).into()), @@ -3649,7 +3649,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xcbc8d1ff).into()), border_variant: Some(rgba(0xe8e5edff).into()), - elevated_surface_background: Some(rgba(0xbfbcc5ff).into()), + elevated_surface_background: Some(rgba(0xe6e3ebff).into()), background: Some(rgba(0xbfbcc5ff).into()), panel_background: Some(rgba(0xe6e3ebff).into()), element_hover: Some(rgba(0x8f8b9680).into()), @@ -4052,7 +4052,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x352f2fff).into()), border_variant: Some(rgba(0x231f1fff).into()), - elevated_surface_background: Some(rgba(0x3b3535ff).into()), + elevated_surface_background: Some(rgba(0x252020ff).into()), background: Some(rgba(0x3b3535ff).into()), panel_background: Some(rgba(0x252020ff).into()), element_hover: Some(rgba(0x564e4e80).into()), @@ -4455,7 +4455,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x393239ff).into()), border_variant: Some(rgba(0x231e23ff).into()), - elevated_surface_background: Some(rgba(0x433a43ff).into()), + elevated_surface_background: Some(rgba(0x252025ff).into()), background: Some(rgba(0x433a43ff).into()), panel_background: Some(rgba(0x252025ff).into()), element_hover: Some(rgba(0x675b6780).into()), @@ -4858,7 +4858,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x2c3b42ff).into()), border_variant: Some(rgba(0x1b2327ff).into()), - elevated_surface_background: Some(rgba(0x33444dff).into()), + elevated_surface_background: Some(rgba(0x1c2529ff).into()), background: Some(rgba(0x33444dff).into()), panel_background: Some(rgba(0x1c2529ff).into()), element_hover: Some(rgba(0x4f6b7880).into()), @@ -5261,7 +5261,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xd6d1cfff).into()), border_variant: Some(rgba(0xebe8e6ff).into()), - elevated_surface_background: Some(rgba(0xcdc8c6ff).into()), + elevated_surface_background: Some(rgba(0xe9e6e4ff).into()), background: Some(rgba(0xcdc8c6ff).into()), panel_background: Some(rgba(0xe9e6e4ff).into()), element_hover: Some(rgba(0xaaa3a180).into()), @@ -5664,7 +5664,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xd7d3beff).into()), border_variant: Some(rgba(0xf2eedcff).into()), - elevated_surface_background: Some(rgba(0xcecab4ff).into()), + elevated_surface_background: Some(rgba(0xeeebd7ff).into()), background: Some(rgba(0xcecab4ff).into()), panel_background: Some(rgba(0xeeebd7ff).into()), element_hover: Some(rgba(0xa8a48e80).into()), @@ -6067,7 +6067,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xcfc7c7ff).into()), border_variant: Some(rgba(0xede5e5ff).into()), - elevated_surface_background: Some(rgba(0xc1bbbbff).into()), + elevated_surface_background: Some(rgba(0xebe3e3ff).into()), background: Some(rgba(0xc1bbbbff).into()), panel_background: Some(rgba(0xebe3e3ff).into()), element_hover: Some(rgba(0x8e898980).into()), @@ -6470,7 +6470,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xbed7beff).into()), border_variant: Some(rgba(0xdff0dfff).into()), - elevated_surface_background: Some(rgba(0xb4ceb4ff).into()), + elevated_surface_background: Some(rgba(0xdaeedaff).into()), background: Some(rgba(0xb4ceb4ff).into()), panel_background: Some(rgba(0xdaeedaff).into()), element_hover: Some(rgba(0x8ea88e80).into()), @@ -6873,7 +6873,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x2f3832ff).into()), border_variant: Some(rgba(0x1e2420ff).into()), - elevated_surface_background: Some(rgba(0x353f39ff).into()), + elevated_surface_background: Some(rgba(0x1f2621ff).into()), background: Some(rgba(0x353f39ff).into()), panel_background: Some(rgba(0x1f2621ff).into()), element_hover: Some(rgba(0x505e5580).into()), @@ -7276,7 +7276,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xcdbecdff).into()), border_variant: Some(rgba(0xe5dce5ff).into()), - elevated_surface_background: Some(rgba(0xc6b8c6ff).into()), + elevated_surface_background: Some(rgba(0xe1d6e1ff).into()), background: Some(rgba(0xc6b8c6ff).into()), panel_background: Some(rgba(0xe1d6e1ff).into()), element_hover: Some(rgba(0xad9dad80).into()), @@ -7679,7 +7679,7 @@ pub fn atelier() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xb0d3e5ff).into()), border_variant: Some(rgba(0xd3edfaff).into()), - elevated_surface_background: Some(rgba(0xa6cadcff).into()), + elevated_surface_background: Some(rgba(0xcdeaf9ff).into()), background: Some(rgba(0xa6cadcff).into()), panel_background: Some(rgba(0xcdeaf9ff).into()), element_hover: Some(rgba(0x80a4b680).into()), diff --git a/crates/theme2/src/themes/ayu.rs b/crates/theme2/src/themes/ayu.rs index 7c0eb701081f002ec5c1bd54ed11fc45e08bee2a..d4c1d0fbe5fd1c8849e2e261d5c89cb02bc5afde 100644 --- a/crates/theme2/src/themes/ayu.rs +++ b/crates/theme2/src/themes/ayu.rs @@ -22,7 +22,7 @@ pub fn ayu() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x2d2f34ff).into()), border_variant: Some(rgba(0x1b1e24ff).into()), - elevated_surface_background: Some(rgba(0x313337ff).into()), + elevated_surface_background: Some(rgba(0x1f2127ff).into()), background: Some(rgba(0x313337ff).into()), panel_background: Some(rgba(0x1f2127ff).into()), element_hover: Some(rgba(0x3f404380).into()), @@ -404,7 +404,7 @@ pub fn ayu() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xdfe0e1ff).into()), border_variant: Some(rgba(0xefeff0ff).into()), - elevated_surface_background: Some(rgba(0xdcdddeff).into()), + elevated_surface_background: Some(rgba(0xececedff).into()), background: Some(rgba(0xdcdddeff).into()), panel_background: Some(rgba(0xececedff).into()), element_hover: Some(rgba(0xcfd1d280).into()), @@ -786,7 +786,7 @@ pub fn ayu() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x43464fff).into()), border_variant: Some(rgba(0x323641ff).into()), - elevated_surface_background: Some(rgba(0x464a52ff).into()), + elevated_surface_background: Some(rgba(0x353944ff).into()), background: Some(rgba(0x464a52ff).into()), panel_background: Some(rgba(0x353944ff).into()), element_hover: Some(rgba(0x53565d80).into()), diff --git a/crates/theme2/src/themes/gruvbox.rs b/crates/theme2/src/themes/gruvbox.rs index 8cc13fb1771a080a8addcf67ef0cbf0b74530948..148264933f9cb585512d879fa52ba2771cc4c07b 100644 --- a/crates/theme2/src/themes/gruvbox.rs +++ b/crates/theme2/src/themes/gruvbox.rs @@ -22,7 +22,7 @@ pub fn gruvbox() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xddcca7ff).into()), border_variant: Some(rgba(0xefe2bcff).into()), - elevated_surface_background: Some(rgba(0xd9c8a4ff).into()), + elevated_surface_background: Some(rgba(0xecddb5ff).into()), background: Some(rgba(0xd9c8a4ff).into()), panel_background: Some(rgba(0xecddb5ff).into()), element_hover: Some(rgba(0xc9b99a80).into()), @@ -411,7 +411,7 @@ pub fn gruvbox() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x494340ff).into()), border_variant: Some(rgba(0x393634ff).into()), - elevated_surface_background: Some(rgba(0x4c4642ff).into()), + elevated_surface_background: Some(rgba(0x3b3735ff).into()), background: Some(rgba(0x4c4642ff).into()), panel_background: Some(rgba(0x3b3735ff).into()), element_hover: Some(rgba(0x5b534d80).into()), @@ -800,7 +800,7 @@ pub fn gruvbox() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xddcca7ff).into()), border_variant: Some(rgba(0xefe1b8ff).into()), - elevated_surface_background: Some(rgba(0xd9c8a4ff).into()), + elevated_surface_background: Some(rgba(0xecddb4ff).into()), background: Some(rgba(0xd9c8a4ff).into()), panel_background: Some(rgba(0xecddb4ff).into()), element_hover: Some(rgba(0xc9b99a80).into()), @@ -1189,7 +1189,7 @@ pub fn gruvbox() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x494340ff).into()), border_variant: Some(rgba(0x373432ff).into()), - elevated_surface_background: Some(rgba(0x4c4642ff).into()), + elevated_surface_background: Some(rgba(0x3a3735ff).into()), background: Some(rgba(0x4c4642ff).into()), panel_background: Some(rgba(0x3a3735ff).into()), element_hover: Some(rgba(0x5b534d80).into()), @@ -1578,7 +1578,7 @@ pub fn gruvbox() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xddcca7ff).into()), border_variant: Some(rgba(0xeddeb5ff).into()), - elevated_surface_background: Some(rgba(0xd9c8a4ff).into()), + elevated_surface_background: Some(rgba(0xecdcb3ff).into()), background: Some(rgba(0xd9c8a4ff).into()), panel_background: Some(rgba(0xecdcb3ff).into()), element_hover: Some(rgba(0xc9b99a80).into()), @@ -1967,7 +1967,7 @@ pub fn gruvbox() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x494340ff).into()), border_variant: Some(rgba(0x343130ff).into()), - elevated_surface_background: Some(rgba(0x4c4642ff).into()), + elevated_surface_background: Some(rgba(0x393634ff).into()), background: Some(rgba(0x4c4642ff).into()), panel_background: Some(rgba(0x393634ff).into()), element_hover: Some(rgba(0x5b534d80).into()), diff --git a/crates/theme2/src/themes/one.rs b/crates/theme2/src/themes/one.rs index e62ccbefdd61e212984bdea40a166967cae026e6..4a0d54648a4eae72ded59f2691b4cdc128c1f524 100644 --- a/crates/theme2/src/themes/one.rs +++ b/crates/theme2/src/themes/one.rs @@ -22,7 +22,7 @@ pub fn one() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xdfdfe0ff).into()), border_variant: Some(rgba(0xeeeeeeff).into()), - elevated_surface_background: Some(rgba(0xdcdcddff).into()), + elevated_surface_background: Some(rgba(0xebebecff).into()), background: Some(rgba(0xdcdcddff).into()), panel_background: Some(rgba(0xebebecff).into()), element_hover: Some(rgba(0xc9c9ca80).into()), @@ -411,7 +411,7 @@ pub fn one() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x363c46ff).into()), border_variant: Some(rgba(0x2e333cff).into()), - elevated_surface_background: Some(rgba(0x3b414dff).into()), + elevated_surface_background: Some(rgba(0x2f343eff).into()), background: Some(rgba(0x3b414dff).into()), panel_background: Some(rgba(0x2f343eff).into()), element_hover: Some(rgba(0x464b5780).into()), diff --git a/crates/theme2/src/themes/rose_pine.rs b/crates/theme2/src/themes/rose_pine.rs index 318767cb2bc943f5db0524254e98d48402675576..48e315ae8014afe765ce0f3dfc608876a3236a26 100644 --- a/crates/theme2/src/themes/rose_pine.rs +++ b/crates/theme2/src/themes/rose_pine.rs @@ -22,7 +22,7 @@ pub fn rose_pine() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xe5e0dfff).into()), border_variant: Some(rgba(0xfdf8f1ff).into()), - elevated_surface_background: Some(rgba(0xdcd8d8ff).into()), + elevated_surface_background: Some(rgba(0xfef9f2ff).into()), background: Some(rgba(0xdcd8d8ff).into()), panel_background: Some(rgba(0xfef9f2ff).into()), element_hover: Some(rgba(0xdcd6d580).into()), @@ -418,7 +418,7 @@ pub fn rose_pine() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x322f48ff).into()), border_variant: Some(rgba(0x27243bff).into()), - elevated_surface_background: Some(rgba(0x38354eff).into()), + elevated_surface_background: Some(rgba(0x28253cff).into()), background: Some(rgba(0x38354eff).into()), panel_background: Some(rgba(0x28253cff).into()), element_hover: Some(rgba(0x504c6880).into()), @@ -814,7 +814,7 @@ pub fn rose_pine() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x232132ff).into()), border_variant: Some(rgba(0x1c1a29ff).into()), - elevated_surface_background: Some(rgba(0x292739ff).into()), + elevated_surface_background: Some(rgba(0x1d1b2aff).into()), background: Some(rgba(0x292739ff).into()), panel_background: Some(rgba(0x1d1b2aff).into()), element_hover: Some(rgba(0x423f5580).into()), diff --git a/crates/theme2/src/themes/sandcastle.rs b/crates/theme2/src/themes/sandcastle.rs index 5aa03988746c8e710657ea89352168ea49f9428b..184a6751de0b94e0ca1f132c230e3aa1b052f897 100644 --- a/crates/theme2/src/themes/sandcastle.rs +++ b/crates/theme2/src/themes/sandcastle.rs @@ -21,7 +21,7 @@ pub fn sandcastle() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x313741ff).into()), border_variant: Some(rgba(0x2a2f38ff).into()), - elevated_surface_background: Some(rgba(0x333944ff).into()), + elevated_surface_background: Some(rgba(0x2b3039ff).into()), background: Some(rgba(0x333944ff).into()), panel_background: Some(rgba(0x2b3039ff).into()), element_hover: Some(rgba(0x3d435080).into()), diff --git a/crates/theme2/src/themes/solarized.rs b/crates/theme2/src/themes/solarized.rs index c71ce54a2f027a32e1bf2424ea4422e893c4265d..0fd20760c2238da0ccb6b134661317ed8a051f5f 100644 --- a/crates/theme2/src/themes/solarized.rs +++ b/crates/theme2/src/themes/solarized.rs @@ -22,7 +22,7 @@ pub fn solarized() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0xdcdacbff).into()), border_variant: Some(rgba(0xf5eedbff).into()), - elevated_surface_background: Some(rgba(0xcfd0c4ff).into()), + elevated_surface_background: Some(rgba(0xf3eddaff).into()), background: Some(rgba(0xcfd0c4ff).into()), panel_background: Some(rgba(0xf3eddaff).into()), element_hover: Some(rgba(0x9faaa880).into()), @@ -404,7 +404,7 @@ pub fn solarized() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x063541ff).into()), border_variant: Some(rgba(0x032f3bff).into()), - elevated_surface_background: Some(rgba(0x083743ff).into()), + elevated_surface_background: Some(rgba(0x04313cff).into()), background: Some(rgba(0x083743ff).into()), panel_background: Some(rgba(0x04313cff).into()), element_hover: Some(rgba(0x2b4f5880).into()), diff --git a/crates/theme2/src/themes/summercamp.rs b/crates/theme2/src/themes/summercamp.rs index a849988f7b2ca4855c0b0e5b38fc91707f7763b2..987c64e9f2146f727170ffd5c94796df95b56bd7 100644 --- a/crates/theme2/src/themes/summercamp.rs +++ b/crates/theme2/src/themes/summercamp.rs @@ -21,7 +21,7 @@ pub fn summercamp() -> UserThemeFamily { colors: ThemeColorsRefinement { border: Some(rgba(0x29251bff).into()), border_variant: Some(rgba(0x221e15ff).into()), - elevated_surface_background: Some(rgba(0x2a261cff).into()), + elevated_surface_background: Some(rgba(0x231f16ff).into()), background: Some(rgba(0x2a261cff).into()), panel_background: Some(rgba(0x231f16ff).into()), element_hover: Some(rgba(0x312d2180).into()), diff --git a/crates/theme_importer/src/zed1/converter.rs b/crates/theme_importer/src/zed1/converter.rs index a12d96054ca83738069540c5883d8bea069ad667..01381b225757c5da70c5cda5475f6d72ccda4795 100644 --- a/crates/theme_importer/src/zed1/converter.rs +++ b/crates/theme_importer/src/zed1/converter.rs @@ -133,7 +133,11 @@ impl Zed1ThemeConverter { border: convert(active_tab.container.border.color), border_variant: convert(toolbar.container.border.color), background: convert(self.theme.workspace.background), - elevated_surface_background: picker.container.background_color.map(zed1_color_to_hsla), + elevated_surface_background: editor + .hover_popover + .container + .background_color + .map(zed1_color_to_hsla), title_bar_background: title_bar.container.background_color.map(zed1_color_to_hsla), status_bar_background: status_bar .container From e932f4cf47e67e7372b0b91dfa32fc3c54b6a558 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Thu, 28 Dec 2023 19:22:43 +0100 Subject: [PATCH 341/644] Bump Rust to 1.75 (#3815) **This PR also bumps wasmtime version from 0.38 to 2.0 as 0.38 does not build with Rust 1.75**. I did not test the plugin runtime as (AFAIK) we intend to deprecate it; also, wasmtime's most recent version is 16.0, so it'd make sense to bump the version at some point anyways. I did not bump the version to 16.0 straight away as that'd require code changes in `plugin_runtime`. Release Notes: - N/A --- Cargo.lock | 507 +++++++++++------- Dockerfile | 2 +- crates/collab2/src/tests.rs | 1 - crates/gpui/src/util.rs | 1 - crates/language/src/buffer.rs | 2 +- crates/language2/src/buffer.rs | 2 +- crates/plugin_runtime/Cargo.toml | 8 +- .../ui2/src/components/button/button_like.rs | 1 + crates/ui2/src/ui2.rs | 3 +- rust-toolchain.toml | 2 +- 10 files changed, 320 insertions(+), 209 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01230cd8052a477214946a30d30362b87de8cd88..7256782e31bc1981d9858c3a959c730ce6404c2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1303,40 +1303,39 @@ dependencies = [ [[package]] name = "cap-fs-ext" -version = "0.24.4" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54b86398b5852ddd45784b1d9b196b98beb39171821bad4b8b44534a1e87927" +checksum = "0b0e103ce36d217d568903ad27b14ec2238ecb5d65bad2e756a8f3c0d651506e" dependencies = [ "cap-primitives", "cap-std", - "io-lifetimes 0.5.3", - "winapi 0.3.9", + "io-lifetimes 0.7.5", + "windows-sys 0.36.1", ] [[package]] name = "cap-primitives" -version = "0.24.4" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8fca3e81fae1d91a36e9784ca22a39ef623702b5f7904d89dc31f10184a178" +checksum = "af3f336aa91cce16033ed3c94ac91d98956c49b420e6d6cd0dd7d0e386a57085" dependencies = [ "ambient-authority", - "errno 0.2.8", "fs-set-times", "io-extras", - "io-lifetimes 0.5.3", + "io-lifetimes 0.7.5", "ipnet", "maybe-owned", - "rustix 0.33.7", - "winapi 0.3.9", + "rustix 0.35.16", "winapi-util", + "windows-sys 0.36.1", "winx", ] [[package]] name = "cap-rand" -version = "0.24.4" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3b27294116983d706f4c8168f6d10c84f9f5daed0c28bc7d0296cf16bcf971" +checksum = "d14b9606aa9550d34651bc481443203bc014237bdb992d201d2afa62d2ec6dea" dependencies = [ "ambient-authority", "rand 0.8.5", @@ -1344,26 +1343,26 @@ dependencies = [ [[package]] name = "cap-std" -version = "0.24.4" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2247568946095c7765ad2b441a56caffc08027734c634a6d5edda648f04e32eb" +checksum = "c9d6e70b626eceac9d6fc790fe2d72cc3f2f7bc3c35f467690c54a526b0f56db" dependencies = [ "cap-primitives", "io-extras", - "io-lifetimes 0.5.3", + "io-lifetimes 0.7.5", "ipnet", - "rustix 0.33.7", + "rustix 0.35.16", ] [[package]] name = "cap-time-ext" -version = "0.24.4" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50472b6ebc302af0401fa3fb939694cd8ff00e0d4c9182001e434fc822ab83a" +checksum = "c3a0524f7c4cff2ea547ae2b652bf7a348fd3e48f76556dc928d8b45ab2f1d50" dependencies = [ "cap-primitives", "once_cell", - "rustix 0.33.7", + "rustix 0.35.16", "winx", ] @@ -2367,19 +2366,21 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.85.3" +version = "0.89.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "749d0d6022c9038dccf480bdde2a38d435937335bf2bb0f14e815d94517cdce8" +checksum = "593b398dd0c5b1e2e3a9c3dae8584e287894ea84e361949ad506376e99196265" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.85.3" +version = "0.89.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94370cc7b37bf652ccd8bb8f09bd900997f7ccf97520edfc75554bb5c4abbea" +checksum = "afc0d8faabd099ea15ab33d49d150e5572c04cfeb95d675fd41286739b754629" dependencies = [ + "arrayvec 0.7.4", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", @@ -2394,33 +2395,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.85.3" +version = "0.89.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a3cea8fdab90e44018c5b9a1dfd460d8ee265ac354337150222a354628bdb6" +checksum = "1ac1669e42579476f001571d6ba4b825fac686282c97b88b18f8e34242066a81" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.85.3" +version = "0.89.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac72f76f2698598951ab26d8c96eaa854810e693e7dd52523958b5909fde6b2" +checksum = "e2a1b1eef9640ab72c1e7b583ac678083855a509da34b4b4378bd99954127c20" [[package]] name = "cranelift-entity" -version = "0.85.3" +version = "0.89.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09eaeacfcd2356fe0e66b295e8f9d59fdd1ac3ace53ba50de14d628ec902f72d" +checksum = "eea4e17c3791fd8134640b26242a9ddbd7c67db78f0bad98cb778bf563ef81a0" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.85.3" +version = "0.89.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba69c9980d5ffd62c18a2bde927855fcd7c8dc92f29feaf8636052662cbd99c" +checksum = "fca1474b5302348799656d43a40eacd716a3b46169405a3af812832c9edf77b4" dependencies = [ "cranelift-codegen", "log", @@ -2430,15 +2431,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.85.3" +version = "0.89.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2920dc1e05cac40304456ed3301fde2c09bd6a9b0210bcfa2f101398d628d5b" +checksum = "77aa537f020ea43483100153278e7215d41695bdcef9eea6642d122675f64249" [[package]] name = "cranelift-native" -version = "0.85.3" +version = "0.89.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04dfa45f9b2a6f587c564d6b63388e00cd6589d2df6ea2758cf79e1a13285e6" +checksum = "8bdc6b65241a95b7d8eafbf4e114c082e49b80162a2dcd9c6bcc5989c3310c9e" dependencies = [ "cranelift-codegen", "libc", @@ -2447,9 +2448,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.85.3" +version = "0.89.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31a46513ae6f26f3f267d8d75b5373d555fbbd1e68681f348d99df43f747ec54" +checksum = "4eb6359f606a1c80ccaa04fae9dbbb504615ec7a49b6c212b341080fff7a65dd" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -3092,12 +3093,12 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ "humantime", - "is-terminal 0.4.9", + "is-terminal 0.4.10", "log", "regex", "termcolor", @@ -3325,7 +3326,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84f2e425d9790201ba4af4630191feac6dcc98765b118d4d18e91d23c2353866" dependencies = [ - "env_logger 0.10.0", + "env_logger 0.10.1", "log", ] @@ -3550,13 +3551,13 @@ dependencies = [ [[package]] name = "fs-set-times" -version = "0.15.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df62ee66ee2d532ea8d567b5a3f0d03ecd64636b98bad5be1e93dcc918b92aa" +checksum = "a267b6a9304912e018610d53fe07115d8b530b160e85db4d2d3a59f3ddde1aec" dependencies = [ - "io-lifetimes 0.5.3", - "rustix 0.33.7", - "winapi 0.3.9", + "io-lifetimes 0.7.5", + "rustix 0.35.16", + "windows-sys 0.36.1", ] [[package]] @@ -4142,15 +4143,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash 0.7.6", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -4545,22 +4537,22 @@ dependencies = [ [[package]] name = "io-extras" -version = "0.13.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c937cc9891c12eaa8c63ad347e4a288364b1328b924886970b47a14ab8f8f8" +checksum = "4a5d8c2ab5becd8720e30fd25f8fa5500d8dc3fceadd8378f05859bd7b46fc49" dependencies = [ - "io-lifetimes 0.5.3", - "winapi 0.3.9", + "io-lifetimes 0.7.5", + "windows-sys 0.36.1", ] [[package]] name = "io-lifetimes" -version = "0.5.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec58677acfea8a15352d42fc87d11d63596ade9239e0a7c9352914417515dbe6" +checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074" dependencies = [ "libc", - "winapi 0.3.9", + "windows-sys 0.42.0", ] [[package]] @@ -4610,25 +4602,25 @@ checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c89a757e762896bdbdfadf2860d0f8b0cea5e363d8cf3e7bdfeb63d1d976352" +checksum = "0d508111813f9af3afd2f92758f77e4ed2cc9371b642112c6a48d22eb73105c5" dependencies = [ "hermit-abi 0.2.6", - "io-lifetimes 0.5.3", - "rustix 0.33.7", - "winapi 0.3.9", + "io-lifetimes 0.7.5", + "rustix 0.35.16", + "windows-sys 0.36.1", ] [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ "hermit-abi 0.3.3", - "rustix 0.38.14", - "windows-sys 0.48.0", + "rustix 0.38.21", + "windows-sys 0.52.0", ] [[package]] @@ -4683,10 +4675,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] -name = "ittapi-rs" -version = "0.2.0" +name = "ittapi" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f712648a1ad72fbfb7adc2772c331e8d90f022f8cf30cbabefba2878dd3172b0" +checksum = "25a5c0b993601cad796222ea076565c5d9f337d35592f8622c753724f06d7271" +dependencies = [ + "anyhow", + "ittapi-sys", + "log", +] + +[[package]] +name = "ittapi-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7b5e473765060536a660eed127f758cf1a810c73e49063264959c60d1727d9" dependencies = [ "cc", ] @@ -5144,9 +5147,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.0.42" +version = "0.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5284f00d480e1c39af34e72f8ad60b94f47007e3481cd3b731c1d67190ddc7b7" +checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" [[package]] name = "linux-raw-sys" @@ -5156,9 +5159,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lipsum" @@ -5428,11 +5431,11 @@ checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memfd" -version = "0.4.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6627dc657574b49d6ad27105ed671822be56e0d2547d413bfbf3e8d8fa92e7a" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "libc", + "rustix 0.38.21", ] [[package]] @@ -5628,12 +5631,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "more-asserts" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" - [[package]] name = "multi_buffer" version = "0.1.0" @@ -6168,12 +6165,12 @@ dependencies = [ [[package]] name = "object" -version = "0.28.4" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ "crc32fast", - "hashbrown 0.11.2", + "hashbrown 0.12.3", "indexmap 1.9.3", "memchr", ] @@ -7534,9 +7531,9 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.2.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a8d23b35d7177df3b9d31ed8a9ab4bf625c668be77a319d4f5efd4a5257701c" +checksum = "91b2eab54204ea0117fe9a060537e0b07a4e72f7c7d182361ecc346cab2240e5" dependencies = [ "fxhash", "log", @@ -7588,18 +7585,6 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" -[[package]] -name = "region" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0" -dependencies = [ - "bitflags 1.3.2", - "libc", - "mach", - "winapi 0.3.9", -] - [[package]] name = "remove_dir_all" version = "0.5.3" @@ -8019,18 +8004,18 @@ dependencies = [ [[package]] name = "rustix" -version = "0.33.7" +version = "0.35.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938a344304321a9da4973b9ff4f9f8db9caf4597dfd9dda6a60b523340a0fff0" +checksum = "5363f616a5244fd47fc1dd0a0b24c28a5c0154f5010c16332a7ad6f78f2e8b62" dependencies = [ "bitflags 1.3.2", "errno 0.2.8", - "io-lifetimes 0.5.3", + "io-lifetimes 0.7.5", "itoa", "libc", - "linux-raw-sys 0.0.42", + "linux-raw-sys 0.0.46", "once_cell", - "winapi 0.3.9", + "windows-sys 0.42.0", ] [[package]] @@ -8049,14 +8034,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ "bitflags 2.4.1", "errno 0.3.3", "libc", - "linux-raw-sys 0.4.7", + "linux-raw-sys 0.4.12", "windows-sys 0.48.0", ] @@ -9521,17 +9506,17 @@ dependencies = [ [[package]] name = "system-interface" -version = "0.20.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e09bb3fb4e02ec4b87e182ea9718fadbc0fa3e50085b40a9af9690572b67f9e" +checksum = "92adbaf536f5aff6986e1e62ba36cee72b1718c5153eee08b9e728ddde3f6029" dependencies = [ "atty", "bitflags 1.3.2", "cap-fs-ext", "cap-std", - "io-lifetimes 0.5.3", - "rustix 0.33.7", - "winapi 0.3.9", + "io-lifetimes 0.7.5", + "rustix 0.35.16", + "windows-sys 0.36.1", "winx", ] @@ -9571,9 +9556,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "tempdir" @@ -9594,7 +9579,7 @@ dependencies = [ "cfg-if 1.0.0", "fastrand 2.0.0", "redox_syscall 0.3.5", - "rustix 0.38.14", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -11101,9 +11086,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi-cap-std-sync" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f086c5026d2fc3b268d138e65373f46422cc810f46d6e0776859c5027cb18728" +checksum = "c4b4953999c746173c263b81e9e5e3e335ff47face7187ba2a5ecc91c716e6f3" dependencies = [ "anyhow", "async-trait", @@ -11113,32 +11098,32 @@ dependencies = [ "cap-time-ext", "fs-set-times", "io-extras", - "io-lifetimes 0.5.3", - "is-terminal 0.1.0", - "lazy_static", - "rustix 0.33.7", + "io-lifetimes 0.7.5", + "is-terminal 0.3.0", + "once_cell", + "rustix 0.35.16", "system-interface", "tracing", "wasi-common", - "winapi 0.3.9", + "windows-sys 0.36.1", ] [[package]] name = "wasi-common" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e8844fede1c3787cc08853872f47e8bd91f6c939c7406bc7a5dba496b260c08" +checksum = "d47faf4f76ebfdeb1f3346a949c6fbf2f2471afc68280b00c76d6c02221d80ad" dependencies = [ "anyhow", "bitflags 1.3.2", "cap-rand", "cap-std", "io-extras", - "rustix 0.33.7", + "rustix 0.35.16", "thiserror", "tracing", "wiggle", - "winapi 0.3.9", + "windows-sys 0.36.1", ] [[package]] @@ -11209,43 +11194,40 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-encoder" -version = "0.33.1" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39de0723a53d3c8f54bed106cfbc0d06b3e4d945c5c5022115a61e3b29183ae" +checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" dependencies = [ "leb128", ] [[package]] name = "wasmparser" -version = "0.85.0" +version = "0.92.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570460c58b21e9150d2df0eaaedbb7816c34bcec009ae0dcc976e40ba81463e7" +checksum = "7da34cec2a8c23db906cdf8b26e988d7a7f0d549eb5d51299129647af61a1b37" dependencies = [ "indexmap 1.9.3", ] [[package]] name = "wasmtime" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f50eadf868ab6a04b7b511460233377d0bfbb92e417b2f6a98b98fef2e098f5" +checksum = "743d37c265fa134a76de653c7e66be22590eaccd03da13cee99f3ac7a59cb826" dependencies = [ "anyhow", "async-trait", - "backtrace", "bincode", "cfg-if 1.0.0", "indexmap 1.9.3", - "lazy_static", "libc", "log", - "object 0.28.4", + "object 0.29.0", "once_cell", "paste", "psm", "rayon", - "region", "serde", "target-lexicon", "wasmparser", @@ -11256,14 +11238,23 @@ dependencies = [ "wasmtime-jit", "wasmtime-runtime", "wat", - "winapi 0.3.9", + "windows-sys 0.36.1", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de327cf46d5218315957138131ed904621e6f99018aa2da508c0dcf0c65f1bf2" +dependencies = [ + "cfg-if 1.0.0", ] [[package]] name = "wasmtime-cache" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1df23c642e1376892f3b72f311596976979cbf8b85469680cdd3a8a063d12a2" +checksum = "42bd53d27df1076100519b680b45d8209aed62b4bbaf0913732810cb216f7b2b" dependencies = [ "anyhow", "base64 0.13.1", @@ -11271,19 +11262,19 @@ dependencies = [ "directories-next", "file-per-thread-logger", "log", - "rustix 0.33.7", + "rustix 0.35.16", "serde", "sha2 0.9.9", "toml 0.5.11", - "winapi 0.3.9", + "windows-sys 0.36.1", "zstd", ] [[package]] name = "wasmtime-cranelift" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f264ff6b4df247d15584f2f53d009fbc90032cfdc2605b52b961bffc71b6eccd" +checksum = "017c3605ccce867b3ba7f71d95e5652acc22b9dc2971ad6a6f9df4a8d7af2648" dependencies = [ "anyhow", "cranelift-codegen", @@ -11293,8 +11284,7 @@ dependencies = [ "cranelift-wasm", "gimli 0.26.2", "log", - "more-asserts", - "object 0.28.4", + "object 0.29.0", "target-lexicon", "thiserror", "wasmparser", @@ -11303,17 +11293,16 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "839d2820e4b830f4b9e7aa08d4c0acabf4a5036105d639f6dfa1c6891c73bdc6" +checksum = "6aec5c1f81aab9bb35997113c171b6bb9093afc90e3757c55e0c08dc9ac612e4" dependencies = [ "anyhow", "cranelift-entity", "gimli 0.26.2", "indexmap 1.9.3", "log", - "more-asserts", - "object 0.28.4", + "object 0.29.0", "serde", "target-lexicon", "thiserror", @@ -11323,20 +11312,22 @@ dependencies = [ [[package]] name = "wasmtime-fiber" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3248be3c4911233535356025f6562193614a40155ee9094bb6a2b43f0dc82803" +checksum = "1075aa43857086ef89afbe87602fe2dae98ad212582e722b6d3d2676bb5ee141" dependencies = [ "cc", - "rustix 0.33.7", - "winapi 0.3.9", + "cfg-if 1.0.0", + "rustix 0.35.16", + "wasmtime-asm-macros", + "windows-sys 0.36.1", ] [[package]] name = "wasmtime-jit" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef0a0bcbfa18b946d890078ba0e1bc76bcc53eccfb40806c0020ec29dcd1bd49" +checksum = "08c683893dbba3986aa71582a5332b87157fb95d34098de2e5f077c7f078726d" dependencies = [ "addr2line 0.17.0", "anyhow", @@ -11344,40 +11335,38 @@ dependencies = [ "cfg-if 1.0.0", "cpp_demangle", "gimli 0.26.2", - "ittapi-rs", + "ittapi", "log", - "object 0.28.4", - "region", + "object 0.29.0", "rustc-demangle", - "rustix 0.33.7", + "rustix 0.35.16", "serde", "target-lexicon", "thiserror", "wasmtime-environ", "wasmtime-jit-debug", "wasmtime-runtime", - "winapi 0.3.9", + "windows-sys 0.36.1", ] [[package]] name = "wasmtime-jit-debug" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4779d976206c458edd643d1ac622b6c37e4a0800a8b1d25dfbf245ac2f2cac" +checksum = "b2f8f15a81292eec468c79a4f887a37a3d02eb0c610f34ddbec607d3e9022f18" dependencies = [ - "lazy_static", - "object 0.28.4", - "rustix 0.33.7", + "object 0.29.0", + "once_cell", + "rustix 0.35.16", ] [[package]] name = "wasmtime-runtime" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7eb6ffa169eb5dcd18ac9473c817358cd57bc62c244622210566d473397954a" +checksum = "09af6238c962e8220424c815a7b1a9a6d0ba0694f0ab0ae12a6cda1923935a0d" dependencies = [ "anyhow", - "backtrace", "cc", "cfg-if 1.0.0", "indexmap 1.9.3", @@ -11386,22 +11375,22 @@ dependencies = [ "mach", "memfd", "memoffset 0.6.5", - "more-asserts", + "paste", "rand 0.8.5", - "region", - "rustix 0.33.7", + "rustix 0.35.16", "thiserror", + "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-fiber", "wasmtime-jit-debug", - "winapi 0.3.9", + "windows-sys 0.36.1", ] [[package]] name = "wasmtime-types" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d932b0ac5336f7308d869703dd225610a6a3aeaa8e968c52b43eed96cefb1c2" +checksum = "5dc3dd9521815984b35d6362f79e6b9c72475027cd1c71c44eb8df8fbf33a9fb" dependencies = [ "cranelift-entity", "serde", @@ -11411,9 +11400,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b68b7d77fb6f2975a6fe6cc4d0015d6b0cebb65c39fce1dd4cc00880dbf7789c" +checksum = "a3bba5cc0a940cef3fbbfa7291c7e5fe0f7ec6fb2efa7bd1504032ed6202a1c0" dependencies = [ "anyhow", "wasi-cap-std-sync", @@ -11433,9 +11422,9 @@ dependencies = [ [[package]] name = "wast" -version = "65.0.1" +version = "69.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd8c1cbadf94a0b0d1071c581d3cfea1b7ed5192c79808dd15406e508dd0afb" +checksum = "c1ee37317321afde358e4d7593745942c48d6d17e0e6e943704de9bbee121e7a" dependencies = [ "leb128", "memchr", @@ -11445,11 +11434,11 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.73" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3209e35eeaf483714f4c6be93f4a03e69aad5f304e3fa66afa7cb90fe1c8051f" +checksum = "aeb338ee8dee4d4cd05e6426683f21c5087dc7cfc8903e839ccf48d43332da3c" dependencies = [ - "wast 65.0.1", + "wast 69.0.1", ] [[package]] @@ -11556,7 +11545,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.14", + "rustix 0.38.21", ] [[package]] @@ -11567,9 +11556,9 @@ checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" [[package]] name = "wiggle" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67dadac11343d2aabc8a906a0db0aaf7cb5046ec3d6fffccdaf2847dccdef8d6" +checksum = "211ef4d238fd83bbe6f1bc57f3e2e20dc8b1f999188be252e7a535b696c6f84f" dependencies = [ "anyhow", "async-trait", @@ -11582,9 +11571,9 @@ dependencies = [ [[package]] name = "wiggle-generate" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63a1dccd6b3fbd9a27417f5d30ce9aa3ee9cf529aad453abbf88a49c5d605b79" +checksum = "63feec26b2fc3708c7a63316949ca75dd96988f03a17e4cb8d533dc62587ada4" dependencies = [ "anyhow", "heck 0.4.1", @@ -11597,9 +11586,9 @@ dependencies = [ [[package]] name = "wiggle-macro" -version = "0.38.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c368d57d9560c34deaa67e06b0953ccf65edb906c525e5a2c866c849b48ec2" +checksum = "494dc2646618c2b7fb0ec5e1d27dbac5ca31194c00a64698a4b5b35a83d80c21" dependencies = [ "proc-macro2", "quote", @@ -11668,6 +11657,34 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -11686,6 +11703,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -11716,6 +11742,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -11728,6 +11769,18 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -11740,6 +11793,18 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -11752,6 +11817,18 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -11764,6 +11841,18 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -11776,6 +11865,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -11788,6 +11883,18 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -11800,6 +11907,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" version = "0.5.15" @@ -11821,13 +11934,13 @@ dependencies = [ [[package]] name = "winx" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d5973cb8cd94a77d03ad7e23bbe14889cb29805da1cec0e4aff75e21aebded" +checksum = "b7b01e010390eb263a4518c8cebf86cb67469d1511c00b749a47b64c39e8054d" dependencies = [ "bitflags 1.3.2", - "io-lifetimes 0.5.3", - "winapi 0.3.9", + "io-lifetimes 0.7.5", + "windows-sys 0.36.1", ] [[package]] diff --git a/Dockerfile b/Dockerfile index f3d0b601b9d042df4138e910729cccac0bb0d019..ed6e4fac8ea0784711a2995ab8b2ed03e8f268d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax = docker/dockerfile:1.2 -FROM rust:1.73-bullseye as builder +FROM rust:1.75-bullseye as builder WORKDIR app COPY . . diff --git a/crates/collab2/src/tests.rs b/crates/collab2/src/tests.rs index a669f260dba91038d4d834d72a03be999823c928..53d42505bdc3babe023c4a8feb4dbbf5c5e24ab6 100644 --- a/crates/collab2/src/tests.rs +++ b/crates/collab2/src/tests.rs @@ -13,7 +13,6 @@ mod random_project_collaboration_tests; mod randomized_test_helpers; mod test_server; -pub use crate as collab2; pub use randomized_test_helpers::{ run_randomized_test, save_randomized_test_plan, RandomizedTest, TestError, UserTestPlan, }; diff --git a/crates/gpui/src/util.rs b/crates/gpui/src/util.rs index dc857b4c66aae09fd42a84f139a93c5c03f68bbd..9e59c387e8c2beee95c5b3692d486b89e68bd771 100644 --- a/crates/gpui/src/util.rs +++ b/crates/gpui/src/util.rs @@ -1,6 +1,5 @@ use smol::future::FutureExt; use std::{future::Future, time::Duration}; -pub use util::*; pub fn post_inc(value: &mut usize) -> usize { let prev = *value; diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 7feffbf3ed58f0c6ea3d18bc77af9e53580c9e6b..c7126d7e8ae2778e392e6dc0461c53d7ddd9a38f 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -2,7 +2,7 @@ pub use crate::{ diagnostic_set::DiagnosticSet, highlight_map::{HighlightId, HighlightMap}, markdown::ParsedMarkdown, - proto, BracketPair, Grammar, Language, LanguageConfig, LanguageRegistry, PLAIN_TEXT, + proto, Grammar, Language, LanguageRegistry, }; use crate::{ diagnostic_set::{DiagnosticEntry, DiagnosticGroup}, diff --git a/crates/language2/src/buffer.rs b/crates/language2/src/buffer.rs index 26ee93adefa7b53d5734e498e24ecf22a4dd0d15..f56b24bb6a1df586405ff1a84f6439463cc1b563 100644 --- a/crates/language2/src/buffer.rs +++ b/crates/language2/src/buffer.rs @@ -2,7 +2,7 @@ pub use crate::{ diagnostic_set::DiagnosticSet, highlight_map::{HighlightId, HighlightMap}, markdown::ParsedMarkdown, - proto, BracketPair, Grammar, Language, LanguageConfig, LanguageRegistry, PLAIN_TEXT, + proto, Grammar, Language, LanguageRegistry, }; use crate::{ diagnostic_set::{DiagnosticEntry, DiagnosticGroup}, diff --git a/crates/plugin_runtime/Cargo.toml b/crates/plugin_runtime/Cargo.toml index 04337741c4584e2d9147cee2dec6fffaa05c3b3f..ddb66068ae5e4402d663d19b6b735e693479d1f1 100644 --- a/crates/plugin_runtime/Cargo.toml +++ b/crates/plugin_runtime/Cargo.toml @@ -5,9 +5,9 @@ edition = "2021" publish = false [dependencies] -wasmtime = "0.38" -wasmtime-wasi = "0.38" -wasi-common = "0.38" +wasmtime = "2.0" +wasmtime-wasi = "2.0" +wasi-common = "2.0" anyhow.workspace = true serde.workspace = true serde_derive.workspace = true @@ -17,4 +17,4 @@ pollster = "0.2.5" smol.workspace = true [build-dependencies] -wasmtime = { version = "0.38", features = ["all-arch"] } +wasmtime = { version = "2.0", features = ["all-arch"] } diff --git a/crates/ui2/src/components/button/button_like.rs b/crates/ui2/src/components/button/button_like.rs index 44e18e850d8496c7994c84abaedf8ef650602229..13d4f360f21b03d029e42ee2893f8742dfd0091d 100644 --- a/crates/ui2/src/components/button/button_like.rs +++ b/crates/ui2/src/components/button/button_like.rs @@ -199,6 +199,7 @@ impl ButtonStyle { } } + #[allow(unused)] pub(crate) fn disabled(self, cx: &mut WindowContext) -> ButtonLikeStyles { match self { ButtonStyle::Filled => ButtonLikeStyles { diff --git a/crates/ui2/src/ui2.rs b/crates/ui2/src/ui2.rs index 5c79199100ed26155cc83f684c32139f3a1ebf54..b34e66dbdaaf990b6c87cfd13be0907d1b2e6cbb 100644 --- a/crates/ui2/src/ui2.rs +++ b/crates/ui2/src/ui2.rs @@ -28,7 +28,6 @@ pub use components::*; pub use disableable::*; pub use fixed::*; pub use prelude::*; -pub use selectable::*; + pub use styled_ext::*; pub use styles::*; -pub use visible_on_hover::*; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 38d54d7aed37e326ed84efe73b9ca7a64d5945ab..79d2d20a7afd81fc00eb1e142d78473562b7f335 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.73" +channel = "1.75" components = [ "rustfmt" ] targets = [ "x86_64-apple-darwin", "aarch64-apple-darwin", "wasm32-wasi" ] From ce8cc50ae50d68ead523d8a1232a20d828c863b5 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 28 Dec 2023 23:45:30 +0200 Subject: [PATCH 342/644] Remove `async_trait` from the only trait that allows it now --- crates/fs/src/repository.rs | 2 -- crates/fs2/src/repository.rs | 2 -- 2 files changed, 4 deletions(-) diff --git a/crates/fs/src/repository.rs b/crates/fs/src/repository.rs index 4637a7f75408c74a4d398b8eb60f21d6ba76ab33..cf5c65105c9e9c473967f8adb9f7de04b6d8f567 100644 --- a/crates/fs/src/repository.rs +++ b/crates/fs/src/repository.rs @@ -23,7 +23,6 @@ pub struct Branch { pub unix_timestamp: Option, } -#[async_trait::async_trait] pub trait GitRepository: Send { fn reload_index(&self); fn load_index_text(&self, relative_file_path: &Path) -> Option; @@ -248,7 +247,6 @@ impl FakeGitRepository { } } -#[async_trait::async_trait] impl GitRepository for FakeGitRepository { fn reload_index(&self) {} diff --git a/crates/fs2/src/repository.rs b/crates/fs2/src/repository.rs index 4637a7f75408c74a4d398b8eb60f21d6ba76ab33..cf5c65105c9e9c473967f8adb9f7de04b6d8f567 100644 --- a/crates/fs2/src/repository.rs +++ b/crates/fs2/src/repository.rs @@ -23,7 +23,6 @@ pub struct Branch { pub unix_timestamp: Option, } -#[async_trait::async_trait] pub trait GitRepository: Send { fn reload_index(&self); fn load_index_text(&self, relative_file_path: &Path) -> Option; @@ -248,7 +247,6 @@ impl FakeGitRepository { } } -#[async_trait::async_trait] impl GitRepository for FakeGitRepository { fn reload_index(&self) {} From 21f0409e3bf2cb760fa045e9630ee2f936924f90 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 28 Dec 2023 10:23:12 -0700 Subject: [PATCH 343/644] Fix anti-aliasing artifacts in borders Previously, we changed borders to be drawn after content, so they are no longer part of the same quads as the background. In our change, we gave the background quad a transparent black border and the border quads transparent black backgrounds. However, this caused the other channels to blend toward that black color before becoming fully transparent, causing them to become darker. In this PR, I source the "placeholder" color by duplicating the values for the other channels and only adjust the alpha down to zero. --- crates/gpui2/src/style.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index c281818c0f0bad1107d49a8b1895762c910e8af7..7f6af4fd21002a56d9daf5e8cfa821e1a18f71d7 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -386,12 +386,14 @@ impl Style { let background_color = self.background.as_ref().and_then(Fill::color); if background_color.map_or(false, |color| !color.is_transparent()) { cx.with_z_index(1, |cx| { + let mut border_color = background_color.unwrap_or_default(); + border_color.a = 0.; cx.paint_quad(quad( bounds, self.corner_radii.to_pixels(bounds.size, rem_size), background_color.unwrap_or_default(), Edges::default(), - Hsla::transparent_black(), + border_color, )); }); } @@ -426,10 +428,12 @@ impl Style { bottom_bounds.upper_right(), ); + let mut background = self.border_color.unwrap_or_default(); + background.a = 0.; let quad = quad( bounds, corner_radii, - Hsla::transparent_black(), + background, border_widths, self.border_color.unwrap_or_default(), ); From 1c13c3a24357c92db8879db05ed998c38f15e2e0 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 30 Dec 2023 01:10:48 +0200 Subject: [PATCH 344/644] Use `ghost_element_background` for avatar background color Also add a couple todo!()s on top of the comments --- crates/theme2/src/styles/colors.rs | 1 + crates/theme2/src/theme2.rs | 1 + crates/ui2/src/components/avatar.rs | 3 +-- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/theme2/src/styles/colors.rs b/crates/theme2/src/styles/colors.rs index ff7163ccdc19e75d18e22e1112687c36f98be452..0b548c5a743ae5455b1b9161ea1399fea5dcf4b9 100644 --- a/crates/theme2/src/styles/colors.rs +++ b/crates/theme2/src/styles/colors.rs @@ -129,6 +129,7 @@ pub struct ThemeColors { /// The border color of the scrollbar track. pub scrollbar_track_border: Hsla, // /// The opacity of the scrollbar status marks, like diagnostic states and git status. + // todo!() // pub scrollbar_status_opacity: Hsla, // === diff --git a/crates/theme2/src/theme2.rs b/crates/theme2/src/theme2.rs index 7b60802e751442ac7889dbefa580ea5c7751043b..fc6253d010321f66e9c96837394369d8a5dd5267 100644 --- a/crates/theme2/src/theme2.rs +++ b/crates/theme2/src/theme2.rs @@ -73,6 +73,7 @@ impl ActiveTheme for AppContext { } } +// todo!() // impl<'a> ActiveTheme for WindowContext<'a> { // fn theme(&self) -> &Arc { // &ThemeSettings::get_global(self.app()).active_theme diff --git a/crates/ui2/src/components/avatar.rs b/crates/ui2/src/components/avatar.rs index 0ab6ce2d85bf39c75f34d8c89849df02752d05ba..793872cd8abf7ecdb86911d2d7eb373d36cf4fab 100644 --- a/crates/ui2/src/components/avatar.rs +++ b/crates/ui2/src/components/avatar.rs @@ -37,8 +37,7 @@ impl RenderOnce for Avatar { .child( self.image .size(size) - // todo!(Pull the avatar fallback background from the theme.) - .bg(gpui::red()), + .bg(cx.theme().colors().ghost_element_background), ) .children(self.is_available.map(|is_free| { // HACK: non-integer sizes result in oval indicators. From 83923fd6d574e210d7afcd795528974d45e8f1b2 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sun, 31 Dec 2023 08:33:40 -0700 Subject: [PATCH 345/644] Clean up Element API and start on docs --- .../src/activity_indicator.rs | 4 +- crates/assistant2/src/assistant_panel.rs | 12 +- .../auto_update2/src/update_notification.rs | 4 +- crates/breadcrumbs2/src/breadcrumbs.rs | 4 +- crates/collab_ui2/src/channel_view.rs | 4 +- crates/collab_ui2/src/chat_panel.rs | 4 +- .../src/chat_panel/message_editor.rs | 4 +- crates/collab_ui2/src/collab_panel.rs | 8 +- .../src/collab_panel/channel_modal.rs | 4 +- .../src/collab_panel/contact_finder.rs | 4 +- crates/collab_ui2/src/collab_titlebar_item.rs | 4 +- crates/collab_ui2/src/face_pile.rs | 4 +- crates/collab_ui2/src/notification_panel.rs | 6 +- .../incoming_call_notification.rs | 4 +- .../project_shared_notification.rs | 4 +- .../command_palette2/src/command_palette.rs | 4 +- crates/copilot2/src/sign_in.rs | 4 +- crates/copilot_button2/src/copilot_button.rs | 4 +- crates/diagnostics2/src/diagnostics.rs | 4 +- crates/diagnostics2/src/items.rs | 4 +- crates/diagnostics2/src/toolbar_controls.rs | 4 +- crates/editor2/src/editor.rs | 4 +- crates/editor2/src/element.rs | 2 +- crates/editor2/src/items.rs | 4 +- .../feedback2/src/deploy_feedback_button.rs | 4 +- crates/feedback2/src/feedback_modal.rs | 4 +- crates/file_finder2/src/file_finder.rs | 4 +- crates/go_to_line2/src/go_to_line.rs | 4 +- crates/gpui2/src/app/test_context.rs | 4 +- crates/gpui2/src/element.rs | 139 +++++++++++------- crates/gpui2/src/elements/canvas.rs | 2 +- crates/gpui2/src/elements/div.rs | 10 +- crates/gpui2/src/elements/img.rs | 2 +- crates/gpui2/src/elements/list.rs | 2 +- crates/gpui2/src/elements/overlay.rs | 2 +- crates/gpui2/src/elements/svg.rs | 2 +- crates/gpui2/src/elements/text.rs | 12 +- crates/gpui2/src/elements/uniform_list.rs | 2 +- crates/gpui2/src/interactive.rs | 8 +- crates/gpui2/src/view.rs | 14 +- crates/gpui2_macros/src/derive_render.rs | 4 +- .../src/active_buffer_language.rs | 2 +- .../src/language_selector.rs | 4 +- crates/language_tools2/src/lsp_log.rs | 8 +- .../language_tools2/src/syntax_tree_view.rs | 6 +- crates/outline2/src/outline.rs | 4 +- crates/picker2/src/picker2.rs | 4 +- crates/project_panel2/src/project_panel.rs | 8 +- .../quick_action_bar2/src/quick_action_bar.rs | 8 +- .../src/highlighted_workspace_location.rs | 4 +- .../recent_projects2/src/recent_projects.rs | 4 +- crates/search2/src/buffer_search.rs | 4 +- crates/search2/src/project_search.rs | 8 +- crates/story/src/story.rs | 12 +- .../src/stories/auto_height_editor.rs | 4 +- crates/storybook2/src/stories/cursor.rs | 4 +- crates/storybook2/src/stories/focus.rs | 4 +- crates/storybook2/src/stories/kitchen_sink.rs | 4 +- .../storybook2/src/stories/overflow_scroll.rs | 4 +- crates/storybook2/src/stories/picker.rs | 4 +- crates/storybook2/src/stories/scroll.rs | 4 +- crates/storybook2/src/stories/text.rs | 4 +- .../storybook2/src/stories/viewport_units.rs | 4 +- crates/storybook2/src/stories/z_index.rs | 8 +- crates/storybook2/src/storybook2.rs | 4 +- crates/terminal_view2/src/terminal_element.rs | 2 +- crates/terminal_view2/src/terminal_panel.rs | 4 +- crates/terminal_view2/src/terminal_view.rs | 4 +- crates/theme_selector2/src/theme_selector.rs | 4 +- crates/ui2/src/components/avatar.rs | 4 +- crates/ui2/src/components/button/button.rs | 4 +- .../ui2/src/components/button/button_icon.rs | 4 +- .../ui2/src/components/button/button_like.rs | 4 +- .../ui2/src/components/button/icon_button.rs | 4 +- .../src/components/button/toggle_button.rs | 4 +- crates/ui2/src/components/checkbox.rs | 4 +- crates/ui2/src/components/context_menu.rs | 4 +- crates/ui2/src/components/disclosure.rs | 4 +- crates/ui2/src/components/divider.rs | 4 +- crates/ui2/src/components/icon.rs | 4 +- crates/ui2/src/components/indicator.rs | 4 +- crates/ui2/src/components/keybinding.rs | 12 +- .../src/components/label/highlighted_label.rs | 4 +- crates/ui2/src/components/label/label.rs | 4 +- crates/ui2/src/components/label/label_like.rs | 4 +- crates/ui2/src/components/list/list.rs | 4 +- crates/ui2/src/components/list/list_header.rs | 4 +- crates/ui2/src/components/list/list_item.rs | 4 +- .../ui2/src/components/list/list_separator.rs | 4 +- .../src/components/list/list_sub_header.rs | 4 +- crates/ui2/src/components/popover.rs | 4 +- crates/ui2/src/components/popover_menu.rs | 2 +- crates/ui2/src/components/right_click_menu.rs | 2 +- crates/ui2/src/components/stories/avatar.rs | 4 +- crates/ui2/src/components/stories/button.rs | 4 +- crates/ui2/src/components/stories/checkbox.rs | 4 +- .../src/components/stories/context_menu.rs | 4 +- .../ui2/src/components/stories/disclosure.rs | 4 +- crates/ui2/src/components/stories/icon.rs | 4 +- .../ui2/src/components/stories/icon_button.rs | 4 +- .../ui2/src/components/stories/keybinding.rs | 4 +- crates/ui2/src/components/stories/label.rs | 4 +- crates/ui2/src/components/stories/list.rs | 4 +- .../ui2/src/components/stories/list_header.rs | 4 +- .../ui2/src/components/stories/list_item.rs | 4 +- crates/ui2/src/components/stories/tab.rs | 4 +- crates/ui2/src/components/stories/tab_bar.rs | 4 +- .../src/components/stories/toggle_button.rs | 4 +- crates/ui2/src/components/tab.rs | 4 +- crates/ui2/src/components/tab_bar.rs | 4 +- crates/ui2/src/components/tooltip.rs | 4 +- crates/vcs_menu2/src/lib.rs | 4 +- crates/vim2/src/mode_indicator.rs | 2 +- crates/welcome2/src/base_keymap_picker.rs | 4 +- crates/welcome2/src/welcome.rs | 4 +- crates/workspace2/src/dock.rs | 12 +- crates/workspace2/src/item.rs | 4 +- crates/workspace2/src/modal_layer.rs | 4 +- crates/workspace2/src/notifications.rs | 4 +- crates/workspace2/src/pane.rs | 8 +- crates/workspace2/src/pane_group.rs | 2 +- crates/workspace2/src/shared_screen.rs | 4 +- crates/workspace2/src/status_bar.rs | 4 +- crates/workspace2/src/toolbar.rs | 4 +- crates/workspace2/src/workspace2.rs | 6 +- 125 files changed, 369 insertions(+), 334 deletions(-) diff --git a/crates/activity_indicator2/src/activity_indicator.rs b/crates/activity_indicator2/src/activity_indicator.rs index 2b7846cd8d96a9c9014c0e4ab05595df4757509e..1332aa8018d644d35aaadd97a776e2a4245f1a8a 100644 --- a/crates/activity_indicator2/src/activity_indicator.rs +++ b/crates/activity_indicator2/src/activity_indicator.rs @@ -304,9 +304,9 @@ impl ActivityIndicator { impl EventEmitter for ActivityIndicator {} impl Render for ActivityIndicator { - type Element = Stateful
; + type Output = Stateful
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let content = self.content_to_render(cx); let mut result = h_stack() diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index bcfb5f0fbc9ae2409b999e4d8698707d2b1f7db5..b04d99842c66a723e316f0c1a5e074cfd5f38c92 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -1101,9 +1101,9 @@ fn build_api_key_editor(cx: &mut ViewContext) -> View { } impl Render for AssistantPanel { - type Element = Focusable
; + type Output = Focusable
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { if let Some(api_key_editor) = self.api_key_editor.clone() { v_stack() .on_action(cx.listener(AssistantPanel::save_credentials)) @@ -2513,9 +2513,9 @@ impl ConversationEditor { impl EventEmitter for ConversationEditor {} impl Render for ConversationEditor { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { div() .key_context("ConversationEditor") .capture_action(cx.listener(ConversationEditor::cancel_last_assist)) @@ -2618,9 +2618,9 @@ struct InlineAssistant { impl EventEmitter for InlineAssistant {} impl Render for InlineAssistant { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let measurements = self.measurements.get(); h_stack() .w_full() diff --git a/crates/auto_update2/src/update_notification.rs b/crates/auto_update2/src/update_notification.rs index 8bb08912b01a13712afe2dbc14e34a9abd49bc24..7bbbcab0feb4f4fc443031809e151dfd390ac28f 100644 --- a/crates/auto_update2/src/update_notification.rs +++ b/crates/auto_update2/src/update_notification.rs @@ -13,9 +13,9 @@ pub struct UpdateNotification { impl EventEmitter for UpdateNotification {} impl Render for UpdateNotification { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Output { let app_name = cx.global::().display_name(); v_stack() diff --git a/crates/breadcrumbs2/src/breadcrumbs.rs b/crates/breadcrumbs2/src/breadcrumbs.rs index da7182ec2c7394512e0ffafef2fcdf0c5cb7936f..77ee22493f439532e77ec5bfbf55287eebb3961a 100644 --- a/crates/breadcrumbs2/src/breadcrumbs.rs +++ b/crates/breadcrumbs2/src/breadcrumbs.rs @@ -30,9 +30,9 @@ impl Breadcrumbs { impl EventEmitter for Breadcrumbs {} impl Render for Breadcrumbs { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let element = h_stack().text_ui(); let Some(active_item) = self.active_item.as_ref() else { return element; diff --git a/crates/collab_ui2/src/channel_view.rs b/crates/collab_ui2/src/channel_view.rs index 0fbe625fe028cc0c203bf679a5c471811db296de..9ba8d506c9d8c5abeffe6c9cd6793d6ed0c1ca8e 100644 --- a/crates/collab_ui2/src/channel_view.rs +++ b/crates/collab_ui2/src/channel_view.rs @@ -222,9 +222,9 @@ impl ChannelView { impl EventEmitter for ChannelView {} impl Render for ChannelView { - type Element = AnyView; + type Output = AnyView; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { self.editor.clone().into() } } diff --git a/crates/collab_ui2/src/chat_panel.rs b/crates/collab_ui2/src/chat_panel.rs index 03e9cfbb4ad64317ede58045ec2a622eda0681ad..17046587a173a999f7d2a6326951278216e12f31 100644 --- a/crates/collab_ui2/src/chat_panel.rs +++ b/crates/collab_ui2/src/chat_panel.rs @@ -549,9 +549,9 @@ impl ChatPanel { impl EventEmitter for ChatPanel {} impl Render for ChatPanel { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { div() .full() .child(if self.client.user_id().is_some() { diff --git a/crates/collab_ui2/src/chat_panel/message_editor.rs b/crates/collab_ui2/src/chat_panel/message_editor.rs index 0b9d0be0b40b6db762f468b7d21f479fde1ea548..908f57f2d66a7a3f083d40b71bc347eae61288c8 100644 --- a/crates/collab_ui2/src/chat_panel/message_editor.rs +++ b/crates/collab_ui2/src/chat_panel/message_editor.rs @@ -196,9 +196,9 @@ impl MessageEditor { } impl Render for MessageEditor { - type Element = AnyView; + type Output = AnyView; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { self.editor.to_any() } } diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index 8fd90af45b40cce837160c886cb5542e9a11e94c..24057f096dd33e93ad5b33f7af0fd2219fd9ba47 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -2263,9 +2263,9 @@ fn render_tree_branch(is_last: bool, cx: &mut WindowContext) -> impl IntoElement } impl Render for CollabPanel { - type Element = Focusable
; + type Output = Focusable
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { v_stack() .key_context("CollabPanel") .on_action(cx.listener(CollabPanel::cancel)) @@ -2453,9 +2453,9 @@ struct DraggedChannelView { } impl Render for DraggedChannelView { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone(); h_stack() .font(ui_font) diff --git a/crates/collab_ui2/src/collab_panel/channel_modal.rs b/crates/collab_ui2/src/collab_panel/channel_modal.rs index d68aa32e9b339159062d36a08cf402c610c7d781..47d142f01e7bcedb8403607ab4c3077c0279c365 100644 --- a/crates/collab_ui2/src/collab_panel/channel_modal.rs +++ b/crates/collab_ui2/src/collab_panel/channel_modal.rs @@ -142,9 +142,9 @@ impl FocusableView for ChannelModal { } impl Render for ChannelModal { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let channel_store = self.channel_store.read(cx); let Some(channel) = channel_store.channel_for_id(self.channel_id) else { return div(); diff --git a/crates/collab_ui2/src/collab_panel/contact_finder.rs b/crates/collab_ui2/src/collab_panel/contact_finder.rs index a38d22c096b0caffc5f6f3ba520ba79ecc2a8924..8368e176b327b4980f1fcfd042444bea119714e6 100644 --- a/crates/collab_ui2/src/collab_panel/contact_finder.rs +++ b/crates/collab_ui2/src/collab_panel/contact_finder.rs @@ -35,7 +35,7 @@ impl ContactFinder { } impl Render for ContactFinder { - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { v_stack() .elevation_3(cx) .child( @@ -52,7 +52,7 @@ impl Render for ContactFinder { .w(rems(34.)) } - type Element = Div; + type Output = Div; } pub struct ContactFinderDelegate { diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 6255e2b833daf2028675fba197bc80d28a1fdea4..2ab2e3f3e229ac123bf3b578feb27898f30be55b 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -56,9 +56,9 @@ pub struct CollabTitlebarItem { } impl Render for CollabTitlebarItem { - type Element = Stateful
; + type Output = Stateful
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let room = ActiveCall::global(cx).read(cx).room().cloned(); let current_user = self.user_store.read(cx).current_user(); let client = self.client.clone(); diff --git a/crates/collab_ui2/src/face_pile.rs b/crates/collab_ui2/src/face_pile.rs index fd675127e4a0786da76f3f5eb044d836652f7fab..1c0d8100d85cd2eb3adb14fd59ffef8d092ecc0f 100644 --- a/crates/collab_ui2/src/face_pile.rs +++ b/crates/collab_ui2/src/face_pile.rs @@ -9,9 +9,9 @@ pub struct FacePile { } impl RenderOnce for FacePile { - type Rendered = Div; + type Output = Div; - fn render(self, _: &mut WindowContext) -> Self::Rendered { + fn render(self, _: &mut WindowContext) -> Self::Output { let player_count = self.faces.len(); let player_list = self.faces.into_iter().enumerate().map(|(ix, player)| { let isnt_last = ix < player_count - 1; diff --git a/crates/collab_ui2/src/notification_panel.rs b/crates/collab_ui2/src/notification_panel.rs index 4b2f38de9b8aad0072e7bc5320baaa7efc2e2779..11e88d8b59353df15d2c7a5417e0b7ccd9bf8e0f 100644 --- a/crates/collab_ui2/src/notification_panel.rs +++ b/crates/collab_ui2/src/notification_panel.rs @@ -540,7 +540,7 @@ impl NotificationPanel { } impl Render for NotificationPanel { - type Element = Div; + type Output = Div; fn render(&mut self, cx: &mut ViewContext) -> Div { v_stack() @@ -706,9 +706,9 @@ impl NotificationToast { } impl Render for NotificationToast { - type Element = Stateful
; + type Output = Stateful
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let user = self.actor.clone(); h_stack() diff --git a/crates/collab_ui2/src/notifications/incoming_call_notification.rs b/crates/collab_ui2/src/notifications/incoming_call_notification.rs index d5bdf4ff446887cd69cfe96676aec6964b9e0c24..dea6fc9359593cc8024136a9a942e554161dd5fa 100644 --- a/crates/collab_ui2/src/notifications/incoming_call_notification.rs +++ b/crates/collab_ui2/src/notifications/incoming_call_notification.rs @@ -117,9 +117,9 @@ impl IncomingCallNotification { } impl Render for IncomingCallNotification { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { // TODO: Is there a better place for us to initialize the font? let (ui_font, ui_font_size) = { let theme_settings = ThemeSettings::get_global(cx); diff --git a/crates/collab_ui2/src/notifications/project_shared_notification.rs b/crates/collab_ui2/src/notifications/project_shared_notification.rs index 707e961423472ddb8b032a253bb20ff66f2adbaa..fc7cc2b2d0ba0c351501fc5d9212f1b65e2fe98b 100644 --- a/crates/collab_ui2/src/notifications/project_shared_notification.rs +++ b/crates/collab_ui2/src/notifications/project_shared_notification.rs @@ -120,9 +120,9 @@ impl ProjectSharedNotification { } impl Render for ProjectSharedNotification { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { // TODO: Is there a better place for us to initialize the font? let (ui_font, ui_font_size) = { let theme_settings = ThemeSettings::get_global(cx); diff --git a/crates/command_palette2/src/command_palette.rs b/crates/command_palette2/src/command_palette.rs index 05891bc0f199a83c2eb911179d042c259a46702a..ae23c0b966f238f9f314575322b4af55d002c1f5 100644 --- a/crates/command_palette2/src/command_palette.rs +++ b/crates/command_palette2/src/command_palette.rs @@ -83,9 +83,9 @@ impl FocusableView for CommandPalette { } impl Render for CommandPalette { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { v_stack().w(rems(34.)).child(self.picker.clone()) } } diff --git a/crates/copilot2/src/sign_in.rs b/crates/copilot2/src/sign_in.rs index 4fa93ffcf89a496ae1b150334c9b7a310b779cec..22e10fbdc312765dbaacada8a403936eb8fb4aab 100644 --- a/crates/copilot2/src/sign_in.rs +++ b/crates/copilot2/src/sign_in.rs @@ -181,9 +181,9 @@ impl CopilotCodeVerification { } impl Render for CopilotCodeVerification { - type Element = Stateful
; + type Output = Stateful
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let prompt = match &self.status { Status::SigningIn { prompt: Some(prompt), diff --git a/crates/copilot_button2/src/copilot_button.rs b/crates/copilot_button2/src/copilot_button.rs index 2c8427732e7043da64aa16b6e72547678f4d82df..0c62a3c48918214f414b773f0c329a5d64efc6c4 100644 --- a/crates/copilot_button2/src/copilot_button.rs +++ b/crates/copilot_button2/src/copilot_button.rs @@ -34,9 +34,9 @@ pub struct CopilotButton { } impl Render for CopilotButton { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let all_language_settings = all_language_settings(None, cx); if !all_language_settings.copilot.feature_enabled { return div(); diff --git a/crates/diagnostics2/src/diagnostics.rs b/crates/diagnostics2/src/diagnostics.rs index 8103231ede627616cd0c47b3f74125704c6fa5bf..dfecdfed51530dc89dcc628876c01a51da4e26ef 100644 --- a/crates/diagnostics2/src/diagnostics.rs +++ b/crates/diagnostics2/src/diagnostics.rs @@ -91,9 +91,9 @@ struct DiagnosticGroupState { impl EventEmitter for ProjectDiagnosticsEditor {} impl Render for ProjectDiagnosticsEditor { - type Element = Focusable
; + type Output = Focusable
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let child = if self.path_states.is_empty() { div() .bg(cx.theme().colors().editor_background) diff --git a/crates/diagnostics2/src/items.rs b/crates/diagnostics2/src/items.rs index cc598ba90ca741e3b4024512544a81d0655d281c..5901b6803dc67188856ff4445c0cb997d46c3576 100644 --- a/crates/diagnostics2/src/items.rs +++ b/crates/diagnostics2/src/items.rs @@ -21,9 +21,9 @@ pub struct DiagnosticIndicator { } impl Render for DiagnosticIndicator { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let diagnostic_indicator = match (self.summary.error_count, self.summary.warning_count) { (0, 0) => h_stack().child( IconElement::new(Icon::Check) diff --git a/crates/diagnostics2/src/toolbar_controls.rs b/crates/diagnostics2/src/toolbar_controls.rs index 1a604b76c86503099239e06edc92a60604485ec0..14460291947c58b1ace86a172333353dc4117677 100644 --- a/crates/diagnostics2/src/toolbar_controls.rs +++ b/crates/diagnostics2/src/toolbar_controls.rs @@ -9,9 +9,9 @@ pub struct ToolbarControls { } impl Render for ToolbarControls { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let include_warnings = self .editor .as_ref() diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index c9fb2fa181f4a1d9d06cfcb21e95c7bbd2c4c34a..817744a47f2481ad143f484aea1494145b681794 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -9291,9 +9291,9 @@ impl FocusableView for Editor { } impl Render for Editor { - type Element = EditorElement; + type Output = EditorElement; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let settings = ThemeSettings::get_global(cx); let text_style = match self.mode { EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle { diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index eb9f4106ea43d57e5339511ad52b8255c6e35882..da7428a8e04e159c5c2f51b5905da182a0914c4b 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -2757,7 +2757,7 @@ enum Invisible { impl Element for EditorElement { type State = (); - fn layout( + fn request_layout( &mut self, _element_state: Option, cx: &mut gpui::WindowContext, diff --git a/crates/editor2/src/items.rs b/crates/editor2/src/items.rs index b10b891d0dbf1e3aa77e8c2a36d0a87add9a53d6..349b3140fe8b01aaf2f32e2f77cfbf5f12fa9379 100644 --- a/crates/editor2/src/items.rs +++ b/crates/editor2/src/items.rs @@ -1193,9 +1193,9 @@ impl CursorPosition { } impl Render for CursorPosition { - type Element = Div; + type Output = Div; - fn render(&mut self, _: &mut ViewContext) -> Self::Element { + fn render(&mut self, _: &mut ViewContext) -> Self::Output { div().when_some(self.position, |el, position| { let mut text = format!( "{}{FILE_ROW_COLUMN_DELIMITER}{}", diff --git a/crates/feedback2/src/deploy_feedback_button.rs b/crates/feedback2/src/deploy_feedback_button.rs index 926a5d791e0550dd27c354a5cc6db3530518f189..9a112c25db7688b8792bacd24ba23921cd5f06a8 100644 --- a/crates/feedback2/src/deploy_feedback_button.rs +++ b/crates/feedback2/src/deploy_feedback_button.rs @@ -17,9 +17,9 @@ impl DeployFeedbackButton { } impl Render for DeployFeedbackButton { - type Element = AnyElement; + type Output = AnyElement; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let is_open = self .workspace .upgrade() diff --git a/crates/feedback2/src/feedback_modal.rs b/crates/feedback2/src/feedback_modal.rs index d22d5d908b1855abf8776f12c7699096c53f9c3d..94e051f24741eff22ab2f059e972cb51543919d5 100644 --- a/crates/feedback2/src/feedback_modal.rs +++ b/crates/feedback2/src/feedback_modal.rs @@ -396,9 +396,9 @@ impl FeedbackModal { } impl Render for FeedbackModal { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { self.update_submission_state(cx); let submit_button_text = if self.awaiting_submission() { diff --git a/crates/file_finder2/src/file_finder.rs b/crates/file_finder2/src/file_finder.rs index 69deba6d2c0da701db779d7f5cc76e9fe5792448..4676d91f72385657e1673c52c18f31543fbd16f0 100644 --- a/crates/file_finder2/src/file_finder.rs +++ b/crates/file_finder2/src/file_finder.rs @@ -118,9 +118,9 @@ impl FocusableView for FileFinder { } } impl Render for FileFinder { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { v_stack().w(rems(34.)).child(self.picker.clone()) } } diff --git a/crates/go_to_line2/src/go_to_line.rs b/crates/go_to_line2/src/go_to_line.rs index 02fcd4771623494bd502b65ca81f900a06d34266..97118dad66fe5187b95a69b92df58ae21a83aaf9 100644 --- a/crates/go_to_line2/src/go_to_line.rs +++ b/crates/go_to_line2/src/go_to_line.rs @@ -153,9 +153,9 @@ impl GoToLine { } impl Render for GoToLine { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { div() .elevation_2(cx) .key_context("GoToLine") diff --git a/crates/gpui2/src/app/test_context.rs b/crates/gpui2/src/app/test_context.rs index c77ec29bdf288f1300210b4c2b82cedbf0aef3bc..3aa09d2189c73f7d80f3cc49ed8260624d4495c9 100644 --- a/crates/gpui2/src/app/test_context.rs +++ b/crates/gpui2/src/app/test_context.rs @@ -733,9 +733,9 @@ impl AnyWindowHandle { pub struct EmptyView {} impl Render for EmptyView { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut crate::ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut crate::ViewContext) -> Self::Output { div() } } diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index 4201123a10110f540258b8afc462aeab63b3fb1a..442b5b3ac5647dd18140fa025017a742f5875d6d 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -6,23 +6,61 @@ use derive_more::{Deref, DerefMut}; pub(crate) use smallvec::SmallVec; use std::{any::Any, fmt::Debug}; -pub trait Render: 'static + Sized { - type Element: Element + 'static; +/// Elements describe the contents of a window for a given frame. +/// Like HTML elements, elements form a tree and participate in layout. +/// In GPUI, elements are single-use objects that do not outlive a single frame. +/// Elements are associated with state. +/// If the element has an identifier, the element's state persists across frames in which the element appears. +/// If the element is anonymous, the state only persists across from layout request to paint in is referred to as "frame state". +/// A potential improvement would be to separate this temporary frame state from persistent element state at the type level, and request element state from the context with an id. /cc @as-cii\ +/// To render the contents of a window, we first walk over the tree of elements recursively via [request_layout], giving each an opportunity to register with the layout engine. +/// Then we compute the requested layout and use the computed bounds to paint the element tree recursively with [paint]. +/// You can implement this trait yourself for performance or other special situations, but you'll typically compose existing elements such as `Div`, `Img`, etc. +pub trait Element: 'static + IntoElement { + /// State that is carried from [request_layout] to [paint] for anonymous elements, and between frames for elements that have an id. + type State: 'static; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element; + /// Recursively register this element and all its descendants with the layout engine. + /// If this element has an id, you'll receive the [State] from the previous frame if an element with this id existed in that frame. + /// Return the [LayoutId] you requested from the engine and whatever state you want to carry over to [paint], and also the next frame if this element has an id. + fn request_layout( + &mut self, + state: Option, + cx: &mut WindowContext, + ) -> (LayoutId, Self::State); + + /// Recursively paint this element by populating the current frame's [Scene] with geometric primitives such as quads, sprites, paths, etc. + /// Receives the state from layout, and potentially the previous frame if this element has an id. + fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext); + + /// Convert into a dynamically-typed [AnyElement]. + /// Before an element can be painted, it must be converted into an [AnyElement]. + /// It's also useful in situations where you need to own an element, but don't care about its specific type. + fn into_any(self) -> AnyElement { + AnyElement::new(self) + } } +/// Implemented by any type that can be converted into an element. pub trait IntoElement: Sized { - type Element: Element + 'static; + /// The specific type of element into which the implementing type is converted. + type Element: Element; + /// The [ElementId] of self once converted into an [Element]. + /// If present, the resulting element's state will be carried across frames. fn element_id(&self) -> Option; + /// Convert self into a type that implements [Element]. fn into_element(self) -> Self::Element; + /// Convert self into a dynamically-typed [AnyElement]. fn into_any_element(self) -> AnyElement { self.into_element().into_any() } + /// Convert into an element, then draw in the current window at the given origin. + /// The provided available space is provided to the layout engine to determine the size of the root element. + /// Once the element is drawn, its associated element staet is yielded to the given callback. fn draw_and_update_state( self, origin: Point, @@ -54,6 +92,7 @@ pub trait IntoElement: Sized { } } + /// Convert self to another type by calling the given closure. Useful in rendering code. fn map(self, f: impl FnOnce(Self) -> U) -> U where Self: Sized, @@ -62,6 +101,7 @@ pub trait IntoElement: Sized { f(self) } + /// Conditionally chain onto self with the given closure. Useful in rendering code. fn when(self, condition: bool, then: impl FnOnce(Self) -> Self) -> Self where Self: Sized, @@ -69,6 +109,8 @@ pub trait IntoElement: Sized { self.map(|this| if condition { then(this) } else { this }) } + /// Conditionally chain onto self with the given closure if the given option is Some. + /// The contents of the option are provided to the closure. fn when_some(self, option: Option, then: impl FnOnce(Self, T) -> Self) -> Self where Self: Sized, @@ -83,35 +125,46 @@ pub trait IntoElement: Sized { } } -pub trait Element: 'static + IntoElement { - type State: 'static; +pub trait Render: 'static + Sized { + type Output: IntoElement; - fn layout( - &mut self, - state: Option, - cx: &mut WindowContext, - ) -> (LayoutId, Self::State); + fn render(&mut self, cx: &mut ViewContext) -> Self::Output; +} - fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext); +pub trait RenderOnce: 'static { + type Output: IntoElement; - fn into_any(self) -> AnyElement { - AnyElement::new(self) - } + fn render(self, cx: &mut WindowContext) -> Self::Output; } -pub trait RenderOnce: 'static { - type Rendered: IntoElement; +pub trait ParentElement { + fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]>; + + fn child(mut self, child: impl IntoElement) -> Self + where + Self: Sized, + { + self.children_mut().push(child.into_element().into_any()); + self + } - fn render(self, cx: &mut WindowContext) -> Self::Rendered; + fn children(mut self, children: impl IntoIterator) -> Self + where + Self: Sized, + { + self.children_mut() + .extend(children.into_iter().map(|child| child.into_any_element())); + self + } } pub struct Component { component: Option, } -pub struct CompositeElementState { - rendered_element: Option<::Element>, - rendered_element_state: Option<<::Element as Element>::State>, +pub struct ComponentState { + rendered_element: Option<::Element>, + rendered_element_state: Option<<::Element as Element>::State>, } impl Component { @@ -123,9 +176,9 @@ impl Component { } impl Element for Component { - type State = CompositeElementState; + type State = ComponentState; - fn layout( + fn request_layout( &mut self, state: Option, cx: &mut WindowContext, @@ -133,16 +186,16 @@ impl Element for Component { let mut element = self.component.take().unwrap().render(cx).into_element(); if let Some(element_id) = element.element_id() { let layout_id = - cx.with_element_state(element_id, |state, cx| element.layout(state, cx)); - let state = CompositeElementState { + cx.with_element_state(element_id, |state, cx| element.request_layout(state, cx)); + let state = ComponentState { rendered_element: Some(element), rendered_element_state: None, }; (layout_id, state) } else { let (layout_id, state) = - element.layout(state.and_then(|s| s.rendered_element_state), cx); - let state = CompositeElementState { + element.request_layout(state.and_then(|s| s.rendered_element_state), cx); + let state = ComponentState { rendered_element: Some(element), rendered_element_state: Some(state), }; @@ -183,27 +236,6 @@ impl IntoElement for Component { #[derive(Deref, DerefMut, Default, Clone, Debug, Eq, PartialEq, Hash)] pub struct GlobalElementId(SmallVec<[ElementId; 32]>); -pub trait ParentElement { - fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]>; - - fn child(mut self, child: impl IntoElement) -> Self - where - Self: Sized, - { - self.children_mut().push(child.into_element().into_any()); - self - } - - fn children(mut self, children: impl IntoIterator) -> Self - where - Self: Sized, - { - self.children_mut() - .extend(children.into_iter().map(|child| child.into_any_element())); - self - } -} - trait ElementObject { fn element_id(&self) -> Option; @@ -262,11 +294,14 @@ impl DrawableElement { let (layout_id, frame_state) = if let Some(id) = self.element.as_ref().unwrap().element_id() { let layout_id = cx.with_element_state(id, |element_state, cx| { - self.element.as_mut().unwrap().layout(element_state, cx) + self.element + .as_mut() + .unwrap() + .request_layout(element_state, cx) }); (layout_id, None) } else { - let (layout_id, frame_state) = self.element.as_mut().unwrap().layout(None, cx); + let (layout_id, frame_state) = self.element.as_mut().unwrap().request_layout(None, cx); (layout_id, Some(frame_state)) }; @@ -454,7 +489,7 @@ impl AnyElement { impl Element for AnyElement { type State = (); - fn layout( + fn request_layout( &mut self, _: Option, cx: &mut WindowContext, @@ -502,7 +537,7 @@ impl IntoElement for () { impl Element for () { type State = (); - fn layout( + fn request_layout( &mut self, _state: Option, cx: &mut WindowContext, diff --git a/crates/gpui2/src/elements/canvas.rs b/crates/gpui2/src/elements/canvas.rs index d04c65811fffeec45bc24b72c3d08a401c48eb52..767417ae40100a7ef3ff8ea6fecea0a4f9eca53f 100644 --- a/crates/gpui2/src/elements/canvas.rs +++ b/crates/gpui2/src/elements/canvas.rs @@ -29,7 +29,7 @@ impl IntoElement for Canvas { impl Element for Canvas { type State = Style; - fn layout( + fn request_layout( &mut self, _: Option, cx: &mut WindowContext, diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index fc129b4f1df6d36e9d480b9f2da7e1c5a0ac38bf..512cc56bb204530e2914493f509a4258145f1ba5 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -768,7 +768,7 @@ impl ParentElement for Div { impl Element for Div { type State = DivState; - fn layout( + fn request_layout( &mut self, element_state: Option, cx: &mut WindowContext, @@ -1818,12 +1818,12 @@ where { type State = E::State; - fn layout( + fn request_layout( &mut self, state: Option, cx: &mut WindowContext, ) -> (LayoutId, Self::State) { - self.element.layout(state, cx) + self.element.request_layout(state, cx) } fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { @@ -1892,12 +1892,12 @@ where { type State = E::State; - fn layout( + fn request_layout( &mut self, state: Option, cx: &mut WindowContext, ) -> (LayoutId, Self::State) { - self.element.layout(state, cx) + self.element.request_layout(state, cx) } fn paint(&mut self, bounds: Bounds, state: &mut Self::State, cx: &mut WindowContext) { diff --git a/crates/gpui2/src/elements/img.rs b/crates/gpui2/src/elements/img.rs index ab7b8d914094b677b647123074883611665d263b..650b5b666bc821e15873c53f2cdc56c0546b6a20 100644 --- a/crates/gpui2/src/elements/img.rs +++ b/crates/gpui2/src/elements/img.rs @@ -71,7 +71,7 @@ impl Img { impl Element for Img { type State = InteractiveElementState; - fn layout( + fn request_layout( &mut self, element_state: Option, cx: &mut WindowContext, diff --git a/crates/gpui2/src/elements/list.rs b/crates/gpui2/src/elements/list.rs index a0467aaaa3c92acd1b045a69bae3fb9658eb0f01..364b610eee761f8cd076c39aa1206c6d97016b0b 100644 --- a/crates/gpui2/src/elements/list.rs +++ b/crates/gpui2/src/elements/list.rs @@ -302,7 +302,7 @@ pub struct ListOffset { impl Element for List { type State = (); - fn layout( + fn request_layout( &mut self, _state: Option, cx: &mut crate::WindowContext, diff --git a/crates/gpui2/src/elements/overlay.rs b/crates/gpui2/src/elements/overlay.rs index 5b72019f177f899f886a375fe4468bcf403c336c..b5d8b53c7f613f92b966cd0afa025d636394b12e 100644 --- a/crates/gpui2/src/elements/overlay.rs +++ b/crates/gpui2/src/elements/overlay.rs @@ -60,7 +60,7 @@ impl ParentElement for Overlay { impl Element for Overlay { type State = OverlayState; - fn layout( + fn request_layout( &mut self, _: Option, cx: &mut WindowContext, diff --git a/crates/gpui2/src/elements/svg.rs b/crates/gpui2/src/elements/svg.rs index 9ca9baf470e6c3bdeec2fafb1806d34430c44aea..5ea7f9bd7825a0142fd38f07a8223ff3a973e9dc 100644 --- a/crates/gpui2/src/elements/svg.rs +++ b/crates/gpui2/src/elements/svg.rs @@ -26,7 +26,7 @@ impl Svg { impl Element for Svg { type State = InteractiveElementState; - fn layout( + fn request_layout( &mut self, element_state: Option, cx: &mut WindowContext, diff --git a/crates/gpui2/src/elements/text.rs b/crates/gpui2/src/elements/text.rs index 7716d81536117a6213133db7cdf8377f94f1f647..91ec8045ad1c91c6e3f8ec7f722eaed62d5cd8bb 100644 --- a/crates/gpui2/src/elements/text.rs +++ b/crates/gpui2/src/elements/text.rs @@ -12,7 +12,7 @@ use util::ResultExt; impl Element for &'static str { type State = TextState; - fn layout( + fn request_layout( &mut self, _: Option, cx: &mut WindowContext, @@ -42,7 +42,7 @@ impl IntoElement for &'static str { impl Element for SharedString { type State = TextState; - fn layout( + fn request_layout( &mut self, _: Option, cx: &mut WindowContext, @@ -118,7 +118,7 @@ impl StyledText { impl Element for StyledText { type State = TextState; - fn layout( + fn request_layout( &mut self, _: Option, cx: &mut WindowContext, @@ -331,7 +331,7 @@ impl InteractiveText { impl Element for InteractiveText { type State = InteractiveTextState; - fn layout( + fn request_layout( &mut self, state: Option, cx: &mut WindowContext, @@ -340,14 +340,14 @@ impl Element for InteractiveText { mouse_down_index, .. }) = state { - let (layout_id, text_state) = self.text.layout(None, cx); + let (layout_id, text_state) = self.text.request_layout(None, cx); let element_state = InteractiveTextState { text_state, mouse_down_index, }; (layout_id, element_state) } else { - let (layout_id, text_state) = self.text.layout(None, cx); + let (layout_id, text_state) = self.text.request_layout(None, cx); let element_state = InteractiveTextState { text_state, mouse_down_index: Rc::default(), diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index e38a37f90d20c8612069f13daaf94ccb06c1dc89..390a10021e856c70cd2099f50212636171316f78 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -116,7 +116,7 @@ pub struct UniformListState { impl Element for UniformList { type State = UniformListState; - fn layout( + fn request_layout( &mut self, state: Option, cx: &mut WindowContext, diff --git a/crates/gpui2/src/interactive.rs b/crates/gpui2/src/interactive.rs index 58ee849aad4a6d665c6ec14176f72eb457c9a82e..7a4c3d013fc89b75cf903b2b52176aef73f093db 100644 --- a/crates/gpui2/src/interactive.rs +++ b/crates/gpui2/src/interactive.rs @@ -205,9 +205,9 @@ impl ExternalPaths { } impl Render for ExternalPaths { - type Element = Div; + type Output = Div; - fn render(&mut self, _: &mut ViewContext) -> Self::Element { + fn render(&mut self, _: &mut ViewContext) -> Self::Output { div() // Intentionally left empty because the platform will render icons for the dragged files } } @@ -305,9 +305,9 @@ mod test { actions!(test, [TestAction]); impl Render for TestView { - type Element = Stateful
; + type Output = Stateful
; - fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Output { div().id("testview").child( div() .key_context("parent") diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index 1b4c2b6346fb56320737ab74a8057da589aba354..afa08f92135b2c54527e0fe7c9637ef757de1be9 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -81,12 +81,12 @@ impl View { impl Element for View { type State = Option; - fn layout( + fn request_layout( &mut self, _state: Option, cx: &mut WindowContext, ) -> (LayoutId, Self::State) { - let mut element = self.update(cx, |view, cx| view.render(cx).into_any()); + let mut element = self.update(cx, |view, cx| view.render(cx).into_any_element()); let layout_id = element.layout(cx); (layout_id, Some(element)) } @@ -229,7 +229,7 @@ impl From> for AnyView { impl Element for AnyView { type State = Option; - fn layout( + fn request_layout( &mut self, _state: Option, cx: &mut WindowContext, @@ -317,22 +317,22 @@ where T: 'static + FnMut(&mut WindowContext) -> E, E: 'static + Send + Element, { - type Element = E; + type Output = E; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { (self)(cx) } } mod any_view { - use crate::{AnyElement, AnyView, Element, LayoutId, Render, WindowContext}; + use crate::{AnyElement, AnyView, IntoElement, LayoutId, Render, WindowContext}; pub(crate) fn layout( view: &AnyView, cx: &mut WindowContext, ) -> (LayoutId, AnyElement) { let view = view.clone().downcast::().unwrap(); - let mut element = view.update(cx, |view, cx| view.render(cx).into_any()); + let mut element = view.update(cx, |view, cx| view.render(cx).into_any_element()); let layout_id = element.layout(cx); (layout_id, element) } diff --git a/crates/gpui2_macros/src/derive_render.rs b/crates/gpui2_macros/src/derive_render.rs index 3983a572f06ae66bbff7686851bb369840213309..2695d4a7c56d0fa9f969b34fdafa1dfbce9a16c8 100644 --- a/crates/gpui2_macros/src/derive_render.rs +++ b/crates/gpui2_macros/src/derive_render.rs @@ -11,9 +11,9 @@ pub fn derive_render(input: TokenStream) -> TokenStream { impl #impl_generics gpui::Render for #type_name #type_generics #where_clause { - type Element = (); + type Output = (); - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { () } } diff --git a/crates/language_selector2/src/active_buffer_language.rs b/crates/language_selector2/src/active_buffer_language.rs index 48224198a2e13a1651102a7e26253b0a7b6568bb..21f7bf233d277db0cca0fb71c4d000e6489305b1 100644 --- a/crates/language_selector2/src/active_buffer_language.rs +++ b/crates/language_selector2/src/active_buffer_language.rs @@ -38,7 +38,7 @@ impl ActiveBufferLanguage { } impl Render for ActiveBufferLanguage { - type Element = Div; + type Output = Div; fn render(&mut self, cx: &mut ViewContext) -> Div { div().when_some(self.active_language.as_ref(), |el, active_language| { diff --git a/crates/language_selector2/src/language_selector.rs b/crates/language_selector2/src/language_selector.rs index 3da8649c6e006fcc56a0255ef96babf76121b881..16c661b6fb45659130d8bc146e1812e718b0290d 100644 --- a/crates/language_selector2/src/language_selector.rs +++ b/crates/language_selector2/src/language_selector.rs @@ -67,9 +67,9 @@ impl LanguageSelector { } impl Render for LanguageSelector { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { v_stack().w(rems(34.)).child(self.picker.clone()) } } diff --git a/crates/language_tools2/src/lsp_log.rs b/crates/language_tools2/src/lsp_log.rs index 310726e4a525c0cbd77eb0ad7092e7f86fca7a27..00f1e86e5f1580ac3ab9dbcece2bcabb51e8101f 100644 --- a/crates/language_tools2/src/lsp_log.rs +++ b/crates/language_tools2/src/lsp_log.rs @@ -595,9 +595,9 @@ fn log_contents(lines: &VecDeque) -> String { } impl Render for LspLogView { - type Element = EditorElement; + type Output = EditorElement; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { self.editor.update(cx, |editor, cx| editor.render(cx)) } } @@ -709,9 +709,9 @@ impl ToolbarItemView for LspLogToolbarItemView { } impl Render for LspLogToolbarItemView { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let Some(log_view) = self.log_view.clone() else { return div(); }; diff --git a/crates/language_tools2/src/syntax_tree_view.rs b/crates/language_tools2/src/syntax_tree_view.rs index e4ee4b0cfb6a7532670beb376262afeb6ca5be44..1794b45337a2274337dbd901143be96c67912f9b 100644 --- a/crates/language_tools2/src/syntax_tree_view.rs +++ b/crates/language_tools2/src/syntax_tree_view.rs @@ -305,9 +305,9 @@ impl SyntaxTreeView { } impl Render for SyntaxTreeView { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Self::Element { + fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Self::Output { let settings = ThemeSettings::get_global(cx); let line_height = cx .text_style() @@ -507,7 +507,7 @@ fn format_node_range(node: Node) -> String { } impl Render for SyntaxTreeToolbarItemView { - type Element = PopoverMenu; + type Output = PopoverMenu; fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> PopoverMenu { self.render_menu(cx) diff --git a/crates/outline2/src/outline.rs b/crates/outline2/src/outline.rs index ba67f33b25de382bdf0b4c30ec8bbf7d635c44b3..2f29534b6ed066f898dc0a9a101be339f0e0c2d7 100644 --- a/crates/outline2/src/outline.rs +++ b/crates/outline2/src/outline.rs @@ -57,9 +57,9 @@ impl EventEmitter for OutlineView {} impl ModalView for OutlineView {} impl Render for OutlineView { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { v_stack().w(rems(34.)).child(self.picker.clone()) } } diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 3abdf953b3469e2e932d2a5f441c90caa44d8f3a..6632c13ddfcb6a2e870dadea85fcef24affb6ed1 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -228,9 +228,9 @@ impl EventEmitter for Picker {} impl ModalView for Picker {} impl Render for Picker { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let picker_editor = h_stack() .overflow_hidden() .flex_none() diff --git a/crates/project_panel2/src/project_panel.rs b/crates/project_panel2/src/project_panel.rs index 21a114c43c925dacdcfbe86da5b0af3f11960522..c0dfe995f638f0e0105d0e60d4986c8ecfbaf74b 100644 --- a/crates/project_panel2/src/project_panel.rs +++ b/crates/project_panel2/src/project_panel.rs @@ -1480,9 +1480,9 @@ impl ProjectPanel { } impl Render for ProjectPanel { - type Element = Focusable>; + type Output = Focusable>; - fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Output { let has_worktree = self.visible_entries.len() != 0; if has_worktree { @@ -1548,9 +1548,9 @@ impl Render for ProjectPanel { } impl Render for DraggedProjectEntryView { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let settings = ProjectPanelSettings::get_global(cx); let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone(); h_stack() diff --git a/crates/quick_action_bar2/src/quick_action_bar.rs b/crates/quick_action_bar2/src/quick_action_bar.rs index 3eba0e60ec20672b0b759d5e041745eb6c46e162..686804e9d9bb03c19ae5bf20436760e2bf68d806 100644 --- a/crates/quick_action_bar2/src/quick_action_bar.rs +++ b/crates/quick_action_bar2/src/quick_action_bar.rs @@ -36,9 +36,9 @@ impl QuickActionBar { } impl Render for QuickActionBar { - type Element = Stateful
; + type Output = Stateful
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let Some(editor) = self.active_editor() else { return div().id("empty quick action bar"); }; @@ -138,9 +138,9 @@ impl QuickActionBarButton { } impl RenderOnce for QuickActionBarButton { - type Rendered = IconButton; + type Output = IconButton; - fn render(self, _: &mut WindowContext) -> Self::Rendered { + fn render(self, _: &mut WindowContext) -> Self::Output { let tooltip = self.tooltip.clone(); let action = self.action.boxed_clone(); diff --git a/crates/recent_projects2/src/highlighted_workspace_location.rs b/crates/recent_projects2/src/highlighted_workspace_location.rs index a4057d2f4bdd090ca46a4f4242bc5b1abdb8e157..2df4409a5fdc20b15ef8e14ccd3b56d082fd1745 100644 --- a/crates/recent_projects2/src/highlighted_workspace_location.rs +++ b/crates/recent_projects2/src/highlighted_workspace_location.rs @@ -43,9 +43,9 @@ impl HighlightedText { } impl RenderOnce for HighlightedText { - type Rendered = HighlightedLabel; + type Output = HighlightedLabel; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { HighlightedLabel::new(self.text, self.highlight_positions) } } diff --git a/crates/recent_projects2/src/recent_projects.rs b/crates/recent_projects2/src/recent_projects.rs index 2d6f4bf0e3160a214bc7a25a24a10d94129c694f..6b62d185ed116e9d46881316d21fee90544123e4 100644 --- a/crates/recent_projects2/src/recent_projects.rs +++ b/crates/recent_projects2/src/recent_projects.rs @@ -103,9 +103,9 @@ impl FocusableView for RecentProjects { } impl Render for RecentProjects { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { v_stack() .w(rems(self.rem_width)) .child(self.picker.clone()) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index 4972908e0d4796fa60c14940158b20cedc6c24f8..a5522cec89c27543462fcd000a3d21379ac7f84d 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -101,9 +101,9 @@ impl BufferSearchBar { impl EventEmitter for BufferSearchBar {} impl EventEmitter for BufferSearchBar {} impl Render for BufferSearchBar { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { if self.dismissed { return div(); } diff --git a/crates/search2/src/project_search.rs b/crates/search2/src/project_search.rs index 9a654c9bf4d9d62947f756457599c2ea4e59af5d..167299ba2d7b2661a94a1b7102ba536d8dee72fe 100644 --- a/crates/search2/src/project_search.rs +++ b/crates/search2/src/project_search.rs @@ -279,9 +279,9 @@ pub enum ViewEvent { impl EventEmitter for ProjectSearchView {} impl Render for ProjectSearchView { - type Element = AnyElement; + type Output = AnyElement; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { if self.has_matches() { div() .flex_1() @@ -1494,9 +1494,9 @@ impl ProjectSearchBar { } impl Render for ProjectSearchBar { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let Some(search) = self.active_project_search.clone() else { return div(); }; diff --git a/crates/story/src/story.rs b/crates/story/src/story.rs index 3419af95b099807609b52b40b9775b17457975a0..1a3e84c0d919d91caac5b0d6bc90654510237714 100644 --- a/crates/story/src/story.rs +++ b/crates/story/src/story.rs @@ -74,9 +74,9 @@ impl ParentElement for StoryContainer { } impl RenderOnce for StoryContainer { - type Rendered = Stateful
; + type Output = Stateful
; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { div() .size_full() .flex() @@ -294,9 +294,9 @@ impl StoryItem { } impl RenderOnce for StoryItem { - type Rendered = Div; + type Output = Div; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { div() .my_2() .flex() @@ -358,9 +358,9 @@ impl StorySection { } impl RenderOnce for StorySection { - type Rendered = Div; + type Output = Div; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { let children: SmallVec<[AnyElement; 2]> = SmallVec::from_iter(Itertools::intersperse_with( self.children.into_iter(), || Story::divider().into_any_element(), diff --git a/crates/storybook2/src/stories/auto_height_editor.rs b/crates/storybook2/src/stories/auto_height_editor.rs index 2f3089a4e6e766057559376f284e570b19701c5c..d4fda251d73d1504ad65fce93b10771136bc35d2 100644 --- a/crates/storybook2/src/stories/auto_height_editor.rs +++ b/crates/storybook2/src/stories/auto_height_editor.rs @@ -22,9 +22,9 @@ impl AutoHeightEditorStory { } impl Render for AutoHeightEditorStory { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { div() .size_full() .bg(white()) diff --git a/crates/storybook2/src/stories/cursor.rs b/crates/storybook2/src/stories/cursor.rs index 7d4cf8145a034906bb87bb944ae926fff5ab9f3a..af8d7440a0d371bc0c7f0c9017dc7d1e81641244 100644 --- a/crates/storybook2/src/stories/cursor.rs +++ b/crates/storybook2/src/stories/cursor.rs @@ -5,9 +5,9 @@ use ui::prelude::*; pub struct CursorStory; impl Render for CursorStory { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { let all_cursors: [(&str, Box) -> Stateful
>); 19] = [ ( "cursor_default", diff --git a/crates/storybook2/src/stories/focus.rs b/crates/storybook2/src/stories/focus.rs index a3a8845947ddd1f78e57991aa701489087cc2033..8ee10b65700dca6ac9e5d3be557c36dc1cf255db 100644 --- a/crates/storybook2/src/stories/focus.rs +++ b/crates/storybook2/src/stories/focus.rs @@ -57,9 +57,9 @@ impl FocusStory { } impl Render for FocusStory { - type Element = Focusable>; + type Output = Focusable>; - fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Output { let theme = cx.theme(); let color_1 = theme.status().created; let color_2 = theme.status().modified; diff --git a/crates/storybook2/src/stories/kitchen_sink.rs b/crates/storybook2/src/stories/kitchen_sink.rs index 271285cc2f56263593f2ed0a7691bd5ca649b5e3..d6598279909ab291582f49828e722db84522ab8a 100644 --- a/crates/storybook2/src/stories/kitchen_sink.rs +++ b/crates/storybook2/src/stories/kitchen_sink.rs @@ -14,9 +14,9 @@ impl KitchenSinkStory { } impl Render for KitchenSinkStory { - type Element = Stateful
; + type Output = Stateful
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let component_stories = ComponentStory::iter() .map(|selector| selector.story(cx)) .collect::>(); diff --git a/crates/storybook2/src/stories/overflow_scroll.rs b/crates/storybook2/src/stories/overflow_scroll.rs index 631b851304c3f0a23fd0333dec720306a270d903..6adc6576accba00f74e2032a61c485b3870b89d5 100644 --- a/crates/storybook2/src/stories/overflow_scroll.rs +++ b/crates/storybook2/src/stories/overflow_scroll.rs @@ -6,9 +6,9 @@ use ui::prelude::*; pub struct OverflowScrollStory; impl Render for OverflowScrollStory { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { Story::container() .child(Story::title("Overflow Scroll")) .child(Story::label("`overflow_x_scroll`")) diff --git a/crates/storybook2/src/stories/picker.rs b/crates/storybook2/src/stories/picker.rs index edaaaa70bd1e8522785ded0c0771963505dbe2fd..85985c5ae34c83dfc1d17443d761321eb0b758f5 100644 --- a/crates/storybook2/src/stories/picker.rs +++ b/crates/storybook2/src/stories/picker.rs @@ -202,9 +202,9 @@ impl PickerStory { } impl Render for PickerStory { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Output { div() .bg(cx.theme().styles.colors.background) .size_full() diff --git a/crates/storybook2/src/stories/scroll.rs b/crates/storybook2/src/stories/scroll.rs index 300aae1144b1c2756c10b7d5a0a697c5448d8784..8d8543304d421462766e610ad869bc1f43cb45ec 100644 --- a/crates/storybook2/src/stories/scroll.rs +++ b/crates/storybook2/src/stories/scroll.rs @@ -11,9 +11,9 @@ impl ScrollStory { } impl Render for ScrollStory { - type Element = Stateful
; + type Output = Stateful
; - fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Output { let theme = cx.theme(); let color_1 = theme.status().created; let color_2 = theme.status().modified; diff --git a/crates/storybook2/src/stories/text.rs b/crates/storybook2/src/stories/text.rs index 99d722988d086d932c6bd734992720273f02e2e3..b044f7ce9af5f10338012872cf66f2687e316ad7 100644 --- a/crates/storybook2/src/stories/text.rs +++ b/crates/storybook2/src/stories/text.rs @@ -14,9 +14,9 @@ impl TextStory { } impl Render for TextStory { - type Element = Component; + type Output = Component; - fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut gpui::ViewContext) -> Self::Output { StoryContainer::new("Text Story", "crates/storybook2/src/stories/text.rs") .children( vec![ diff --git a/crates/storybook2/src/stories/viewport_units.rs b/crates/storybook2/src/stories/viewport_units.rs index 8a95a6b66c30da05df7458988bf8362a25480d74..746f385ab5ca5f3c9c5082a8e1a9bcf867eb4d18 100644 --- a/crates/storybook2/src/stories/viewport_units.rs +++ b/crates/storybook2/src/stories/viewport_units.rs @@ -6,9 +6,9 @@ use ui::prelude::*; pub struct ViewportUnitsStory; impl Render for ViewportUnitsStory { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { Story::container().child( div() .flex() diff --git a/crates/storybook2/src/stories/z_index.rs b/crates/storybook2/src/stories/z_index.rs index 9579b8c7fcf891c4fcda7ef691d37f583b2bd77a..1f7141fbfd581eebe51b93bf7b4310c88faf76aa 100644 --- a/crates/storybook2/src/stories/z_index.rs +++ b/crates/storybook2/src/stories/z_index.rs @@ -7,9 +7,9 @@ use ui::prelude::*; pub struct ZIndexStory; impl Render for ZIndexStory { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { Story::container().child(Story::title("z-index")).child( div() .flex() @@ -82,9 +82,9 @@ struct ZIndexExample { } impl RenderOnce for ZIndexExample { - type Rendered = Div; + type Output = Div; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { div() .relative() .size_full() diff --git a/crates/storybook2/src/storybook2.rs b/crates/storybook2/src/storybook2.rs index 523e93cf5267e310d691ee4ca19db1cc67cfbb4b..4fdf65f67305e69fdca7c20407ca6eb04af91d45 100644 --- a/crates/storybook2/src/storybook2.rs +++ b/crates/storybook2/src/storybook2.rs @@ -113,9 +113,9 @@ impl StoryWrapper { } impl Render for StoryWrapper { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { div() .flex() .flex_col() diff --git a/crates/terminal_view2/src/terminal_element.rs b/crates/terminal_view2/src/terminal_element.rs index cb46f742f66135c2148fd6073ef010889bc1d8cd..8be10f9469fd8a2fb716f469c39bae841500920e 100644 --- a/crates/terminal_view2/src/terminal_element.rs +++ b/crates/terminal_view2/src/terminal_element.rs @@ -750,7 +750,7 @@ impl TerminalElement { impl Element for TerminalElement { type State = InteractiveElementState; - fn layout( + fn request_layout( &mut self, element_state: Option, cx: &mut WindowContext<'_>, diff --git a/crates/terminal_view2/src/terminal_panel.rs b/crates/terminal_view2/src/terminal_panel.rs index dd0c7d39995e539b542492b4b01ff52d60d7e82d..746c2480c03f498374d80aff776553d0990f938e 100644 --- a/crates/terminal_view2/src/terminal_panel.rs +++ b/crates/terminal_view2/src/terminal_panel.rs @@ -329,9 +329,9 @@ impl TerminalPanel { impl EventEmitter for TerminalPanel {} impl Render for TerminalPanel { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { div().size_full().child(self.pane.clone()) } } diff --git a/crates/terminal_view2/src/terminal_view.rs b/crates/terminal_view2/src/terminal_view.rs index 6d18d6f8f95f3b1bb201217d5379a609e593ee00..231de1444a76bbd919cd6c71d00c633ffc6fcdbb 100644 --- a/crates/terminal_view2/src/terminal_view.rs +++ b/crates/terminal_view2/src/terminal_view.rs @@ -617,9 +617,9 @@ impl TerminalView { } impl Render for TerminalView { - type Element = Focusable
; + type Output = Focusable
; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { let terminal_handle = self.terminal.clone(); let focused = self.focus_handle.is_focused(cx); diff --git a/crates/theme_selector2/src/theme_selector.rs b/crates/theme_selector2/src/theme_selector.rs index ae067ce87cfe037f8b75f0ca2f8edabfdb2f3bf7..240742025eac475cffef66db69663782aab90565 100644 --- a/crates/theme_selector2/src/theme_selector.rs +++ b/crates/theme_selector2/src/theme_selector.rs @@ -67,9 +67,9 @@ impl FocusableView for ThemeSelector { } impl Render for ThemeSelector { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { v_stack().w(rems(34.)).child(self.picker.clone()) } } diff --git a/crates/ui2/src/components/avatar.rs b/crates/ui2/src/components/avatar.rs index 793872cd8abf7ecdb86911d2d7eb373d36cf4fab..257e46989b6faf0b615d668aa3d18e3ede8dc83d 100644 --- a/crates/ui2/src/components/avatar.rs +++ b/crates/ui2/src/components/avatar.rs @@ -16,9 +16,9 @@ pub struct Avatar { } impl RenderOnce for Avatar { - type Rendered = Div; + type Output = Div; - fn render(mut self, cx: &mut WindowContext) -> Self::Rendered { + fn render(mut self, cx: &mut WindowContext) -> Self::Output { if self.image.style().corner_radii.top_left.is_none() { self = self.shape(Shape::Circle); } diff --git a/crates/ui2/src/components/button/button.rs b/crates/ui2/src/components/button/button.rs index bc5d03d639ffe4ba4fb1d5c8c6886268b7660159..2ad12919fba8a0daf31b3c7d54d0032ee5777e1b 100644 --- a/crates/ui2/src/components/button/button.rs +++ b/crates/ui2/src/components/button/button.rs @@ -136,9 +136,9 @@ impl ButtonCommon for Button { } impl RenderOnce for Button { - type Rendered = ButtonLike; + type Output = ButtonLike; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { let is_disabled = self.base.disabled; let is_selected = self.base.selected; diff --git a/crates/ui2/src/components/button/button_icon.rs b/crates/ui2/src/components/button/button_icon.rs index 3b2c703938bf0564179a1ce3b9305933b55b0810..a82aa14e6ed249d6615c01d6d4567510afdf9d9f 100644 --- a/crates/ui2/src/components/button/button_icon.rs +++ b/crates/ui2/src/components/button/button_icon.rs @@ -63,9 +63,9 @@ impl Selectable for ButtonIcon { } impl RenderOnce for ButtonIcon { - type Rendered = IconElement; + type Output = IconElement; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { let icon = self .selected_icon .filter(|_| self.selected) diff --git a/crates/ui2/src/components/button/button_like.rs b/crates/ui2/src/components/button/button_like.rs index 13d4f360f21b03d029e42ee2893f8742dfd0091d..0f304ae15d970172825a0ae7f487da7b3ac555b1 100644 --- a/crates/ui2/src/components/button/button_like.rs +++ b/crates/ui2/src/components/button/button_like.rs @@ -363,9 +363,9 @@ impl ParentElement for ButtonLike { } impl RenderOnce for ButtonLike { - type Rendered = Stateful
; + type Output = Stateful
; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { self.base .h_flex() .id(self.id.clone()) diff --git a/crates/ui2/src/components/button/icon_button.rs b/crates/ui2/src/components/button/icon_button.rs index 3a53bb6cb0178ffb3046d385debd3c0ecb35d23d..9dcb0c04d49f671331a2f0f8d0e1ed7620d98626 100644 --- a/crates/ui2/src/components/button/icon_button.rs +++ b/crates/ui2/src/components/button/icon_button.rs @@ -106,9 +106,9 @@ impl VisibleOnHover for IconButton { } impl RenderOnce for IconButton { - type Rendered = ButtonLike; + type Output = ButtonLike; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { let is_disabled = self.base.disabled; let is_selected = self.base.selected; diff --git a/crates/ui2/src/components/button/toggle_button.rs b/crates/ui2/src/components/button/toggle_button.rs index 4a6ecdeb2fc6cea673e8f695a35e0b7ec7cfa517..7ac642011f97299dabbd483abf0ed49f41a02ead 100644 --- a/crates/ui2/src/components/button/toggle_button.rs +++ b/crates/ui2/src/components/button/toggle_button.rs @@ -99,9 +99,9 @@ impl ButtonCommon for ToggleButton { } impl RenderOnce for ToggleButton { - type Rendered = ButtonLike; + type Output = ButtonLike; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { let is_disabled = self.base.disabled; let is_selected = self.base.selected; diff --git a/crates/ui2/src/components/checkbox.rs b/crates/ui2/src/components/checkbox.rs index 51e38a38f4fbceca10ceec6af0ed475dd5b6eb86..fd92e9694608da5e273f32f262e55bd7b771b220 100644 --- a/crates/ui2/src/components/checkbox.rs +++ b/crates/ui2/src/components/checkbox.rs @@ -19,9 +19,9 @@ pub struct Checkbox { } impl RenderOnce for Checkbox { - type Rendered = gpui::Stateful
; + type Output = gpui::Stateful
; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { let group_id = format!("checkbox_group_{:?}", self.id); let icon = match self.checked { diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 6df6a290964b00f3ebdf455afb2feca594eee33e..3ea5e9bc5fd0db03b138345fedcbdb3e2943f3d9 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -232,9 +232,9 @@ impl ContextMenuItem { } impl Render for ContextMenu { - type Element = Div; + type Output = Div; - fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, cx: &mut ViewContext) -> Self::Output { div().elevation_2(cx).flex().flex_row().child( v_stack() .min_w(px(200.)) diff --git a/crates/ui2/src/components/disclosure.rs b/crates/ui2/src/components/disclosure.rs index 729023986d2f1bda905c17850d2e209bc982071b..663fba30ca873536319f08680dcacaf9ba0bd7e7 100644 --- a/crates/ui2/src/components/disclosure.rs +++ b/crates/ui2/src/components/disclosure.rs @@ -28,9 +28,9 @@ impl Disclosure { } impl RenderOnce for Disclosure { - type Rendered = IconButton; + type Output = IconButton; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { IconButton::new( self.id, match self.is_open { diff --git a/crates/ui2/src/components/divider.rs b/crates/ui2/src/components/divider.rs index 20744d6c48e94ea80312acd9bf3ef63b7a30496f..dd30ce0ec57e60f78d37b764656c8507ca7bb242 100644 --- a/crates/ui2/src/components/divider.rs +++ b/crates/ui2/src/components/divider.rs @@ -31,9 +31,9 @@ pub struct Divider { } impl RenderOnce for Divider { - type Rendered = Div; + type Output = Div; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { div() .map(|this| match self.direction { DividerDirection::Horizontal => { diff --git a/crates/ui2/src/components/icon.rs b/crates/ui2/src/components/icon.rs index a168f97a50f047fbf8d338a779c46f6cfef57639..b0eed862505f990d05e3c74c8e471e1f9e606c95 100644 --- a/crates/ui2/src/components/icon.rs +++ b/crates/ui2/src/components/icon.rs @@ -196,9 +196,9 @@ pub struct IconElement { } impl RenderOnce for IconElement { - type Rendered = Svg; + type Output = Svg; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { svg() .size(self.size.rems()) .flex_none() diff --git a/crates/ui2/src/components/indicator.rs b/crates/ui2/src/components/indicator.rs index 4a94650dfc6cdd4a17290413587c2fd17898e20f..f3dc62d20f4d8b057320d74aa49e182d0869e7f9 100644 --- a/crates/ui2/src/components/indicator.rs +++ b/crates/ui2/src/components/indicator.rs @@ -45,9 +45,9 @@ impl Indicator { } impl RenderOnce for Indicator { - type Rendered = Div; + type Output = Div; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { div() .flex_none() .map(|this| match self.style { diff --git a/crates/ui2/src/components/keybinding.rs b/crates/ui2/src/components/keybinding.rs index 8314f607fefd24a968fa2b5b099594985929736c..f0de9891a7f2c21729ade7a69cc464966f4f93cd 100644 --- a/crates/ui2/src/components/keybinding.rs +++ b/crates/ui2/src/components/keybinding.rs @@ -11,9 +11,9 @@ pub struct KeyBinding { } impl RenderOnce for KeyBinding { - type Rendered = Div; + type Output = Div; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { h_stack() .flex_none() .gap_2() @@ -91,9 +91,9 @@ pub struct Key { } impl RenderOnce for Key { - type Rendered = Div; + type Output = Div; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { let single_char = self.key.len() == 1; div() @@ -125,9 +125,9 @@ pub struct KeyIcon { } impl RenderOnce for KeyIcon { - type Rendered = Div; + type Output = Div; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { div() .w(rems(14. / 16.)) .child(IconElement::new(self.icon).size(IconSize::Small)) diff --git a/crates/ui2/src/components/label/highlighted_label.rs b/crates/ui2/src/components/label/highlighted_label.rs index a7fbb0d8167cd0f78fd40f01454621a3e26ca33d..08dfbe2391a270e9a019d8df59d9ececc413cd8c 100644 --- a/crates/ui2/src/components/label/highlighted_label.rs +++ b/crates/ui2/src/components/label/highlighted_label.rs @@ -46,9 +46,9 @@ impl LabelCommon for HighlightedLabel { } impl RenderOnce for HighlightedLabel { - type Rendered = LabelLike; + type Output = LabelLike; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { let highlight_color = cx.theme().colors().text_accent; let mut highlight_indices = self.highlight_indices.iter().copied().peekable(); diff --git a/crates/ui2/src/components/label/label.rs b/crates/ui2/src/components/label/label.rs index 8272340888837ca3f2ec2a0294a3168c14009cd0..888cd506d78d77ec2314b31ca48c28f0c288a7af 100644 --- a/crates/ui2/src/components/label/label.rs +++ b/crates/ui2/src/components/label/label.rs @@ -40,9 +40,9 @@ impl LabelCommon for Label { } impl RenderOnce for Label { - type Rendered = LabelLike; + type Output = LabelLike; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { self.base.child(self.label) } } diff --git a/crates/ui2/src/components/label/label_like.rs b/crates/ui2/src/components/label/label_like.rs index ebfbbecceb6d2468d3c7da98929d3cd4bd20f1ba..54e383eb487e274140eb433b18c560f21f5daa20 100644 --- a/crates/ui2/src/components/label/label_like.rs +++ b/crates/ui2/src/components/label/label_like.rs @@ -76,9 +76,9 @@ impl ParentElement for LabelLike { } impl RenderOnce for LabelLike { - type Rendered = Div; + type Output = Div; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { div() .when(self.strikethrough, |this| { this.relative().child( diff --git a/crates/ui2/src/components/list/list.rs b/crates/ui2/src/components/list/list.rs index fdfe256bd6b40b3c3926e74d517c28dc1f2f9216..23ebd8427c55932f6df6ad8e0a2b79fbac708096 100644 --- a/crates/ui2/src/components/list/list.rs +++ b/crates/ui2/src/components/list/list.rs @@ -46,9 +46,9 @@ impl ParentElement for List { } impl RenderOnce for List { - type Rendered = Div; + type Output = Div; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { v_stack().w_full().py_1().children(self.header).map(|this| { match (self.children.is_empty(), self.toggle) { (false, _) => this.children(self.children), diff --git a/crates/ui2/src/components/list/list_header.rs b/crates/ui2/src/components/list/list_header.rs index 0c07867c6d08941258488349b67498b25e832d1b..9726ed2c2b524f999a9f178237faff51e8164866 100644 --- a/crates/ui2/src/components/list/list_header.rs +++ b/crates/ui2/src/components/list/list_header.rs @@ -76,9 +76,9 @@ impl Selectable for ListHeader { } impl RenderOnce for ListHeader { - type Rendered = Stateful
; + type Output = Stateful
; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { h_stack() .id(self.label.clone()) .w_full() diff --git a/crates/ui2/src/components/list/list_item.rs b/crates/ui2/src/components/list/list_item.rs index 6295e2940d3a086d77b4d1aadec98b8c44f1d765..403c24b8e52344ac53b295cc10ac9811e3150313 100644 --- a/crates/ui2/src/components/list/list_item.rs +++ b/crates/ui2/src/components/list/list_item.rs @@ -147,9 +147,9 @@ impl ParentElement for ListItem { } impl RenderOnce for ListItem { - type Rendered = Stateful
; + type Output = Stateful
; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { h_stack() .id(self.id) .w_full() diff --git a/crates/ui2/src/components/list/list_separator.rs b/crates/ui2/src/components/list/list_separator.rs index 346b13ddaa3d7f672813724022a323f29c6b720a..d7afb0ed930e260a8dba20cefd584e44b56a1593 100644 --- a/crates/ui2/src/components/list/list_separator.rs +++ b/crates/ui2/src/components/list/list_separator.rs @@ -6,9 +6,9 @@ use crate::prelude::*; pub struct ListSeparator; impl RenderOnce for ListSeparator { - type Rendered = Div; + type Output = Div; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { div() .h_px() .w_full() diff --git a/crates/ui2/src/components/list/list_sub_header.rs b/crates/ui2/src/components/list/list_sub_header.rs index 07a99dabe5bbb29bd25bde471948b709350123dc..9f49587a458eba5c8668bad17771609bbd7a493f 100644 --- a/crates/ui2/src/components/list/list_sub_header.rs +++ b/crates/ui2/src/components/list/list_sub_header.rs @@ -26,9 +26,9 @@ impl ListSubHeader { } impl RenderOnce for ListSubHeader { - type Rendered = Div; + type Output = Div; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + fn render(self, _cx: &mut WindowContext) -> Self::Output { h_stack().flex_1().w_full().relative().py_1().child( div() .h_6() diff --git a/crates/ui2/src/components/popover.rs b/crates/ui2/src/components/popover.rs index 91713bc3072ad76fd1344fe1eebc32b23171163f..7d888ed3aa4f17dd68a14932102facbc606f0cca 100644 --- a/crates/ui2/src/components/popover.rs +++ b/crates/ui2/src/components/popover.rs @@ -41,9 +41,9 @@ pub struct Popover { } impl RenderOnce for Popover { - type Rendered = Div; + type Output = Div; - fn render(self, cx: &mut WindowContext) -> Self::Rendered { + fn render(self, cx: &mut WindowContext) -> Self::Output { div() .flex() .gap_1() diff --git a/crates/ui2/src/components/popover_menu.rs b/crates/ui2/src/components/popover_menu.rs index 1a02dd526e464a7c9ef7483bf575afc21f24c753..3cc925e0b5f0db95cb04553fc330d82a124a4833 100644 --- a/crates/ui2/src/components/popover_menu.rs +++ b/crates/ui2/src/components/popover_menu.rs @@ -130,7 +130,7 @@ pub struct PopoverMenuState { impl Element for PopoverMenu { type State = PopoverMenuState; - fn layout( + fn request_layout( &mut self, element_state: Option, cx: &mut WindowContext, diff --git a/crates/ui2/src/components/right_click_menu.rs b/crates/ui2/src/components/right_click_menu.rs index a3a454d652fa4dcbea48a6c8114c7c83e390c555..81f553a6a2cb2c2fdef829098e5ee5047358fb05 100644 --- a/crates/ui2/src/components/right_click_menu.rs +++ b/crates/ui2/src/components/right_click_menu.rs @@ -60,7 +60,7 @@ pub struct MenuHandleState { impl Element for RightClickMenu { type State = MenuHandleState; - fn layout( + fn request_layout( &mut self, element_state: Option, cx: &mut WindowContext, diff --git a/crates/ui2/src/components/stories/avatar.rs b/crates/ui2/src/components/stories/avatar.rs index 09adfe480a434491ff6db2b4010ccbc611db51c7..3b40f07c896f73e20dd6699130e8f24388480ea0 100644 --- a/crates/ui2/src/components/stories/avatar.rs +++ b/crates/ui2/src/components/stories/avatar.rs @@ -7,9 +7,9 @@ use crate::Avatar; pub struct AvatarStory; impl Render for AvatarStory { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { Story::container() .child(Story::title_for::()) .child(Story::label("Default")) diff --git a/crates/ui2/src/components/stories/button.rs b/crates/ui2/src/components/stories/button.rs index 9fe4f55dcb35c820c4553ef23e462714a51da5a0..8066f77353f351627c39e119bbc87e07b7c19df1 100644 --- a/crates/ui2/src/components/stories/button.rs +++ b/crates/ui2/src/components/stories/button.rs @@ -7,9 +7,9 @@ use crate::{Button, ButtonStyle}; pub struct ButtonStory; impl Render for ButtonStory { - type Element = Div; + type Output = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { + fn render(&mut self, _cx: &mut ViewContext) -> Self::Output { Story::container() .child(Story::title_for::