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