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.
This commit is contained in:
1 parent
3577d7a0e5
commit
98fad00b01
7 files changed
+51
-48
No files matched your search
@@ -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<String> {
|
||||
self.hidden.iter().filter(|host| self.configured.contains(host)).cloned().collect()
|
||||
|
||||
@@ -636,15 +636,6 @@ fn ssh_host_icon_ids(data_dir: &Path) -> std::collections::HashMap<String, Strin
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// 地址 → 展示名(用户在 SSH 设置里起的"主机名称"),与 `ssh_host_icon_ids`
|
||||
/// 同一缓存策略:启动器 / Quick Jump / 命令面板在打开时各读一次,编辑保存后
|
||||
/// 由下一轮打开刷新。没起名的主机不在这里,展示端回落地址本身。
|
||||
fn ssh_host_labels(data_dir: &Path) -> std::collections::HashMap<String, String> {
|
||||
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),
|
||||
|
||||
@@ -37,8 +37,7 @@ fn open(cx: &mut TestAppContext) -> (Entity<NebulaWorkspace>, 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,
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -142,15 +142,14 @@ fn directory_rows(language: crate::display::UiLanguage) -> Vec<WorkspacePaletteR
|
||||
fn ssh_rows(language: crate::display::UiLanguage) -> Vec<WorkspacePaletteRow> {
|
||||
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,
|
||||
|
||||
@@ -19,10 +19,7 @@ fn fallback_shell_glyph(id: &str, has_brand: bool) -> Option<char> {
|
||||
///
|
||||
/// - 用户在 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<crate::shell_detect::DetectedShell>,
|
||||
profiles: Vec<crate::config::ui_config::Profile>,
|
||||
ssh_hosts: impl IntoIterator<Item = String>,
|
||||
ssh_labels: &std::collections::HashMap<String, String>,
|
||||
ssh_hosts: impl IntoIterator<Item = (String, String)>,
|
||||
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,
|
||||
|
||||
@@ -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::<String>, &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::<String>,
|
||||
&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::<String>,
|
||||
&std::collections::HashMap::new(),
|
||||
None::<(String, String)>,
|
||||
&id,
|
||||
crate::display::UiLanguage::ZhCn,
|
||||
1.0,
|
||||
|
||||
Reference in new issue
Block a user