跳转至

Mini REPL

从 5005 行的 src/screens/REPL.tsx 提炼到 ~200 行 的 readline + history + completion + multi-line。 真实 REPL 强依赖 React + Ink 难演示,本 demo 用 Node 内置 readline + scripted inputs 跑测试。

文件

mini-repl/
├── src/
│   ├── repl.ts  Repl class + readline + history + completion + multi-line(~180 行)
│   └── cli.ts   5 场景测试
└── README.md

npm install && npm start
# 或真交互:node dist/cli.js 后输命令

真实代码对照

Demo 真实文件 简化
readline REPL.tsx:500(用 ink-text-input) Node 内置 readline
history REPL.tsx:1500(用 history stack) string[] 数组
completion REPL.tsx:2000(基于 register 命令) 简单 prefix 匹配
multiLine REPL.tsx:3000(反引号 / 三引号) 数 backtick 配对

核心 4 件套

1️⃣ readline = 一问一答

const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
rl.on("line", (line) => { /* process */ });
rl.on("close", () => { /* cleanup */ });
事件驱动——line 一来就处理,close 触发退出。

2️⃣ history = 简单数组

private history: string[] = [];
// 加: this.history.push(trimmed)
// 读: /history 命令遍历
// 真实 CC: ↑↓ 方向键浏览(readline 自带 + history reverse-search)

3️⃣ tab completion = prefix 匹配

complete(line: string): string[] {
  if (tokens.length === 1) return this.commands.filter(c => c.startsWith(line));
  const cmd = this.commands.get(tokens[0]);
  return cmd?.subcommands?.filter(s => s.startsWith(line)) ?? [];
}
两级:第一 token = 命令名,之后 = 子命令。

4️⃣ multi-line = backtick 配对

// 奇数 backtick = 开
// 偶数 backtick = 关
if (countBackticks(trimmed) % 2 === 1) { /* 累积 */ }
为什么数 backtick: - "echo \line 1"(1) → 开 -"line 2"(0) → 继续 -"line 3`"` (1) → 累计 2 = 偶 → 关

5 场景输出

📌 Test 1: basic commands (scripted)
Hello, Alice!
hello world
3 + 5 = 8
(unknown command: unknown_cmd)
greet      Greet someone
echo       Echo back input
add        Add two numbers
(exit)

📌 Test 2: history (/history)
1: greet A
2: greet B
3: greet C
4: /history

📌 Test 3: tab completion
  complete("gr") → greet
  complete("ec") → echo
  complete("greet he") → hello

📌 Test 4: multi-line input (backtick)
(multi-line: send even more ` to close)
`line 1 line 2 line 3`

📌 Test 5: integrated session
  全场景混合

进阶练习

  1. 接真 readline 模式:删 scriptedInputs 分支
  2. 加 reverse-search:Ctrl+R 搜历史
  3. 加 syntax highlight:在 readline 高亮命令/参数
  4. 加 color prompt:根据 state 变色
  5. 加 persistent history:写到 ~/.ccmin_history
  6. 加 multiline detection 三引号...

相关阅读