Replace build_workspace fn with an initialize function that takes a workspace

This makes it clearer that the function is not providing necessary
dependencies to a workspace, but rather configuring it with all of
the panels and widgets which are defined in downstream crates.
This commit is contained in:
Max Brunsfeld 2022-05-19 14:56:40 -07:00
parent 9e47e19f4e
commit c4554c1720
6 changed files with 125 additions and 115 deletions

View file

@ -6598,7 +6598,7 @@ mod tests {
themes: ThemeRegistry::new((), cx.font_cache()), themes: ThemeRegistry::new((), cx.font_cache()),
fs: FakeFs::new(cx.background()), fs: FakeFs::new(cx.background()),
build_window_options: || Default::default(), build_window_options: || Default::default(),
build_workspace: |_, _, _| unimplemented!(), initialize_workspace: |_, _, _| unimplemented!(),
}); });
Channel::init(&client); Channel::init(&client);

View file

@ -1111,8 +1111,8 @@ mod tests {
client, client,
user_store: user_store.clone(), user_store: user_store.clone(),
fs, fs,
build_window_options: || unimplemented!(), build_window_options: || Default::default(),
build_workspace: |_, _, _| unimplemented!(), initialize_workspace: |_, _, _| {},
}), }),
server, server,
) )

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
sidebar::{Side, ToggleSidebarItem}, sidebar::{Side, ToggleSidebarItem},
AppState, ToggleFollow, AppState, ToggleFollow, Workspace,
}; };
use anyhow::Result; use anyhow::Result;
use client::{proto, Client, Contact}; use client::{proto, Client, Contact};
@ -77,86 +77,87 @@ impl WaitingRoom {
) -> Self { ) -> Self {
let project_id = contact.projects[project_index].id; let project_id = contact.projects[project_index].id;
let client = app_state.client.clone(); let client = app_state.client.clone();
let _join_task = cx.spawn_weak({ let _join_task =
let contact = contact.clone(); cx.spawn_weak({
|this, mut cx| async move { let contact = contact.clone();
let project = Project::remote( |this, mut cx| async move {
project_id, let project = Project::remote(
app_state.client.clone(), project_id,
app_state.user_store.clone(), app_state.client.clone(),
app_state.languages.clone(), app_state.user_store.clone(),
app_state.fs.clone(), app_state.languages.clone(),
&mut cx, app_state.fs.clone(),
) &mut cx,
.await; )
.await;
if let Some(this) = this.upgrade(&cx) { if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
this.waiting = false; this.waiting = false;
match project { match project {
Ok(project) => { Ok(project) => {
cx.replace_root_view(|cx| { cx.replace_root_view(|cx| {
let mut workspace = (app_state.build_workspace)( let mut workspace = Workspace::new(project, cx);
project.clone(), (app_state.initialize_workspace)(
&app_state, &mut workspace,
cx, &app_state,
); cx,
workspace.toggle_sidebar_item( );
&ToggleSidebarItem { workspace.toggle_sidebar_item(
side: Side::Left, &ToggleSidebarItem {
item_index: 0, side: Side::Left,
}, item_index: 0,
cx, },
); cx,
if let Some((host_peer_id, _)) = project );
.read(cx) if let Some((host_peer_id, _)) =
.collaborators() workspace.project.read(cx).collaborators().iter().find(
.iter() |(_, collaborator)| collaborator.replica_id == 0,
.find(|(_, collaborator)| collaborator.replica_id == 0)
{
if let Some(follow) = workspace
.toggle_follow(&ToggleFollow(*host_peer_id), cx)
{
follow.detach_and_log_err(cx);
}
}
workspace
});
}
Err(error @ _) => {
let login = &contact.user.github_login;
let message = match error {
project::JoinProjectError::HostDeclined => {
format!("@{} declined your request.", login)
}
project::JoinProjectError::HostClosedProject => {
format!(
"@{} closed their copy of {}.",
login,
humanize_list(
&contact.projects[project_index]
.worktree_root_names
) )
) {
} if let Some(follow) = workspace
project::JoinProjectError::HostWentOffline => { .toggle_follow(&ToggleFollow(*host_peer_id), cx)
format!("@{} went offline.", login) {
} follow.detach_and_log_err(cx);
project::JoinProjectError::Other(error) => { }
log::error!("error joining project: {}", error); }
"An error occurred.".to_string() workspace
} });
}; }
this.message = message; Err(error @ _) => {
cx.notify(); let login = &contact.user.github_login;
let message = match error {
project::JoinProjectError::HostDeclined => {
format!("@{} declined your request.", login)
}
project::JoinProjectError::HostClosedProject => {
format!(
"@{} closed their copy of {}.",
login,
humanize_list(
&contact.projects[project_index]
.worktree_root_names
)
)
}
project::JoinProjectError::HostWentOffline => {
format!("@{} went offline.", login)
}
project::JoinProjectError::Other(error) => {
log::error!("error joining project: {}", error);
"An error occurred.".to_string()
}
};
this.message = message;
cx.notify();
}
} }
} })
}) }
}
Ok(()) Ok(())
} }
}); });
Self { Self {
project_id, project_id,

View file

@ -190,8 +190,7 @@ pub struct AppState {
pub user_store: ModelHandle<client::UserStore>, pub user_store: ModelHandle<client::UserStore>,
pub fs: Arc<dyn fs::Fs>, pub fs: Arc<dyn fs::Fs>,
pub build_window_options: fn() -> WindowOptions<'static>, pub build_window_options: fn() -> WindowOptions<'static>,
pub build_workspace: pub initialize_workspace: fn(&mut Workspace, &Arc<AppState>, &mut ViewContext<Workspace>),
fn(ModelHandle<Project>, &Arc<AppState>, &mut ViewContext<Workspace>) -> Workspace,
} }
pub trait Item: View { pub trait Item: View {
@ -654,7 +653,7 @@ impl AppState {
fs, fs,
languages, languages,
user_store, user_store,
build_workspace: |project, _, cx| Workspace::new(project, cx), initialize_workspace: |_, _, _| {},
build_window_options: || Default::default(), build_window_options: || Default::default(),
}) })
} }
@ -2219,14 +2218,17 @@ pub fn open_paths(
.contains(&false); .contains(&false);
cx.add_window((app_state.build_window_options)(), |cx| { cx.add_window((app_state.build_window_options)(), |cx| {
let project = Project::local( let mut workspace = Workspace::new(
app_state.client.clone(), Project::local(
app_state.user_store.clone(), app_state.client.clone(),
app_state.languages.clone(), app_state.user_store.clone(),
app_state.fs.clone(), app_state.languages.clone(),
app_state.fs.clone(),
cx,
),
cx, cx,
); );
let mut workspace = (app_state.build_workspace)(project, &app_state, cx); (app_state.initialize_workspace)(&mut workspace, &app_state, cx);
if contains_directory { if contains_directory {
workspace.toggle_sidebar_item( workspace.toggle_sidebar_item(
&ToggleSidebarItem { &ToggleSidebarItem {
@ -2272,14 +2274,18 @@ pub fn join_project(
fn open_new(app_state: &Arc<AppState>, cx: &mut MutableAppContext) { fn open_new(app_state: &Arc<AppState>, cx: &mut MutableAppContext) {
let (window_id, workspace) = cx.add_window((app_state.build_window_options)(), |cx| { let (window_id, workspace) = cx.add_window((app_state.build_window_options)(), |cx| {
let project = Project::local( let mut workspace = Workspace::new(
app_state.client.clone(), Project::local(
app_state.user_store.clone(), app_state.client.clone(),
app_state.languages.clone(), app_state.user_store.clone(),
app_state.fs.clone(), app_state.languages.clone(),
app_state.fs.clone(),
cx,
),
cx, cx,
); );
(app_state.build_workspace)(project, app_state, cx) (app_state.initialize_workspace)(&mut workspace, app_state, cx);
workspace
}); });
cx.dispatch_action(window_id, vec![workspace.id()], &OpenNew); cx.dispatch_action(window_id, vec![workspace.id()], &OpenNew);
} }

View file

@ -40,9 +40,9 @@ use theme::{ThemeRegistry, DEFAULT_THEME_NAME};
use util::{ResultExt, TryFutureExt}; use util::{ResultExt, TryFutureExt};
use workspace::{self, AppState, OpenNew, OpenPaths}; use workspace::{self, AppState, OpenNew, OpenPaths};
use zed::{ use zed::{
self, build_window_options, build_workspace, self, build_window_options,
fs::RealFs, fs::RealFs,
languages, menus, initialize_workspace, languages, menus,
settings_file::{settings_from_files, watch_keymap_file, WatchedJsonFile}, settings_file::{settings_from_files, watch_keymap_file, WatchedJsonFile},
}; };
@ -193,7 +193,7 @@ fn main() {
user_store, user_store,
fs, fs,
build_window_options, build_window_options,
build_workspace, initialize_workspace,
}); });
workspace::init(app_state.clone(), cx); workspace::init(app_state.clone(), cx);
journal::init(app_state.clone(), cx); journal::init(app_state.clone(), cx);

View file

@ -15,7 +15,7 @@ use gpui::{
actions, actions,
geometry::vector::vec2f, geometry::vector::vec2f,
platform::{WindowBounds, WindowOptions}, platform::{WindowBounds, WindowOptions},
AsyncAppContext, ModelHandle, ViewContext, AsyncAppContext, ViewContext,
}; };
use lazy_static::lazy_static; use lazy_static::lazy_static;
pub use lsp; pub use lsp;
@ -115,13 +115,13 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
settings::KeymapFileContent::load_defaults(cx); settings::KeymapFileContent::load_defaults(cx);
} }
pub fn build_workspace( pub fn initialize_workspace(
project: ModelHandle<Project>, workspace: &mut Workspace,
app_state: &Arc<AppState>, app_state: &Arc<AppState>,
cx: &mut ViewContext<Workspace>, cx: &mut ViewContext<Workspace>,
) -> Workspace { ) {
cx.subscribe(&cx.handle(), { cx.subscribe(&cx.handle(), {
let project = project.clone(); let project = workspace.project().clone();
move |_, _, event, cx| { move |_, _, event, cx| {
if let workspace::Event::PaneAdded(pane) = event { if let workspace::Event::PaneAdded(pane) = event {
pane.update(cx, |pane, cx| { pane.update(cx, |pane, cx| {
@ -139,11 +139,12 @@ pub fn build_workspace(
}) })
.detach(); .detach();
let workspace = Workspace::new(project.clone(), cx); cx.emit(workspace::Event::PaneAdded(workspace.active_pane().clone()));
let theme_names = app_state.themes.list().collect(); let theme_names = app_state.themes.list().collect();
let language_names = app_state.languages.language_names(); let language_names = app_state.languages.language_names();
project.update(cx, |project, cx| { workspace.project().update(cx, |project, cx| {
let action_names = cx.all_action_names().collect::<Vec<_>>(); let action_names = cx.all_action_names().collect::<Vec<_>>();
project.set_language_server_settings(serde_json::json!({ project.set_language_server_settings(serde_json::json!({
"json": { "json": {
@ -161,7 +162,7 @@ pub fn build_workspace(
})); }));
}); });
let project_panel = ProjectPanel::new(project, cx); let project_panel = ProjectPanel::new(workspace.project().clone(), cx);
let contact_panel = cx.add_view(|cx| { let contact_panel = cx.add_view(|cx| {
ContactsPanel::new(app_state.user_store.clone(), workspace.weak_handle(), cx) ContactsPanel::new(app_state.user_store.clone(), workspace.weak_handle(), cx)
}); });
@ -186,8 +187,6 @@ pub fn build_workspace(
status_bar.add_right_item(cursor_position, cx); status_bar.add_right_item(cursor_position, cx);
status_bar.add_right_item(auto_update, cx); status_bar.add_right_item(auto_update, cx);
}); });
workspace
} }
pub fn build_window_options() -> WindowOptions<'static> { pub fn build_window_options() -> WindowOptions<'static> {
@ -277,14 +276,18 @@ fn open_config_file(
workspace.open_paths(vec![path.to_path_buf()], cx) workspace.open_paths(vec![path.to_path_buf()], cx)
} else { } else {
let (_, workspace) = cx.add_window((app_state.build_window_options)(), |cx| { let (_, workspace) = cx.add_window((app_state.build_window_options)(), |cx| {
let project = Project::local( let mut workspace = Workspace::new(
app_state.client.clone(), Project::local(
app_state.user_store.clone(), app_state.client.clone(),
app_state.languages.clone(), app_state.user_store.clone(),
app_state.fs.clone(), app_state.languages.clone(),
app_state.fs.clone(),
cx,
),
cx, cx,
); );
(app_state.build_workspace)(project, &app_state, cx) (app_state.initialize_workspace)(&mut workspace, &app_state, cx);
workspace
}); });
workspace.update(cx, |workspace, cx| { workspace.update(cx, |workspace, cx| {
workspace.open_paths(vec![path.to_path_buf()], cx) workspace.open_paths(vec![path.to_path_buf()], cx)
@ -1168,7 +1171,7 @@ mod tests {
cx.update(|cx| { cx.update(|cx| {
let mut app_state = AppState::test(cx); let mut app_state = AppState::test(cx);
let state = Arc::get_mut(&mut app_state).unwrap(); let state = Arc::get_mut(&mut app_state).unwrap();
state.build_workspace = build_workspace; state.initialize_workspace = initialize_workspace;
state.build_window_options = build_window_options; state.build_window_options = build_window_options;
workspace::init(app_state.clone(), cx); workspace::init(app_state.clone(), cx);
editor::init(cx); editor::init(cx);