From a4d5646f1d9663412c2c4bd1624e238bfae760ae Mon Sep 17 00:00:00 2001 From: Aisland Date: Wed, 19 Aug 2026 23:28:49 +0800 Subject: [PATCH] fix: terminal garbled glyph + clipped long lines (spawn powershell with -NoProfile, force DECAWM wrap, Cascadia font) --- 01_content/src/client/split.tsx | 6 ++++-- 01_content/src/index.ts | 2 +- 02_process/worklogs/2026-08-16_worktable-v2.md | 13 +++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/01_content/src/client/split.tsx b/01_content/src/client/split.tsx index f5123f0..cbfc94a 100644 --- a/01_content/src/client/split.tsx +++ b/01_content/src/client/split.tsx @@ -1104,7 +1104,7 @@ function TerminalPane() { try { term = new Terminal({ cursorBlink: true, - fontFamily: 'Consolas, Menlo, monospace', + fontFamily: 'Cascadia Code, Cascadia Mono, Consolas, Menlo, monospace', fontSize: 12, convertEol: true, theme: { background: '#010409' }, @@ -1114,6 +1114,8 @@ function TerminalPane() { return } term.open(el) + // 强制自动换行(DECAWM on):超长行在窗口宽度处换行,不被截断 + try { term.write('\x1b[?7h') } catch {} const focusTerm = () => { try { term.focus() } catch {} } focusTerm() el.addEventListener('pointerdown', focusTerm) @@ -1127,7 +1129,7 @@ function TerminalPane() { setFailed(T('pane.termFail')) return } - ws.onopen = () => { focusTerm() } + ws.onopen = () => { focusTerm(); try { term.write('\x1b[?7h') } catch {} } ws.onmessage = (ev) => { try { term.write(String(ev.data)) } catch {} } ws.onclose = () => { if (!disposed) { try { term.write('\r\n[连接已关闭]') } catch {} } } ws.onerror = () => { if (!disposed) setFailed(T('pane.termFail')) } diff --git a/01_content/src/index.ts b/01_content/src/index.ts index 56e672c..deb40e0 100644 --- a/01_content/src/index.ts +++ b/01_content/src/index.ts @@ -151,7 +151,7 @@ function setupTerminal(webServer: any, ctx: any) { const wss = new WebSocketServer({ noServer: true }) const spawnShell = (): { cmd: string; args: string[] } => process.platform === 'win32' - ? { cmd: 'powershell.exe', args: ['-NoLogo'] } + ? { cmd: 'powershell.exe', args: ['-NoLogo', '-NoProfile'] } // -NoProfile:跳过用户配置(oh-my-posh 花哨提示符在 xterm 里是乱码,PSReadLine 长输入行不换行被截断) : { cmd: process.env.SHELL || '/bin/bash', args: [] } const clampDim = (v: number, fallback: number) => Math.min(1024, Math.max(2, Number.isFinite(v) ? v : fallback)) diff --git a/02_process/worklogs/2026-08-16_worktable-v2.md b/02_process/worklogs/2026-08-16_worktable-v2.md index 8662f48..591711d 100644 --- a/02_process/worklogs/2026-08-16_worktable-v2.md +++ b/02_process/worklogs/2026-08-16_worktable-v2.md @@ -952,6 +952,19 @@ knowledgeNeutral/stillHasHtmlForTools 全 true;functional-diag 全 20 STEP ERROR_COUNT: 0。 - 备注:纯客户端改动,F5 即生效;组件窗(配置驱动)方向另行讨论。 +## 补记(终端窗修复:乱码图标 + 长行截断) + +- 用户反馈(附图):终端窗左上角有奇怪乱码;长行输入超过窗口宽度被截断、不换行。 +- 根因:服务端以 powershell.exe -NoLogo 启动会加载用户 Profile——oh-my-posh 等花哨提示符 + 的 nerd 字体字符在 xterm 里渲染为乱码;PSReadLine 接管输入行后按 cols 宽度绘制、超宽部分 + 不换行直接截断。 +- 修复:① 服务端加 -NoProfile(干净标准提示符 + 控制台原生换行,一举两得);② 客户端字体 + 改 Cascadia Code 优先;③ term.open 与 ws 连接建立时写入 \x1b[?7h(DECAWM on)强制自动换行。 +- 验证:powershell.exe -NoLogo -NoProfile 正常启动(输出 OK);functional-diag 全 20 STEP + ERROR_COUNT: 0(终端窗不在回归范围内,视觉部分请用户重启后确认)。 +- 备注:-NoProfile 为服务端改动,需重启 dsh web 生效;字体/换行转义为客户端改动,F5 生效。 + +