Added 'open in terminal' action to the project panel context menu

Also slightly re-arranged the project panel context menu
This commit is contained in:
Mikayla 2023-09-15 21:32:58 -07:00
parent 5df9a57a8b
commit d46816589e
No known key found for this signature in database
3 changed files with 72 additions and 16 deletions

View file

@ -122,6 +122,7 @@ actions!(
CopyPath,
CopyRelativePath,
RevealInFinder,
OpenInTerminal,
Cut,
Paste,
Delete,
@ -156,6 +157,7 @@ pub fn init(assets: impl AssetSource, cx: &mut AppContext) {
cx.add_action(ProjectPanel::copy_path);
cx.add_action(ProjectPanel::copy_relative_path);
cx.add_action(ProjectPanel::reveal_in_finder);
cx.add_action(ProjectPanel::open_in_terminal);
cx.add_action(ProjectPanel::new_search_in_directory);
cx.add_action(
|this: &mut ProjectPanel, action: &Paste, cx: &mut ViewContext<ProjectPanel>| {
@ -423,24 +425,30 @@ impl ProjectPanel {
menu_entries.push(ContextMenuItem::Separator);
menu_entries.push(ContextMenuItem::action("Cut", Cut));
menu_entries.push(ContextMenuItem::action("Copy", Copy));
if let Some(clipboard_entry) = self.clipboard_entry {
if clipboard_entry.worktree_id() == worktree.id() {
menu_entries.push(ContextMenuItem::action("Paste", Paste));
}
}
menu_entries.push(ContextMenuItem::Separator);
menu_entries.push(ContextMenuItem::action("Copy Path", CopyPath));
menu_entries.push(ContextMenuItem::action(
"Copy Relative Path",
CopyRelativePath,
));
if entry.is_dir() {
menu_entries.push(ContextMenuItem::Separator);
}
menu_entries.push(ContextMenuItem::action("Reveal in Finder", RevealInFinder));
if entry.is_dir() {
menu_entries.push(ContextMenuItem::action("Open in Terminal", OpenInTerminal));
menu_entries.push(ContextMenuItem::action(
"Search Inside",
NewSearchInDirectory,
));
}
if let Some(clipboard_entry) = self.clipboard_entry {
if clipboard_entry.worktree_id() == worktree.id() {
menu_entries.push(ContextMenuItem::action("Paste", Paste));
}
}
menu_entries.push(ContextMenuItem::Separator);
menu_entries.push(ContextMenuItem::action("Rename", Rename));
if !is_root {
@ -965,6 +973,26 @@ impl ProjectPanel {
}
}
fn open_in_terminal(&mut self, _: &OpenInTerminal, cx: &mut ViewContext<Self>) {
if let Some((worktree, entry)) = self.selected_entry(cx) {
let window = cx.window();
let view_id = cx.view_id();
let path = worktree.abs_path().join(&entry.path);
cx.app_context()
.spawn(|mut cx| async move {
window.dispatch_action(
view_id,
&workspace::OpenTerminal {
working_directory: path,
},
&mut cx,
);
})
.detach();
}
}
pub fn new_search_in_directory(
&mut self,
_: &NewSearchInDirectory,

View file

@ -1,4 +1,4 @@
use std::sync::Arc;
use std::{path::PathBuf, sync::Arc};
use crate::TerminalView;
use db::kvp::KEY_VALUE_STORE;
@ -23,6 +23,7 @@ actions!(terminal_panel, [ToggleFocus]);
pub fn init(cx: &mut AppContext) {
cx.add_action(TerminalPanel::new_terminal);
cx.add_action(TerminalPanel::open_terminal);
}
#[derive(Debug)]
@ -79,7 +80,7 @@ impl TerminalPanel {
cx.window_context().defer(move |cx| {
if let Some(this) = this.upgrade(cx) {
this.update(cx, |this, cx| {
this.add_terminal(cx);
this.add_terminal(None, cx);
});
}
})
@ -230,6 +231,21 @@ impl TerminalPanel {
}
}
pub fn open_terminal(
workspace: &mut Workspace,
action: &workspace::OpenTerminal,
cx: &mut ViewContext<Workspace>,
) {
let Some(this) = workspace.focus_panel::<Self>(cx) else {
return;
};
this.update(cx, |this, cx| {
this.add_terminal(Some(action.working_directory.clone()), cx)
})
}
///Create a new Terminal in the current working directory or the user's home directory
fn new_terminal(
workspace: &mut Workspace,
_: &workspace::NewTerminal,
@ -239,19 +255,23 @@ impl TerminalPanel {
return;
};
this.update(cx, |this, cx| this.add_terminal(cx))
this.update(cx, |this, cx| this.add_terminal(None, cx))
}
fn add_terminal(&mut self, cx: &mut ViewContext<Self>) {
fn add_terminal(&mut self, working_directory: Option<PathBuf>, cx: &mut ViewContext<Self>) {
let workspace = self.workspace.clone();
cx.spawn(|this, mut cx| async move {
let pane = this.read_with(&cx, |this, _| this.pane.clone())?;
workspace.update(&mut cx, |workspace, cx| {
let working_directory_strategy = settings::get::<TerminalSettings>(cx)
.working_directory
.clone();
let working_directory =
crate::get_working_directory(workspace, cx, working_directory_strategy);
let working_directory = if let Some(working_directory) = working_directory {
Some(working_directory)
} else {
let working_directory_strategy = settings::get::<TerminalSettings>(cx)
.working_directory
.clone();
crate::get_working_directory(workspace, cx, working_directory_strategy)
};
let window = cx.window();
if let Some(terminal) = workspace.project().update(cx, |project, cx| {
project
@ -389,7 +409,7 @@ impl Panel for TerminalPanel {
fn set_active(&mut self, active: bool, cx: &mut ViewContext<Self>) {
if active && self.pane.read(cx).items_len() == 0 {
self.add_terminal(cx)
self.add_terminal(None, cx)
}
}

View file

@ -203,7 +203,15 @@ impl Clone for Toast {
}
}
impl_actions!(workspace, [ActivatePane, ActivatePaneInDirection, Toast]);
#[derive(Clone, Deserialize, PartialEq)]
pub struct OpenTerminal {
pub working_directory: PathBuf,
}
impl_actions!(
workspace,
[ActivatePane, ActivatePaneInDirection, Toast, OpenTerminal]
);
pub type WorkspaceId = i64;