Files
pebrel/nebula_app/src/gpui_shell/settings_pane/setting_help.rs
T
kuddev 1552a5f7e5 feat(settings): expand UI languages and simplify preferences
Share the locale registry and generate typed static catalogs with tested
fallback and allocation contracts. Add searchable sections, a backed-up
defaults reset, compact navigation and expandable appearance help.

Include the existing formatter corrections required by the repository
hook, and remove the obsolete settings-pane line-budget exception after
its construction, localization and navigation responsibilities move out.
Update both English and Chinese unreleased notes.
2026-09-06 19:23:32 +08:00

222 lines
12 KiB
Rust

use crate::display::UiLanguage;
#[derive(Clone, Copy)]
pub(super) struct SettingHelp {
pub summary: &'static str,
pub details: Option<&'static str>,
}
impl From<&'static str> for SettingHelp {
fn from(summary: &'static str) -> Self {
Self { summary, details: None }
}
}
pub(super) fn help(key: &str, language: UiLanguage) -> SettingHelp {
let (summary, details) = match key {
"background" => (
language.pick("只更改终端底色,设置页仍跟随主题。", "Changes only the terminal background; Settings keeps the theme colors."),
None,
),
"background_image" => (
language.pick("在终端文字后方显示图片。", "Shows an image behind terminal text."),
Some(language.pick("图片不改变文字配色;看不清时可降低背景图像不透明度。", "Text colors still come from the theme. Lower the image opacity if text is hard to read.")),
),
"background_image_fit" => (
language.pick("调整图片的铺放方式。", "Chooses how the background image fills the terminal."),
Some(language.pick("拉伸会改变比例;适应和填充保持比例;原始尺寸不缩放。", "Fill stretches the image. Uniform and Uniform to fill preserve its aspect ratio. Original size does not scale it.")),
),
"background_image_alignment" => (
language.pick("设置图片在终端中的位置。", "Positions the image within the terminal."),
None,
),
"background_image_opacity" => (
language.pick("数值越低,图片越淡。", "Lower values make the image less prominent."),
None,
),
"background_image_cover_chrome" => (
language.pick("关闭后,图片只显示在终端区域。", "When disabled, the image appears only behind the terminal."),
None,
),
"cursor_shape" => ("", None),
"cursor_blink" => (
language.pick("关闭后,光标保持常亮。", "When disabled, the cursor stays lit."),
None,
),
"tab_close_visible" => (
language.pick("隐藏后,仍可用鼠标中键关闭标签。", "Middle-click still closes tabs when their close buttons are hidden."),
None,
),
"language" => (
language.pick("只更改应用界面的语言。", "Changes only the application interface language."),
Some(language.pick("终端内程序的输出语言由各自的环境设置决定。", "Programs inside the terminal choose their output language from their own environment.")),
),
"density" => (
language.pick("调整界面留白,不改变终端行距。", "Adjusts interface spacing without changing terminal line spacing."),
None,
),
"opacity" => (
language.pick("100% 为完全不透明,不影响设置页。", "100% is fully opaque. The Settings page is unaffected."),
None,
),
"blur" => (
language.pick("选择窗口背景的模糊效果。", "Chooses the window background effect."),
Some(language.pick("Mica 系列开销较低;Aero 和 Acrylic 实时模糊窗口后方的内容,开销较高。", "Mica effects use fewer resources. Aero and Acrylic blur live content behind the window and cost more.")),
),
"cell_width_mode" => (
language.pick("调整终端字符的列宽。", "Adjusts terminal character cell width."),
Some(language.pick("紧凑向下取整;宽松向上补齐,避免小数字宽的字体显得拥挤。只影响终端网格。", "Compact rounds down. Relaxed rounds up to avoid squeezing fonts with fractional widths. Only the terminal grid is affected.")),
),
"fetch" => (
language.pick("新会话启动时显示系统信息。", "Shows system information when a new session starts."),
Some(language.pick("通过 fastfetch 显示系统信息;关闭可减少新标签的启动等待。", "Uses fastfetch to display system information. Disabling it reduces startup work for new tabs.")),
),
"powerline" => (
language.pick("显示分段提示符,需字体支持。", "Shows a segmented prompt. Requires a compatible font."),
Some(language.pick("字体须包含 Powerline 字形,否则分段箭头可能显示为方框。", "The font must include Powerline glyphs or the segment arrows may appear as boxes.")),
),
"shell" => (
language.pick("用于新标签,不影响已打开的终端。", "Used for new tabs. Existing terminals are unaffected."),
None,
),
"startup_directory" => (
language.pick("未设置时,继承应用的启动目录。", "When unset, inherits the directory used to launch the application."),
Some(language.pick("从资源管理器的文件夹中启动时,默认进入该文件夹。", "Launching from a File Explorer folder uses that folder by default.")),
),
"bell" => (
language.pick("程序提示时,选择声音或闪烁提醒。", "Chooses sound or visual feedback for terminal alerts."),
None,
),
"font_family" => (
language.pick("按字体组顺序查找可用字形。", "Uses the font group in order to find available glyphs."),
Some(language.pick("前面的字体缺少字形时,会继续尝试后面的字体。", "When a font lacks a glyph, the next font in the group is tried.")),
),
"ghost" => (
language.pick("根据历史命令给出建议,确认后才填入。", "Suggests commands from history and inserts them only after acceptance."),
None,
),
"accept" => (
language.pick("选择填入建议时使用的按键。", "Chooses the key used to accept a suggestion."),
Some(language.pick("如果 Tab 与 Shell 自带补全冲突,可改用右方向键。", "Use Right arrow if Tab conflicts with the shell's own completion.")),
),
"completion_style" => (
language.pick("选择行内建议或候选列表。", "Chooses inline suggestions or a list of candidates."),
Some(language.pick("行内建议不遮挡下方输出;候选列表能同时显示多项建议。", "Inline suggestions leave output visible. A popup list shows several candidates at once.")),
),
"copy_on_select" => (
language.pick("松开鼠标自动复制,右键直接粘贴。", "Copies on mouse release and pastes on right-click."),
Some(language.pick("关闭后,选中不会自动复制;右键改为打开复制与粘贴菜单。", "When disabled, selection does not copy automatically and right-click opens the copy/paste menu.")),
),
"multiline_paste_confirm" => (
language.pick("在普通 shell 中粘贴多行或高风险内容时先确认。", "Asks before multiline or risky pastes in a plain shell."),
Some(language.pick("检查换行、提权命令和控制字符。Bracketed paste 模式与全屏程序不受此项保护;关闭后直接粘贴。", "Checks line breaks, privileged commands and control characters. Bracketed paste and full-screen apps are unaffected; disabling this pastes directly.")),
),
"panel_resize" => (
language.pick("关闭后锁定分界线,避免误拖。", "Locks the divider when disabled to prevent accidental resizing."),
None,
),
"cjk_bold_regular" => (
language.pick("用提亮代替加粗,让密集笔画更清楚。", "Brightens dense glyphs instead of thickening their strokes."),
Some(language.pick("只影响中日韩(CJK)粗体字形,拉丁字母仍使用真正的粗体。", "Only CJK bold glyphs are affected. Latin letters still use true bold.")),
),
"tabs_position" => ("", None),
"tab_reveal" => (
language.pick("新标签滑动出现,或立即显示。", "Slides new tabs into view or shows them immediately."),
None,
),
"new_tab_position" => (
language.pick("只影响新标签,不改变恢复时的顺序。", "Affects new tabs only, not the order of restored tabs."),
None,
),
"windowing_behavior" => (
language.pick("再次启动应用时,新开窗口或加入已有窗口。", "Opens a new window or joins an existing one when launched again."),
None,
),
"vcs_display" => (
language.pick("选择侧栏显示 Git 还是 SVN 状态。", "Chooses whether the sidebar shows Git or SVN status."),
Some(language.pick("自动检测会识别 .git 和 .svn;同目录存在两者时可手动指定。", "Auto detect checks for .git and .svn. Choose manually when both are present.")),
),
"keep_session" => (
language.pick("关窗后终端继续运行;关闭此项会结束会话。", "Keeps terminals running after closing the window; disabling it ends sessions."),
Some(language.pick("关闭此项后,关窗会终止 Shell,未保存的工作可能丢失。开启后可重新附着到后台会话。", "When disabled, closing the window terminates its shells and may lose unsaved work. When enabled, background sessions can be reattached.")),
),
"restore_session" => (
language.pick("恢复标签、布局和目录,不恢复原进程。", "Restores tabs, layout and directories, not the original processes."),
Some(language.pick("恢复的标签会启动新的 Shell,不会让已结束的程序继续运行。", "Restored tabs start new shells; terminated programs are not resumed.")),
),
"resume_ai" => (
language.pick("恢复 AI 标签时,继续上次的对话。", "Continues the previous conversation when restoring an AI tab."),
None,
),
"tray" => (
language.pick("在通知区域查看 AI 会话状态。", "Shows AI session status in the notification area."),
None,
),
_ => unreachable!("unknown settings help key: {key}"),
};
SettingHelp { summary, details }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn descriptions_stay_short_in_both_interface_languages() {
let keys = [
"background",
"background_image",
"background_image_fit",
"background_image_alignment",
"background_image_opacity",
"background_image_cover_chrome",
"cursor_shape",
"cursor_blink",
"tab_close_visible",
"language",
"density",
"opacity",
"blur",
"cell_width_mode",
"fetch",
"powerline",
"shell",
"startup_directory",
"bell",
"font_family",
"ghost",
"accept",
"completion_style",
"copy_on_select",
"multiline_paste_confirm",
"panel_resize",
"cjk_bold_regular",
"tabs_position",
"tab_reveal",
"new_tab_position",
"windowing_behavior",
"vcs_display",
"keep_session",
"restore_session",
"resume_ai",
"tray",
];
for key in keys {
for language in [UiLanguage::ZhCn, UiLanguage::EnUs] {
let description = help(key, language);
let limit = if language == UiLanguage::ZhCn { 32 } else { 100 };
assert!(description.summary.chars().count() <= limit, "long summary: {key}");
assert!(description.details.is_none_or(|details| !details.is_empty()));
}
}
}
#[test]
fn critical_limits_remain_in_the_short_description() {
let language = UiLanguage::ZhCn;
assert!(help("keep_session", language).summary.contains("结束会话"));
assert!(help("restore_session", language).summary.contains("不恢复原进程"));
assert!(help("multiline_paste_confirm", language).details.unwrap().contains("全屏程序"));
}
}