Detailed changes
@@ -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",
@@ -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",
@@ -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();
})),
@@ -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(
@@ -350,7 +350,11 @@ impl RemoteServerProjects {
_window: Option<&mut Window>,
_: &mut Context<Workspace>,
) {
- 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))
@@ -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(),
)
@@ -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()
{
@@ -70,7 +70,12 @@ pub fn app_menus() -> Vec<Menu> {
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(),
@@ -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)]