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