From 41fea2de1c80bb1005b78c429841462fde07a2b5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 30 Sep 2021 16:19:24 +0200 Subject: [PATCH] Open buffer when trying to expand a file --- zed/src/project_panel.rs | 111 +++++++++++++++++++++++++-------------- zed/src/workspace.rs | 13 +---- 2 files changed, 75 insertions(+), 49 deletions(-) diff --git a/zed/src/project_panel.rs b/zed/src/project_panel.rs index a7f8ee094909d689505a5aecaf9afa65940b7b62..5e6747de7812eb27426a30b6795a00436540a884 100644 --- a/zed/src/project_panel.rs +++ b/zed/src/project_panel.rs @@ -1,6 +1,7 @@ use crate::{ project::{self, Project}, theme, + workspace::Workspace, worktree::{self, Worktree}, Settings, }; @@ -14,7 +15,7 @@ use gpui::{ }, platform::CursorStyle, AppContext, Element, ElementBox, Entity, ModelHandle, MutableAppContext, ReadModel, View, - ViewContext, WeakViewHandle, + ViewContext, ViewHandle, WeakViewHandle, }; use postage::watch; use std::{ @@ -51,7 +52,7 @@ struct EntryDetails { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct ProjectEntry { - pub worktree_ix: usize, + pub worktree_id: usize, pub entry_id: usize, } @@ -66,51 +67,73 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(ProjectPanel::toggle_expanded); cx.add_action(ProjectPanel::select_prev); cx.add_action(ProjectPanel::select_next); + cx.add_action(ProjectPanel::open_entry); cx.add_bindings([ Binding::new("right", ExpandSelectedEntry, None), Binding::new("left", CollapseSelectedEntry, None), ]); } -pub enum Event {} +pub enum Event { + OpenedEntry { worktree_id: usize, entry_id: usize }, +} impl ProjectPanel { pub fn new( project: ModelHandle, settings: watch::Receiver, - cx: &mut ViewContext, - ) -> Self { - cx.observe(&project, |this, _, cx| { - this.update_visible_entries(None, cx); - cx.notify(); - }) - .detach(); - cx.subscribe(&project, |this, _, event, cx| match event { - project::Event::ActiveEntryChanged(Some((worktree_id, entry_id))) => { - this.expand_entry(*worktree_id, *entry_id, cx); - this.update_visible_entries(Some((*worktree_id, *entry_id)), cx); - cx.notify(); - } - project::Event::WorktreeRemoved(id) => { - this.expanded_dir_ids.remove(id); + cx: &mut ViewContext, + ) -> ViewHandle { + let project_panel = cx.add_view(|cx: &mut ViewContext| { + cx.observe(&project, |this, _, cx| { this.update_visible_entries(None, cx); cx.notify(); + }) + .detach(); + cx.subscribe(&project, |this, _, event, cx| match event { + project::Event::ActiveEntryChanged(Some((worktree_id, entry_id))) => { + this.expand_entry(*worktree_id, *entry_id, cx); + this.update_visible_entries(Some((*worktree_id, *entry_id)), cx); + cx.notify(); + } + project::Event::WorktreeRemoved(id) => { + this.expanded_dir_ids.remove(id); + this.update_visible_entries(None, cx); + cx.notify(); + } + _ => {} + }) + .detach(); + + let mut this = Self { + project: project.clone(), + settings, + list: Default::default(), + visible_entries: Default::default(), + expanded_dir_ids: Default::default(), + selection: None, + handle: cx.handle().downgrade(), + }; + this.update_visible_entries(None, cx); + this + }); + cx.subscribe(&project_panel, move |workspace, _, event, cx| match event { + Event::OpenedEntry { + worktree_id, + entry_id, + } => { + if let Some(worktree) = project.read(cx).worktree_for_id(*worktree_id) { + if let Some(entry) = worktree.read(cx).entry_for_id(*entry_id) { + workspace + .open_entry((worktree.id(), entry.path.clone()), cx) + .map(|t| t.detach()); + } + } } - _ => {} }) .detach(); - let mut this = Self { - project, - settings, - list: Default::default(), - visible_entries: Default::default(), - expanded_dir_ids: Default::default(), - selection: None, - handle: cx.handle().downgrade(), - }; - this.update_visible_entries(None, cx); - this + project_panel } fn expand_selected_entry(&mut self, _: &ExpandSelectedEntry, cx: &mut ViewContext) { @@ -132,6 +155,11 @@ impl ProjectPanel { } } } else { + let event = Event::OpenedEntry { + worktree_id: worktree.id(), + entry_id: entry.id, + }; + cx.emit(event); } } } @@ -169,10 +197,10 @@ impl ProjectPanel { fn toggle_expanded(&mut self, action: &ToggleExpanded, cx: &mut ViewContext) { let ProjectEntry { - worktree_ix, + worktree_id, entry_id, } = action.0; - let worktree_id = self.project.read(cx).worktrees()[worktree_ix].id(); + if let Some(expanded_dir_ids) = self.expanded_dir_ids.get_mut(&worktree_id) { match expanded_dir_ids.binary_search(&entry_id) { Ok(ix) => { @@ -203,6 +231,13 @@ impl ProjectPanel { } } + fn open_entry(&mut self, action: &Open, cx: &mut ViewContext) { + cx.emit(Event::OpenedEntry { + worktree_id: action.0.worktree_id, + entry_id: action.0.entry_id, + }); + } + fn select_next(&mut self, _: &SelectNext, cx: &mut ViewContext) { if let Some(selection) = self.selection { let next_ix = selection.index + 1; @@ -411,7 +446,7 @@ impl ProjectPanel { }), }; let entry = ProjectEntry { - worktree_ix, + worktree_id: worktree.id(), entry_id: entry.id, }; callback(entry, details, cx); @@ -429,7 +464,7 @@ impl ProjectPanel { ) -> ElementBox { let is_dir = details.is_dir; MouseEventHandler::new::( - (entry.worktree_ix, entry.entry_id), + (entry.worktree_id, entry.entry_id), cx, |state, _| { let style = if details.is_selected { @@ -568,7 +603,8 @@ mod tests { .read_with(&cx, |t, _| t.as_local().unwrap().scan_complete()) .await; - let (_, panel) = cx.add_window(|cx| ProjectPanel::new(project, settings, cx)); + let (_, workspace) = cx.add_window(|cx| Workspace::new(&app_state, cx)); + let panel = workspace.update(&mut cx, |_, cx| ProjectPanel::new(project, settings, cx)); assert_eq!( visible_entry_details(&panel, 0..50, &mut cx), &[ @@ -742,14 +778,13 @@ mod tests { ) { let path = path.as_ref(); panel.update(cx, |panel, cx| { - for (worktree_ix, worktree) in panel.project.read(cx).worktrees().iter().enumerate() - { + for worktree in panel.project.read(cx).worktrees() { let worktree = worktree.read(cx); if let Ok(relative_path) = path.strip_prefix(worktree.root_name()) { let entry_id = worktree.entry_for_path(relative_path).unwrap().id; panel.toggle_expanded( &ToggleExpanded(ProjectEntry { - worktree_ix, + worktree_id: worktree.id(), entry_id, }), cx, diff --git a/zed/src/workspace.rs b/zed/src/workspace.rs index 9478c40a57b8d45144f152537aa7782b013f683b..81f1e10a41a0429501bd1546778dfa5e05f2272d 100644 --- a/zed/src/workspace.rs +++ b/zed/src/workspace.rs @@ -8,7 +8,7 @@ use crate::{ fs::Fs, people_panel::{JoinWorktree, LeaveWorktree, PeoplePanel, ShareWorktree, UnshareWorktree}, project::Project, - project_panel::{self, ProjectPanel}, + project_panel::ProjectPanel, rpc, settings::Settings, user, @@ -54,14 +54,6 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(Workspace::save_active_item); cx.add_action(Workspace::debug_elements); cx.add_action(Workspace::open_new_file); - cx.add_action(|this: &mut Workspace, action: &project_panel::Open, cx| { - if let Some(worktree) = this.worktrees(cx).get(action.0.worktree_ix) { - if let Some(entry) = worktree.read(cx).entry_for_id(action.0.entry_id) { - this.open_entry((worktree.id(), entry.path.clone()), cx) - .map(|task| task.detach()); - } - } - }); cx.add_action(Workspace::toggle_sidebar_item); cx.add_action(Workspace::share_worktree); cx.add_action(Workspace::unshare_worktree); @@ -386,8 +378,7 @@ impl Workspace { let mut left_sidebar = Sidebar::new(Side::Left); left_sidebar.add_item( "icons/folder-tree-16.svg", - cx.add_view(|cx| ProjectPanel::new(project.clone(), app_state.settings.clone(), cx)) - .into(), + ProjectPanel::new(project.clone(), app_state.settings.clone(), cx).into(), ); let mut right_sidebar = Sidebar::new(Side::Right);