editor: Save base buffers when applying changes from their branches (#19562)
This PR makes it so that when we apply changes within a branch buffer—currently just the edits buffer—we save the underlying buffer. This also fixes an issue where new files created via edits were not properly flushed to disk. Release Notes: - N/A --------- Co-authored-by: Max <max@zed.dev>
This commit is contained in:
parent
d8d84bf5d4
commit
5dbf68ddc4
4 changed files with 67 additions and 30 deletions
|
@ -6260,28 +6260,6 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
fn apply_selected_diff_hunks(&mut self, _: &ApplyDiffHunk, cx: &mut ViewContext<Self>) {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
let hunks = hunks_for_selections(&snapshot, &self.selections.disjoint_anchors());
|
||||
let mut ranges_by_buffer = HashMap::default();
|
||||
self.transact(cx, |editor, cx| {
|
||||
for hunk in hunks {
|
||||
if let Some(buffer) = editor.buffer.read(cx).buffer(hunk.buffer_id) {
|
||||
ranges_by_buffer
|
||||
.entry(buffer.clone())
|
||||
.or_insert_with(Vec::new)
|
||||
.push(hunk.buffer_range.to_offset(buffer.read(cx)));
|
||||
}
|
||||
}
|
||||
|
||||
for (buffer, ranges) in ranges_by_buffer {
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
buffer.merge_into_base(ranges, cx);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn open_active_item_in_terminal(&mut self, _: &OpenInTerminal, cx: &mut ViewContext<Self>) {
|
||||
if let Some(working_directory) = self.active_excerpt(cx).and_then(|(_, buffer, _)| {
|
||||
let project_path = buffer.read(cx).project_path(cx)?;
|
||||
|
|
|
@ -7,11 +7,13 @@ use multi_buffer::{
|
|||
MultiBufferSnapshot, ToPoint,
|
||||
};
|
||||
use std::{ops::Range, sync::Arc};
|
||||
use text::OffsetRangeExt;
|
||||
use ui::{
|
||||
prelude::*, ActiveTheme, ContextMenu, IconButtonShape, InteractiveElement, IntoElement,
|
||||
ParentElement, PopoverMenu, Styled, Tooltip, ViewContext, VisualContext,
|
||||
};
|
||||
use util::RangeExt;
|
||||
use workspace::Item;
|
||||
|
||||
use crate::{
|
||||
editor_settings::CurrentLineHighlight, hunk_status, hunks_for_selections, ApplyDiffHunk,
|
||||
|
@ -327,7 +329,7 @@ impl Editor {
|
|||
Some(())
|
||||
}
|
||||
|
||||
fn apply_changes_in_range(
|
||||
fn apply_diff_hunks_in_range(
|
||||
&mut self,
|
||||
range: Range<Anchor>,
|
||||
cx: &mut ViewContext<'_, Editor>,
|
||||
|
@ -343,16 +345,54 @@ impl Editor {
|
|||
branch_buffer.merge_into_base(vec![range], cx);
|
||||
});
|
||||
|
||||
if let Some(project) = self.project.clone() {
|
||||
self.save(true, project, cx).detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn apply_all_changes(&self, cx: &mut ViewContext<Self>) {
|
||||
pub(crate) fn apply_all_diff_hunks(&mut self, cx: &mut ViewContext<Self>) {
|
||||
let buffers = self.buffer.read(cx).all_buffers();
|
||||
for branch_buffer in buffers {
|
||||
branch_buffer.update(cx, |branch_buffer, cx| {
|
||||
branch_buffer.merge_into_base(Vec::new(), cx);
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(project) = self.project.clone() {
|
||||
self.save(true, project, cx).detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn apply_selected_diff_hunks(
|
||||
&mut self,
|
||||
_: &ApplyDiffHunk,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
let hunks = hunks_for_selections(&snapshot, &self.selections.disjoint_anchors());
|
||||
let mut ranges_by_buffer = HashMap::default();
|
||||
self.transact(cx, |editor, cx| {
|
||||
for hunk in hunks {
|
||||
if let Some(buffer) = editor.buffer.read(cx).buffer(hunk.buffer_id) {
|
||||
ranges_by_buffer
|
||||
.entry(buffer.clone())
|
||||
.or_insert_with(Vec::new)
|
||||
.push(hunk.buffer_range.to_offset(buffer.read(cx)));
|
||||
}
|
||||
}
|
||||
|
||||
for (buffer, ranges) in ranges_by_buffer {
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
buffer.merge_into_base(ranges, cx);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(project) = self.project.clone() {
|
||||
self.save(true, project, cx).detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn hunk_header_block(
|
||||
|
@ -548,11 +588,12 @@ impl Editor {
|
|||
let hunk = hunk.clone();
|
||||
move |_event, cx| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.apply_changes_in_range(
|
||||
hunk.multi_buffer_range
|
||||
.clone(),
|
||||
cx,
|
||||
);
|
||||
editor
|
||||
.apply_diff_hunks_in_range(
|
||||
hunk.multi_buffer_range
|
||||
.clone(),
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -720,6 +720,10 @@ impl Item for Editor {
|
|||
) -> Task<Result<()>> {
|
||||
self.report_editor_event("save", None, cx);
|
||||
let buffers = self.buffer().clone().read(cx).all_buffers();
|
||||
let buffers = buffers
|
||||
.into_iter()
|
||||
.map(|handle| handle.read(cx).diff_base_buffer().unwrap_or(handle.clone()))
|
||||
.collect::<HashSet<_>>();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
if format {
|
||||
this.update(&mut cx, |editor, cx| {
|
||||
|
|
|
@ -298,6 +298,20 @@ impl Item for ProposedChangesEditor {
|
|||
Item::set_nav_history(editor, nav_history, cx)
|
||||
});
|
||||
}
|
||||
|
||||
fn can_save(&self, cx: &AppContext) -> bool {
|
||||
self.editor.read(cx).can_save(cx)
|
||||
}
|
||||
|
||||
fn save(
|
||||
&mut self,
|
||||
format: bool,
|
||||
project: Model<Project>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Task<gpui::Result<()>> {
|
||||
self.editor
|
||||
.update(cx, |editor, cx| Item::save(editor, format, project, cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ProposedChangesEditorToolbar {
|
||||
|
@ -323,7 +337,7 @@ impl Render for ProposedChangesEditorToolbar {
|
|||
if let Some(editor) = &editor {
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.editor.update(cx, |editor, cx| {
|
||||
editor.apply_all_changes(cx);
|
||||
editor.apply_all_diff_hunks(cx);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue