diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index b541ff90e8..7f02488407 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -512,6 +512,8 @@ "alt-ctrl-o": "projects::OpenRecent", "alt-shift-open": "projects::OpenRemote", "alt-ctrl-shift-o": "projects::OpenRemote", + // Change to open path modal for existing remote connection by setting the parameter + // "alt-ctrl-shift-o": "["projects::OpenRemote", { "from_existing_connection": true }]", "alt-ctrl-shift-b": "branches::OpenRecent", "alt-shift-enter": "toast::RunAction", "ctrl-~": "workspace::NewTerminal", diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index 57c0e7c2be..6506aae9aa 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -588,6 +588,7 @@ // "alt-cmd-o": ["projects::OpenRecent", {"create_new_window": true }], "alt-cmd-o": "projects::OpenRecent", "ctrl-cmd-o": "projects::OpenRemote", + "ctrl-cmd-shift-o": ["projects::OpenRemote", { "from_existing_connection": true }], "alt-cmd-b": "branches::OpenRecent", "ctrl-~": "workspace::NewTerminal", "cmd-s": "workspace::Save", diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 00f49a5e82..8667036b7e 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -65,6 +65,7 @@ use workspace::{ notifications::{DetachAndPromptErr, NotifyTaskExt}, }; use worktree::CreatedEntry; +use zed_actions::OpenRecent; const PROJECT_PANEL_KEY: &str = "ProjectPanel"; const NEW_ENTRY_ID: ProjectEntryId = ProjectEntryId::MAX; @@ -4881,11 +4882,16 @@ impl Render for ProjectPanel { .child( Button::new("open_project", "Open a project") .full_width() - .key_binding(KeyBinding::for_action(&workspace::Open, window, cx)) + .key_binding(KeyBinding::for_action_in( + &OpenRecent::default(), + &self.focus_handle, + window, + cx, + )) .on_click(cx.listener(|this, _, window, cx| { this.workspace .update(cx, |_, cx| { - window.dispatch_action(Box::new(workspace::Open), cx) + window.dispatch_action(OpenRecent::default().boxed_clone(), cx); }) .log_err(); })), diff --git a/crates/recent_projects/src/recent_projects.rs b/crates/recent_projects/src/recent_projects.rs index 03444f03e5..60f7b38d56 100644 --- a/crates/recent_projects/src/recent_projects.rs +++ b/crates/recent_projects/src/recent_projects.rs @@ -468,9 +468,21 @@ impl PickerDelegate for RecentProjectsDelegate { .border_color(cx.theme().colors().border_variant) .child( Button::new("remote", "Open Remote Folder") - .key_binding(KeyBinding::for_action(&OpenRemote, window, cx)) + .key_binding(KeyBinding::for_action( + &OpenRemote { + from_existing_connection: false, + }, + window, + cx, + )) .on_click(|_, window, cx| { - window.dispatch_action(OpenRemote.boxed_clone(), cx) + window.dispatch_action( + OpenRemote { + from_existing_connection: false, + } + .boxed_clone(), + cx, + ) }), ) .child( diff --git a/crates/recent_projects/src/remote_servers.rs b/crates/recent_projects/src/remote_servers.rs index c12b3462ae..d2c985946f 100644 --- a/crates/recent_projects/src/remote_servers.rs +++ b/crates/recent_projects/src/remote_servers.rs @@ -350,7 +350,11 @@ impl RemoteServerProjects { _window: Option<&mut Window>, _: &mut Context, ) { - workspace.register_action(|workspace, _: &OpenRemote, window, cx| { + workspace.register_action(|workspace, action: &OpenRemote, window, cx| { + if action.from_existing_connection { + cx.propagate(); + return; + } let handle = cx.entity().downgrade(); let fs = workspace.project().read(cx).fs().clone(); workspace.toggle_modal(window, cx, |window, cx| Self::new(fs, window, cx, handle)) diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index c629981541..668a0828f3 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -432,14 +432,22 @@ impl TitleBar { .tooltip(move |window, cx| { Tooltip::with_meta( "Remote Project", - Some(&OpenRemote), + Some(&OpenRemote { + from_existing_connection: false, + }), meta.clone(), window, cx, ) }) .on_click(|_, window, cx| { - window.dispatch_action(OpenRemote.boxed_clone(), cx); + window.dispatch_action( + OpenRemote { + from_existing_connection: false, + } + .boxed_clone(), + cx, + ); }) .into_any_element(), ) diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 2d092f7eb4..d330241184 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -503,7 +503,7 @@ fn register_actions( directories: true, multiple: true, }, - DirectoryLister::Project(workspace.project().clone()), + DirectoryLister::Local(workspace.app_state().fs.clone()), window, cx, ); @@ -515,11 +515,42 @@ fn register_actions( if let Some(task) = this .update_in(cx, |this, window, cx| { - if this.project().read(cx).is_local() { - this.open_workspace_for_paths(false, paths, window, cx) - } else { - open_new_ssh_project_from_project(this, paths, window, cx) - } + this.open_workspace_for_paths(false, paths, window, cx) + }) + .log_err() + { + task.await.log_err(); + } + }) + .detach() + }) + .register_action(|workspace, action: &zed_actions::OpenRemote, window, cx| { + if !action.from_existing_connection { + cx.propagate(); + return; + } + // You need existing remote connection to open it this way + if workspace.project().read(cx).is_local() { + return; + } + telemetry::event!("Project Opened"); + let paths = workspace.prompt_for_open_path( + PathPromptOptions { + files: true, + directories: true, + multiple: true, + }, + DirectoryLister::Project(workspace.project().clone()), + window, + cx, + ); + cx.spawn_in(window, async move |this, cx| { + let Some(paths) = paths.await.log_err().flatten() else { + return; + }; + if let Some(task) = this + .update_in(cx, |this, window, cx| { + open_new_ssh_project_from_project(this, paths, window, cx) }) .log_err() { diff --git a/crates/zed/src/zed/app_menus.rs b/crates/zed/src/zed/app_menus.rs index 17a7e43927..c6c3ef5959 100644 --- a/crates/zed/src/zed/app_menus.rs +++ b/crates/zed/src/zed/app_menus.rs @@ -70,7 +70,12 @@ pub fn app_menus() -> Vec { create_new_window: true, }, ), - MenuItem::action("Open Remote...", zed_actions::OpenRemote), + MenuItem::action( + "Open Remote...", + zed_actions::OpenRemote { + from_existing_connection: false, + }, + ), MenuItem::separator(), MenuItem::action("Add Folder to Project…", workspace::AddFolderToProject), MenuItem::separator(), diff --git a/crates/zed_actions/src/lib.rs b/crates/zed_actions/src/lib.rs index 61887d3563..8ad7a6edc9 100644 --- a/crates/zed_actions/src/lib.rs +++ b/crates/zed_actions/src/lib.rs @@ -243,8 +243,14 @@ pub struct OpenRecent { pub create_new_window: bool, } -impl_actions!(projects, [OpenRecent]); -actions!(projects, [OpenRemote]); +#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)] +#[serde(deny_unknown_fields)] +pub struct OpenRemote { + #[serde(default)] + pub from_existing_connection: bool, +} + +impl_actions!(projects, [OpenRecent, OpenRemote]); /// Where to spawn the task in the UI. #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]