feat(ssh): add host duplicate context action
This commit is contained in:
1 parent
9dc058d127
commit
31cb03a396
1 file changed
+93
@@ -121,6 +121,39 @@ impl SettingsPane {
|
|||||||
self.ssh_library.reset_scroll();
|
self.ssh_library.reset_scroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn duplicate_ssh_host(
|
||||||
|
&mut self,
|
||||||
|
host: String,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
let label = self
|
||||||
|
.ssh_hosts
|
||||||
|
.profiles
|
||||||
|
.for_destination(&host)
|
||||||
|
.label
|
||||||
|
.filter(|label| !label.trim().is_empty())
|
||||||
|
.unwrap_or_else(|| host.clone());
|
||||||
|
let label = self.ssh_hosts.profiles.next_default_label(label.trim());
|
||||||
|
|
||||||
|
self.open_ssh_editor(Some(host), window, cx);
|
||||||
|
if let Some(editor) = self.ssh_editor.as_mut() {
|
||||||
|
editor.original_destination = None;
|
||||||
|
}
|
||||||
|
self.ssh_destination_input
|
||||||
|
.update(cx, |input, cx| input.set_value("", window, cx));
|
||||||
|
self.ssh_label_input
|
||||||
|
.update(cx, |input, cx| input.set_value(label, window, cx));
|
||||||
|
self.ssh_password_input.update(cx, |input, cx| {
|
||||||
|
input.set_placeholder(
|
||||||
|
crate::gpui_shell::config::ui_language(cx)
|
||||||
|
.pick("留空则连接时询问", "Leave empty to ask when connecting"),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn filtered_library_hosts(&self, cx: &gpui::App) -> Vec<String> {
|
fn filtered_library_hosts(&self, cx: &gpui::App) -> Vec<String> {
|
||||||
let query = self.ssh_library.search.read(cx).value();
|
let query = self.ssh_library.search.read(cx).value();
|
||||||
let mut hosts = if self.ssh_library.scope == HostScope::Recent {
|
let mut hosts = if self.ssh_library.scope == HostScope::Recent {
|
||||||
@@ -421,6 +454,8 @@ impl SettingsPane {
|
|||||||
// 行首 OS 图标(旧壳裁定 2026-08-09):id 取自 ssh_profiles 存储,
|
// 行首 OS 图标(旧壳裁定 2026-08-09):id 取自 ssh_profiles 存储,
|
||||||
// 未认出回落通用终端形状;mono 字体渲染 Nerd Font 字位。
|
// 未认出回落通用终端形状;mono 字体渲染 Nerd Font 字位。
|
||||||
let os_icon = crate::display::ui::os_icons::resolve(icons.get(&host).map(String::as_str));
|
let os_icon = crate::display::ui::os_icons::resolve(icons.get(&host).map(String::as_str));
|
||||||
|
let context_owner = cx.entity().downgrade();
|
||||||
|
let context_host = host.clone();
|
||||||
let connect_host = host.clone();
|
let connect_host = host.clone();
|
||||||
let edit_host = host.clone();
|
let edit_host = host.clone();
|
||||||
let pin_host = host.clone();
|
let pin_host = host.clone();
|
||||||
@@ -443,6 +478,64 @@ impl SettingsPane {
|
|||||||
.border_color(theme.border)
|
.border_color(theme.border)
|
||||||
.bg(theme.secondary.opacity(0.25))
|
.bg(theme.secondary.opacity(0.25))
|
||||||
.hover(move |row| row.bg(hover_bg))
|
.hover(move |row| row.bg(hover_bg))
|
||||||
|
.context_menu(move |menu, _, _| {
|
||||||
|
let connect_owner = context_owner.clone();
|
||||||
|
let edit_owner = context_owner.clone();
|
||||||
|
let duplicate_owner = context_owner.clone();
|
||||||
|
let delete_owner = context_owner.clone();
|
||||||
|
let connect_host = context_host.clone();
|
||||||
|
let edit_host = context_host.clone();
|
||||||
|
let duplicate_host = context_host.clone();
|
||||||
|
let delete_host = context_host.clone();
|
||||||
|
menu.item(
|
||||||
|
PopupMenuItem::new(language.text(Message::LauncherConnect)).on_click(
|
||||||
|
move |_, _, cx| {
|
||||||
|
let _ = connect_owner.update(cx, |this, cx| {
|
||||||
|
cx.emit(SettingsPaneEvent::LaunchSsh(connect_host.clone()));
|
||||||
|
this.ssh_status =
|
||||||
|
Some(SshStatus::Opening(connect_host.clone()));
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.item(
|
||||||
|
PopupMenuItem::new(language.text(Message::LauncherEdit)).on_click(
|
||||||
|
move |_, window, cx| {
|
||||||
|
let _ = edit_owner.update(cx, |this, cx| {
|
||||||
|
this.open_ssh_editor(
|
||||||
|
Some(edit_host.clone()),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.item(
|
||||||
|
PopupMenuItem::new(language.text(Message::CommonCopy)).on_click(
|
||||||
|
move |_, window, cx| {
|
||||||
|
let _ = duplicate_owner.update(cx, |this, cx| {
|
||||||
|
this.duplicate_ssh_host(
|
||||||
|
duplicate_host.clone(),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.item(
|
||||||
|
PopupMenuItem::new(language.text(Message::LauncherDelete)).on_click(
|
||||||
|
move |_, _, cx| {
|
||||||
|
let _ = delete_owner.update(cx, |this, cx| {
|
||||||
|
this.ssh_delete_confirm = Some(delete_host.clone());
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
.child(
|
.child(
|
||||||
crate::gpui_shell::widgets::device_icon_container(cx)
|
crate::gpui_shell::widgets::device_icon_container(cx)
|
||||||
.id(SharedString::from(format!("ssh-host-icon-{ix}")))
|
.id(SharedString::from(format!("ssh-host-icon-{ix}")))
|
||||||
|
|||||||
Reference in new issue
Block a user