1730 lines · 54.7 KB · Rust
RawDownload
use crate::{    CollaboratorId, DelayedDebouncedEditAction, FollowableViewRegistry, ItemNavHistory,    SerializableItemRegistry, ToolbarItemLocation, ViewId, Workspace, WorkspaceId,    invalid_item_view::InvalidItemView,    pane::{self, Pane},    persistence::model::ItemId,    searchable::SearchableItemHandle,    workspace_settings::{AutosaveSetting, WorkspaceSettings},};use anyhow::Result;use client::{Client, proto};use futures::{StreamExt, channel::mpsc};use gpui::{    Action, AnyElement, AnyEntity, AnyView, App, AppContext, Context, Entity, EntityId,    EventEmitter, FocusHandle, Focusable, Font, HighlightStyle, Pixels, Point, Render,    SharedString, Task, WeakEntity, Window,};use language::Capability;use project::{Project, ProjectEntryId, ProjectPath};pub use settings::{    ActivateOnClose, ClosePosition, RegisterSetting, Settings, SettingsLocation, ShowCloseButton,    ShowDiagnostics,};use smallvec::SmallVec;use std::{    any::{Any, TypeId},    cell::RefCell,    ops::Range,    path::Path,    rc::Rc,    sync::Arc,    time::Duration,};use theme::Theme;use ui::{Color, Icon, IntoElement, Label, LabelCommon};use util::ResultExt; pub const LEADER_UPDATE_THROTTLE: Duration = Duration::from_millis(200); #[derive(Clone, Copy, Debug)]pub struct SaveOptions {    pub format: bool,    pub autosave: bool,} impl Default for SaveOptions {    fn default() -> Self {        Self {            format: true,            autosave: false,        }    }} #[derive(RegisterSetting)]pub struct ItemSettings {    pub git_status: bool,    pub close_position: ClosePosition,    pub activate_on_close: ActivateOnClose,    pub file_icons: bool,    pub show_diagnostics: ShowDiagnostics,    pub show_close_button: ShowCloseButton,} #[derive(RegisterSetting)]pub struct PreviewTabsSettings {    pub enabled: bool,    pub enable_preview_from_project_panel: bool,    pub enable_preview_from_file_finder: bool,    pub enable_preview_from_multibuffer: bool,    pub enable_preview_multibuffer_from_code_navigation: bool,    pub enable_preview_file_from_code_navigation: bool,    pub enable_keep_preview_on_code_navigation: bool,} impl Settings for ItemSettings {    fn from_settings(content: &settings::SettingsContent) -> Self {        let tabs = content.tabs.as_ref().unwrap();        Self {            git_status: tabs.git_status.unwrap()                && content                    .git                    .unwrap()                    .enabled                    .unwrap()                    .is_git_status_enabled(),            close_position: tabs.close_position.unwrap(),            activate_on_close: tabs.activate_on_close.unwrap(),            file_icons: tabs.file_icons.unwrap(),            show_diagnostics: tabs.show_diagnostics.unwrap(),            show_close_button: tabs.show_close_button.unwrap(),        }    }} impl Settings for PreviewTabsSettings {    fn from_settings(content: &settings::SettingsContent) -> Self {        let preview_tabs = content.preview_tabs.as_ref().unwrap();        Self {            enabled: preview_tabs.enabled.unwrap(),            enable_preview_from_project_panel: preview_tabs                .enable_preview_from_project_panel                .unwrap(),            enable_preview_from_file_finder: preview_tabs.enable_preview_from_file_finder.unwrap(),            enable_preview_from_multibuffer: preview_tabs.enable_preview_from_multibuffer.unwrap(),            enable_preview_multibuffer_from_code_navigation: preview_tabs                .enable_preview_multibuffer_from_code_navigation                .unwrap(),            enable_preview_file_from_code_navigation: preview_tabs                .enable_preview_file_from_code_navigation                .unwrap(),            enable_keep_preview_on_code_navigation: preview_tabs                .enable_keep_preview_on_code_navigation                .unwrap(),        }    }} #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]pub enum ItemEvent {    CloseItem,    UpdateTab,    UpdateBreadcrumbs,    Edit,} // TODO: Combine this with existing HighlightedText struct?#[derive(Debug)]pub struct BreadcrumbText {    pub text: String,    pub highlights: Option<Vec<(Range<usize>, HighlightStyle)>>,    pub font: Option<Font>,} #[derive(Clone, Copy, Default, Debug)]pub struct TabContentParams {    pub detail: Option<usize>,    pub selected: bool,    pub preview: bool,    /// Tab content should be deemphasized when active pane does not have focus.    pub deemphasized: bool,} impl TabContentParams {    /// Returns the text color to be used for the tab content.    pub fn text_color(&self) -> Color {        if self.deemphasized {            if self.selected {                Color::Muted            } else {                Color::Hidden            }        } else if self.selected {            Color::Default        } else {            Color::Muted        }    }} pub enum TabTooltipContent {    Text(SharedString),    Custom(Box<dyn Fn(&mut Window, &mut App) -> AnyView>),} #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]pub enum ItemBufferKind {    Multibuffer,    Singleton,    None,} pub trait Item: Focusable + EventEmitter<Self::Event> + Render + Sized {    type Event;     /// Returns the tab contents.    ///    /// By default this returns a [`Label`] that displays that text from    /// `tab_content_text`.    fn tab_content(&self, params: TabContentParams, _window: &Window, cx: &App) -> AnyElement {        let text = self.tab_content_text(params.detail.unwrap_or_default(), cx);         Label::new(text)            .color(params.text_color())            .into_any_element()    }     /// Returns the textual contents of the tab.    fn tab_content_text(&self, _detail: usize, _cx: &App) -> SharedString;     /// Returns the suggested filename for saving this item.    /// By default, returns the tab content text.    fn suggested_filename(&self, cx: &App) -> SharedString {        self.tab_content_text(0, cx)    }     fn tab_icon(&self, _window: &Window, _cx: &App) -> Option<Icon> {        None    }     /// Returns the tab tooltip text.    ///    /// Use this if you don't need to customize the tab tooltip content.    fn tab_tooltip_text(&self, _: &App) -> Option<SharedString> {        None    }     /// Returns the tab tooltip content.    ///    /// By default this returns a Tooltip text from    /// `tab_tooltip_text`.    fn tab_tooltip_content(&self, cx: &App) -> Option<TabTooltipContent> {        self.tab_tooltip_text(cx).map(TabTooltipContent::Text)    }     fn to_item_events(_event: &Self::Event, _f: impl FnMut(ItemEvent)) {}     fn deactivated(&mut self, _window: &mut Window, _: &mut Context<Self>) {}    fn discarded(&self, _project: Entity<Project>, _window: &mut Window, _cx: &mut Context<Self>) {}    fn on_removed(&self, _cx: &App) {}    fn workspace_deactivated(&mut self, _window: &mut Window, _: &mut Context<Self>) {}    fn navigate(&mut self, _: Box<dyn Any>, _window: &mut Window, _: &mut Context<Self>) -> bool {        false    }     fn telemetry_event_text(&self) -> Option<&'static str> {        None    }     /// (model id, Item)    fn for_each_project_item(        &self,        _: &App,        _: &mut dyn FnMut(EntityId, &dyn project::ProjectItem),    ) {    }    fn buffer_kind(&self, _cx: &App) -> ItemBufferKind {        ItemBufferKind::None    }    fn set_nav_history(&mut self, _: ItemNavHistory, _window: &mut Window, _: &mut Context<Self>) {}     fn can_split(&self) -> bool {        false    }    fn clone_on_split(        &self,        workspace_id: Option<WorkspaceId>,        window: &mut Window,        cx: &mut Context<Self>,    ) -> Task<Option<Entity<Self>>>    where        Self: Sized,    {        _ = (workspace_id, window, cx);        unimplemented!("clone_on_split() must be implemented if can_split() returns true")    }    fn is_dirty(&self, _: &App) -> bool {        false    }    fn capability(&self, _: &App) -> Capability {        Capability::ReadWrite    }     fn toggle_read_only(&mut self, _window: &mut Window, _cx: &mut Context<Self>) {}     fn has_deleted_file(&self, _: &App) -> bool {        false    }    fn has_conflict(&self, _: &App) -> bool {        false    }    fn can_save(&self, _cx: &App) -> bool {        false    }    fn can_save_as(&self, _: &App) -> bool {        false    }    fn save(        &mut self,        _options: SaveOptions,        _project: Entity<Project>,        _window: &mut Window,        _cx: &mut Context<Self>,    ) -> Task<Result<()>> {        unimplemented!("save() must be implemented if can_save() returns true")    }    fn save_as(        &mut self,        _project: Entity<Project>,        _path: ProjectPath,        _window: &mut Window,        _cx: &mut Context<Self>,    ) -> Task<Result<()>> {        unimplemented!("save_as() must be implemented if can_save() returns true")    }    fn reload(        &mut self,        _project: Entity<Project>,        _window: &mut Window,        _cx: &mut Context<Self>,    ) -> Task<Result<()>> {        unimplemented!("reload() must be implemented if can_save() returns true")    }     fn act_as_type<'a>(        &'a self,        type_id: TypeId,        self_handle: &'a Entity<Self>,        _: &'a App,    ) -> Option<AnyEntity> {        if TypeId::of::<Self>() == type_id {            Some(self_handle.clone().into())        } else {            None        }    }     fn as_searchable(&self, _: &Entity<Self>, _: &App) -> Option<Box<dyn SearchableItemHandle>> {        None    }     fn breadcrumb_location(&self, _: &App) -> ToolbarItemLocation {        ToolbarItemLocation::Hidden    }     fn breadcrumbs(&self, _theme: &Theme, _cx: &App) -> Option<Vec<BreadcrumbText>> {        None    }     /// Returns optional elements to render to the left of the breadcrumb.    fn breadcrumb_prefix(        &self,        _window: &mut Window,        _cx: &mut Context<Self>,    ) -> Option<gpui::AnyElement> {        None    }     fn added_to_workspace(        &mut self,        _workspace: &mut Workspace,        _window: &mut Window,        _cx: &mut Context<Self>,    ) {    }     fn show_toolbar(&self) -> bool {        true    }     fn pixel_position_of_cursor(&self, _: &App) -> Option<Point<Pixels>> {        None    }     fn preserve_preview(&self, _cx: &App) -> bool {        false    }     fn include_in_nav_history() -> bool {        true    }} pub trait SerializableItem: Item {    fn serialized_item_kind() -> &'static str;     fn cleanup(        workspace_id: WorkspaceId,        alive_items: Vec<ItemId>,        window: &mut Window,        cx: &mut App,    ) -> Task<Result<()>>;     fn deserialize(        _project: Entity<Project>,        _workspace: WeakEntity<Workspace>,        _workspace_id: WorkspaceId,        _item_id: ItemId,        _window: &mut Window,        _cx: &mut App,    ) -> Task<Result<Entity<Self>>>;     fn serialize(        &mut self,        workspace: &mut Workspace,        item_id: ItemId,        closing: bool,        window: &mut Window,        cx: &mut Context<Self>,    ) -> Option<Task<Result<()>>>;     fn should_serialize(&self, event: &Self::Event) -> bool;} pub trait SerializableItemHandle: ItemHandle {    fn serialized_item_kind(&self) -> &'static str;    fn serialize(        &self,        workspace: &mut Workspace,        closing: bool,        window: &mut Window,        cx: &mut App,    ) -> Option<Task<Result<()>>>;    fn should_serialize(&self, event: &dyn Any, cx: &App) -> bool;} impl<T> SerializableItemHandle for Entity<T>where    T: SerializableItem,{    fn serialized_item_kind(&self) -> &'static str {        T::serialized_item_kind()    }     fn serialize(        &self,        workspace: &mut Workspace,        closing: bool,        window: &mut Window,        cx: &mut App,    ) -> Option<Task<Result<()>>> {        self.update(cx, |this, cx| {            this.serialize(workspace, cx.entity_id().as_u64(), closing, window, cx)        })    }     fn should_serialize(&self, event: &dyn Any, cx: &App) -> bool {        event            .downcast_ref::<T::Event>()            .is_some_and(|event| self.read(cx).should_serialize(event))    }} pub trait ItemHandle: 'static + Send {    fn item_focus_handle(&self, cx: &App) -> FocusHandle;    fn subscribe_to_item_events(        &self,        window: &mut Window,        cx: &mut App,        handler: Box<dyn Fn(ItemEvent, &mut Window, &mut App)>,    ) -> gpui::Subscription;    fn tab_content(&self, params: TabContentParams, window: &Window, cx: &App) -> AnyElement;    fn tab_content_text(&self, detail: usize, cx: &App) -> SharedString;    fn suggested_filename(&self, cx: &App) -> SharedString;    fn tab_icon(&self, window: &Window, cx: &App) -> Option<Icon>;    fn tab_tooltip_text(&self, cx: &App) -> Option<SharedString>;    fn tab_tooltip_content(&self, cx: &App) -> Option<TabTooltipContent>;    fn telemetry_event_text(&self, cx: &App) -> Option<&'static str>;    fn dragged_tab_content(        &self,        params: TabContentParams,        window: &Window,        cx: &App,    ) -> AnyElement;    fn project_path(&self, cx: &App) -> Option<ProjectPath>;    fn project_entry_ids(&self, cx: &App) -> SmallVec<[ProjectEntryId; 3]>;    fn project_paths(&self, cx: &App) -> SmallVec<[ProjectPath; 3]>;    fn project_item_model_ids(&self, cx: &App) -> SmallVec<[EntityId; 3]>;    fn for_each_project_item(        &self,        _: &App,        _: &mut dyn FnMut(EntityId, &dyn project::ProjectItem),    );    fn buffer_kind(&self, cx: &App) -> ItemBufferKind;    fn boxed_clone(&self) -> Box<dyn ItemHandle>;    fn can_split(&self, cx: &App) -> bool;    fn clone_on_split(        &self,        workspace_id: Option<WorkspaceId>,        window: &mut Window,        cx: &mut App,    ) -> Task<Option<Box<dyn ItemHandle>>>;    fn added_to_pane(        &self,        workspace: &mut Workspace,        pane: Entity<Pane>,        window: &mut Window,        cx: &mut Context<Workspace>,    );    fn deactivated(&self, window: &mut Window, cx: &mut App);    fn on_removed(&self, cx: &App);    fn workspace_deactivated(&self, window: &mut Window, cx: &mut App);    fn navigate(&self, data: Box<dyn Any>, window: &mut Window, cx: &mut App) -> bool;    fn item_id(&self) -> EntityId;    fn to_any_view(&self) -> AnyView;    fn is_dirty(&self, cx: &App) -> bool;    fn capability(&self, cx: &App) -> Capability;    fn toggle_read_only(&self, window: &mut Window, cx: &mut App);    fn has_deleted_file(&self, cx: &App) -> bool;    fn has_conflict(&self, cx: &App) -> bool;    fn can_save(&self, cx: &App) -> bool;    fn can_save_as(&self, cx: &App) -> bool;    fn save(        &self,        options: SaveOptions,        project: Entity<Project>,        window: &mut Window,        cx: &mut App,    ) -> Task<Result<()>>;    fn save_as(

Lines 1–500 of 1730.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t