mod.rs

  1pub mod pane;
  2pub mod pane_group;
  3pub mod workspace;
  4pub mod workspace_view;
  5
  6pub use pane::*;
  7pub use pane_group::*;
  8pub use workspace::*;
  9pub use workspace_view::*;
 10
 11use crate::{
 12    settings::Settings,
 13    watch::{self, Receiver},
 14};
 15use gpui::{MutableAppContext, PathPromptOptions};
 16use std::path::PathBuf;
 17
 18pub fn init(app: &mut MutableAppContext) {
 19    app.add_global_action("workspace:open", open);
 20    app.add_global_action("workspace:open_paths", open_paths);
 21    app.add_global_action("app:quit", quit);
 22    pane::init(app);
 23    workspace_view::init(app);
 24}
 25
 26pub struct OpenParams {
 27    pub paths: Vec<PathBuf>,
 28    pub settings: watch::Receiver<Settings>,
 29}
 30
 31fn open(settings: &Receiver<Settings>, ctx: &mut MutableAppContext) {
 32    if let Some(paths) = ctx.platform().prompt_for_paths(PathPromptOptions {
 33        files: true,
 34        directories: true,
 35        multiple: true,
 36    }) {
 37        ctx.dispatch_global_action(
 38            "workspace:open_paths",
 39            OpenParams {
 40                paths,
 41                settings: settings.clone(),
 42            },
 43        );
 44    }
 45}
 46
 47fn open_paths(params: &OpenParams, app: &mut MutableAppContext) {
 48    log::info!("open paths {:?}", params.paths);
 49
 50    // Open paths in existing workspace if possible
 51    for window_id in app.window_ids().collect::<Vec<_>>() {
 52        if let Some(handle) = app.root_view::<WorkspaceView>(window_id) {
 53            if handle.update(app, |view, ctx| {
 54                if view.contains_paths(&params.paths, ctx.app()) {
 55                    view.open_paths(&params.paths, ctx.app_mut());
 56                    log::info!("open paths on existing workspace");
 57                    true
 58                } else {
 59                    false
 60                }
 61            }) {
 62                return;
 63            }
 64        }
 65    }
 66
 67    log::info!("open new workspace");
 68
 69    // Add a new workspace if necessary
 70    let workspace = app.add_model(|ctx| Workspace::new(params.paths.clone(), ctx));
 71    app.add_window(|ctx| WorkspaceView::new(workspace, params.settings.clone(), ctx));
 72}
 73
 74fn quit(_: &(), app: &mut MutableAppContext) {
 75    app.platform().quit();
 76}
 77
 78#[cfg(test)]
 79mod tests {
 80    use super::*;
 81    use crate::{settings, test::*};
 82    use gpui::App;
 83    use serde_json::json;
 84
 85    #[test]
 86    fn test_open_paths_action() {
 87        App::test((), |app| {
 88            let settings = settings::channel(&app.font_cache()).unwrap().1;
 89
 90            init(app);
 91
 92            let dir = temp_tree(json!({
 93                "a": {
 94                    "aa": null,
 95                    "ab": null,
 96                },
 97                "b": {
 98                    "ba": null,
 99                    "bb": null,
100                },
101                "c": {
102                    "ca": null,
103                    "cb": null,
104                },
105            }));
106
107            app.dispatch_global_action(
108                "workspace:open_paths",
109                OpenParams {
110                    paths: vec![
111                        dir.path().join("a").to_path_buf(),
112                        dir.path().join("b").to_path_buf(),
113                    ],
114                    settings: settings.clone(),
115                },
116            );
117            assert_eq!(app.window_ids().count(), 1);
118
119            app.dispatch_global_action(
120                "workspace:open_paths",
121                OpenParams {
122                    paths: vec![dir.path().join("a").to_path_buf()],
123                    settings: settings.clone(),
124                },
125            );
126            assert_eq!(app.window_ids().count(), 1);
127            let workspace_view_1 = app
128                .root_view::<WorkspaceView>(app.window_ids().next().unwrap())
129                .unwrap();
130            assert_eq!(
131                workspace_view_1
132                    .read(app)
133                    .workspace
134                    .read(app)
135                    .worktrees()
136                    .len(),
137                2
138            );
139
140            app.dispatch_global_action(
141                "workspace:open_paths",
142                OpenParams {
143                    paths: vec![
144                        dir.path().join("b").to_path_buf(),
145                        dir.path().join("c").to_path_buf(),
146                    ],
147                    settings: settings.clone(),
148                },
149            );
150            assert_eq!(app.window_ids().count(), 2);
151        });
152    }
153}