diff --git a/Cargo.lock b/Cargo.lock index 7b653eeed43a5cf723f37e229c549c3204105713..6ade8ba1a03351b12d818d7550f61101f9bf139a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1532,6 +1532,7 @@ dependencies = [ "log", "parking_lot", "postage", + "project", "rand 0.8.3", "serde", "smallvec", diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index 7f5ffec97ee79f7bb5761feb521ef80fefc7e26c..32bac7b7a01488757c0a75307796ddeda4020c52 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -15,6 +15,7 @@ buffer = { path = "../buffer" } clock = { path = "../clock" } gpui = { path = "../gpui" } language = { path = "../language" } +project = { path = "../project" } sum_tree = { path = "../sum_tree" } theme = { path = "../theme" } util = { path = "../util" } diff --git a/crates/workspace/src/lib.rs b/crates/workspace/src/lib.rs index 0ca07d2246b19ac125284dba4403719fde05f10d..1073ea96a508e4fddb48aa4484b8e1679ca02a91 100644 --- a/crates/workspace/src/lib.rs +++ b/crates/workspace/src/lib.rs @@ -5,12 +5,12 @@ pub mod settings; pub mod sidebar; mod status_bar; -use anyhow::Result; +use anyhow::{anyhow, Result}; use client::{Authenticate, ChannelList, Client, UserStore}; use gpui::{ action, elements::*, json::to_string_pretty, keymap::Binding, platform::CursorStyle, - AnyViewHandle, AppContext, ClipboardItem, Entity, ModelHandle, MutableAppContext, PromptLevel, - RenderContext, Task, View, ViewContext, ViewHandle, WeakModelHandle, + AnyViewHandle, AppContext, ClipboardItem, Entity, ModelContext, ModelHandle, MutableAppContext, + PromptLevel, RenderContext, Task, View, ViewContext, ViewHandle, WeakModelHandle, }; use language::{Buffer, LanguageRegistry}; use log::error; @@ -33,7 +33,28 @@ action!(OpenNew, WorkspaceParams); action!(Save); action!(DebugElements); -pub fn init(cx: &mut MutableAppContext) { +struct BufferOpener; + +impl EntryOpener for BufferOpener { + fn open( + &self, + worktree: &mut Worktree, + project_path: ProjectPath, + cx: &mut ModelContext, + ) -> Option>>> { + let buffer = worktree.open_buffer(project_path.path, cx); + let task = cx.spawn(|_, _| async move { + buffer + .await + .map(|buffer| Box::new(buffer) as Box) + }); + Some(task) + } +} + +pub fn init(cx: &mut MutableAppContext, entry_openers: &mut Vec>) { + entry_openers.push(Box::new(BufferOpener)); + cx.add_action(Workspace::save_active_item); cx.add_action(Workspace::debug_elements); cx.add_action(Workspace::open_new_file); @@ -62,6 +83,15 @@ pub fn init(cx: &mut MutableAppContext) { pane::init(cx); } +pub trait EntryOpener { + fn open( + &self, + worktree: &mut Worktree, + path: ProjectPath, + cx: &mut ModelContext, + ) -> Option>>>; +} + pub trait Item: Entity + Sized { type View: ItemView; @@ -268,6 +298,7 @@ pub struct WorkspaceParams { pub settings: watch::Receiver, pub user_store: ModelHandle, pub channel_list: ModelHandle, + pub entry_openers: Arc<[Box]>, } impl WorkspaceParams { @@ -299,6 +330,7 @@ impl WorkspaceParams { languages: Arc::new(languages), settings: watch::channel_with(settings).1, user_store, + entry_openers: Arc::from([]), } } } @@ -316,6 +348,7 @@ pub struct Workspace { active_pane: ViewHandle, status_bar: ViewHandle, project: ModelHandle, + entry_openers: Arc<[Box]>, items: Vec>, loading_items: HashMap< ProjectPath, @@ -388,6 +421,7 @@ impl Workspace { left_sidebar: Sidebar::new(Side::Left), right_sidebar: Sidebar::new(Side::Right), project, + entry_openers: params.entry_openers.clone(), items: Default::default(), loading_items: Default::default(), _observe_current_user, @@ -600,18 +634,21 @@ impl Workspace { entry.insert(rx); let project_path = project_path.clone(); + let entry_openers = self.entry_openers.clone(); cx.as_mut() .spawn(|mut cx| async move { - let buffer = worktree - .update(&mut cx, |worktree, cx| { - worktree.open_buffer(project_path.path.as_ref(), cx) + let item = worktree.update(&mut cx, move |worktree, cx| { + for opener in entry_openers.iter() { + if let Some(task) = opener.open(worktree, project_path.clone(), cx) { + return task; + } + } + + cx.spawn(|_, _| async move { + Err(anyhow!("no opener for path {:?} found", project_path)) }) - .await; - *tx.borrow_mut() = Some( - buffer - .map(|buffer| Box::new(buffer) as Box) - .map_err(Arc::new), - ); + }); + *tx.borrow_mut() = Some(item.await.map_err(Arc::new)); }) .detach(); } diff --git a/crates/zed/src/lib.rs b/crates/zed/src/lib.rs index 4590230851da2bb43aff41f5fa69e0bdf5e95cac..cbc8ef803da04f090f779b9855f022a1904bc781 100644 --- a/crates/zed/src/lib.rs +++ b/crates/zed/src/lib.rs @@ -45,6 +45,7 @@ pub struct AppState { pub user_store: ModelHandle, pub fs: Arc, pub channel_list: ModelHandle, + pub entry_openers: Arc<[Box]>, } #[derive(Clone)] @@ -185,6 +186,7 @@ impl<'a> From<&'a AppState> for WorkspaceParams { settings: state.settings.clone(), user_store: state.user_store.clone(), channel_list: state.channel_list.clone(), + entry_openers: state.entry_openers.clone(), } } } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index d2357ea3c37ea2a0476957918eee27f001888972..8dd2dc53e684a963b793b8ece4ee827d21d9ad74 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -33,6 +33,16 @@ fn main() { let client = client::Client::new(); let http = http::client(); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx)); + let mut entry_openers = Vec::new(); + + client::init(client.clone(), cx); + workspace::init(cx, &mut entry_openers); + editor::init(cx); + file_finder::init(cx); + people_panel::init(cx); + chat_panel::init(cx); + project_panel::init(cx); + let app_state = Arc::new(AppState { languages: languages.clone(), settings_tx: Arc::new(Mutex::new(settings_tx)), @@ -43,16 +53,9 @@ fn main() { client, user_store, fs: Arc::new(RealFs), + entry_openers: Arc::from(entry_openers), }); - zed::init(&app_state, cx); - client::init(app_state.client.clone(), cx); - workspace::init(cx); - editor::init(cx); - file_finder::init(cx); - people_panel::init(cx); - chat_panel::init(cx); - project_panel::init(cx); theme_selector::init(app_state.as_ref().into(), cx); cx.set_menus(menus::menus(&app_state.clone())); diff --git a/crates/zed/src/menus.rs b/crates/zed/src/menus.rs index 52557e3904d90bc2090e59e0cdc5db6a5ca275f0..25a4b5e6f96d85683b05dbd93819866e683c4d86 100644 --- a/crates/zed/src/menus.rs +++ b/crates/zed/src/menus.rs @@ -11,6 +11,7 @@ pub fn menus(state: &Arc) -> Vec> { settings: state.settings.clone(), user_store: state.user_store.clone(), channel_list: state.channel_list.clone(), + entry_openers: state.entry_openers.clone(), }; vec![ diff --git a/crates/zed/src/test.rs b/crates/zed/src/test.rs index 8a7a3989100bbea4bc55b862f526f3749f1a8b73..f868ab704b47e1cd6eb9540ba2d2f44bd52fbf6b 100644 --- a/crates/zed/src/test.rs +++ b/crates/zed/src/test.rs @@ -30,6 +30,7 @@ pub fn test_app_state(cx: &mut MutableAppContext) -> Arc { client, user_store, fs: Arc::new(FakeFs::new()), + entry_openers: Arc::from([]), }) }