From ca0d7e5e1f52c5b8d1815109aa7438cc3434d2bf Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 18 Dec 2021 08:12:59 -0700 Subject: [PATCH] Add journal crate and move supporting logic into workspace crate I needed to interact with the workspace to open a file from the journal crate, so I moved a bunch of logic out of main related to opening new workspaces and paths. --- Cargo.lock | 82 ++++----- crates/journal/Cargo.toml | 16 ++ crates/journal/src/journal.rs | 65 ++++++++ crates/theme_selector/src/theme_selector.rs | 12 +- crates/util/src/lib.rs | 5 +- crates/workspace/Cargo.toml | 1 + crates/workspace/src/workspace.rs | 126 +++++++++++++- crates/zed/Cargo.toml | 9 +- crates/zed/src/main.rs | 11 +- crates/zed/src/menus.rs | 16 +- crates/zed/src/test.rs | 4 +- crates/zed/src/zed.rs | 174 ++++---------------- 12 files changed, 299 insertions(+), 222 deletions(-) create mode 100644 crates/journal/Cargo.toml create mode 100644 crates/journal/src/journal.rs diff --git a/Cargo.lock b/Cargo.lock index 0aadd18f66..09e08a510b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -633,17 +633,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] - [[package]] name = "blake3" version = "0.3.8" @@ -1437,6 +1426,15 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -1449,12 +1447,12 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" dependencies = [ "libc", - "redox_users 0.3.5", + "redox_users", "winapi", ] @@ -1465,7 +1463,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", - "redox_users 0.4.0", + "redox_users", "winapi", ] @@ -2499,6 +2497,19 @@ dependencies = [ "libc", ] +[[package]] +name = "journal" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "dirs 4.0.0", + "gpui", + "log", + "util", + "workspace", +] + [[package]] name = "jpeg-decoder" version = "0.1.22" @@ -3130,7 +3141,7 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.5", + "redox_syscall", "smallvec", "winapi", ] @@ -3697,12 +3708,6 @@ dependencies = [ "rand_core 0.3.1", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.2.5" @@ -3712,17 +3717,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "redox_users" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" -dependencies = [ - "getrandom 0.1.16", - "redox_syscall 0.1.57", - "rust-argon2", -] - [[package]] name = "redox_users" version = "0.4.0" @@ -3730,7 +3724,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ "getrandom 0.2.2", - "redox_syscall 0.2.5", + "redox_syscall", ] [[package]] @@ -3858,18 +3852,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rust-argon2" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" -dependencies = [ - "base64 0.13.0", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", -] - [[package]] name = "rust-embed" version = "6.2.0" @@ -4522,7 +4504,7 @@ dependencies = [ "crossbeam-channel", "crossbeam-queue", "crossbeam-utils", - "dirs", + "dirs 3.0.1", "either", "futures-channel", "futures-core", @@ -4827,7 +4809,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "rand 0.8.3", - "redox_syscall 0.2.5", + "redox_syscall", "remove_dir_all", "winapi", ] @@ -5649,6 +5631,7 @@ dependencies = [ "gpui", "language", "log", + "parking_lot", "postage", "project", "serde_json", @@ -5693,7 +5676,7 @@ dependencies = [ "contacts_panel", "crossbeam-channel", "ctor", - "dirs", + "dirs 3.0.1", "easy-parallel", "editor", "env_logger", @@ -5707,6 +5690,7 @@ dependencies = [ "ignore", "image", "indexmap", + "journal", "language", "lazy_static", "libc", diff --git a/crates/journal/Cargo.toml b/crates/journal/Cargo.toml new file mode 100644 index 0000000000..64786f34ae --- /dev/null +++ b/crates/journal/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "journal" +version = "0.1.0" +edition = "2021" + +[lib] +path = "src/journal.rs" + +[dependencies] +gpui = { path = "../gpui" } +util = { path = "../util" } +workspace = { path = "../workspace" } +anyhow = "1.0" +chrono = "0.4" +dirs = "4.0" +log = "0.4" \ No newline at end of file diff --git a/crates/journal/src/journal.rs b/crates/journal/src/journal.rs new file mode 100644 index 0000000000..68a77295ce --- /dev/null +++ b/crates/journal/src/journal.rs @@ -0,0 +1,65 @@ +use std::{fs::OpenOptions, sync::Arc}; + +use anyhow::anyhow; +use chrono::{Datelike, Local}; +use gpui::{action, keymap::Binding, MutableAppContext}; +use util::TryFutureExt as _; +use workspace::AppState; + +action!(NewJournalEntry); + +pub fn init(app_state: Arc, cx: &mut MutableAppContext) { + log::info!("JOURNAL INIT"); + cx.add_bindings(vec![Binding::new("ctrl-alt-cmd-j", NewJournalEntry, None)]); + + let mut counter = 0; + cx.add_global_action(move |_: &NewJournalEntry, cx| { + log::info!("NEW JOURNAL ENTRY ACTION"); + counter += 1; + if counter == 2 { + log::info!("called twice?"); + } + new_journal_entry(app_state.clone(), cx) + }); +} + +pub fn new_journal_entry(app_state: Arc, cx: &mut MutableAppContext) { + log::info!("NEW JOURNAL ENTRY"); + let paths = cx.background().spawn(async move { + let now = Local::now(); + let home_dir = dirs::home_dir().ok_or_else(|| anyhow!("can't determine home directory"))?; + let journal_dir = home_dir.join("journal"); + let month_dir = journal_dir + .join(now.year().to_string()) + .join(now.month().to_string()); + let entry_path = month_dir.join(format!("{}.md", now.day())); + + std::fs::create_dir_all(dbg!(month_dir))?; + OpenOptions::new() + .create(true) + .write(true) + .open(dbg!(&entry_path))?; + + Ok::<_, anyhow::Error>((journal_dir, entry_path)) + }); + + cx.spawn(|mut cx| { + async move { + let (journal_dir, entry_path) = paths.await?; + let workspace = cx + .update(|cx| workspace::open_paths(&[journal_dir], &app_state, cx)) + .await; + + workspace + .update(&mut cx, |workspace, cx| { + workspace.open_paths(&[entry_path], cx) + }) + .await; + + dbg!(workspace); + Ok(()) + } + .log_err() + }) + .detach(); +} diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 545b512a8b..ef5512a3ea 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -11,7 +11,7 @@ use parking_lot::Mutex; use postage::watch; use std::{cmp, sync::Arc}; use theme::ThemeRegistry; -use workspace::{Settings, Workspace}; +use workspace::{Settings, Workspace, AppState}; #[derive(Clone)] pub struct ThemeSelectorParams { @@ -317,3 +317,13 @@ impl View for ThemeSelector { cx } } + +impl<'a> From<&'a AppState> for ThemeSelectorParams { + fn from(state: &'a AppState) -> Self { + Self { + settings_tx: state.settings_tx.clone(), + settings: state.settings.clone(), + themes: state.themes.clone(), + } + } +} diff --git a/crates/util/src/lib.rs b/crates/util/src/lib.rs index 66a36889f5..b0c66b005b 100644 --- a/crates/util/src/lib.rs +++ b/crates/util/src/lib.rs @@ -43,7 +43,10 @@ pub trait ResultExt { fn warn_on_err(self) -> Option; } -impl ResultExt for anyhow::Result { +impl ResultExt for Result +where + E: std::fmt::Debug, +{ type Ok = T; fn log_err(self) -> Option { diff --git a/crates/workspace/Cargo.toml b/crates/workspace/Cargo.toml index a5ca3c91e9..497254074e 100644 --- a/crates/workspace/Cargo.toml +++ b/crates/workspace/Cargo.toml @@ -17,6 +17,7 @@ project = { path = "../project" } theme = { path = "../theme" } anyhow = "1.0.38" log = "0.4" +parking_lot = "0.11.1" postage = { version = "0.4.1", features = ["futures-traits"] } [dev-dependencies] diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 1f11f11693..87f792054b 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -13,16 +13,18 @@ use gpui::{ geometry::{vector::vec2f, PathBuilder}, json::{self, to_string_pretty, ToJson}, keymap::Binding, - platform::CursorStyle, + platform::{CursorStyle, WindowOptions}, AnyViewHandle, AppContext, ClipboardItem, Entity, ModelContext, ModelHandle, MutableAppContext, - PromptLevel, RenderContext, Task, View, ViewContext, ViewHandle, WeakModelHandle, + PathPromptOptions, PromptLevel, RenderContext, Task, View, ViewContext, ViewHandle, + WeakModelHandle, }; use language::LanguageRegistry; use log::error; pub use pane::*; pub use pane_group::*; +use parking_lot::Mutex; use postage::{prelude::Stream, watch}; -use project::{Fs, Project, ProjectPath, Worktree}; +use project::{fs, Fs, Project, ProjectPath, Worktree}; pub use settings::Settings; use sidebar::{Side, Sidebar, SidebarItemId, ToggleSidebarItem, ToggleSidebarItemFocus}; use status_bar::StatusBar; @@ -33,13 +35,23 @@ use std::{ path::{Path, PathBuf}, sync::Arc, }; -use theme::Theme; +use theme::{Theme, ThemeRegistry}; -action!(OpenNew, WorkspaceParams); +action!(Open, Arc); +action!(OpenNew, Arc); +action!(OpenPaths, OpenParams); action!(Save); action!(DebugElements); pub fn init(cx: &mut MutableAppContext) { + cx.add_global_action(open); + cx.add_global_action(move |action: &OpenPaths, cx: &mut MutableAppContext| { + open_paths(&action.0.paths, &action.0.app_state, cx).detach() + }); + cx.add_global_action(move |action: &OpenNew, cx: &mut MutableAppContext| { + open_new(&action.0, cx) + }); + cx.add_action(Workspace::save_active_item); cx.add_action(Workspace::debug_elements); cx.add_action(Workspace::toggle_sidebar_item); @@ -67,6 +79,27 @@ pub fn init(cx: &mut MutableAppContext) { pane::init(cx); } +pub struct AppState { + pub settings_tx: Arc>>, + pub settings: watch::Receiver, + pub languages: Arc, + pub themes: Arc, + pub client: Arc, + pub user_store: ModelHandle, + pub fs: Arc, + pub channel_list: ModelHandle, + pub entry_openers: Arc<[Box]>, + pub build_window_options: &'static dyn Fn() -> WindowOptions<'static>, + pub build_workspace: + &'static dyn Fn(&WorkspaceParams, &mut ViewContext) -> Workspace, +} + +#[derive(Clone)] +pub struct OpenParams { + pub paths: Vec, + pub app_state: Arc, +} + pub trait EntryOpener { fn open( &self, @@ -1226,3 +1259,86 @@ impl Element for AvatarRibbon { }) } } + +impl std::fmt::Debug for OpenParams { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("OpenParams") + .field("paths", &self.paths) + .finish() + } +} + +impl<'a> From<&'a AppState> for WorkspaceParams { + fn from(state: &'a AppState) -> Self { + Self { + client: state.client.clone(), + fs: state.fs.clone(), + languages: state.languages.clone(), + settings: state.settings.clone(), + user_store: state.user_store.clone(), + channel_list: state.channel_list.clone(), + entry_openers: state.entry_openers.clone(), + } + } +} + +fn open(action: &Open, cx: &mut MutableAppContext) { + let app_state = action.0.clone(); + cx.prompt_for_paths( + PathPromptOptions { + files: true, + directories: true, + multiple: true, + }, + move |paths, cx| { + if let Some(paths) = paths { + cx.dispatch_global_action(OpenPaths(OpenParams { paths, app_state })); + } + }, + ); +} + +pub fn open_paths( + abs_paths: &[PathBuf], + app_state: &Arc, + cx: &mut MutableAppContext, +) -> Task> { + log::info!("open paths {:?}", abs_paths); + + // Open paths in existing workspace if possible + let mut existing = None; + for window_id in cx.window_ids().collect::>() { + if let Some(workspace) = cx.root_view::(window_id) { + if workspace.update(cx, |view, cx| { + if view.contains_paths(abs_paths, cx.as_ref()) { + existing = Some(workspace.clone()); + true + } else { + false + } + }) { + break; + } + } + } + + let workspace = existing.unwrap_or_else(|| { + cx.add_window((app_state.build_window_options)(), |cx| { + (app_state.build_workspace)(&WorkspaceParams::from(app_state.as_ref()), cx) + }) + .1 + }); + + let task = workspace.update(cx, |workspace, cx| workspace.open_paths(abs_paths, cx)); + cx.spawn(|_| async move { + task.await; + workspace + }) +} + +fn open_new(app_state: &Arc, cx: &mut MutableAppContext) { + let (window_id, workspace) = cx.add_window((app_state.build_window_options)(), |cx| { + (app_state.build_workspace)(&app_state.as_ref().into(), cx) + }); + cx.dispatch_action(window_id, vec![workspace.id()], &OpenNew(app_state.clone())); +} diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index e03ef6dcf9..adcd7365ae 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -28,23 +28,24 @@ test-support = [ ] [dependencies] -text = { path = "../text" } chat_panel = { path = "../chat_panel" } client = { path = "../client" } clock = { path = "../clock" } -fsevent = { path = "../fsevent" } -fuzzy = { path = "../fuzzy" } +contacts_panel = { path = "../contacts_panel" } editor = { path = "../editor" } file_finder = { path = "../file_finder" } +fsevent = { path = "../fsevent" } +fuzzy = { path = "../fuzzy" } go_to_line = { path = "../go_to_line" } gpui = { path = "../gpui" } +journal = { path = "../journal" } language = { path = "../language" } lsp = { path = "../lsp" } -contacts_panel = { path = "../contacts_panel" } project = { path = "../project" } project_panel = { path = "../project_panel" } rpc = { path = "../rpc" } sum_tree = { path = "../sum_tree" } +text = { path = "../text" } theme = { path = "../theme" } theme_selector = { path = "../theme_selector" } util = { path = "../util" } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index c6374c66e7..34828b7fa7 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -9,8 +9,10 @@ use parking_lot::Mutex; use simplelog::SimpleLogger; use std::{fs, path::PathBuf, sync::Arc}; use theme::{ThemeRegistry, DEFAULT_THEME_NAME}; -use workspace::{self, settings, OpenNew, Settings}; -use zed::{self, assets::Assets, fs::RealFs, language, menus, AppState, OpenParams, OpenPaths}; +use workspace::{self, settings, AppState, OpenNew, OpenParams, OpenPaths, Settings}; +use zed::{ + self, assets::Assets, build_window_options, build_workspace, fs::RealFs, language, menus, +}; fn main() { init_logger(); @@ -71,7 +73,10 @@ fn main() { user_store, fs: Arc::new(RealFs), entry_openers: Arc::from(entry_openers), + build_window_options: &build_window_options, + build_workspace: &build_workspace, }); + journal::init(app_state.clone(), cx); zed::init(&app_state, cx); theme_selector::init(app_state.as_ref().into(), cx); @@ -83,7 +88,7 @@ fn main() { let paths = collect_path_args(); if paths.is_empty() { - cx.dispatch_global_action(OpenNew(app_state.as_ref().into())); + cx.dispatch_global_action(OpenNew(app_state.clone())); } else { cx.dispatch_global_action(OpenPaths(OpenParams { paths, app_state })); } diff --git a/crates/zed/src/menus.rs b/crates/zed/src/menus.rs index 25a4b5e6f9..33ac76e63c 100644 --- a/crates/zed/src/menus.rs +++ b/crates/zed/src/menus.rs @@ -1,19 +1,9 @@ -use crate::{AppState, WorkspaceParams}; +use crate::AppState; use gpui::{Menu, MenuItem}; use std::sync::Arc; #[cfg(target_os = "macos")] pub fn menus(state: &Arc) -> Vec> { - let workspace_params = WorkspaceParams { - client: state.client.clone(), - fs: state.fs.clone(), - languages: state.languages.clone(), - settings: state.settings.clone(), - user_store: state.user_store.clone(), - channel_list: state.channel_list.clone(), - entry_openers: state.entry_openers.clone(), - }; - vec![ Menu { name: "Zed", @@ -37,13 +27,13 @@ pub fn menus(state: &Arc) -> Vec> { MenuItem::Action { name: "New", keystroke: Some("cmd-n"), - action: Box::new(workspace::OpenNew(workspace_params)), + action: Box::new(workspace::OpenNew(state.clone())), }, MenuItem::Separator, MenuItem::Action { name: "Open…", keystroke: Some("cmd-o"), - action: Box::new(crate::Open(state.clone())), + action: Box::new(workspace::Open(state.clone())), }, ], }, diff --git a/crates/zed/src/test.rs b/crates/zed/src/test.rs index 91f1c165ee..a495b2689d 100644 --- a/crates/zed/src/test.rs +++ b/crates/zed/src/test.rs @@ -1,4 +1,4 @@ -use crate::{assets::Assets, AppState}; +use crate::{assets::Assets, build_window_options, AppState, build_workspace}; use client::{http::ServerResponse, test::FakeHttpClient, ChannelList, Client, UserStore}; use gpui::{AssetSource, MutableAppContext}; use language::LanguageRegistry; @@ -42,6 +42,8 @@ pub fn test_app_state(cx: &mut MutableAppContext) -> Arc { user_store, fs: Arc::new(FakeFs::new()), entry_openers: Arc::from(entry_openers), + build_window_options: &build_window_options, + build_workspace: &build_workspace, }) } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 16f67fa171..3c3f4f7f45 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -4,7 +4,6 @@ pub mod menus; #[cfg(any(test, feature = "test-support"))] pub mod test; -use self::language::LanguageRegistry; use chat_panel::ChatPanel; pub use client; pub use contacts_panel; @@ -15,51 +14,22 @@ use gpui::{ geometry::vector::vec2f, keymap::Binding, platform::{WindowBounds, WindowOptions}, - ModelHandle, MutableAppContext, PathPromptOptions, Task, ViewContext, + ViewContext, }; pub use lsp; -use parking_lot::Mutex; -use postage::watch; pub use project::{self, fs}; use project_panel::ProjectPanel; -use std::{path::PathBuf, sync::Arc}; -use theme::ThemeRegistry; -use theme_selector::ThemeSelectorParams; +use std::sync::Arc; pub use workspace; -use workspace::{OpenNew, Settings, Workspace, WorkspaceParams}; +use workspace::{AppState, Workspace, WorkspaceParams}; action!(About); -action!(Open, Arc); -action!(OpenPaths, OpenParams); action!(Quit); action!(AdjustBufferFontSize, f32); const MIN_FONT_SIZE: f32 = 6.0; -pub struct AppState { - pub settings_tx: Arc>>, - pub settings: watch::Receiver, - pub languages: Arc, - pub themes: Arc, - pub client: Arc, - pub user_store: ModelHandle, - pub fs: Arc, - pub channel_list: ModelHandle, - pub entry_openers: Arc<[Box]>, -} - -#[derive(Clone)] -pub struct OpenParams { - pub paths: Vec, - pub app_state: Arc, -} - pub fn init(app_state: &Arc, cx: &mut gpui::MutableAppContext) { - cx.add_global_action(open); - cx.add_global_action(|action: &OpenPaths, cx: &mut MutableAppContext| { - open_paths(action, cx).detach() - }); - cx.add_global_action(open_new); cx.add_global_action(quit); cx.add_global_action({ @@ -79,63 +49,7 @@ pub fn init(app_state: &Arc, cx: &mut gpui::MutableAppContext) { ]) } -fn open(action: &Open, cx: &mut MutableAppContext) { - let app_state = action.0.clone(); - cx.prompt_for_paths( - PathPromptOptions { - files: true, - directories: true, - multiple: true, - }, - move |paths, cx| { - if let Some(paths) = paths { - cx.dispatch_global_action(OpenPaths(OpenParams { paths, app_state })); - } - }, - ); -} - -fn open_paths(action: &OpenPaths, cx: &mut MutableAppContext) -> Task<()> { - log::info!("open paths {:?}", action.0.paths); - - // Open paths in existing workspace if possible - for window_id in cx.window_ids().collect::>() { - if let Some(handle) = cx.root_view::(window_id) { - let task = handle.update(cx, |view, cx| { - if view.contains_paths(&action.0.paths, cx.as_ref()) { - log::info!("open paths on existing workspace"); - Some(view.open_paths(&action.0.paths, cx)) - } else { - None - } - }); - - if let Some(task) = task { - return task; - } - } - } - - log::info!("open new workspace"); - - // Add a new workspace if necessary - let app_state = &action.0.app_state; - let (_, workspace) = cx.add_window(window_options(), |cx| { - build_workspace(&WorkspaceParams::from(app_state.as_ref()), cx) - }); - // cx.resize_window(window_id); - workspace.update(cx, |workspace, cx| { - workspace.open_paths(&action.0.paths, cx) - }) -} - -fn open_new(action: &OpenNew, cx: &mut MutableAppContext) { - let (window_id, workspace) = - cx.add_window(window_options(), |cx| build_workspace(&action.0, cx)); - cx.dispatch_action(window_id, vec![workspace.id()], action); -} - -fn build_workspace(params: &WorkspaceParams, cx: &mut ViewContext) -> Workspace { +pub fn build_workspace(params: &WorkspaceParams, cx: &mut ViewContext) -> Workspace { let mut workspace = Workspace::new(params, cx); let project = workspace.project().clone(); workspace.left_sidebar_mut().add_item( @@ -174,7 +88,7 @@ fn build_workspace(params: &WorkspaceParams, cx: &mut ViewContext) -> workspace } -fn window_options() -> WindowOptions<'static> { +pub fn build_window_options() -> WindowOptions<'static> { WindowOptions { bounds: WindowBounds::Maximized, title: None, @@ -187,41 +101,23 @@ fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) { cx.platform().quit(); } -impl<'a> From<&'a AppState> for WorkspaceParams { - fn from(state: &'a AppState) -> Self { - Self { - client: state.client.clone(), - fs: state.fs.clone(), - languages: state.languages.clone(), - settings: state.settings.clone(), - user_store: state.user_store.clone(), - channel_list: state.channel_list.clone(), - entry_openers: state.entry_openers.clone(), - } - } -} - -impl<'a> From<&'a AppState> for ThemeSelectorParams { - fn from(state: &'a AppState) -> Self { - Self { - settings_tx: state.settings_tx.clone(), - settings: state.settings.clone(), - themes: state.themes.clone(), - } - } -} - #[cfg(test)] mod tests { use super::*; use editor::Editor; + use gpui::MutableAppContext; use project::ProjectPath; use serde_json::json; - use std::{collections::HashSet, path::Path}; + use std::{ + collections::HashSet, + path::{Path, PathBuf}, + }; use test::test_app_state; use theme::DEFAULT_THEME_NAME; use util::test::temp_tree; - use workspace::{pane, ItemView, ItemViewHandle, SplitDirection, WorkspaceHandle}; + use workspace::{ + open_paths, pane, ItemView, ItemViewHandle, OpenNew, SplitDirection, WorkspaceHandle, + }; #[gpui::test] async fn test_open_paths_action(mut cx: gpui::TestAppContext) { @@ -243,29 +139,19 @@ mod tests { cx.update(|cx| { open_paths( - &OpenPaths(OpenParams { - paths: vec![ - dir.path().join("a").to_path_buf(), - dir.path().join("b").to_path_buf(), - ], - app_state: app_state.clone(), - }), + &[ + dir.path().join("a").to_path_buf(), + dir.path().join("b").to_path_buf(), + ], + &app_state, cx, ) }) .await; assert_eq!(cx.window_ids().len(), 1); - cx.update(|cx| { - open_paths( - &OpenPaths(OpenParams { - paths: vec![dir.path().join("a").to_path_buf()], - app_state: app_state.clone(), - }), - cx, - ) - }) - .await; + cx.update(|cx| open_paths(&[dir.path().join("a").to_path_buf()], &app_state, cx)) + .await; assert_eq!(cx.window_ids().len(), 1); let workspace_1 = cx.root_view::(cx.window_ids()[0]).unwrap(); workspace_1.read_with(&cx, |workspace, cx| { @@ -274,13 +160,11 @@ mod tests { cx.update(|cx| { open_paths( - &OpenPaths(OpenParams { - paths: vec![ - dir.path().join("b").to_path_buf(), - dir.path().join("c").to_path_buf(), - ], - app_state: app_state.clone(), - }), + &[ + dir.path().join("b").to_path_buf(), + dir.path().join("c").to_path_buf(), + ], + &app_state, cx, ) }) @@ -292,7 +176,7 @@ mod tests { async fn test_new_empty_workspace(mut cx: gpui::TestAppContext) { let app_state = cx.update(test_app_state); cx.update(|cx| init(&app_state, cx)); - cx.dispatch_global_action(workspace::OpenNew(app_state.as_ref().into())); + cx.dispatch_global_action(workspace::OpenNew(app_state.clone())); let window_id = *cx.window_ids().first().unwrap(); let workspace = cx.root_view::(window_id).unwrap(); let editor = workspace.update(&mut cx, |workspace, cx| { @@ -576,7 +460,7 @@ mod tests { }); // Create a new untitled buffer - cx.dispatch_action(window_id, vec![workspace.id()], OpenNew(params.clone())); + cx.dispatch_action(window_id, vec![workspace.id()], OpenNew(app_state.clone())); let editor = workspace.read_with(&cx, |workspace, cx| { workspace .active_item(cx) @@ -639,7 +523,7 @@ mod tests { // Open the same newly-created file in another pane item. The new editor should reuse // the same buffer. - cx.dispatch_action(window_id, vec![workspace.id()], OpenNew(params.clone())); + cx.dispatch_action(window_id, vec![workspace.id()], OpenNew(app_state.clone())); workspace.update(&mut cx, |workspace, cx| { workspace.split_pane(workspace.active_pane().clone(), SplitDirection::Right, cx); assert!(workspace @@ -675,7 +559,7 @@ mod tests { let (window_id, workspace) = cx.add_window(|cx| Workspace::new(¶ms, cx)); // Create a new untitled buffer - cx.dispatch_action(window_id, vec![workspace.id()], OpenNew(params.clone())); + cx.dispatch_action(window_id, vec![workspace.id()], OpenNew(app_state.clone())); let editor = workspace.read_with(&cx, |workspace, cx| { workspace .active_item(cx)