diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 7c69f85acf..dbc8fc3e82 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -144,7 +144,7 @@ impl ProjectDiagnosticsEditor { let diagnostics = cx.add_view(|cx| { ProjectDiagnosticsEditor::new(workspace.project().clone(), workspace_handle, cx) }); - workspace.open_item(Box::new(diagnostics), cx); + workspace.add_item(Box::new(diagnostics), cx); } } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 39dad90ece..5a5a7cd5e6 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -57,7 +57,7 @@ pub use sum_tree::Bias; use text::rope::TextDimension; use theme::DiagnosticStyle; use util::{post_inc, ResultExt, TryFutureExt}; -use workspace::{settings, ItemNavHistory, PathOpener, Settings, Workspace}; +use workspace::{settings, ItemNavHistory, Settings, Workspace}; const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500); const MAX_LINE_LEN: usize = 1024; @@ -141,8 +141,7 @@ pub enum Direction { Next, } -pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec>) { - path_openers.push(Box::new(items::BufferOpener)); +pub fn init(cx: &mut MutableAppContext) { cx.add_bindings(vec![ Binding::new("escape", Cancel, Some("Editor")), Binding::new("backspace", Backspace, Some("Editor")), @@ -340,6 +339,11 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec ViewHandle { let project = workspace.project().clone(); - if let Some(project_entry) = project::File::from_dyn(buffer.read(cx).file()) + if let Some(item) = project::File::from_dyn(buffer.read(cx).file()) .and_then(|file| file.project_entry_id(cx)) + .and_then(|entry_id| workspace.item_for_entry(entry_id, cx)) + .and_then(|item| item.downcast()) { - return workspace - .open_editor(project_entry, cx) - .downcast::() - .unwrap(); + return item; } let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let editor = cx.add_view(|cx| Editor::for_buffer(multibuffer, Some(project.clone()), cx)); - workspace.open_item(Box::new(editor.clone()), cx); + workspace.add_item(Box::new(editor.clone()), cx); editor } @@ -966,7 +969,7 @@ impl Editor { .log_err() { let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - workspace.open_item( + workspace.add_item( Box::new( cx.add_view(|cx| Editor::for_buffer(multibuffer, Some(project.clone()), cx)), ), @@ -2376,16 +2379,12 @@ impl Editor { workspace.update(&mut cx, |workspace, cx| { let project = workspace.project().clone(); - let editor = workspace.open_item( - Box::new(cx.add_view(|cx| Editor::for_buffer(excerpt_buffer, Some(project), cx))), - cx, - ); - if let Some(editor) = editor.act_as::(cx) { - editor.update(cx, |editor, cx| { - let color = editor.style(cx).highlighted_line_background; - editor.highlight_background::(ranges_to_highlight, color, cx); - }); - } + let editor = cx.add_view(|cx| Editor::for_buffer(excerpt_buffer, Some(project), cx)); + workspace.add_item(Box::new(editor.clone()), cx); + editor.update(cx, |editor, cx| { + let color = editor.style(cx).highlighted_line_background; + editor.highlight_background::(ranges_to_highlight, color, cx); + }); }); Ok(()) @@ -4402,7 +4401,7 @@ impl Editor { let color = editor.style(cx).highlighted_line_background; editor.highlight_background::(ranges_to_highlight, color, cx); }); - workspace.open_item(Box::new(editor), cx); + workspace.add_item(Box::new(editor), cx); }); Ok(()) diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 6fec3d7a1c..8946328b1a 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -1,8 +1,8 @@ use crate::{Autoscroll, Editor, Event, MultiBuffer, NavigationData, ToOffset, ToPoint as _}; use anyhow::Result; use gpui::{ - elements::*, AppContext, Entity, ModelContext, ModelHandle, RenderContext, Subscription, Task, - View, ViewContext, ViewHandle, WeakModelHandle, + elements::*, AppContext, Entity, ModelHandle, RenderContext, Subscription, Task, View, + ViewContext, ViewHandle, WeakModelHandle, }; use language::{Bias, Buffer, Diagnostic, File as _}; use project::{File, Project, ProjectPath}; @@ -10,9 +10,7 @@ use std::fmt::Write; use std::path::PathBuf; use text::{Point, Selection}; use util::ResultExt; -use workspace::{ItemNavHistory, ItemView, ItemViewHandle, PathOpener, Settings, StatusItemView}; - -pub struct BufferOpener; +use workspace::{ItemNavHistory, ItemView, ItemViewHandle, Settings, StatusItemView}; #[derive(Clone)] pub struct BufferItemHandle(pub ModelHandle); @@ -26,26 +24,6 @@ pub struct MultiBufferItemHandle(pub ModelHandle); #[derive(Clone)] struct WeakMultiBufferItemHandle(WeakModelHandle); -impl PathOpener for BufferOpener { - fn open( - &self, - project: &mut Project, - project_path: ProjectPath, - window_id: usize, - cx: &mut ModelContext, - ) -> Option>>> { - let buffer = project.open_buffer_for_path(project_path, cx); - Some(cx.spawn(|project, mut cx| async move { - let buffer = buffer.await?; - let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); - let editor = cx.add_view(window_id, |cx| { - Editor::for_buffer(multibuffer, Some(project), cx) - }); - Ok(Box::new(editor) as Box) - })) - } -} - impl ItemView for Editor { fn navigate(&mut self, data: Box, cx: &mut ViewContext) { if let Some(data) = data.downcast_ref::() { diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 4340cd5a1b..0dbb336007 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -409,14 +409,12 @@ mod tests { #[gpui::test] async fn test_matching_paths(cx: &mut gpui::TestAppContext) { - let mut path_openers = Vec::new(); cx.update(|cx| { super::init(cx); - editor::init(cx, &mut path_openers); + editor::init(cx); }); - let mut params = cx.update(WorkspaceParams::test); - params.path_openers = Arc::from(path_openers); + let params = cx.update(WorkspaceParams::test); params .fs .as_fake() diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index a479e5fba1..9831c3aa34 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -3473,6 +3473,12 @@ impl PartialEq> for ViewHandle { } } +impl PartialEq> for WeakViewHandle { + fn eq(&self, other: &ViewHandle) -> bool { + self.window_id == other.window_id && self.view_id == other.view_id + } +} + impl Eq for ViewHandle {} impl Debug for ViewHandle { diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 6208ff4aaa..7644b2f55d 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -391,7 +391,7 @@ impl ProjectSearchView { workspace.activate_item(&existing, cx); } else { let model = cx.add_model(|cx| ProjectSearch::new(workspace.project().clone(), cx)); - workspace.open_item( + workspace.add_item( Box::new(cx.add_view(|cx| ProjectSearchView::new(model, cx))), cx, ); @@ -429,7 +429,7 @@ impl ProjectSearchView { model.search(new_query, cx); model }); - workspace.open_item( + workspace.add_item( Box::new(cx.add_view(|cx| ProjectSearchView::new(model, cx))), cx, ); diff --git a/crates/server/src/rpc.rs b/crates/server/src/rpc.rs index f891dca71c..e70957740f 100644 --- a/crates/server/src/rpc.rs +++ b/crates/server/src/rpc.rs @@ -3201,8 +3201,7 @@ mod tests { cx_a.foreground().forbid_parking(); let mut lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); - let mut path_openers_b = Vec::new(); - cx_b.update(|cx| editor::init(cx, &mut path_openers_b)); + cx_b.update(|cx| editor::init(cx)); // Set up a fake language server. let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); @@ -3271,7 +3270,6 @@ mod tests { params.client = client_b.client.clone(); params.user_store = client_b.user_store.clone(); params.project = project_b; - params.path_openers = path_openers_b.into(); let (_window_b, workspace_b) = cx_b.add_window(|cx| Workspace::new(¶ms, cx)); let editor_b = workspace_b @@ -3437,8 +3435,7 @@ mod tests { cx_a.foreground().forbid_parking(); let mut lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); - let mut path_openers_b = Vec::new(); - cx_b.update(|cx| editor::init(cx, &mut path_openers_b)); + cx_b.update(|cx| editor::init(cx)); // Set up a fake language server. let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); @@ -3507,7 +3504,6 @@ mod tests { params.client = client_b.client.clone(); params.user_store = client_b.user_store.clone(); params.project = project_b; - params.path_openers = path_openers_b.into(); let (_window_b, workspace_b) = cx_b.add_window(|cx| Workspace::new(¶ms, cx)); let editor_b = workspace_b diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 73420e213a..e8cbd185f6 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -253,12 +253,12 @@ impl Pane { let pane = pane.downgrade(); let task = workspace.load_path(project_path, cx); cx.spawn(|workspace, mut cx| async move { - let item = task.await; + let task = task.await; if let Some(pane) = pane.upgrade(&cx) { - if let Some(item) = item.log_err() { + if let Some((project_entry_id, build_item)) = task.log_err() { pane.update(&mut cx, |pane, cx| { pane.nav_history.borrow_mut().set_mode(mode); - pane.open_item(item, cx); + let item = pane.open_item(project_entry_id, cx, build_item); pane.nav_history .borrow_mut() .set_mode(NavigationMode::Normal); @@ -280,7 +280,7 @@ impl Pane { } } - pub(crate) fn open_editor( + pub(crate) fn open_item( &mut self, project_entry_id: ProjectEntryId, cx: &mut ViewContext, @@ -299,14 +299,6 @@ impl Pane { item_view } - pub fn open_item( - &mut self, - item_view_to_open: Box, - cx: &mut ViewContext, - ) { - self.add_item(None, item_view_to_open.boxed_clone(), cx); - } - pub(crate) fn add_item( &mut self, project_entry_id: Option, diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index d11e773c3f..33415e2360 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -9,7 +9,6 @@ mod status_bar; use anyhow::{anyhow, Result}; use client::{Authenticate, ChannelList, Client, User, UserStore}; use clock::ReplicaId; -use futures::TryFutureExt; use gpui::{ action, color::Color, @@ -18,9 +17,9 @@ use gpui::{ json::{self, to_string_pretty, ToJson}, keymap::Binding, platform::{CursorStyle, WindowOptions}, - AnyViewHandle, AppContext, ClipboardItem, Entity, ImageData, ModelContext, ModelHandle, - MutableAppContext, PathPromptOptions, PromptLevel, RenderContext, Task, View, ViewContext, - ViewHandle, WeakViewHandle, + AnyViewHandle, AppContext, ClipboardItem, Entity, ImageData, ModelHandle, MutableAppContext, + PathPromptOptions, PromptLevel, RenderContext, Task, View, ViewContext, ViewHandle, + WeakViewHandle, }; use language::{Buffer, LanguageRegistry}; use log::error; @@ -42,7 +41,7 @@ use std::{ }; use theme::{Theme, ThemeRegistry}; -pub type BuildEditor = Box< +pub type BuildEditor = Arc< dyn Fn( usize, ModelHandle, @@ -110,7 +109,7 @@ where V: ItemView, F: 'static + Fn(ModelHandle, ModelHandle, &mut ViewContext) -> V, { - cx.add_app_state::(Box::new(|window_id, project, model, cx| { + cx.add_app_state::(Arc::new(move |window_id, project, model, cx| { Box::new(cx.add_view(window_id, |cx| build_editor(project, model, cx))) })); } @@ -122,7 +121,6 @@ pub struct AppState { pub user_store: ModelHandle, pub fs: Arc, pub channel_list: ModelHandle, - pub path_openers: Arc<[Box]>, pub build_window_options: &'static dyn Fn() -> WindowOptions<'static>, pub build_workspace: &'static dyn Fn( ModelHandle, @@ -143,16 +141,6 @@ pub struct JoinProjectParams { pub app_state: Arc, } -pub trait PathOpener { - fn open( - &self, - project: &mut Project, - path: ProjectPath, - window_id: usize, - cx: &mut ModelContext, - ) -> Option>>>; -} - pub trait ItemView: View { fn deactivated(&mut self, _: &mut ViewContext) {} fn navigate(&mut self, _: Box, _: &mut ViewContext) {} @@ -378,7 +366,6 @@ pub struct WorkspaceParams { pub languages: Arc, pub user_store: ModelHandle, pub channel_list: ModelHandle, - pub path_openers: Arc<[Box]>, } impl WorkspaceParams { @@ -409,7 +396,6 @@ impl WorkspaceParams { fs, languages, user_store, - path_openers: Arc::from([]), } } @@ -428,7 +414,6 @@ impl WorkspaceParams { languages: app_state.languages.clone(), user_store: app_state.user_store.clone(), channel_list: app_state.channel_list.clone(), - path_openers: app_state.path_openers.clone(), } } } @@ -446,7 +431,6 @@ pub struct Workspace { active_pane: ViewHandle, status_bar: ViewHandle, project: ModelHandle, - path_openers: Arc<[Box]>, // items: BTreeMap, Box>, _observe_current_user: Task<()>, } @@ -510,7 +494,6 @@ impl Workspace { left_sidebar: Sidebar::new(Side::Left), right_sidebar: Sidebar::new(Side::Right), project: params.project.clone(), - path_openers: params.path_openers.clone(), _observe_current_user, } } @@ -665,76 +648,14 @@ impl Workspace { } } - pub fn open_path( - &mut self, - path: ProjectPath, - cx: &mut ViewContext, - ) -> Task, Arc>> { - let project_entry = self.project.read(cx).entry_for_path(&path, cx); - - let existing_entry = self - .active_pane() - .update(cx, |pane, cx| pane.activate_project_entry(project_entry)); - - cx.spawn(|this, cx| { - if let Some(existing_entry) = existing_entry { - return Ok(existing_entry); - } - - let load_task = this - .update(&mut cx, |this, cx| { - this.load_project_entry(project_entry, cx) - }) - .await; - }); - - let load_task = self.load_path(path, cx); - let pane = self.active_pane().clone().downgrade(); - cx.as_mut().spawn(|mut cx| async move { - let item = load_task.await?; - let pane = pane - .upgrade(&cx) - .ok_or_else(|| anyhow!("could not upgrade pane reference"))?; - Ok(pane.update(&mut cx, |pane, cx| pane.open_editor(item, cx))) - }) - } - - pub fn load_path( - &mut self, - path: ProjectPath, - cx: &mut ViewContext, - ) -> Task>> { - if let Some(project_entry) = self.project.read(cx).entry_for_path(&path, cx) { - self.load_project_entry(project_entry, cx) - } else { - Task::ready(Err(anyhow!("no such file {:?}", path))) - } - } - - pub fn load_project_entry( - &mut self, - project_entry: ProjectEntryId, - cx: &mut ViewContext, - ) -> Task>> { - if let Some(existing_item) = self - .panes + pub fn item_for_entry( + &self, + entry_id: ProjectEntryId, + cx: &AppContext, + ) -> Option> { + self.panes() .iter() - .find_map(|pane| pane.read(cx).item_for_entry(project_entry)) - { - return Task::ready(Ok(existing_item)); - } - - let project_path = path.clone(); - let path_openers = self.path_openers.clone(); - let window_id = cx.window_id(); - self.project.update(cx, |project, cx| { - for opener in path_openers.iter() { - if let Some(task) = opener.open(project, project_path.clone(), window_id, cx) { - return task; - } - } - Task::ready(Err(anyhow!("no opener found for path {:?}", project_path))) - }) + .find_map(|pane| pane.read(cx).item_for_entry(entry_id)) } pub fn item_of_type(&self, cx: &AppContext) -> Option> { @@ -871,107 +792,58 @@ impl Workspace { pane } - pub fn open_item(&mut self, item_view: Box, cx: &mut ViewContext) { + pub fn add_item(&mut self, item_view: Box, cx: &mut ViewContext) { self.active_pane() - .update(cx, |pane, cx| pane.open_item(item_view, cx)) + .update(cx, |pane, cx| pane.add_item(None, item_view, cx)) } - pub fn open_editor( + pub fn open_path( &mut self, - project_entry: ProjectEntryId, + path: ProjectPath, cx: &mut ViewContext, ) -> Task, Arc>> { - let pane = self.active_pane().clone(); - let project = self.project().clone(); - let buffer = project.update(cx, |project, cx| { - project.open_buffer_for_entry(project_entry, cx) - }); - - cx.spawn(|this, cx| async move { - let buffer = buffer.await?; - let editor = this.update(&mut cx, |this, cx| { - let window_id = cx.window_id(); + let pane = self.active_pane().downgrade(); + let task = self.load_path(path, cx); + cx.spawn(|this, mut cx| async move { + let (project_entry_id, build_editor) = task.await?; + let pane = pane + .upgrade(&cx) + .ok_or_else(|| anyhow!("pane was closed"))?; + this.update(&mut cx, |_, cx| { pane.update(cx, |pane, cx| { - pane.open_editor(project_entry, cx, |cx| { - cx.app_state::()(window_id, project, buffer, cx) - }) + Ok(pane.open_item(project_entry_id, cx, build_editor)) }) - }); - Ok(editor) + }) }) } - // pub fn open_path( - // &mut self, - // path: ProjectPath, - // cx: &mut ViewContext, - // ) -> Task, Arc>> { - // let project_entry = self.project.read(cx).entry_for_path(&path, cx); - - // let existing_entry = self - // .active_pane() - // .update(cx, |pane, cx| pane.activate_project_entry(project_entry)); - - // cx.spawn(|this, cx| { - // if let Some(existing_entry) = existing_entry { - // return Ok(existing_entry); - // } - - // let load_task = this - // .update(&mut cx, |this, cx| { - // this.load_project_entry(project_entry, cx) - // }) - // .await; - // }); - - // let load_task = self.load_path(path, cx); - // let pane = self.active_pane().clone().downgrade(); - // cx.as_mut().spawn(|mut cx| async move { - // let item = load_task.await?; - // let pane = pane - // .upgrade(&cx) - // .ok_or_else(|| anyhow!("could not upgrade pane reference"))?; - // Ok(pane.update(&mut cx, |pane, cx| pane.open_editor(item, cx))) - // }) - // } - - // pub fn load_path( - // &mut self, - // path: ProjectPath, - // cx: &mut ViewContext, - // ) -> Task>> { - // if let Some(project_entry) = self.project.read(cx).entry_for_path(&path, cx) { - // self.load_project_entry(project_entry, cx) - // } else { - // Task::ready(Err(anyhow!("no such file {:?}", path))) - // } - // } - - // pub fn load_project_entry( - // &mut self, - // project_entry: ProjectEntryId, - // cx: &mut ViewContext, - // ) -> Task>> { - // if let Some(existing_item) = self - // .panes - // .iter() - // .find_map(|pane| pane.read(cx).item_for_entry(project_entry)) - // { - // return Task::ready(Ok(existing_item)); - // } - - // let project_path = path.clone(); - // let path_openers = self.path_openers.clone(); - // let window_id = cx.window_id(); - // self.project.update(cx, |project, cx| { - // for opener in path_openers.iter() { - // if let Some(task) = opener.open(project, project_path.clone(), window_id, cx) { - // return task; - // } - // } - // Task::ready(Err(anyhow!("no opener found for path {:?}", project_path))) - // }) - // } + pub(crate) fn load_path( + &mut self, + path: ProjectPath, + cx: &mut ViewContext, + ) -> Task< + Result<( + ProjectEntryId, + impl 'static + FnOnce(&mut MutableAppContext) -> Box, + )>, + > { + let project = self.project().clone(); + let buffer = project.update(cx, |project, cx| project.open_buffer_for_path(path, cx)); + cx.spawn(|this, mut cx| async move { + let buffer = buffer.await?; + let project_entry_id = buffer.read_with(&cx, |buffer, cx| { + project::File::from_dyn(buffer.file()) + .and_then(|file| file.project_entry_id(cx)) + .ok_or_else(|| anyhow!("buffer has no entry")) + })?; + let (window_id, build_editor) = this.update(&mut cx, |_, cx| { + (cx.window_id(), cx.app_state::().clone()) + }); + let build_editor = + move |cx: &mut MutableAppContext| build_editor(window_id, project, buffer, cx); + Ok((project_entry_id, build_editor)) + }) + } pub fn activate_item(&mut self, item: &dyn ItemViewHandle, cx: &mut ViewContext) -> bool { let result = self.panes.iter().find_map(|pane| { @@ -1046,7 +918,7 @@ impl Workspace { let project_entry_id = pane.read(cx).project_entry_id_for_item(item.as_ref()); if let Some(clone) = item.clone_on_split(cx.as_mut()) { new_pane.update(cx, |new_pane, cx| { - new_pane.open_item(project_entry_id, clone, cx); + new_pane.add_item(project_entry_id, clone, cx); }); } } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 8596000246..190a279737 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -61,7 +61,6 @@ fn main() { app.run(move |cx| { let http = http::client(); let client = client::Client::new(http.clone()); - let mut path_openers = Vec::new(); let mut languages = language::build_language_registry(login_shell_env_loaded); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx)); let channel_list = @@ -71,7 +70,7 @@ fn main() { client::Channel::init(&client); client::init(client.clone(), cx); workspace::init(cx); - editor::init(cx, &mut path_openers); + editor::init(cx); go_to_line::init(cx); file_finder::init(cx); chat_panel::init(cx); @@ -120,7 +119,6 @@ fn main() { client, user_store, fs, - path_openers: Arc::from(path_openers), build_window_options: &build_window_options, build_workspace: &build_workspace, }); diff --git a/crates/zed/src/test.rs b/crates/zed/src/test.rs index 35610854f3..f42e57c35d 100644 --- a/crates/zed/src/test.rs +++ b/crates/zed/src/test.rs @@ -17,8 +17,7 @@ fn init_logger() { pub fn test_app_state(cx: &mut MutableAppContext) -> Arc { let settings = Settings::test(cx); - let mut path_openers = Vec::new(); - editor::init(cx, &mut path_openers); + editor::init(cx); cx.add_app_state(settings); let themes = ThemeRegistry::new(Assets, cx.font_cache().clone()); let http = FakeHttpClient::with_404_response(); @@ -40,7 +39,6 @@ pub fn test_app_state(cx: &mut MutableAppContext) -> Arc { client, user_store, fs: FakeFs::new(cx.background().clone()), - path_openers: Arc::from(path_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 20da4e4800..99f02119ce 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -111,7 +111,6 @@ pub fn build_workspace( languages: app_state.languages.clone(), user_store: app_state.user_store.clone(), channel_list: app_state.channel_list.clone(), - path_openers: app_state.path_openers.clone(), }; let mut workspace = Workspace::new(&workspace_params, cx); let project = workspace.project().clone();