From 7ca0b38048f270f64b8da90f54b7df4bbf64f8f5 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Fri, 3 Mar 2023 09:32:54 -0800 Subject: [PATCH] Made fold inline styles be driven by the fold map co-authored-by: Max --- crates/editor/src/editor.rs | 165 +---------------------------------- crates/editor/src/element.rs | 54 +++++------- 2 files changed, 23 insertions(+), 196 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 643dd5b951..8a3acef996 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -458,8 +458,6 @@ type CompletionId = usize; type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor; type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option; -type TextClickedCallback = - fn(&MouseClick, &Range, &EditorSnapshot, &mut EventContext); pub struct Editor { handle: WeakViewHandle, @@ -488,7 +486,6 @@ pub struct Editor { highlighted_rows: Option>, #[allow(clippy::type_complexity)] background_highlights: BTreeMap Color, Vec>)>, - clickable_text: BTreeMap>)>, nav_history: Option, context_menu: Option, mouse_context_menu: ViewHandle, @@ -1159,7 +1156,6 @@ impl Editor { placeholder_text: None, highlighted_rows: None, background_highlights: Default::default(), - clickable_text: Default::default(), nav_history: None, context_menu: None, mouse_context_menu: cx.add_view(context_menu::ContextMenu::new), @@ -1196,19 +1192,6 @@ impl Editor { if mode == EditorMode::Full { let should_auto_hide_scrollbars = cx.platform().should_auto_hide_scrollbars(); cx.set_global(ScrollbarAutoHide(should_auto_hide_scrollbars)); - - // TODO: this does not work at all - let display_snapshot = this.snapshot(cx).display_snapshot; - let editor_snapshot = this.snapshot(cx); - if buffer.read(cx).is_singleton() { - this.insert_fold_styles( - display_snapshot - .folds_in_range(Anchor::min()..Anchor::max()) - .cloned(), - &editor_snapshot, - cx, - ) - } } this.report_event("open editor", cx); @@ -5866,47 +5849,16 @@ impl Editor { ) { let mut ranges = ranges.into_iter().peekable(); if ranges.peek().is_some() { - let ranges = ranges.collect_vec(); - - self.display_map - .update(cx, |map, cx| map.fold(ranges.iter().cloned(), cx)); + self.display_map.update(cx, |map, cx| map.fold(ranges, cx)); if auto_scroll { self.request_autoscroll(Autoscroll::fit(), cx); } - let snapshot = self.snapshot(cx); - let anchor_ranges = offset_to_anchors(ranges, &snapshot); - - self.insert_fold_styles(anchor_ranges, &snapshot, cx); - cx.notify(); } } - fn insert_fold_styles( - &mut self, - anchor_ranges: impl Iterator>, - snapshot: &EditorSnapshot, - cx: &mut ViewContext, - ) { - self.change_click_ranges::(cx, |click_ranges| { - for range in anchor_ranges { - if let Err(idx) = click_ranges.binary_search_by(|click_range| { - click_range.cmp(&range, &snapshot.buffer_snapshot) - }) { - click_ranges.insert(idx, range) - } - } - }); - let click_ranges = self.clone_click_ranges::(); - self.highlight_background::( - click_ranges, - |theme| theme.editor.document_highlight_write_background, - cx, - ); - } - pub fn unfold_ranges( &mut self, ranges: impl IntoIterator>, @@ -5916,41 +5868,12 @@ impl Editor { ) { let mut ranges = ranges.into_iter().peekable(); if ranges.peek().is_some() { - let ranges = ranges.collect_vec(); - - self.display_map.update(cx, |map, cx| { - map.unfold(ranges.iter().cloned(), inclusive, cx) - }); + self.display_map + .update(cx, |map, cx| map.unfold(ranges, inclusive, cx)); if auto_scroll { self.request_autoscroll(Autoscroll::fit(), cx); } - let snapshot = self.snapshot(cx); - let anchor_ranges = offset_to_anchors(ranges, &snapshot); - - self.change_click_ranges::(cx, |click_ranges| { - for range in anchor_ranges { - let range_point = range.start.to_point(&snapshot.buffer_snapshot); - // Fold and unfold ranges start at different points in the row. - // But their rows do match, so we can use that to detect sameness. - if let Ok(idx) = click_ranges.binary_search_by(|click_range| { - click_range - .start - .to_point(&snapshot.buffer_snapshot) - .row - .cmp(&range_point.row) - }) { - click_ranges.remove(idx); - } - } - }); - let click_ranges = self.clone_click_ranges::(); - self.highlight_background::( - click_ranges, - |theme| theme.editor.document_highlight_write_background, - cx, - ); - cx.notify(); } } @@ -6076,69 +5999,6 @@ impl Editor { } } - // FIXME: Consolidate the range styling APIs so that this clone isn't nescessary - pub fn clone_click_ranges(&self) -> Vec> { - self.clickable_text - .get(&TypeId::of::()) - .map(|click_range| click_range.1.clone()) - .unwrap_or_default() - } - - pub fn change_click_ranges( - &mut self, - cx: &mut ViewContext, - change: impl FnOnce(&mut Vec>), - ) { - let mut ranges = self - .clickable_text - .remove(&TypeId::of::()) - .map(|click_range| click_range.1) - .unwrap_or_default(); - - change(&mut ranges); - - self.clickable_text - .insert(TypeId::of::(), (T::click_handler, ranges)); - - cx.notify(); - } - - pub fn click_ranges_in_range( - &self, - search_range: Range, - display_snapshot: &DisplaySnapshot, - ) -> Vec<(Range, TextClickedCallback)> { - let mut results = Vec::new(); - let buffer = &display_snapshot.buffer_snapshot; - for (callback, ranges) in self.clickable_text.values() { - let start_ix = match ranges.binary_search_by(|probe| { - let cmp = probe.end.cmp(&search_range.start, buffer); - if cmp.is_gt() { - Ordering::Greater - } else { - Ordering::Less - } - }) { - Ok(i) | Err(i) => i, - }; - for range in &ranges[start_ix..] { - if range.start.cmp(&search_range.end, buffer).is_ge() { - break; - } - let start = range - .start - .to_point(buffer) - .to_display_point(display_snapshot); - let end = range - .end - .to_point(buffer) - .to_display_point(display_snapshot); - results.push((start..end, *callback)) - } - } - results - } - pub fn highlight_rows(&mut self, rows: Option>) { self.highlighted_rows = rows; } @@ -6517,25 +6377,6 @@ fn ending_row(next_selection: &Selection, display_map: &DisplaySnapshot) } } -fn offset_to_anchors< - 'snapshot, - 'iter: 'snapshot, - T: ToOffset, - I: IntoIterator> + 'iter, ->( - ranges: I, - snapshot: &'snapshot EditorSnapshot, -) -> impl Iterator> + 'snapshot { - ranges.into_iter().map(|range| { - snapshot - .buffer_snapshot - .anchor_at(range.start.to_offset(&snapshot.buffer_snapshot), Bias::Left) - ..snapshot - .buffer_snapshot - .anchor_at(range.end.to_offset(&snapshot.buffer_snapshot), Bias::Right) - }) -} - impl EditorSnapshot { pub fn language_at(&self, position: T) -> Option<&Arc> { self.display_snapshot.buffer_snapshot.language_at(position) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 239be52461..fac90f2507 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, GutterHover, TextClickedCallback, UnfoldAt, + EditorStyle, GutterHover, UnfoldAt, }; use clock::ReplicaId; use collections::{BTreeMap, HashMap}; @@ -30,7 +30,6 @@ use gpui::{ }, json::{self, ToJson}, platform::CursorStyle, - scene::MouseClick, text_layout::{self, Line, RunStyle, TextLayoutCache}, AppContext, Axis, Border, CursorRegion, Element, ElementBox, EventContext, LayoutContext, Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent, MouseRegion, MutableAppContext, @@ -116,7 +115,7 @@ impl EditorElement { fn attach_mouse_handlers( view: &WeakViewHandle, position_map: &Arc, - click_ranges: Arc, TextClickedCallback)>>, + fold_ranges: Arc<[Range]>, has_popovers: bool, visible_bounds: RectF, text_bounds: RectF, @@ -220,10 +219,12 @@ impl EditorElement { let point = position_to_display_point(e.position, text_bounds, &position_map); if let Some(point) = point { - for (range, callback) in click_ranges.iter() { + for range in fold_ranges.iter() { // Range -> RangeInclusive if range.contains(&point) || range.end == point { - callback(&e, range, &position_map.snapshot, cx) + cx.dispatch_action(UnfoldAt { + display_row: point.row(), + }) } } } @@ -723,7 +724,7 @@ impl EditorElement { }, }); - for (range, _) in layout.click_ranges.iter() { + for range in layout.fold_ranges.iter() { for bound in range_to_bounds( range, content_origin, @@ -1676,7 +1677,7 @@ impl Element for EditorElement { let mut active_rows = BTreeMap::new(); let mut highlighted_rows = None; let mut highlighted_ranges = Vec::new(); - let mut click_ranges = Vec::new(); + let mut fold_ranges = Vec::new(); let mut show_scrollbars = false; let mut include_root = false; let mut is_singleton = false; @@ -1689,7 +1690,15 @@ impl Element for EditorElement { let theme = cx.global::().theme.as_ref(); highlighted_ranges = view.background_highlights_in_range(start_anchor..end_anchor, &display_map, theme); - click_ranges = view.click_ranges_in_range(start_anchor..end_anchor, &display_map); + + fold_ranges.extend( + snapshot + .folds_in_range(start_anchor..end_anchor) + .map(|anchor| { + anchor.start.to_display_point(&snapshot.display_snapshot) + ..anchor.end.to_display_point(&snapshot.display_snapshot) + }), + ); let mut remote_selections = HashMap::default(); for (replica_id, line_mode, cursor_shape, selection) in display_map @@ -1946,7 +1955,7 @@ impl Element for EditorElement { active_rows, highlighted_rows, highlighted_ranges, - click_ranges: Arc::new(click_ranges), + fold_ranges: fold_ranges.into(), line_number_layouts, display_hunks, blocks, @@ -1978,7 +1987,7 @@ impl Element for EditorElement { Self::attach_mouse_handlers( &self.view, &layout.position_map, - layout.click_ranges.clone(), // No need to clone the vec + layout.fold_ranges.clone(), // No need to clone the vec layout.hover_popovers.is_some(), visible_bounds, text_bounds, @@ -2076,7 +2085,7 @@ pub struct LayoutState { display_hunks: Vec, blocks: Vec, highlighted_ranges: Vec<(Range, Color)>, - click_ranges: Arc, TextClickedCallback)>>, + fold_ranges: Arc<[Range]>, selections: Vec<(ReplicaId, Vec)>, scrollbar_row_range: Range, show_scrollbars: bool, @@ -2383,29 +2392,6 @@ impl HighlightedRange { } } -pub trait ClickRange: 'static { - fn click_handler( - click: &MouseClick, - range: &Range, - snapshot: &EditorSnapshot, - cx: &mut EventContext, - ); -} - -pub enum FoldMarker {} -impl ClickRange for FoldMarker { - fn click_handler( - _click: &MouseClick, - range: &Range, - _snapshot: &EditorSnapshot, - cx: &mut EventContext, - ) { - cx.dispatch_action(UnfoldAt { - display_row: range.start.row(), - }) - } -} - pub fn position_to_display_point( position: Vector2F, text_bounds: RectF,