117 lines · 3.7 KB · Rust
RawDownload
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.pub struct InvalidBufferView {    /// 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 InvalidBufferView {    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 InvalidBufferView {    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 InvalidBufferView {} impl Focusable for InvalidBufferView {    fn focus_handle(&self, _: &App) -> FocusHandle {        self.focus_handle.clone()    }} impl Render for InvalidBufferView {    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,                                        )),                                ),                            )                        }),                ),            )    }}