Don't consider empty deleted files to be dirty or conflicting (#27701)
When a file is deleted outside of Zed, but it doesn't have any unsaved changes, it shouldn't be considered "dirty" (prompting you before you close it). Release Notes: - Fixed an bug where unchanged buffers were marked as conflicting if their files were deleted outside of Zed. --------- Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
parent
5c0adde7bb
commit
9445005bff
2 changed files with 43 additions and 11 deletions
|
@ -1950,13 +1950,14 @@ impl Buffer {
|
|||
if self.capability == Capability::ReadOnly {
|
||||
return false;
|
||||
}
|
||||
if self.has_conflict || self.has_unsaved_edits() {
|
||||
if self.has_conflict {
|
||||
return true;
|
||||
}
|
||||
match self.file.as_ref().map(|f| f.disk_state()) {
|
||||
Some(DiskState::New) => !self.is_empty(),
|
||||
Some(DiskState::Deleted) => true,
|
||||
_ => false,
|
||||
Some(DiskState::New) | Some(DiskState::Deleted) => {
|
||||
!self.is_empty() && self.has_unsaved_edits()
|
||||
}
|
||||
_ => self.has_unsaved_edits(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1977,7 +1978,7 @@ impl Buffer {
|
|||
}
|
||||
None => true,
|
||||
},
|
||||
DiskState::Deleted => true,
|
||||
DiskState::Deleted => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3884,7 +3884,7 @@ async fn test_buffer_is_dirty(cx: &mut gpui::TestAppContext) {
|
|||
]
|
||||
);
|
||||
|
||||
// When a file is deleted, the buffer is considered dirty.
|
||||
// When a file is deleted, it is not considered dirty.
|
||||
let events = Arc::new(Mutex::new(Vec::new()));
|
||||
let buffer2 = project
|
||||
.update(cx, |p, cx| p.open_local_buffer(path!("/dir/file2"), cx))
|
||||
|
@ -3893,7 +3893,10 @@ async fn test_buffer_is_dirty(cx: &mut gpui::TestAppContext) {
|
|||
buffer2.update(cx, |_, cx| {
|
||||
cx.subscribe(&buffer2, {
|
||||
let events = events.clone();
|
||||
move |_, _, event, _| events.lock().push(event.clone())
|
||||
move |_, _, event, _| match event {
|
||||
BufferEvent::Operation { .. } => {}
|
||||
_ => events.lock().push(event.clone()),
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
|
@ -3902,12 +3905,37 @@ async fn test_buffer_is_dirty(cx: &mut gpui::TestAppContext) {
|
|||
.await
|
||||
.unwrap();
|
||||
cx.executor().run_until_parked();
|
||||
buffer2.update(cx, |buffer, _| assert!(buffer.is_dirty()));
|
||||
buffer2.update(cx, |buffer, _| assert!(!buffer.is_dirty()));
|
||||
assert_eq!(
|
||||
mem::take(&mut *events.lock()),
|
||||
&[language::BufferEvent::FileHandleChanged]
|
||||
);
|
||||
|
||||
// Buffer becomes dirty when edited.
|
||||
buffer2.update(cx, |buffer, cx| {
|
||||
buffer.edit([(2..3, "")], None, cx);
|
||||
assert_eq!(buffer.is_dirty(), true);
|
||||
});
|
||||
assert_eq!(
|
||||
mem::take(&mut *events.lock()),
|
||||
&[
|
||||
language::BufferEvent::Edited,
|
||||
language::BufferEvent::DirtyChanged
|
||||
]
|
||||
);
|
||||
|
||||
// Buffer becomes clean again when all of its content is removed, because
|
||||
// the file was deleted.
|
||||
buffer2.update(cx, |buffer, cx| {
|
||||
buffer.edit([(0..2, "")], None, cx);
|
||||
assert_eq!(buffer.is_empty(), true);
|
||||
assert_eq!(buffer.is_dirty(), false);
|
||||
});
|
||||
assert_eq!(
|
||||
*events.lock(),
|
||||
&[
|
||||
language::BufferEvent::DirtyChanged,
|
||||
language::BufferEvent::FileHandleChanged
|
||||
language::BufferEvent::Edited,
|
||||
language::BufferEvent::DirtyChanged
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -3920,7 +3948,10 @@ async fn test_buffer_is_dirty(cx: &mut gpui::TestAppContext) {
|
|||
buffer3.update(cx, |_, cx| {
|
||||
cx.subscribe(&buffer3, {
|
||||
let events = events.clone();
|
||||
move |_, _, event, _| events.lock().push(event.clone())
|
||||
move |_, _, event, _| match event {
|
||||
BufferEvent::Operation { .. } => {}
|
||||
_ => events.lock().push(event.clone()),
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue