diff --git a/TERMINAL_ROADMAP.md b/TERMINAL_ROADMAP.md new file mode 100644 index 0000000..da0970a --- /dev/null +++ b/TERMINAL_ROADMAP.md @@ -0,0 +1,135 @@ +# Terminal Roadmap — 对照 xterm.js 的追平计划 + +本文档记录 `base-path-demo` 浏览器终端**当前已实现的能力**、**相比 xterm.js 仍缺失的功能**,以及每一项**计划的实现方式与优先级**,供后续开发接手。 + +> 定位提醒:本项目目标不是复刻 xterm.js 这个通用 JS 终端库,而是按 [TERMINAL_HANDOFF.md](TERMINAL_HANDOFF.md) 的方向,用 `Axum + portable-pty`(后端)+ `Leptos + Rust/WASM`(前端)沉淀一套**可复用的 Rust 终端组件**。因此追平的重点是「让真实终端会话好用」,而非铺平 xterm.js 的全部 API 面。 + +--- + +## 1. 覆盖度自评(截至本文档) + +按用途粗估: + +- **「跑通真实终端会话」核心用途**:约 50–60% +- **xterm.js 完整 API / 特性面**:约 15–20% + +差距集中在**输入完整性**、**API/生态**、**可配置性**,而非「能不能用」。 + +### 已实现(有代码 + 单元测试) + +| 能力 | 位置 | +|---|---| +| PTY 会话 + WebSocket 双向流 | `server/src/terminal/{pty_session,ws}.rs` | +| ANSI 解析(vt100 crate):颜色 / 粗体 / 斜体 / 下划线 / 反色、CSI 光标控制、擦除、滚动区 | `app/src/terminal/core.rs` | +| 256 色 + RGB 真彩 | `core.rs::indexed_color` / `resolve_*` | +| alt-screen(vim / btm / htop),含历史隔离 | `core.rs::process` | +| scrollback + 虚拟滚动(万行不卡,绝对定位) | `core.rs::collect_window` / `component.rs::virtual_window` | +| 宽字符 / 组合字符网格对齐 | `core.rs` `TerminalSegment.cols` | +| resize / reflow | `core.rs::resize` | +| `clear`(含 `ESC[3J` 清 scrollback) | `core.rs::contains_erase_scrollback` | +| alt-screen 滚轮 → 方向键翻页 | `component.rs::handle_wheel` | +| 基础按键:Ctrl-C/D/L、方向键、Enter/Tab/Esc/Backspace | `component.rs::map_key_to_terminal_input` | + +--- + +## 2. 追平项(按优先级) + +### P0 — 复制 / 粘贴 + 文本选区 ⭐ 投入产出比最高 + +**现状**:完全没有。无法选中终端文本、无法粘贴。这是「能用 vs 好用」的分界线。 + +**计划实现**: +1. **粘贴(先做,最简单)** + - 监听 `on:paste`(`ClipboardEvent`),读 `clipboard_data().get_data("text")`。 + - 直接作为 `ClientTerminalMessage::Input` 发送。 + - 若应用开启 bracketed paste 模式(vt100 的 `screen().bracketed_paste()` 为真),把粘贴内容包进 `ESC[200~ … ESC[201~`,避免 vim 等把粘贴当连续输入触发自动缩进。 +2. **选区(较复杂)** + - 因为渲染是 DOM(每行一个 `