From 98fad00b01da9dd089581e4d4f66a251bfc1404d Mon Sep 17 00:00:00 2001 From: ZiChuanShanFeng <270144683+WMU-Demo@users.noreply.github.com> Date: Thu, 24 Sep 2026 01:00:33 +0800 Subject: [PATCH] refactor(launcher): keep workspace.rs within its line budget The architecture contracts check enforces max(target, base) lines per exception file, and workspace.rs is already at its base size. Move the SSH label lookup out of workspace.rs instead of growing it: - ssh_hosts.rs: add `merged_with_labels()` which reuses the profiles already loaded by `SshHostLists::load()` (no extra JSON parse) and yields (host, label) pairs in the same authoritative merge order. - shell_picker.rs / quick_jump.rs / palette.rs: consume the label from those pairs; `ssh_host_display()` keeps the alias-or-fallback rule. - workspace.rs: net zero lines (helper and extra argument removed). Also apply the pinned rustfmt (1.97.1) to the touched files. Verified locally: check_architecture.py --base origin/main passes, architecture guardrail tests 53/53, file_line_budget 2/2, workspace:: tests 107/107, gpui-shell --tests check clean. --- nebula_app/src/gpui_shell/ssh_hosts.rs | 15 +++++++++++ nebula_app/src/gpui_shell/workspace.rs | 12 +-------- .../workspace/launcher_menu/tests.rs | 3 +-- .../src/gpui_shell/workspace/palette.rs | 20 +++++++-------- .../src/gpui_shell/workspace/quick_jump.rs | 9 +++---- .../src/gpui_shell/workspace/shell_picker.rs | 15 +++++------ nebula_app/src/gpui_shell/workspace/tests.rs | 25 +++++++++++-------- 7 files changed, 51 insertions(+), 48 deletions(-) diff --git a/nebula_app/src/gpui_shell/ssh_hosts.rs b/nebula_app/src/gpui_shell/ssh_hosts.rs index 6267a37..9b9c0be 100644 --- a/nebula_app/src/gpui_shell/ssh_hosts.rs +++ b/nebula_app/src/gpui_shell/ssh_hosts.rs @@ -64,6 +64,21 @@ impl SshHostLists { ) } + /// 与 [`Self::merged`] 同一顺序权威,同时带出用户在 SSH 设置里起的 + /// 主机名称(地址 → 别名;没起名的是空串,展示端回落地址本身)。 + /// profiles 在 [`Self::load`] 时已经读盘,这里不重复读 JSON;launcher / + /// Quick Jump / 命令面板三处 SSH 行共用,避免各自再解析一次。 + pub fn merged_with_labels(&self) -> Vec<(String, String)> { + let labels = self.profiles.labels(); + self.merged() + .into_iter() + .map(|host| { + let label = labels.get(&host).cloned().unwrap_or_default(); + (host, label) + }) + .collect() + } + /// 隐藏区(设置页"已隐藏"折叠列表的数据源)。 pub fn hidden_hosts(&self) -> Vec { self.hidden.iter().filter(|host| self.configured.contains(host)).cloned().collect() diff --git a/nebula_app/src/gpui_shell/workspace.rs b/nebula_app/src/gpui_shell/workspace.rs index 567d976..f0d7be7 100644 --- a/nebula_app/src/gpui_shell/workspace.rs +++ b/nebula_app/src/gpui_shell/workspace.rs @@ -636,15 +636,6 @@ fn ssh_host_icon_ids(data_dir: &Path) -> std::collections::HashMap std::collections::HashMap { - crate::ssh_profiles::SshProfiles::load(&data_dir.join("ssh_profiles.json")) - .map(|profiles| profiles.labels()) - .unwrap_or_default() -} - /// 标签的用户可编辑元数据:重命名与色标(旧壳 `TabEntry::custom_name` / /// `custom_color` 的对应物,字段与共享 session v4 的 `TabSession` 同名同义, /// 所以导出/恢复不需要转换层)。 @@ -2237,8 +2228,7 @@ impl NebulaWorkspace { crate::terminal_profiles::TerminalProfiles::load() .map(|store| store.as_config_profiles()) .unwrap_or_default(), - crate::gpui_shell::ssh_hosts::SshHostLists::load().merged(), - &ssh_host_labels(&crate::display::nebula_data_dir()), + crate::gpui_shell::ssh_hosts::SshHostLists::load().merged_with_labels(), &default_shell_id, language, window.scale_factor().max(0.5), diff --git a/nebula_app/src/gpui_shell/workspace/launcher_menu/tests.rs b/nebula_app/src/gpui_shell/workspace/launcher_menu/tests.rs index 3a4d0d1..d8caafd 100644 --- a/nebula_app/src/gpui_shell/workspace/launcher_menu/tests.rs +++ b/nebula_app/src/gpui_shell/workspace/launcher_menu/tests.rs @@ -37,8 +37,7 @@ fn open(cx: &mut TestAppContext) -> (Entity, VisualTestContext) workspace.palette_override = Some(shell_palette_rows( vec![shell("cmd"), shell("pwsh")], vec![], - ["test-host".into()], - &std::collections::HashMap::new(), + [("test-host".into(), String::new())], "cmd", workspace_ui_language(), 1.0, diff --git a/nebula_app/src/gpui_shell/workspace/palette.rs b/nebula_app/src/gpui_shell/workspace/palette.rs index b4ad9e1..63b49c3 100644 --- a/nebula_app/src/gpui_shell/workspace/palette.rs +++ b/nebula_app/src/gpui_shell/workspace/palette.rs @@ -99,20 +99,19 @@ impl NebulaWorkspace { // 启动器混排(旧壳 ⌘K 裁定):SSH 主机与命令同列,置顶/隐藏 // 次序由共享 merge 权威裁定。 let ssh_icons = ssh_host_icon_ids(&crate::display::nebula_data_dir()); - let ssh_labels = ssh_host_labels(&crate::display::nebula_data_dir()); rows.extend( - crate::gpui_shell::ssh_hosts::SshHostLists::load().merged().into_iter().map( - |host| { + crate::gpui_shell::ssh_hosts::SshHostLists::load() + .merged_with_labels() + .into_iter() + .map(|(host, label)| { let glyph = crate::display::ui::os_icons::resolve( ssh_icons.get(&host).map(String::as_str), ) .glyph; - let (label, hint) = shell_picker::ssh_host_display( - ssh_labels.get(&host).map(String::as_str), - &host, - ); - let search = format!("{label} {host} ssh host remote lianjie 连接") - .to_lowercase(); + let named = (!label.is_empty()).then_some(label.as_str()); + let (label, hint) = shell_picker::ssh_host_display(named, &host); + let search = + format!("{label} {host} ssh host remote lianjie 连接").to_lowercase(); WorkspacePaletteRow { group_order: usize::MAX, group: language.pick("SSH 主机", "SSH HOSTS").to_owned(), @@ -125,8 +124,7 @@ impl NebulaWorkspace { icon_glyph: Some(glyph), icon_path: None, } - }, - ), + }), ); rows }); diff --git a/nebula_app/src/gpui_shell/workspace/quick_jump.rs b/nebula_app/src/gpui_shell/workspace/quick_jump.rs index 4ab3d5d..234f40e 100644 --- a/nebula_app/src/gpui_shell/workspace/quick_jump.rs +++ b/nebula_app/src/gpui_shell/workspace/quick_jump.rs @@ -142,15 +142,14 @@ fn directory_rows(language: crate::display::UiLanguage) -> Vec Vec { let group = language.pick("SSH 主机", "SSH hosts"); let icons = ssh_host_icon_ids(&crate::display::nebula_data_dir()); - let labels = ssh_host_labels(&crate::display::nebula_data_dir()); crate::gpui_shell::ssh_hosts::SshHostLists::load() - .merged() + .merged_with_labels() .into_iter() - .map(|host| { + .map(|(host, label)| { let glyph = crate::display::ui::os_icons::resolve(icons.get(&host).map(String::as_str)).glyph; - let (label, hint) = - super::shell_picker::ssh_host_display(labels.get(&host).map(String::as_str), &host); + let named = (!label.is_empty()).then_some(label.as_str()); + let (label, hint) = shell_picker::ssh_host_display(named, &host); let search = format!("{label} {host} ssh host remote 远程 连接").to_lowercase(); WorkspacePaletteRow { group_order: 3, diff --git a/nebula_app/src/gpui_shell/workspace/shell_picker.rs b/nebula_app/src/gpui_shell/workspace/shell_picker.rs index c0a9b8a..4702c6d 100644 --- a/nebula_app/src/gpui_shell/workspace/shell_picker.rs +++ b/nebula_app/src/gpui_shell/workspace/shell_picker.rs @@ -19,10 +19,7 @@ fn fallback_shell_glyph(id: &str, has_brand: bool) -> Option { /// /// - 用户在 SSH 设置里起过"主机名称":label 显示别名,hint 给真实连接地址; /// - 没起名:回落地址本身当 label,hint 保持 "SSH" 类型标签,避免重复。 -pub(super) fn ssh_host_display( - label: Option<&str>, - host: &str, -) -> (String, String) { +pub(super) fn ssh_host_display(label: Option<&str>, host: &str) -> (String, String) { match label { Some(label) if !label.trim().is_empty() => (label.trim().to_owned(), host.to_owned()), _ => (host.to_owned(), "SSH".to_owned()), @@ -35,8 +32,7 @@ pub(super) fn ssh_host_display( pub(super) fn shell_palette_rows( shells: Vec, profiles: Vec, - ssh_hosts: impl IntoIterator, - ssh_labels: &std::collections::HashMap, + ssh_hosts: impl IntoIterator, default_shell_id: &str, language: crate::display::UiLanguage, scale_factor: f32, @@ -100,11 +96,12 @@ pub(super) fn shell_palette_rows( rows.insert(0, default_row); } let ssh_icons = ssh_host_icon_ids(&crate::display::nebula_data_dir()); - rows.extend(ssh_hosts.into_iter().map(|host| { + rows.extend(ssh_hosts.into_iter().map(|(host, label)| { let glyph = crate::display::ui::os_icons::resolve(ssh_icons.get(&host).map(String::as_str)).glyph; - let (label, hint) = - ssh_host_display(ssh_labels.get(&host).map(String::as_str), &host); + // 空串 = 没起名:`ssh_host_display` 回落地址本身,hint 保持 "SSH"。 + let named = (!label.is_empty()).then_some(label.as_str()); + let (label, hint) = ssh_host_display(named, &host); let search = format!("{label} {host} ssh host remote lianjie 连接").to_lowercase(); WorkspacePaletteRow { group_order: 2, diff --git a/nebula_app/src/gpui_shell/workspace/tests.rs b/nebula_app/src/gpui_shell/workspace/tests.rs index 0c0bc03..fb76b4b 100644 --- a/nebula_app/src/gpui_shell/workspace/tests.rs +++ b/nebula_app/src/gpui_shell/workspace/tests.rs @@ -556,8 +556,7 @@ fn shell_palette_puts_the_default_shell_first() { let rows = shell_palette_rows( shells.clone(), Vec::new(), - ["box.example".to_owned()], - &std::collections::HashMap::new(), + [("box.example".to_owned(), String::new())], "nu", language, 1.0, @@ -584,7 +583,14 @@ fn shell_palette_puts_the_default_shell_first() { assert_eq!(rows[4].group, "SSH 主机"); // 默认 id 没在检测结果里(WSL 发行版被卸载等):不置顶也不 panic。 - let rows = shell_palette_rows(shells, Vec::new(), None::, &std::collections::HashMap::new(), "wsl:Ghost", language, 1.0); + let rows = shell_palette_rows( + shells, + Vec::new(), + None::<(String, String)>, + "wsl:Ghost", + language, + 1.0, + ); assert!(matches!( &rows[0].action, WorkspacePaletteAction::LaunchShell(shell) if shell.id == "pwsh" @@ -596,12 +602,13 @@ fn shell_palette_puts_the_default_shell_first() { /// 回落地址本身、hint 保持 "SSH"。搜索词必须同时覆盖别名与地址。 #[test] fn shell_palette_ssh_rows_show_the_configured_host_name() { - let labels = [("root@box.example".to_owned(), "生产机".to_owned())].into(); let rows = shell_palette_rows( Vec::new(), Vec::new(), - ["root@box.example".to_owned(), "plain.example".to_owned()], - &labels, + [ + ("root@box.example".to_owned(), "生产机".to_owned()), + ("plain.example".to_owned(), String::new()), + ], "cmd", crate::display::UiLanguage::ZhCn, 1.0, @@ -644,8 +651,7 @@ fn shell_palette_falls_back_to_an_id_glyph_when_brand_art_is_absent() { let rows = shell_palette_rows( shells, Vec::new(), - None::, - &std::collections::HashMap::new(), + None::<(String, String)>, "zsh", crate::display::UiLanguage::ZhCn, 1.0, @@ -686,8 +692,7 @@ fn shell_palette_includes_imported_terminal_profiles() { let rows = shell_palette_rows( Vec::new(), vec![profile], - None::, - &std::collections::HashMap::new(), + None::<(String, String)>, &id, crate::display::UiLanguage::ZhCn, 1.0,