diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 0a59d7e835..ced92c6e13 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -24,7 +24,7 @@ pub use block_map::{ BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock, TransformBlock, }; -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum FoldStatus { Folded, Foldable, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 0586669624..5f2f27a15e 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -171,6 +171,11 @@ pub struct UnfoldAt { pub display_row: DisplayRow, } +#[derive(Clone, Default, Deserialize, PartialEq)] +pub struct GutterHover { + pub hovered: bool, +} + actions!( editor, [ @@ -270,7 +275,8 @@ impl_actions!( ConfirmCodeAction, ToggleComments, FoldAt, - UnfoldAt + UnfoldAt, + GutterHover ] ); @@ -364,6 +370,7 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(Editor::fold_at); cx.add_action(Editor::unfold_lines); cx.add_action(Editor::unfold_at); + cx.add_action(Editor::gutter_hover); cx.add_action(Editor::fold_selected_ranges); cx.add_action(Editor::show_completions); cx.add_action(Editor::toggle_code_actions); @@ -495,6 +502,7 @@ pub struct Editor { leader_replica_id: Option, remote_id: Option, hover_state: HoverState, + gutter_hovered: bool, link_go_to_definition_state: LinkGoToDefinitionState, _subscriptions: Vec, } @@ -1166,6 +1174,7 @@ impl Editor { remote_id: None, hover_state: Default::default(), link_go_to_definition_state: Default::default(), + gutter_hovered: false, _subscriptions: vec![ cx.observe(&buffer, Self::on_buffer_changed), cx.subscribe(&buffer, Self::on_buffer_event), @@ -2688,6 +2697,7 @@ impl Editor { &self, fold_data: Option>, style: &EditorStyle, + gutter_hovered: bool, cx: &mut RenderContext, ) -> Option> { enum FoldIndicators {} @@ -2695,26 +2705,31 @@ impl Editor { fold_data.map(|fold_data| { fold_data .iter() + .copied() .map(|(fold_location, fold_status)| { ( - *fold_location, + fold_location, MouseEventHandler::::new( - *fold_location as usize, + fold_location as usize, cx, |_, _| -> ElementBox { - Svg::new(match *fold_status { + Svg::new(match fold_status { FoldStatus::Folded => "icons/chevron_right_8.svg", FoldStatus::Foldable => "icons/chevron_down_8.svg", }) - .with_color(style.folds.indicator) + .with_color( + if gutter_hovered || fold_status == FoldStatus::Folded { + style.folds.indicator + } else { + style.folds.faded_indicator + }, + ) .boxed() }, ) .with_cursor_style(CursorStyle::PointingHand) .with_padding(Padding::uniform(3.)) .on_down(MouseButton::Left, { - let fold_location = *fold_location; - let fold_status = *fold_status; move |_, cx| { cx.dispatch_any_action(match fold_status { FoldStatus::Folded => Box::new(UnfoldAt { @@ -5838,6 +5853,15 @@ impl Editor { } } + pub fn gutter_hover( + &mut self, + GutterHover { hovered }: &GutterHover, + cx: &mut ViewContext, + ) { + self.gutter_hovered = *hovered; + cx.notify(); + } + pub fn insert_blocks( &mut self, blocks: impl IntoIterator>, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 9a205b39fc..98cec4fdac 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -14,7 +14,7 @@ use crate::{ }, mouse_context_menu::DeployMouseContextMenu, scroll::actions::Scroll, - EditorStyle, + EditorStyle, GutterHover, }; use clock::ReplicaId; use collections::{BTreeMap, HashMap}; @@ -213,6 +213,17 @@ impl EditorElement { } }), ); + + enum GutterHandlers {} + cx.scene.push_mouse_region( + MouseRegion::new::(view.id(), view.id() + 1, gutter_bounds).on_hover( + |hover, cx| { + cx.dispatch_action(GutterHover { + hovered: hover.started, + }) + }, + ), + ) } fn mouse_down( @@ -419,6 +430,7 @@ impl EditorElement { }); cx.dispatch_action(HoverAt { point }); + true } @@ -1815,7 +1827,7 @@ impl Element for EditorElement { hover = view.hover_state.render(&snapshot, &style, visible_rows, cx); mode = view.mode; - view.render_fold_indicators(folds, &style, cx) + view.render_fold_indicators(folds, &style, view.gutter_hovered, cx) }); if let Some((_, context_menu)) = context_menu.as_mut() { diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index c9695d4f36..87e0224286 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -643,6 +643,7 @@ pub struct CodeActions { pub struct Folds { #[serde(default)] pub indicator: Color, + pub faded_indicator: Color, pub fold_background: Color, } diff --git a/styles/src/styleTree/editor.ts b/styles/src/styleTree/editor.ts index 3518c2aba5..c50c368f26 100644 --- a/styles/src/styleTree/editor.ts +++ b/styles/src/styleTree/editor.ts @@ -49,7 +49,8 @@ export default function editor(colorScheme: ColorScheme) { }, folds: { indicator: foreground(layer, "variant"), - fold_background: foreground(layer, "variant"), + fadedIndicator: background(layer, "on"), + foldBackground: foreground(layer, "variant"), }, diff: { deleted: foreground(layer, "negative"),