Fix not able to navigate to files in git commit multibuffer (#42558)
Closes #40851 Release Notes: - Fixed: Commit diff multibuffers now open real project files whenever possible, restoring navigation and annotations inside those excerpts. --------- Co-authored-by: Anthony Eid <anthony@zed.dev>
This commit is contained in:
co-authored by
Anthony Eid
parent
b168679c18
commit
85ccd7c98b
@@ -21936,10 +21936,17 @@ impl Editor {
|
||||
};
|
||||
|
||||
for (buffer, (ranges, scroll_offset)) in new_selections_by_buffer {
|
||||
let editor = buffer
|
||||
.read(cx)
|
||||
.file()
|
||||
.is_none()
|
||||
let buffer_read = buffer.read(cx);
|
||||
let (has_file, is_project_file) = if let Some(file) = buffer_read.file() {
|
||||
(true, project::File::from_dyn(Some(file)).is_some())
|
||||
} else {
|
||||
(false, false)
|
||||
};
|
||||
|
||||
// If project file is none workspace.open_project_item will fail to open the excerpt
|
||||
// in a pre existing workspace item if one exists, because Buffer entity_id will be None
|
||||
// so we check if there's a tab match in that case first
|
||||
let editor = (!has_file || !is_project_file)
|
||||
.then(|| {
|
||||
// Handle file-less buffers separately: those are not really the project items, so won't have a project path or entity id,
|
||||
// so `workspace.open_project_item` will never find them, always opening a new editor.
|
||||
@@ -21973,6 +21980,9 @@ impl Editor {
|
||||
});
|
||||
|
||||
editor.update(cx, |editor, cx| {
|
||||
if has_file && !is_project_file {
|
||||
editor.set_read_only(true);
|
||||
}
|
||||
let autoscroll = match scroll_offset {
|
||||
Some(scroll_offset) => Autoscroll::top_relative(scroll_offset as usize),
|
||||
None => Autoscroll::newest(),
|
||||
@@ -21996,10 +22006,11 @@ impl Editor {
|
||||
});
|
||||
}
|
||||
|
||||
// For now, don't allow opening excerpts in buffers that aren't backed by
|
||||
// regular project files.
|
||||
// Allow opening excerpts for buffers that either belong to the current project
|
||||
// or represent synthetic/non-local files (e.g., git blobs). File-less buffers
|
||||
// are also supported so tests and other in-memory views keep working.
|
||||
fn can_open_excerpts_in_file(file: Option<&Arc<dyn language::File>>) -> bool {
|
||||
file.is_none_or(|file| project::File::from_dyn(Some(file)).is_some())
|
||||
file.is_none_or(|file| project::File::from_dyn(Some(file)).is_some() || !file.is_local())
|
||||
}
|
||||
|
||||
fn marked_text_ranges(&self, cx: &App) -> Option<Vec<Range<MultiBufferOffsetUtf16>>> {
|
||||
|
||||
@@ -1891,15 +1891,20 @@ fn path_for_buffer<'a>(
|
||||
cx: &'a App,
|
||||
) -> Option<Cow<'a, str>> {
|
||||
let file = buffer.read(cx).as_singleton()?.read(cx).file()?;
|
||||
path_for_file(file.as_ref(), height, include_filename, cx)
|
||||
path_for_file(file, height, include_filename, cx)
|
||||
}
|
||||
|
||||
fn path_for_file<'a>(
|
||||
file: &'a dyn language::File,
|
||||
file: &'a Arc<dyn language::File>,
|
||||
mut height: usize,
|
||||
include_filename: bool,
|
||||
cx: &'a App,
|
||||
) -> Option<Cow<'a, str>> {
|
||||
if project::File::from_dyn(Some(file)).is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let file = file.as_ref();
|
||||
// Ensure we always render at least the filename.
|
||||
height += 1;
|
||||
|
||||
@@ -1946,11 +1951,11 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_path_for_file(cx: &mut App) {
|
||||
let file = TestFile {
|
||||
let file: Arc<dyn language::File> = Arc::new(TestFile {
|
||||
path: RelPath::empty().into(),
|
||||
root_name: String::new(),
|
||||
local_root: None,
|
||||
};
|
||||
});
|
||||
assert_eq!(path_for_file(&file, 0, false, cx), None);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ struct GitBlob {
|
||||
path: RepoPath,
|
||||
worktree_id: WorktreeId,
|
||||
is_deleted: bool,
|
||||
display_name: Arc<str>,
|
||||
}
|
||||
|
||||
const FILE_NAMESPACE_SORT_PREFIX: u64 = 1;
|
||||
@@ -157,6 +158,7 @@ impl CommitView {
|
||||
});
|
||||
editor
|
||||
});
|
||||
let commit_sha = Arc::<str>::from(commit.sha.as_ref());
|
||||
|
||||
let first_worktree_id = project
|
||||
.read(cx)
|
||||
@@ -180,10 +182,20 @@ impl CommitView {
|
||||
.or(first_worktree_id)
|
||||
})?
|
||||
.context("project has no worktrees")?;
|
||||
let short_sha = commit_sha.get(0..7).unwrap_or(&commit_sha);
|
||||
let file_name = file
|
||||
.path
|
||||
.file_name()
|
||||
.map(|name| name.to_string())
|
||||
.unwrap_or_else(|| file.path.display(PathStyle::Posix).to_string());
|
||||
let display_name: Arc<str> =
|
||||
Arc::from(format!("{short_sha} - {file_name}").into_boxed_str());
|
||||
|
||||
let file = Arc::new(GitBlob {
|
||||
path: file.path.clone(),
|
||||
is_deleted,
|
||||
worktree_id,
|
||||
display_name,
|
||||
}) as Arc<dyn language::File>;
|
||||
|
||||
let buffer = build_buffer(new_text, file, &language_registry, cx).await?;
|
||||
@@ -647,7 +659,7 @@ impl language::File for GitBlob {
|
||||
}
|
||||
|
||||
fn file_name<'a>(&'a self, _: &'a App) -> &'a str {
|
||||
self.path.file_name().unwrap()
|
||||
self.display_name.as_ref()
|
||||
}
|
||||
|
||||
fn worktree_id(&self, _: &App) -> WorktreeId {
|
||||
|
||||
Reference in New Issue
Block a user