Tidy up single-file worktrees' opening errors (#44455)
Part of https://github.com/zed-industries/zed/issues/44370 Also log when fail to open the project item. Release Notes: - N/A
This commit is contained in:
@@ -620,9 +620,21 @@ impl LocalBufferStore {
|
||||
let load_file = worktree.update(cx, |worktree, cx| worktree.load_file(path.as_ref(), cx));
|
||||
cx.spawn(async move |this, cx| {
|
||||
let path = path.clone();
|
||||
let buffer = match load_file.await.with_context(|| {
|
||||
format!("Could not open path: {}", path.display(PathStyle::local()))
|
||||
}) {
|
||||
let single_file_path = cx.update(|cx| {
|
||||
if worktree.read(cx).is_single_file() {
|
||||
Some(worktree.read(cx).abs_path())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})?;
|
||||
let path_string = single_file_path
|
||||
.as_ref()
|
||||
.map(|path| path.to_string_lossy())
|
||||
.unwrap_or_else(|| path.display(PathStyle::local()));
|
||||
let buffer = match load_file
|
||||
.await
|
||||
.with_context(|| format!("Opening path \"{path_string}\""))
|
||||
{
|
||||
Ok(loaded) => {
|
||||
let reservation = cx.reserve_entity::<Buffer>()?;
|
||||
let buffer_id = BufferId::from(reservation.entity_id().as_non_zero_u64());
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
use std::{path::Path, sync::Arc};
|
||||
|
||||
use gpui::{EventEmitter, FocusHandle, Focusable};
|
||||
use ui::{
|
||||
App, Button, ButtonCommon, ButtonStyle, Clickable, Context, FluentBuilder, InteractiveElement,
|
||||
KeyBinding, Label, LabelCommon, LabelSize, ParentElement, Render, SharedString, Styled as _,
|
||||
Window, h_flex, v_flex,
|
||||
};
|
||||
use zed_actions::workspace::OpenWithSystem;
|
||||
|
||||
use crate::Item;
|
||||
|
||||
/// A view to display when a certain buffer fails to open.
|
||||
#[derive(Debug)]
|
||||
pub struct InvalidItemView {
|
||||
/// Which path was attempted to open.
|
||||
pub abs_path: Arc<Path>,
|
||||
/// An error message, happened when opening the buffer.
|
||||
pub error: SharedString,
|
||||
is_local: bool,
|
||||
focus_handle: FocusHandle,
|
||||
}
|
||||
|
||||
impl InvalidItemView {
|
||||
pub fn new(
|
||||
abs_path: &Path,
|
||||
is_local: bool,
|
||||
e: &anyhow::Error,
|
||||
_: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Self {
|
||||
Self {
|
||||
is_local,
|
||||
abs_path: Arc::from(abs_path),
|
||||
error: format!("{}", e.root_cause()).into(),
|
||||
focus_handle: cx.focus_handle(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Item for InvalidItemView {
|
||||
type Event = ();
|
||||
|
||||
fn tab_content_text(&self, mut detail: usize, _: &App) -> SharedString {
|
||||
// Ensure we always render at least the filename.
|
||||
detail += 1;
|
||||
|
||||
let path = self.abs_path.as_ref();
|
||||
|
||||
let mut prefix = path;
|
||||
while detail > 0 {
|
||||
if let Some(parent) = prefix.parent() {
|
||||
prefix = parent;
|
||||
detail -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let path = if detail > 0 {
|
||||
path
|
||||
} else {
|
||||
path.strip_prefix(prefix).unwrap_or(path)
|
||||
};
|
||||
|
||||
SharedString::new(path.to_string_lossy())
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEmitter<()> for InvalidItemView {}
|
||||
|
||||
impl Focusable for InvalidItemView {
|
||||
fn focus_handle(&self, _: &App) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for InvalidItemView {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl gpui::IntoElement {
|
||||
let abs_path = self.abs_path.clone();
|
||||
v_flex()
|
||||
.size_full()
|
||||
.track_focus(&self.focus_handle(cx))
|
||||
.flex_none()
|
||||
.justify_center()
|
||||
.overflow_hidden()
|
||||
.key_context("InvalidBuffer")
|
||||
.child(
|
||||
h_flex().size_full().justify_center().child(
|
||||
v_flex()
|
||||
.justify_center()
|
||||
.gap_2()
|
||||
.child(h_flex().justify_center().child("Could not open file"))
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_center()
|
||||
.child(Label::new(self.error.clone()).size(LabelSize::Small)),
|
||||
)
|
||||
.when(self.is_local, |contents| {
|
||||
contents.child(
|
||||
h_flex().justify_center().child(
|
||||
Button::new("open-with-system", "Open in Default App")
|
||||
.on_click(move |_, _, cx| {
|
||||
cx.open_with_system(&abs_path);
|
||||
})
|
||||
.style(ButtonStyle::Outlined)
|
||||
.key_binding(KeyBinding::for_action(
|
||||
&OpenWithSystem,
|
||||
window,
|
||||
cx,
|
||||
)),
|
||||
),
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use zed_actions::workspace::OpenWithSystem;
|
||||
use crate::Item;
|
||||
|
||||
/// A view to display when a certain buffer/image/other item fails to open.
|
||||
#[derive(Debug)]
|
||||
pub struct InvalidItemView {
|
||||
/// Which path was attempted to open.
|
||||
pub abs_path: Arc<Path>,
|
||||
|
||||
@@ -675,6 +675,7 @@ impl ProjectItemRegistry {
|
||||
Ok((project_entry_id, build_workspace_item))
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("Failed to open a project item: {e:#}");
|
||||
if e.error_code() == ErrorCode::Internal {
|
||||
if let Some(abs_path) =
|
||||
entry_abs_path.as_deref().filter(|_| is_file)
|
||||
|
||||
Reference in New Issue
Block a user