From 3906b16cd6648530492e29562feced334a665bec Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 1 Nov 2024 19:01:52 +0100 Subject: [PATCH] WIP --- crates/editor/src/display_map.rs | 34 ++++++--- crates/editor/src/display_map/crease_map.rs | 34 +++++---- crates/editor/src/editor.rs | 79 ++++++++++----------- crates/editor/src/editor_tests.rs | 10 +-- 4 files changed, 87 insertions(+), 70 deletions(-) diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 5685038b4e..ab11bb021e 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -255,7 +255,7 @@ impl DisplayMap { pub fn insert_creases( &mut self, - creases: impl IntoIterator, + creases: impl IntoIterator>, cx: &mut ModelContext, ) -> Vec { let snapshot = self.buffer.read(cx).snapshot(cx); @@ -1054,19 +1054,27 @@ impl DisplaySnapshot { .unwrap_or(false) } - pub fn foldable_range( - &self, - buffer_row: MultiBufferRow, - ) -> Option<(Range, FoldPlaceholder)> { + pub fn crease_for_buffer_row(&self, buffer_row: MultiBufferRow) -> Option> { let start = MultiBufferPoint::new(buffer_row.0, self.buffer_snapshot.line_len(buffer_row)); if let Some(crease) = self .crease_snapshot .query_row(buffer_row, &self.buffer_snapshot) { - Some(( - crease.range().to_point(&self.buffer_snapshot), - crease.placeholder.clone(), - )) + match crease { + Crease::Inline { + range, + placeholder, + render_toggle, + render_trailer, + metadata, + } => Some(Crease::Inline { + range: range.to_point(&self.buffer_snapshot), + placeholder: placeholder.clone(), + render_toggle: render_toggle.clone(), + render_trailer: render_trailer.clone(), + metadata: metadata.clone(), + }), + } } else if self.starts_indent(MultiBufferRow(start.row)) && !self.is_line_folded(MultiBufferRow(start.row)) { @@ -1103,7 +1111,13 @@ impl DisplaySnapshot { .line_len(MultiBufferRow(row_before_line_breaks.row)), ); - Some((start..row_before_line_breaks, self.fold_placeholder.clone())) + Some(Crease::Inline { + range: start..row_before_line_breaks, + placeholder: self.fold_placeholder, + render_toggle: None, + render_trailer: None, + metadata: None, + }) } else { None } diff --git a/crates/editor/src/display_map/crease_map.rs b/crates/editor/src/display_map/crease_map.rs index c1d88a990c..7a835283a4 100644 --- a/crates/editor/src/display_map/crease_map.rs +++ b/crates/editor/src/display_map/crease_map.rs @@ -2,7 +2,7 @@ use collections::HashMap; use gpui::{AnyElement, IntoElement}; use multi_buffer::{Anchor, AnchorRangeExt, MultiBufferRow, MultiBufferSnapshot, ToPoint}; use serde::{Deserialize, Serialize}; -use std::{cmp::Ordering, ops::Range, sync::Arc}; +use std::{cmp::Ordering, fmt::Debug, ops::Range, sync::Arc}; use sum_tree::{Bias, SeekTarget, SumTree}; use text::Point; use ui::{IconName, SharedString, WindowContext}; @@ -45,7 +45,7 @@ impl CreaseSnapshot { &'a self, row: MultiBufferRow, snapshot: &'a MultiBufferSnapshot, - ) -> Option<&'a Crease> { + ) -> Option<&'a Crease> { let start = snapshot.anchor_before(Point::new(row.0, 0)); let mut cursor = self.creases.cursor::(snapshot); cursor.seek(&start, Bias::Left, snapshot); @@ -69,7 +69,7 @@ impl CreaseSnapshot { &'a self, range: Range, snapshot: &'a MultiBufferSnapshot, - ) -> impl 'a + Iterator { + ) -> impl 'a + Iterator> { let start = snapshot.anchor_before(Point::new(range.start.0, 0)); let mut cursor = self.creases.cursor::(snapshot); cursor.seek(&start, Bias::Left, snapshot); @@ -125,9 +125,9 @@ type RenderTrailerFn = Arc AnyElement>; #[derive(Clone)] -pub enum Crease { +pub enum Crease { Inline { - range: Range, + range: Range, placeholder: FoldPlaceholder, render_toggle: RenderToggleFn, render_trailer: RenderTrailerFn, @@ -142,9 +142,9 @@ pub struct CreaseMetadata { pub label: SharedString, } -impl Crease { +impl Crease { pub fn inline( - range: Range, + range: Range, placeholder: FoldPlaceholder, render_toggle: RenderToggle, render_trailer: RenderTrailer, @@ -199,20 +199,26 @@ impl Crease { } } - pub fn range(&self) -> &Range { + pub fn range(&self) -> &Range { match self { Crease::Inline { range, .. } => range, } } } -impl std::fmt::Debug for Crease { +impl std::fmt::Debug for Crease +where + T: Debug, +{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Crease::Inline { range, .. } => f - .debug_struct("Crease::Fold") + Crease::Inline { + range, metadata, .. + } => f + .debug_struct("Crease::Inline") .field("range", range) - .finish(), + .field("metadata", metadata) + .finish_non_exhaustive(), } } } @@ -220,7 +226,7 @@ impl std::fmt::Debug for Crease { #[derive(Clone, Debug)] struct CreaseItem { id: CreaseId, - crease: Crease, + crease: Crease, } impl CreaseMap { @@ -230,7 +236,7 @@ impl CreaseMap { pub fn insert( &mut self, - creases: impl IntoIterator, + creases: impl IntoIterator>, snapshot: &MultiBufferSnapshot, ) -> Vec { let mut new_ids = Vec::new(); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index c5d708384c..24849318ce 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -6706,7 +6706,7 @@ impl Editor { buffer.edit([(range, text)], None, cx); } }); - this.fold_ranges(refold_ranges, true, cx); + this.fold_creases(refold_ranges, true, cx); this.change_selections(Some(Autoscroll::fit()), cx, |s| { s.select(new_selections); }) @@ -6800,7 +6800,7 @@ impl Editor { buffer.edit([(range, text)], None, cx); } }); - this.fold_ranges(refold_ranges, true, cx); + this.fold_creases(refold_ranges, true, cx); this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(new_selections)); }); } @@ -10703,7 +10703,7 @@ impl Editor { } pub fn fold(&mut self, _: &actions::Fold, cx: &mut ViewContext) { - let mut fold_ranges = Vec::new(); + let mut to_fold = Vec::new(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let selections = self.selections.all_adjusted(cx); @@ -10715,12 +10715,10 @@ impl Editor { let mut found = false; let mut row = range.start.row; while row <= range.end.row { - if let Some((foldable_range, fold_text)) = - { display_map.foldable_range(MultiBufferRow(row)) } - { + if let Some(crease) = display_map.crease_for_buffer_row(MultiBufferRow(row)) { found = true; - row = foldable_range.end.row + 1; - fold_ranges.push((foldable_range, fold_text)); + row = crease.range().end.row + 1; + to_fold.push(crease); } else { row += 1 } @@ -10731,11 +10729,9 @@ impl Editor { } for row in (0..=range.start.row).rev() { - if let Some((foldable_range, fold_text)) = - display_map.foldable_range(MultiBufferRow(row)) - { - if foldable_range.end.row >= buffer_start_row { - fold_ranges.push((foldable_range, fold_text)); + if let Some(crease) = display_map.crease_for_buffer_row(MultiBufferRow(row)) { + if crease.range().end.row >= buffer_start_row { + to_fold.push(crease); if row <= range.start.row { break; } @@ -10744,26 +10740,29 @@ impl Editor { } } - self.fold_ranges(fold_ranges, true, cx); + self.fold_creases(to_fold, true, cx); } fn fold_at_level(&mut self, fold_at: &FoldAtLevel, cx: &mut ViewContext) { let fold_at_level = fold_at.level; let snapshot = self.buffer.read(cx).snapshot(cx); - let mut fold_ranges = Vec::new(); + let mut to_fold = Vec::new(); let mut stack = vec![(0, snapshot.max_buffer_row().0, 1)]; while let Some((mut start_row, end_row, current_level)) = stack.pop() { while start_row < end_row { - match self.snapshot(cx).foldable_range(MultiBufferRow(start_row)) { - Some(foldable_range) => { - let nested_start_row = foldable_range.0.start.row + 1; - let nested_end_row = foldable_range.0.end.row; + match self + .snapshot(cx) + .crease_for_buffer_row(MultiBufferRow(start_row)) + { + Some(crease) => { + let nested_start_row = crease.range().start.row + 1; + let nested_end_row = crease.range().end.row; if current_level < fold_at_level { stack.push((nested_start_row, nested_end_row, current_level + 1)); } else if current_level == fold_at_level { - fold_ranges.push(foldable_range); + to_fold.push(crease); } start_row = nested_end_row + 1; @@ -10773,7 +10772,7 @@ impl Editor { } } - self.fold_ranges(fold_ranges, true, cx); + self.fold_creases(to_fold, true, cx); } pub fn fold_all(&mut self, _: &actions::FoldAll, cx: &mut ViewContext) { @@ -10781,16 +10780,18 @@ impl Editor { let snapshot = self.buffer.read(cx).snapshot(cx); for row in 0..snapshot.max_buffer_row().0 { - if let Some(foldable_range) = self.snapshot(cx).foldable_range(MultiBufferRow(row)) { + if let Some(foldable_range) = + self.snapshot(cx).crease_for_buffer_row(MultiBufferRow(row)) + { fold_ranges.push(foldable_range); } } - self.fold_ranges(fold_ranges, true, cx); + self.fold_creases(fold_ranges, true, cx); } pub fn fold_recursive(&mut self, _: &actions::FoldRecursive, cx: &mut ViewContext) { - let mut fold_ranges = Vec::new(); + let mut to_fold = Vec::new(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let selections = self.selections.all_adjusted(cx); @@ -10801,11 +10802,9 @@ impl Editor { if range.start.row != range.end.row { let mut found = false; for row in range.start.row..=range.end.row { - if let Some((foldable_range, fold_text)) = - { display_map.foldable_range(MultiBufferRow(row)) } - { + if let Some(crease) = display_map.crease_for_buffer_row(MultiBufferRow(row)) { found = true; - fold_ranges.push((foldable_range, fold_text)); + to_fold.push(crease); } } if found { @@ -10814,11 +10813,9 @@ impl Editor { } for row in (0..=range.start.row).rev() { - if let Some((foldable_range, fold_text)) = - display_map.foldable_range(MultiBufferRow(row)) - { - if foldable_range.end.row >= buffer_start_row { - fold_ranges.push((foldable_range, fold_text)); + if let Some(crease) = display_map.crease_for_buffer_row(MultiBufferRow(row)) { + if crease.range().end.row >= buffer_start_row { + to_fold.push(crease); } else { break; } @@ -10826,21 +10823,21 @@ impl Editor { } } - self.fold_ranges(fold_ranges, true, cx); + self.fold_creases(to_fold, true, cx); } pub fn fold_at(&mut self, fold_at: &FoldAt, cx: &mut ViewContext) { let buffer_row = fold_at.buffer_row; let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); - if let Some((fold_range, placeholder)) = display_map.foldable_range(buffer_row) { + if let Some(crease) = display_map.crease_for_buffer_row(buffer_row) { let autoscroll = self .selections .all::(cx) .iter() - .any(|selection| fold_range.overlaps(&selection.range())); + .any(|selection| crease.range().overlaps(&selection.range())); - self.fold_ranges([(fold_range, placeholder)], autoscroll, cx); + self.fold_creases([crease], autoscroll, cx); } } @@ -10927,12 +10924,12 @@ impl Editor { (s.start..s.end, display_map.fold_placeholder.clone()) } }); - self.fold_ranges(ranges, true, cx); + self.fold_creases(ranges, true, cx); } - pub fn fold_ranges( + pub fn fold_creases( &mut self, - ranges: impl IntoIterator, FoldPlaceholder)>, + ranges: impl IntoIterator>, auto_scroll: bool, cx: &mut ViewContext, ) { @@ -11102,7 +11099,7 @@ impl Editor { pub fn insert_creases( &mut self, - creases: impl IntoIterator, + creases: impl IntoIterator>, cx: &mut ViewContext, ) -> Vec { self.display_map diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 45f7c423bd..bba42ace4c 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -592,7 +592,7 @@ fn test_clone(cx: &mut TestAppContext) { _ = editor.update(cx, |editor, cx| { editor.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone())); - editor.fold_ranges( + editor.fold_creases( [ (Point::new(1, 0)..Point::new(2, 0), FoldPlaceholder::test()), (Point::new(3, 0)..Point::new(4, 0), FoldPlaceholder::test()), @@ -1279,7 +1279,7 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) { assert_eq!('α'.len_utf8(), 2); _ = view.update(cx, |view, cx| { - view.fold_ranges( + view.fold_creases( vec![ (Point::new(0, 6)..Point::new(0, 12), FoldPlaceholder::test()), (Point::new(1, 2)..Point::new(1, 4), FoldPlaceholder::test()), @@ -3871,7 +3871,7 @@ fn test_move_line_up_down(cx: &mut TestAppContext) { build_editor(buffer, cx) }); _ = view.update(cx, |view, cx| { - view.fold_ranges( + view.fold_creases( vec![ (Point::new(0, 2)..Point::new(1, 2), FoldPlaceholder::test()), (Point::new(2, 3)..Point::new(4, 1), FoldPlaceholder::test()), @@ -4770,7 +4770,7 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) { build_editor(buffer, cx) }); _ = view.update(cx, |view, cx| { - view.fold_ranges( + view.fold_creases( vec![ (Point::new(0, 2)..Point::new(1, 2), FoldPlaceholder::test()), (Point::new(2, 3)..Point::new(4, 1), FoldPlaceholder::test()), @@ -5451,7 +5451,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. editor.update(cx, |view, cx| { - view.fold_ranges( + view.fold_creases( vec![ ( Point::new(0, 21)..Point::new(0, 24),