Use replace blocks for patches (#20605)

Release Notes:

- N/A

---------

Co-authored-by: Max <max@zed.dev>
Co-authored-by: Richard <richard@zed.dev>
This commit is contained in:
Antonio Scandurra 2024-11-13 18:55:23 +01:00 committed by GitHub
parent 96deabfb78
commit 92613a8904
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 925 additions and 918 deletions

View file

@ -6779,7 +6779,7 @@ impl Editor {
let mut edits = Vec::new();
let mut unfold_ranges = Vec::new();
let mut refold_ranges = Vec::new();
let mut refold_creases = Vec::new();
let selections = self.selections.all::<Point>(cx);
let mut selections = selections.iter().peekable();
@ -6854,7 +6854,7 @@ impl Editor {
let mut end = fold.range.end.to_point(&buffer);
start.row -= row_delta;
end.row -= row_delta;
refold_ranges.push((start..end, fold.placeholder.clone()));
refold_creases.push(Crease::simple(start..end, fold.placeholder.clone()));
}
}
}
@ -6870,7 +6870,7 @@ impl Editor {
buffer.edit([(range, text)], None, cx);
}
});
this.fold_ranges(refold_ranges, true, cx);
this.fold_creases(refold_creases, true, cx);
this.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.select(new_selections);
})
@ -6883,7 +6883,7 @@ impl Editor {
let mut edits = Vec::new();
let mut unfold_ranges = Vec::new();
let mut refold_ranges = Vec::new();
let mut refold_creases = Vec::new();
let selections = self.selections.all::<Point>(cx);
let mut selections = selections.iter().peekable();
@ -6948,7 +6948,7 @@ impl Editor {
let mut end = fold.range.end.to_point(&buffer);
start.row += row_delta;
end.row += row_delta;
refold_ranges.push((start..end, fold.placeholder.clone()));
refold_creases.push(Crease::simple(start..end, fold.placeholder.clone()));
}
}
}
@ -6964,7 +6964,7 @@ impl Editor {
buffer.edit([(range, text)], None, cx);
}
});
this.fold_ranges(refold_ranges, true, cx);
this.fold_creases(refold_creases, true, cx);
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(new_selections));
});
}
@ -10421,7 +10421,7 @@ impl Editor {
style: BlockStyle::Flex,
placement: BlockPlacement::Below(range.start),
height: 1,
render: Box::new({
render: Arc::new({
let rename_editor = rename_editor.clone();
move |cx: &mut BlockContext| {
let mut text_style = cx.editor_style.text.clone();
@ -10431,6 +10431,7 @@ impl Editor {
text_style = text_style.highlight(highlight_style);
}
div()
.occlude()
.pl(cx.anchor_x)
.child(EditorElement::new(
&rename_editor,
@ -10894,7 +10895,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);
@ -10906,12 +10907,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
}
@ -10922,11 +10921,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;
}
@ -10935,26 +10932,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;
@ -10964,7 +10964,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>) {
@ -10972,16 +10972,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);
@ -10992,11 +10994,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 {
@ -11005,11 +11005,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;
}
@ -11017,21 +11015,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(vec![crease], autoscroll, cx);
}
}
@ -11092,81 +11090,78 @@ impl Editor {
pub fn unfold_all(&mut self, _: &actions::UnfoldAll, cx: &mut ViewContext<Self>) {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
self.unfold_ranges(
&[Point::zero()..display_map.max_point().to_point(&display_map)],
true,
true,
cx,
);
self.unfold_ranges(&[0..display_map.buffer_snapshot.len()], true, true, cx);
}
pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext<Self>) {
let selections = self.selections.all::<Point>(cx);
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let line_mode = self.selections.line_mode;
let ranges = selections.into_iter().map(|s| {
if line_mode {
let start = Point::new(s.start.row, 0);
let end = Point::new(
s.end.row,
display_map
.buffer_snapshot
.line_len(MultiBufferRow(s.end.row)),
);
(start..end, display_map.fold_placeholder.clone())
} else {
(s.start..s.end, display_map.fold_placeholder.clone())
}
});
self.fold_ranges(ranges, true, cx);
let ranges = selections
.into_iter()
.map(|s| {
if line_mode {
let start = Point::new(s.start.row, 0);
let end = Point::new(
s.end.row,
display_map
.buffer_snapshot
.line_len(MultiBufferRow(s.end.row)),
);
Crease::simple(start..end, display_map.fold_placeholder.clone())
} else {
Crease::simple(s.start..s.end, display_map.fold_placeholder.clone())
}
})
.collect::<Vec<_>>();
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)>,
creases: Vec<Crease<T>>,
auto_scroll: bool,
cx: &mut ViewContext<Self>,
) {
let mut fold_ranges = Vec::new();
if creases.is_empty() {
return;
}
let mut buffers_affected = HashMap::default();
let multi_buffer = self.buffer().read(cx);
for (fold_range, fold_text) in ranges {
for crease in &creases {
if let Some((_, buffer, _)) =
multi_buffer.excerpt_containing(fold_range.start.clone(), cx)
multi_buffer.excerpt_containing(crease.range().start.clone(), cx)
{
buffers_affected.insert(buffer.read(cx).remote_id(), buffer);
};
fold_ranges.push((fold_range, fold_text));
}
let mut ranges = fold_ranges.into_iter().peekable();
if ranges.peek().is_some() {
self.display_map.update(cx, |map, cx| map.fold(ranges, cx));
self.display_map.update(cx, |map, cx| map.fold(creases, cx));
if auto_scroll {
self.request_autoscroll(Autoscroll::fit(), cx);
}
for buffer in buffers_affected.into_values() {
self.sync_expanded_diff_hunks(buffer, cx);
}
cx.notify();
if let Some(active_diagnostics) = self.active_diagnostics.take() {
// Clear diagnostics block when folding a range that contains it.
let snapshot = self.snapshot(cx);
if snapshot.intersects_fold(active_diagnostics.primary_range.start) {
drop(snapshot);
self.active_diagnostics = Some(active_diagnostics);
self.dismiss_diagnostics(cx);
} else {
self.active_diagnostics = Some(active_diagnostics);
}
}
self.scrollbar_marker_state.dirty = true;
if auto_scroll {
self.request_autoscroll(Autoscroll::fit(), cx);
}
for buffer in buffers_affected.into_values() {
self.sync_expanded_diff_hunks(buffer, cx);
}
cx.notify();
if let Some(active_diagnostics) = self.active_diagnostics.take() {
// Clear diagnostics block when folding a range that contains it.
let snapshot = self.snapshot(cx);
if snapshot.intersects_fold(active_diagnostics.primary_range.start) {
drop(snapshot);
self.active_diagnostics = Some(active_diagnostics);
self.dismiss_diagnostics(cx);
} else {
self.active_diagnostics = Some(active_diagnostics);
}
}
self.scrollbar_marker_state.dirty = true;
}
/// Removes any folds whose ranges intersect any of the given ranges.
@ -11215,6 +11210,7 @@ impl Editor {
}
self.display_map.update(cx, update);
if auto_scroll {
self.request_autoscroll(Autoscroll::fit(), cx);
}
@ -11317,7 +11313,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
@ -14056,7 +14052,7 @@ impl EditorSnapshot {
}
}
pub fn render_fold_toggle(
pub fn render_crease_toggle(
&self,
buffer_row: MultiBufferRow,
row_contains_cursor: bool,
@ -14064,34 +14060,38 @@ impl EditorSnapshot {
cx: &mut WindowContext,
) -> Option<AnyElement> {
let folded = self.is_line_folded(buffer_row);
let mut is_foldable = false;
if let Some(crease) = self
.crease_snapshot
.query_row(buffer_row, &self.buffer_snapshot)
{
let toggle_callback = Arc::new(move |folded, cx: &mut WindowContext| {
if folded {
editor.update(cx, |editor, cx| {
editor.fold_at(&crate::FoldAt { buffer_row }, cx)
});
} else {
editor.update(cx, |editor, cx| {
editor.unfold_at(&crate::UnfoldAt { buffer_row }, cx)
});
is_foldable = true;
match crease {
Crease::Inline { render_toggle, .. } | Crease::Block { render_toggle, .. } => {
if let Some(render_toggle) = render_toggle {
let toggle_callback = Arc::new(move |folded, cx: &mut WindowContext| {
if folded {
editor.update(cx, |editor, cx| {
editor.fold_at(&crate::FoldAt { buffer_row }, cx)
});
} else {
editor.update(cx, |editor, cx| {
editor.unfold_at(&crate::UnfoldAt { buffer_row }, cx)
});
}
});
return Some((render_toggle)(buffer_row, folded, toggle_callback, cx));
}
}
});
}
}
Some((crease.render_toggle)(
buffer_row,
folded,
toggle_callback,
cx,
))
} else if folded
|| (self.starts_indent(buffer_row) && (row_contains_cursor || self.gutter_hovered))
{
is_foldable |= self.starts_indent(buffer_row);
if folded || (is_foldable && (row_contains_cursor || self.gutter_hovered)) {
Some(
Disclosure::new(("indent-fold-indicator", buffer_row.0), !folded)
Disclosure::new(("gutter_crease", buffer_row.0), !folded)
.selected(folded)
.on_click(cx.listener_for(&editor, move |this, _e, cx| {
if folded {
@ -14113,10 +14113,15 @@ impl EditorSnapshot {
cx: &mut WindowContext,
) -> Option<AnyElement> {
let folded = self.is_line_folded(buffer_row);
let crease = self
if let Crease::Inline { render_trailer, .. } = self
.crease_snapshot
.query_row(buffer_row, &self.buffer_snapshot)?;
Some((crease.render_trailer)(buffer_row, folded, cx))
.query_row(buffer_row, &self.buffer_snapshot)?
{
let render_trailer = render_trailer.as_ref()?;
Some(render_trailer(buffer_row, folded, cx))
} else {
None
}
}
}
@ -14621,7 +14626,7 @@ pub fn diagnostic_block_renderer(
let (text_without_backticks, code_ranges) =
highlight_diagnostic_message(&diagnostic, max_message_rows);
Box::new(move |cx: &mut BlockContext| {
Arc::new(move |cx: &mut BlockContext| {
let group_id: SharedString = cx.block_id.to_string().into();
let mut text_style = cx.text_style().clone();
@ -14676,6 +14681,7 @@ pub fn diagnostic_block_renderer(
.group(group_id.clone())
.relative()
.size_full()
.occlude()
.pl(cx.gutter_dimensions.width)
.w(cx.max_width - cx.gutter_dimensions.full_width())
.child(