From 991eb742b0d653f54e74be40bc33a6ccf27fe66b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 26 May 2022 15:23:40 +0200 Subject: [PATCH] Start adding project panel context menu actions --- crates/project_panel/src/project_panel.rs | 61 ++++++++++++++++++++--- crates/workspace/src/workspace.rs | 25 +++++++++- 2 files changed, 76 insertions(+), 10 deletions(-) diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index d4c3410b1b..13b27d62dd 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -115,6 +115,10 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_async_action(ProjectPanel::delete); cx.add_async_action(ProjectPanel::confirm); cx.add_action(ProjectPanel::cancel); + cx.add_action(ProjectPanel::copy); + cx.add_action(ProjectPanel::copy_path); + cx.add_action(ProjectPanel::cut); + cx.add_action(ProjectPanel::paste); } pub enum Event { @@ -212,22 +216,47 @@ impl ProjectPanel { fn deploy_context_menu(&mut self, action: &DeployContextMenu, cx: &mut ViewContext) { let mut menu_entries = Vec::new(); - menu_entries.push(ContextMenuItem::item("New File", AddFile)); - menu_entries.push(ContextMenuItem::item("New Directory", AddDirectory)); + if let Some(entry_id) = action.entry_id { if let Some(worktree_id) = self.project.read(cx).worktree_id_for_entry(entry_id, cx) { self.selection = Some(Selection { worktree_id, entry_id, }); - menu_entries.push(ContextMenuItem::Separator); - menu_entries.push(ContextMenuItem::item("Copy", Copy)); - menu_entries.push(ContextMenuItem::item("Copy Path", CopyPath)); - menu_entries.push(ContextMenuItem::item("Cut", Cut)); - menu_entries.push(ContextMenuItem::item("Rename", Rename)); - menu_entries.push(ContextMenuItem::item("Delete", Delete)); + + if let Some((worktree, entry)) = self.selected_entry(cx) { + let is_root = Some(entry) == worktree.root_entry(); + menu_entries.push(ContextMenuItem::item( + "Add Folder to Project", + workspace::AddFolderToProject, + )); + if is_root { + menu_entries.push(ContextMenuItem::item( + "Remove Folder from Project", + workspace::RemoveFolderFromProject(worktree_id), + )); + } + menu_entries.push(ContextMenuItem::item("New File", AddFile)); + menu_entries.push(ContextMenuItem::item("New Folder", AddDirectory)); + menu_entries.push(ContextMenuItem::Separator); + menu_entries.push(ContextMenuItem::item("Copy", Copy)); + menu_entries.push(ContextMenuItem::item("Copy Path", CopyPath)); + menu_entries.push(ContextMenuItem::item("Cut", Cut)); + menu_entries.push(ContextMenuItem::Separator); + menu_entries.push(ContextMenuItem::item("Rename", Rename)); + if !is_root { + menu_entries.push(ContextMenuItem::item("Delete", Delete)); + } + } } + } else { + self.selection.take(); + menu_entries.push(ContextMenuItem::item( + "Add Folder to Project", + workspace::AddFolderToProject, + )); } + self.context_menu.update(cx, |menu, cx| { menu.show(action.position, menu_entries, cx); }); @@ -581,6 +610,22 @@ impl ProjectPanel { } } + fn cut(&mut self, _: &Cut, cx: &mut ViewContext) { + todo!() + } + + fn copy(&mut self, _: &Copy, cx: &mut ViewContext) { + todo!() + } + + fn paste(&mut self, _: &Paste, cx: &mut ViewContext) { + todo!() + } + + fn copy_path(&mut self, _: &CopyPath, cx: &mut ViewContext) { + todo!() + } + fn index_for_selection(&self, selection: Selection) -> Option<(usize, usize, usize)> { let mut worktree_index = 0; let mut entry_index = 0; diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index f4197e7296..6fa4c9a6b2 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -30,7 +30,7 @@ use log::error; pub use pane::*; pub use pane_group::*; use postage::prelude::Stream; -use project::{fs, Fs, Project, ProjectEntryId, ProjectPath, Worktree}; +use project::{fs, Fs, Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId}; use settings::Settings; use sidebar::{Side, Sidebar, SidebarButtons, ToggleSidebarItem, ToggleSidebarItemFocus}; use smallvec::SmallVec; @@ -72,6 +72,9 @@ type FollowableItemBuilders = HashMap< ), >; +#[derive(Clone)] +pub struct RemoveFolderFromProject(pub WorktreeId); + actions!( workspace, [ @@ -104,7 +107,15 @@ pub struct JoinProject { pub project_index: usize, } -impl_internal_actions!(workspace, [OpenPaths, ToggleFollow, JoinProject]); +impl_internal_actions!( + workspace, + [ + OpenPaths, + ToggleFollow, + JoinProject, + RemoveFolderFromProject + ] +); pub fn init(app_state: Arc, cx: &mut MutableAppContext) { pane::init(cx); @@ -148,6 +159,7 @@ pub fn init(app_state: Arc, cx: &mut MutableAppContext) { cx.add_async_action(Workspace::close); cx.add_async_action(Workspace::save_all); cx.add_action(Workspace::add_folder_to_project); + cx.add_action(Workspace::remove_folder_from_project); cx.add_action( |workspace: &mut Workspace, _: &Unfollow, cx: &mut ViewContext| { let pane = workspace.active_pane().clone(); @@ -1028,6 +1040,15 @@ impl Workspace { .detach(); } + fn remove_folder_from_project( + &mut self, + RemoveFolderFromProject(worktree_id): &RemoveFolderFromProject, + cx: &mut ViewContext, + ) { + self.project + .update(cx, |project, cx| project.remove_worktree(*worktree_id, cx)); + } + fn project_path_for_path( &self, abs_path: &Path,