Only allow save_as for pane if can_save_as is true (#25028)

When saving an item, some logic is done to determine whether one can
save it. In the special case where the intent is to `SaveAs`, it was
previously allowed to proceed as long as the buffer was a singleton
(presumably since it only makes sense to provide a save path for a
single file). However, we need to _also_ check that this item can be
"saved as" at all.

For this, we resurrect the `ItemHandle`/`Item` trait method
`can_save_as`. We have given it the default implementation of returning
`false`, and then overridden this in the implementation for
`TerminalView`.

Closes #25023


Release Notes:

- Fixed crash when trying to save terminal buffer

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Dylan 2025-02-17 17:01:56 -06:00 committed by GitHub
parent 62a11b047d
commit bb53ad9862
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 38 additions and 13 deletions

View file

@ -1794,18 +1794,23 @@ impl Pane {
return Ok(true);
};
let (mut has_conflict, mut is_dirty, mut can_save, is_singleton, has_deleted_file) = cx
.update(|_window, cx| {
(
item.has_conflict(cx),
item.is_dirty(cx),
item.can_save(cx),
item.is_singleton(cx),
item.has_deleted_file(cx),
)
})?;
let can_save_as = is_singleton;
let (
mut has_conflict,
mut is_dirty,
mut can_save,
can_save_as,
is_singleton,
has_deleted_file,
) = cx.update(|_window, cx| {
(
item.has_conflict(cx),
item.is_dirty(cx),
item.can_save(cx),
item.can_save_as(cx),
item.is_singleton(cx),
item.has_deleted_file(cx),
)
})?;
// when saving a single buffer, we ignore whether or not it's dirty.
if save_intent == SaveIntent::Save || save_intent == SaveIntent::SaveWithoutFormat {
@ -1939,7 +1944,7 @@ impl Pane {
item.save(should_format, project, window, cx)
})?
.await?;
} else if can_save_as {
} else if can_save_as && is_singleton {
let abs_path = pane.update_in(cx, |pane, window, cx| {
pane.activate_item(item_ix, true, true, window, cx);
pane.workspace.update(cx, |workspace, cx| {