mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-12 13:24:19 +00:00
WIP
This commit is contained in:
parent
896ee3c374
commit
3906b16cd6
4 changed files with 87 additions and 70 deletions
|
@ -255,7 +255,7 @@ impl DisplayMap {
|
|||
|
||||
pub fn insert_creases(
|
||||
&mut self,
|
||||
creases: impl IntoIterator<Item = Crease>,
|
||||
creases: impl IntoIterator<Item = Crease<Anchor>>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Vec<CreaseId> {
|
||||
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<Point>, FoldPlaceholder)> {
|
||||
pub fn crease_for_buffer_row(&self, buffer_row: MultiBufferRow) -> Option<Crease<Point>> {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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<Anchor>> {
|
||||
let start = snapshot.anchor_before(Point::new(row.0, 0));
|
||||
let mut cursor = self.creases.cursor::<ItemSummary>(snapshot);
|
||||
cursor.seek(&start, Bias::Left, snapshot);
|
||||
|
@ -69,7 +69,7 @@ impl CreaseSnapshot {
|
|||
&'a self,
|
||||
range: Range<MultiBufferRow>,
|
||||
snapshot: &'a MultiBufferSnapshot,
|
||||
) -> impl 'a + Iterator<Item = &'a Crease> {
|
||||
) -> impl 'a + Iterator<Item = &'a Crease<Anchor>> {
|
||||
let start = snapshot.anchor_before(Point::new(range.start.0, 0));
|
||||
let mut cursor = self.creases.cursor::<ItemSummary>(snapshot);
|
||||
cursor.seek(&start, Bias::Left, snapshot);
|
||||
|
@ -125,9 +125,9 @@ type RenderTrailerFn =
|
|||
Arc<dyn Send + Sync + Fn(MultiBufferRow, bool, &mut WindowContext) -> AnyElement>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Crease {
|
||||
pub enum Crease<T> {
|
||||
Inline {
|
||||
range: Range<Anchor>,
|
||||
range: Range<T>,
|
||||
placeholder: FoldPlaceholder,
|
||||
render_toggle: RenderToggleFn,
|
||||
render_trailer: RenderTrailerFn,
|
||||
|
@ -142,9 +142,9 @@ pub struct CreaseMetadata {
|
|||
pub label: SharedString,
|
||||
}
|
||||
|
||||
impl Crease {
|
||||
impl<T> Crease<T> {
|
||||
pub fn inline<RenderToggle, ToggleElement, RenderTrailer, TrailerElement>(
|
||||
range: Range<Anchor>,
|
||||
range: Range<T>,
|
||||
placeholder: FoldPlaceholder,
|
||||
render_toggle: RenderToggle,
|
||||
render_trailer: RenderTrailer,
|
||||
|
@ -199,20 +199,26 @@ impl Crease {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn range(&self) -> &Range<Anchor> {
|
||||
pub fn range(&self) -> &Range<T> {
|
||||
match self {
|
||||
Crease::Inline { range, .. } => range,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Crease {
|
||||
impl<T> std::fmt::Debug for Crease<T>
|
||||
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<Anchor>,
|
||||
}
|
||||
|
||||
impl CreaseMap {
|
||||
|
@ -230,7 +236,7 @@ impl CreaseMap {
|
|||
|
||||
pub fn insert(
|
||||
&mut self,
|
||||
creases: impl IntoIterator<Item = Crease>,
|
||||
creases: impl IntoIterator<Item = Crease<Anchor>>,
|
||||
snapshot: &MultiBufferSnapshot,
|
||||
) -> Vec<CreaseId> {
|
||||
let mut new_ids = Vec::new();
|
||||
|
|
|
@ -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<Self>) {
|
||||
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<Self>) {
|
||||
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<Self>) {
|
||||
|
@ -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<Self>) {
|
||||
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<Self>) {
|
||||
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::<Point>(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<T: ToOffset + Clone>(
|
||||
pub fn fold_creases<T: ToOffset + Clone>(
|
||||
&mut self,
|
||||
ranges: impl IntoIterator<Item = (Range<T>, FoldPlaceholder)>,
|
||||
ranges: impl IntoIterator<Item = Crease<T>>,
|
||||
auto_scroll: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
|
@ -11102,7 +11099,7 @@ impl Editor {
|
|||
|
||||
pub fn insert_creases(
|
||||
&mut self,
|
||||
creases: impl IntoIterator<Item = Crease>,
|
||||
creases: impl IntoIterator<Item = Crease<Anchor>>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Vec<CreaseId> {
|
||||
self.display_map
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue