Keep all hunks expanded in proposed change editor (#18598)
Also, fix visual bug when pressing escape with a non-empty selection in a deleted text block. Release Notes: - N/A Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
parent
9b148f3dcc
commit
7dcb0de28c
3 changed files with 259 additions and 190 deletions
|
@ -3059,7 +3059,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
|
pub fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
|
||||||
if self.clear_clicked_diff_hunks(cx) {
|
if self.clear_expanded_diff_hunks(cx) {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ pub(super) struct ExpandedHunks {
|
||||||
pub(crate) hunks: Vec<ExpandedHunk>,
|
pub(crate) hunks: Vec<ExpandedHunk>,
|
||||||
diff_base: HashMap<BufferId, DiffBaseBuffer>,
|
diff_base: HashMap<BufferId, DiffBaseBuffer>,
|
||||||
hunk_update_tasks: HashMap<Option<BufferId>, Task<()>>,
|
hunk_update_tasks: HashMap<Option<BufferId>, Task<()>>,
|
||||||
|
expand_all: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -72,6 +73,10 @@ impl ExpandedHunks {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Editor {
|
impl Editor {
|
||||||
|
pub fn set_expand_all_diff_hunks(&mut self) {
|
||||||
|
self.expanded_hunks.expand_all = true;
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn toggle_hovered_hunk(
|
pub(super) fn toggle_hovered_hunk(
|
||||||
&mut self,
|
&mut self,
|
||||||
hovered_hunk: &HoveredHunk,
|
hovered_hunk: &HoveredHunk,
|
||||||
|
@ -133,6 +138,10 @@ impl Editor {
|
||||||
hunks_to_toggle: Vec<MultiBufferDiffHunk>,
|
hunks_to_toggle: Vec<MultiBufferDiffHunk>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
|
if self.expanded_hunks.expand_all {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let previous_toggle_task = self.expanded_hunks.hunk_update_tasks.remove(&None);
|
let previous_toggle_task = self.expanded_hunks.hunk_update_tasks.remove(&None);
|
||||||
let new_toggle_task = cx.spawn(move |editor, mut cx| async move {
|
let new_toggle_task = cx.spawn(move |editor, mut cx| async move {
|
||||||
if let Some(task) = previous_toggle_task {
|
if let Some(task) = previous_toggle_task {
|
||||||
|
@ -426,62 +435,64 @@ impl Editor {
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(
|
.when(!is_branch_buffer, |row| {
|
||||||
IconButton::new("next-hunk", IconName::ArrowDown)
|
row.child(
|
||||||
.shape(IconButtonShape::Square)
|
IconButton::new("next-hunk", IconName::ArrowDown)
|
||||||
.icon_size(IconSize::Small)
|
.shape(IconButtonShape::Square)
|
||||||
.tooltip({
|
.icon_size(IconSize::Small)
|
||||||
let focus_handle = editor.focus_handle(cx);
|
.tooltip({
|
||||||
move |cx| {
|
let focus_handle = editor.focus_handle(cx);
|
||||||
Tooltip::for_action_in(
|
move |cx| {
|
||||||
"Next Hunk",
|
Tooltip::for_action_in(
|
||||||
&GoToHunk,
|
"Next Hunk",
|
||||||
&focus_handle,
|
&GoToHunk,
|
||||||
cx,
|
&focus_handle,
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on_click({
|
|
||||||
let editor = editor.clone();
|
|
||||||
let hunk = hunk.clone();
|
|
||||||
move |_event, cx| {
|
|
||||||
editor.update(cx, |editor, cx| {
|
|
||||||
editor.go_to_subsequent_hunk(
|
|
||||||
hunk.multi_buffer_range.end,
|
|
||||||
cx,
|
cx,
|
||||||
);
|
)
|
||||||
});
|
}
|
||||||
}
|
})
|
||||||
}),
|
.on_click({
|
||||||
)
|
let editor = editor.clone();
|
||||||
.child(
|
let hunk = hunk.clone();
|
||||||
IconButton::new("prev-hunk", IconName::ArrowUp)
|
move |_event, cx| {
|
||||||
.shape(IconButtonShape::Square)
|
editor.update(cx, |editor, cx| {
|
||||||
.icon_size(IconSize::Small)
|
editor.go_to_subsequent_hunk(
|
||||||
.tooltip({
|
hunk.multi_buffer_range.end,
|
||||||
let focus_handle = editor.focus_handle(cx);
|
cx,
|
||||||
move |cx| {
|
);
|
||||||
Tooltip::for_action_in(
|
});
|
||||||
"Previous Hunk",
|
}
|
||||||
&GoToPrevHunk,
|
}),
|
||||||
&focus_handle,
|
)
|
||||||
cx,
|
.child(
|
||||||
)
|
IconButton::new("prev-hunk", IconName::ArrowUp)
|
||||||
}
|
.shape(IconButtonShape::Square)
|
||||||
})
|
.icon_size(IconSize::Small)
|
||||||
.on_click({
|
.tooltip({
|
||||||
let editor = editor.clone();
|
let focus_handle = editor.focus_handle(cx);
|
||||||
let hunk = hunk.clone();
|
move |cx| {
|
||||||
move |_event, cx| {
|
Tooltip::for_action_in(
|
||||||
editor.update(cx, |editor, cx| {
|
"Previous Hunk",
|
||||||
editor.go_to_preceding_hunk(
|
&GoToPrevHunk,
|
||||||
hunk.multi_buffer_range.start,
|
&focus_handle,
|
||||||
cx,
|
cx,
|
||||||
);
|
)
|
||||||
});
|
}
|
||||||
}
|
})
|
||||||
}),
|
.on_click({
|
||||||
)
|
let editor = editor.clone();
|
||||||
|
let hunk = hunk.clone();
|
||||||
|
move |_event, cx| {
|
||||||
|
editor.update(cx, |editor, cx| {
|
||||||
|
editor.go_to_preceding_hunk(
|
||||||
|
hunk.multi_buffer_range.start,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
.child(
|
.child(
|
||||||
IconButton::new("discard", IconName::Undo)
|
IconButton::new("discard", IconName::Undo)
|
||||||
.shape(IconButtonShape::Square)
|
.shape(IconButtonShape::Square)
|
||||||
|
@ -527,99 +538,115 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.when(is_branch_buffer, |this| {
|
.map(|this| {
|
||||||
this.child(
|
if is_branch_buffer {
|
||||||
IconButton::new("apply", IconName::Check)
|
this.child(
|
||||||
.shape(IconButtonShape::Square)
|
IconButton::new("apply", IconName::Check)
|
||||||
.icon_size(IconSize::Small)
|
.shape(IconButtonShape::Square)
|
||||||
.tooltip({
|
.icon_size(IconSize::Small)
|
||||||
let focus_handle = editor.focus_handle(cx);
|
.tooltip({
|
||||||
move |cx| {
|
let focus_handle =
|
||||||
Tooltip::for_action_in(
|
editor.focus_handle(cx);
|
||||||
"Apply Hunk",
|
move |cx| {
|
||||||
&ApplyDiffHunk,
|
Tooltip::for_action_in(
|
||||||
&focus_handle,
|
"Apply Hunk",
|
||||||
cx,
|
&ApplyDiffHunk,
|
||||||
)
|
&focus_handle,
|
||||||
}
|
|
||||||
})
|
|
||||||
.on_click({
|
|
||||||
let editor = editor.clone();
|
|
||||||
let hunk = hunk.clone();
|
|
||||||
move |_event, cx| {
|
|
||||||
editor.update(cx, |editor, cx| {
|
|
||||||
editor.apply_changes_in_range(
|
|
||||||
hunk.multi_buffer_range.clone(),
|
|
||||||
cx,
|
cx,
|
||||||
);
|
)
|
||||||
});
|
}
|
||||||
}
|
})
|
||||||
}),
|
.on_click({
|
||||||
)
|
let editor = editor.clone();
|
||||||
})
|
let hunk = hunk.clone();
|
||||||
.child({
|
move |_event, cx| {
|
||||||
let focus = editor.focus_handle(cx);
|
editor.update(cx, |editor, cx| {
|
||||||
PopoverMenu::new("hunk-controls-dropdown")
|
editor.apply_changes_in_range(
|
||||||
.trigger(
|
hunk.multi_buffer_range
|
||||||
IconButton::new(
|
.clone(),
|
||||||
"toggle_editor_selections_icon",
|
cx,
|
||||||
IconName::EllipsisVertical,
|
);
|
||||||
)
|
});
|
||||||
.shape(IconButtonShape::Square)
|
}
|
||||||
.icon_size(IconSize::Small)
|
}),
|
||||||
.style(ButtonStyle::Subtle)
|
|
||||||
.selected(
|
|
||||||
hunk_controls_menu_handle.is_deployed(),
|
|
||||||
)
|
|
||||||
.when(
|
|
||||||
!hunk_controls_menu_handle.is_deployed(),
|
|
||||||
|this| {
|
|
||||||
this.tooltip(|cx| {
|
|
||||||
Tooltip::text("Hunk Controls", cx)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.anchor(AnchorCorner::TopRight)
|
} else {
|
||||||
.with_handle(hunk_controls_menu_handle)
|
this.child({
|
||||||
.menu(move |cx| {
|
let focus = editor.focus_handle(cx);
|
||||||
let focus = focus.clone();
|
PopoverMenu::new("hunk-controls-dropdown")
|
||||||
let menu =
|
.trigger(
|
||||||
ContextMenu::build(cx, move |menu, _| {
|
IconButton::new(
|
||||||
menu.context(focus.clone()).action(
|
"toggle_editor_selections_icon",
|
||||||
"Discard All",
|
IconName::EllipsisVertical,
|
||||||
RevertFile.boxed_clone(),
|
|
||||||
)
|
)
|
||||||
});
|
.shape(IconButtonShape::Square)
|
||||||
Some(menu)
|
.icon_size(IconSize::Small)
|
||||||
|
.style(ButtonStyle::Subtle)
|
||||||
|
.selected(
|
||||||
|
hunk_controls_menu_handle
|
||||||
|
.is_deployed(),
|
||||||
|
)
|
||||||
|
.when(
|
||||||
|
!hunk_controls_menu_handle
|
||||||
|
.is_deployed(),
|
||||||
|
|this| {
|
||||||
|
this.tooltip(|cx| {
|
||||||
|
Tooltip::text(
|
||||||
|
"Hunk Controls",
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.anchor(AnchorCorner::TopRight)
|
||||||
|
.with_handle(hunk_controls_menu_handle)
|
||||||
|
.menu(move |cx| {
|
||||||
|
let focus = focus.clone();
|
||||||
|
let menu = ContextMenu::build(
|
||||||
|
cx,
|
||||||
|
move |menu, _| {
|
||||||
|
menu.context(focus.clone())
|
||||||
|
.action(
|
||||||
|
"Discard All",
|
||||||
|
RevertFile
|
||||||
|
.boxed_clone(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
Some(menu)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.child(
|
.when(!is_branch_buffer, |div| {
|
||||||
IconButton::new("collapse", IconName::Close)
|
div.child(
|
||||||
.shape(IconButtonShape::Square)
|
IconButton::new("collapse", IconName::Close)
|
||||||
.icon_size(IconSize::Small)
|
.shape(IconButtonShape::Square)
|
||||||
.tooltip({
|
.icon_size(IconSize::Small)
|
||||||
let focus_handle = editor.focus_handle(cx);
|
.tooltip({
|
||||||
move |cx| {
|
let focus_handle = editor.focus_handle(cx);
|
||||||
Tooltip::for_action_in(
|
move |cx| {
|
||||||
"Collapse Hunk",
|
Tooltip::for_action_in(
|
||||||
&ToggleHunkDiff,
|
"Collapse Hunk",
|
||||||
&focus_handle,
|
&ToggleHunkDiff,
|
||||||
cx,
|
&focus_handle,
|
||||||
)
|
cx,
|
||||||
}
|
)
|
||||||
})
|
}
|
||||||
.on_click({
|
})
|
||||||
let editor = editor.clone();
|
.on_click({
|
||||||
let hunk = hunk.clone();
|
let editor = editor.clone();
|
||||||
move |_event, cx| {
|
let hunk = hunk.clone();
|
||||||
editor.update(cx, |editor, cx| {
|
move |_event, cx| {
|
||||||
editor.toggle_hovered_hunk(&hunk, cx);
|
editor.update(cx, |editor, cx| {
|
||||||
});
|
editor.toggle_hovered_hunk(&hunk, cx);
|
||||||
}
|
});
|
||||||
}),
|
}
|
||||||
),
|
}),
|
||||||
|
)
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
@ -694,7 +721,10 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn clear_clicked_diff_hunks(&mut self, cx: &mut ViewContext<'_, Editor>) -> bool {
|
pub(super) fn clear_expanded_diff_hunks(&mut self, cx: &mut ViewContext<'_, Editor>) -> bool {
|
||||||
|
if self.expanded_hunks.expand_all {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
self.expanded_hunks.hunk_update_tasks.clear();
|
self.expanded_hunks.hunk_update_tasks.clear();
|
||||||
self.clear_row_highlights::<DiffRowHighlight>();
|
self.clear_row_highlights::<DiffRowHighlight>();
|
||||||
let to_remove = self
|
let to_remove = self
|
||||||
|
@ -798,33 +828,43 @@ impl Editor {
|
||||||
status,
|
status,
|
||||||
} => {
|
} => {
|
||||||
let hunk_display_range = display_row_range;
|
let hunk_display_range = display_row_range;
|
||||||
|
|
||||||
if expanded_hunk_display_range.start
|
if expanded_hunk_display_range.start
|
||||||
> hunk_display_range.end
|
> hunk_display_range.end
|
||||||
{
|
{
|
||||||
recalculated_hunks.next();
|
recalculated_hunks.next();
|
||||||
continue;
|
if editor.expanded_hunks.expand_all {
|
||||||
} else if expanded_hunk_display_range.end
|
|
||||||
< hunk_display_range.start
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
if !expanded_hunk.folded
|
|
||||||
&& expanded_hunk_display_range == hunk_display_range
|
|
||||||
&& expanded_hunk.status == hunk_status(buffer_hunk)
|
|
||||||
&& expanded_hunk.diff_base_byte_range
|
|
||||||
== buffer_hunk.diff_base_byte_range
|
|
||||||
{
|
|
||||||
recalculated_hunks.next();
|
|
||||||
retain = true;
|
|
||||||
} else {
|
|
||||||
hunks_to_reexpand.push(HoveredHunk {
|
hunks_to_reexpand.push(HoveredHunk {
|
||||||
status,
|
status,
|
||||||
multi_buffer_range,
|
multi_buffer_range,
|
||||||
diff_base_byte_range,
|
diff_base_byte_range,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if expanded_hunk_display_range.end
|
||||||
|
< hunk_display_range.start
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !expanded_hunk.folded
|
||||||
|
&& expanded_hunk_display_range == hunk_display_range
|
||||||
|
&& expanded_hunk.status == hunk_status(buffer_hunk)
|
||||||
|
&& expanded_hunk.diff_base_byte_range
|
||||||
|
== buffer_hunk.diff_base_byte_range
|
||||||
|
{
|
||||||
|
recalculated_hunks.next();
|
||||||
|
retain = true;
|
||||||
|
} else {
|
||||||
|
hunks_to_reexpand.push(HoveredHunk {
|
||||||
|
status,
|
||||||
|
multi_buffer_range,
|
||||||
|
diff_base_byte_range,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -836,6 +876,26 @@ impl Editor {
|
||||||
retain
|
retain
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if editor.expanded_hunks.expand_all {
|
||||||
|
for hunk in recalculated_hunks {
|
||||||
|
match diff_hunk_to_display(&hunk, &snapshot) {
|
||||||
|
DisplayDiffHunk::Folded { .. } => {}
|
||||||
|
DisplayDiffHunk::Unfolded {
|
||||||
|
diff_base_byte_range,
|
||||||
|
multi_buffer_range,
|
||||||
|
status,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
hunks_to_reexpand.push(HoveredHunk {
|
||||||
|
status,
|
||||||
|
multi_buffer_range,
|
||||||
|
diff_base_byte_range,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
editor.remove_highlighted_rows::<DiffRowHighlight>(highlights_to_remove, cx);
|
editor.remove_highlighted_rows::<DiffRowHighlight>(highlights_to_remove, cx);
|
||||||
editor.remove_blocks(blocks_to_remove, None, cx);
|
editor.remove_blocks(blocks_to_remove, None, cx);
|
||||||
|
|
||||||
|
@ -1000,13 +1060,15 @@ fn editor_with_deleted_text(
|
||||||
editor.scroll_manager.set_forbid_vertical_scroll(true);
|
editor.scroll_manager.set_forbid_vertical_scroll(true);
|
||||||
editor.set_read_only(true);
|
editor.set_read_only(true);
|
||||||
editor.set_show_inline_completions(Some(false), cx);
|
editor.set_show_inline_completions(Some(false), cx);
|
||||||
editor.highlight_rows::<DiffRowHighlight>(
|
|
||||||
|
enum DeletedBlockRowHighlight {}
|
||||||
|
editor.highlight_rows::<DeletedBlockRowHighlight>(
|
||||||
Anchor::min()..Anchor::max(),
|
Anchor::min()..Anchor::max(),
|
||||||
deleted_color,
|
deleted_color,
|
||||||
false,
|
false,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
editor.set_current_line_highlight(Some(CurrentLineHighlight::None));
|
editor.set_current_line_highlight(Some(CurrentLineHighlight::None)); //
|
||||||
editor
|
editor
|
||||||
._subscriptions
|
._subscriptions
|
||||||
.extend([cx.on_blur(&editor.focus_handle, |editor, cx| {
|
.extend([cx.on_blur(&editor.focus_handle, |editor, cx| {
|
||||||
|
@ -1015,37 +1077,41 @@ fn editor_with_deleted_text(
|
||||||
});
|
});
|
||||||
})]);
|
})]);
|
||||||
|
|
||||||
let parent_editor_for_reverts = parent_editor.clone();
|
|
||||||
let original_multi_buffer_range = hunk.multi_buffer_range.clone();
|
let original_multi_buffer_range = hunk.multi_buffer_range.clone();
|
||||||
let diff_base_range = hunk.diff_base_byte_range.clone();
|
let diff_base_range = hunk.diff_base_byte_range.clone();
|
||||||
editor
|
editor
|
||||||
.register_action::<RevertSelectedHunks>(move |_, cx| {
|
.register_action::<RevertSelectedHunks>({
|
||||||
parent_editor_for_reverts
|
let parent_editor = parent_editor.clone();
|
||||||
.update(cx, |editor, cx| {
|
move |_, cx| {
|
||||||
let Some((buffer, original_text)) =
|
parent_editor
|
||||||
editor.buffer().update(cx, |buffer, cx| {
|
.update(cx, |editor, cx| {
|
||||||
let (_, buffer, _) = buffer
|
let Some((buffer, original_text)) =
|
||||||
.excerpt_containing(original_multi_buffer_range.start, cx)?;
|
editor.buffer().update(cx, |buffer, cx| {
|
||||||
let original_text =
|
let (_, buffer, _) = buffer.excerpt_containing(
|
||||||
buffer.read(cx).diff_base()?.slice(diff_base_range.clone());
|
original_multi_buffer_range.start,
|
||||||
Some((buffer, Arc::from(original_text.to_string())))
|
cx,
|
||||||
})
|
)?;
|
||||||
else {
|
let original_text =
|
||||||
return;
|
buffer.read(cx).diff_base()?.slice(diff_base_range.clone());
|
||||||
};
|
Some((buffer, Arc::from(original_text.to_string())))
|
||||||
buffer.update(cx, |buffer, cx| {
|
})
|
||||||
buffer.edit(
|
else {
|
||||||
Some((
|
return;
|
||||||
original_multi_buffer_range.start.text_anchor
|
};
|
||||||
..original_multi_buffer_range.end.text_anchor,
|
buffer.update(cx, |buffer, cx| {
|
||||||
original_text,
|
buffer.edit(
|
||||||
)),
|
Some((
|
||||||
None,
|
original_multi_buffer_range.start.text_anchor
|
||||||
cx,
|
..original_multi_buffer_range.end.text_anchor,
|
||||||
)
|
original_text,
|
||||||
});
|
)),
|
||||||
})
|
None,
|
||||||
.ok();
|
cx,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
let hunk = hunk.clone();
|
let hunk = hunk.clone();
|
||||||
|
|
|
@ -63,8 +63,11 @@ impl ProposedChangesEditor {
|
||||||
let (recalculate_diffs_tx, mut recalculate_diffs_rx) = mpsc::unbounded();
|
let (recalculate_diffs_tx, mut recalculate_diffs_rx) = mpsc::unbounded();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
editor: cx
|
editor: cx.new_view(|cx| {
|
||||||
.new_view(|cx| Editor::for_multibuffer(multibuffer.clone(), project, true, cx)),
|
let mut editor = Editor::for_multibuffer(multibuffer.clone(), project, true, cx);
|
||||||
|
editor.set_expand_all_diff_hunks();
|
||||||
|
editor
|
||||||
|
}),
|
||||||
recalculate_diffs_tx,
|
recalculate_diffs_tx,
|
||||||
_recalculate_diffs_task: cx.spawn(|_, mut cx| async move {
|
_recalculate_diffs_task: cx.spawn(|_, mut cx| async move {
|
||||||
let mut buffers_to_diff = HashSet::default();
|
let mut buffers_to_diff = HashSet::default();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue