From 69e641c2bd74688645e755e2604e34d73b534e2d Mon Sep 17 00:00:00 2001 From: Xuz Date: Sun, 11 Oct 2026 21:41:27 +0800 Subject: [PATCH] =?UTF-8?q?Windows=20=E6=9C=AC=E5=9C=B0=E7=BB=88=E7=AB=AF?= =?UTF-8?q?=E7=9A=84=E6=A0=87=E7=AD=BE=E5=8F=AA=E6=98=BE=E7=A4=BA=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E5=90=8D=EF=BC=8C=E4=B8=8D=E6=98=BE=E7=A4=BA=E5=AE=8C?= =?UTF-8?q?=E6=95=B4=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows 控制台把正在运行的程序的完整路径设成标题,标签显示成 「C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe」「C:\Windows\system32\cmd.exe」。 现在标题里的程序路径显示为程序名(powershell、cmd、cmd - ping localhost),其余标题不变。 Co-Authored-By: Claude Opus 5.5 --- src/terminal/local_terminal_panel.rs | 52 +++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/terminal/local_terminal_panel.rs b/src/terminal/local_terminal_panel.rs index 5df8b95..21f0a87 100644 --- a/src/terminal/local_terminal_panel.rs +++ b/src/terminal/local_terminal_panel.rs @@ -1,3 +1,6 @@ +use std::borrow::Cow; +use std::sync::LazyLock; + use gpui_kit::component::{ ActiveTheme as _, Icon, Sizable as _, button::Button, @@ -8,6 +11,7 @@ use gpui_kit::component::{ }; use gpui_kit::prelude::FluentBuilder as _; use gpui_kit::*; +use regex::Regex; use crate::app::{CatalogIcon, CenterTab, CloseLocalTerminal, RestartLocalTerminal}; use crate::i18n::t; @@ -104,10 +108,10 @@ impl LocalTerminalPanel { } fn display_title(&self, cx: &App) -> SharedString { - self.terminal - .read(cx) - .title(cx) - .map_or_else(|| self.default_title(), SharedString::from) + self.terminal.read(cx).title(cx).map_or_else( + || self.default_title(), + |title| short_title(&title).into_owned().into(), + ) } } @@ -232,6 +236,18 @@ impl Render for LocalTerminalPanel { } } +/// The shell's title without the folders of programs. The Windows console +/// titles a window with the whole path of what runs in it +/// (`C:\Windows\system32\cmd.exe - ping localhost`), which leaves a tab +/// little else; each such path shows as the program's name, `cmd`. +fn short_title(title: &str) -> Cow<'_, str> { + static PROGRAM_PATH: LazyLock = LazyLock::new(|| { + Regex::new(r#"(?i)\b[a-z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*([^\\/:*?"<>|\r\n]+?)\.exe\b"#) + .expect("pattern") + }); + PROGRAM_PATH.replace_all(title, "$1") +} + /// 「本地终端 1」, in the interface language. fn default_title(id: LocalTerminalId) -> SharedString { t!("terminal.local.title", number = id.0) @@ -255,3 +271,31 @@ fn tab_menu( .separator(); close_tab_items(menu, CenterTab::LocalTerminal(id), group, panel, cx) } + +#[cfg(test)] +mod tests { + use super::short_title; + + #[test] + fn a_programs_path_in_the_title_shows_as_its_name() { + for (title, shown) in [ + ( + r"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", + "powershell", + ), + (r"C:\Windows\system32\cmd.exe", "cmd"), + ( + r"C:\WINDOWS\system32\cmd.exe - ping localhost", + "cmd - ping localhost", + ), + (r"C:\Program Files\PowerShell\7\pwsh.exe", "pwsh"), + (r"管理员: C:\Windows\system32\cmd.exe", "管理员: cmd"), + // What is not a program's path stays. + ("xuz@mac: ~/src", "xuz@mac: ~/src"), + (r"D:\work", r"D:\work"), + ("vim notes.exe.txt", "vim notes.exe.txt"), + ] { + assert_eq!(short_title(title), shown, "{title}"); + } + } +}