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 {
|
if self.capability == Capability::ReadOnly {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if self.has_conflict || self.has_unsaved_edits() {
|
if self.has_conflict {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
match self.file.as_ref().map(|f| f.disk_state()) {
|
match self.file.as_ref().map(|f| f.disk_state()) {
|
||||||
Some(DiskState::New) => !self.is_empty(),
|
Some(DiskState::New) | Some(DiskState::Deleted) => {
|
||||||
Some(DiskState::Deleted) => true,
|
!self.is_empty() && self.has_unsaved_edits()
|
||||||
_ => false,
|
}
|
||||||
|
_ => self.has_unsaved_edits(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1977,7 +1978,7 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
None => true,
|
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 events = Arc::new(Mutex::new(Vec::new()));
|
||||||
let buffer2 = project
|
let buffer2 = project
|
||||||
.update(cx, |p, cx| p.open_local_buffer(path!("/dir/file2"), cx))
|
.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| {
|
buffer2.update(cx, |_, cx| {
|
||||||
cx.subscribe(&buffer2, {
|
cx.subscribe(&buffer2, {
|
||||||
let events = events.clone();
|
let events = events.clone();
|
||||||
move |_, _, event, _| events.lock().push(event.clone())
|
move |_, _, event, _| match event {
|
||||||
|
BufferEvent::Operation { .. } => {}
|
||||||
|
_ => events.lock().push(event.clone()),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
});
|
});
|
||||||
|
@ -3902,12 +3905,37 @@ async fn test_buffer_is_dirty(cx: &mut gpui::TestAppContext) {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
cx.executor().run_until_parked();
|
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!(
|
assert_eq!(
|
||||||
*events.lock(),
|
*events.lock(),
|
||||||
&[
|
&[
|
||||||
language::BufferEvent::DirtyChanged,
|
language::BufferEvent::Edited,
|
||||||
language::BufferEvent::FileHandleChanged
|
language::BufferEvent::DirtyChanged
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3920,7 +3948,10 @@ async fn test_buffer_is_dirty(cx: &mut gpui::TestAppContext) {
|
||||||
buffer3.update(cx, |_, cx| {
|
buffer3.update(cx, |_, cx| {
|
||||||
cx.subscribe(&buffer3, {
|
cx.subscribe(&buffer3, {
|
||||||
let events = events.clone();
|
let events = events.clone();
|
||||||
move |_, _, event, _| events.lock().push(event.clone())
|
move |_, _, event, _| match event {
|
||||||
|
BufferEvent::Operation { .. } => {}
|
||||||
|
_ => events.lock().push(event.clone()),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue