# 🔧 自动退出问题修复

## 问题现象

用户在使用时遇到意外退出：

```
1. 输入问题 ✅
2. Agent 开始执行 ✅
3. 按 ESC 取消 ✅
4. 输入框显示 "> [O" ❓
5. 程序自动退出 ❌
```

---

## 🔍 问题分析

### 发现的根因

**`[O` 是什么？**
- `ESC [ O` 是一个**转义序列**
- 通常来自 **F1-F4** 功能键
- 或其他特殊键组合

### 问题链路

```
用户按某个键（如 F1）
  ↓
终端发送 ESC [ O
  ↓
C 代码 parseEscapeSequence() 识别为未知 CSI
  ↓
返回 -1（错误）
  ↓
Cangjie 代码将 -1 视为 EOF
  ↓
返回 None
  ↓
readline 认为是 EOF
  ↓
程序退出 ❌
```

### 代码位置

**`ffi/raw_input_linux.c` 第 192-193 行（修复前）：**

```c
default:
    return -1; // Unknown CSI → 被误判为 EOF！
```

---

## ✅ 修复方案

### 修复策略

**不将未知转义序列视为错误**，而是返回 ESC 字符本身：

```c
default:
    // Unknown CSI sequence (e.g., ESC[O for F1-F4)
    // Don't return -1, just return ESC to avoid EOF
    bytes[0] = 0x1b;  // Return ESC character
    return 1;
```

### 修复效果

**修复前：**
```
按 F1 → 返回 -1 → 被视为 EOF → 程序退出 ❌
```

**修复后：**
```
按 F1 → 返回 ESC → 被忽略或处理 → 程序继续 ✅
```

---

## 🔧 修改的文件

### 1. `ffi/raw_input_linux.c`

**修改位置：** 第 185-200 行

**关键修改：**

1. **DELETE 键处理（第 187-188 行）：**
   ```c
   // 修复前
   if (n <= 0) return -1;  // ❌ 返回 -1
   if (c != '~') return -1; // ❌ 返回 -1
   
   // 修复后
   if (n <= 0) return 1;   // ✅ 返回 ESC
   if (c != '~') return 1;  // ✅ 返回 ESC
   ```

2. **未知 CSI 处理（第 192-196 行）：**
   ```c
   // 修复前
   default:
       return -1; // ❌ 返回错误
   
   // 修复后
   default:
       // Unknown CSI sequence (e.g., ESC[O for F1-F4)
       // Don't return -1, just return ESC to avoid EOF
       bytes[0] = 0x1b;  // ✅ 返回 ESC 字符
       return 1;
   ```

---

## 🎯 修复的问题

### 场景 1: 按功能键（F1-F4）
**修复前：** 程序退出 ❌  
**修复后：** 忽略或正常处理 ✅

### 场景 2: 其他未知转义序列
**修复前：** 程序退出 ❌  
**修复后：** 返回 ESC，继续运行 ✅

### 场景 3: 真正的 EOF（Ctrl+D）
**修复前：** 正常退出 ✅  
**修复后：** 仍然正常退出 ✅

### 场景 4: 取消后的操作
**修复前：** 某些键导致退出 ❌  
**修复后：** 所有键正常处理 ✅

---

## 📊 测试验证

### 测试场景

```bash
# 启动程序
cjpm run --name cli

# 测试 1: 按 F1-F4
# 期望：不退出，程序继续

# 测试 2: 按 ESC（单独）
# 期望：不退出（或取消当前操作）

# 测试 3: 输入问题 → 按 ESC 取消 → 按 F1
# 期望：不退出，程序继续

# 测试 4: 按 Ctrl+D
# 期望：优雅退出（正常行为）
```

---

## 🔄 编译和部署

### 编译命令

```bash
cd /Users/louloulin/Documents/linchong/cjproject/codelin
rm -f ffi/librawinput.dylib
cjpm build
```

### 验证编译

```bash
# 检查 FFI 库
ls -lh ffi/librawinput.dylib

# 检查可执行文件
ls -lh target/release/bin/cli
```

---

## 💡 技术细节

### EOF vs 错误 vs 未知序列

| 情况 | C 返回值 | Cangjie 处理 | 结果 |
|------|---------|-------------|------|
| **真正的 EOF** | 0 | 返回 None | 退出 ✅ |
| **读取错误** | -1 | 返回 None | 退出 ✅ |
| **未知转义序列** | 1 (ESC) | 处理或忽略 | 继续 ✅ |
| **已知转义序列** | 1/3/4 | 正常处理 | 继续 ✅ |

### 为什么返回 ESC 而非忽略？

1. **保持一致性：** 与其他未知序列处理一致
2. **可扩展性：** 未来可以添加 ESC 键的特定功能
3. **安全性：** 不会丢失用户输入

---

## ✅ 修复完成

### 修复清单

- [x] 识别问题根因
- [x] 修改 C 代码
- [x] 修复 DELETE 键处理
- [x] 修复未知 CSI 处理
- [x] 重新编译
- [x] 准备测试

### 状态

**状态：** ✅ 修复完成，待用户测试  
**修复文件：** `ffi/raw_input_linux.c`  
**影响范围：** 功能键和未知转义序列处理  
**风险：** 低（只影响边缘情况）  

---

## 🚀 下一步

### 立即测试

```bash
cd /Users/louloulin/Documents/linchong/cjproject/codelin
cjpm run --name cli
```

### 测试步骤

1. 启动程序 ✅
2. 输入问题 ✅
3. 按 ESC 取消 ✅
4. **尝试按各种键**（包括功能键）✅
5. 验证程序不会意外退出 ✅

### 如遇问题

如果仍有问题，请告诉我：
1. 按了什么键
2. 输入框显示什么
3. 程序如何反应

---

**🎊 修复完成！现在未知的转义序列不会导致程序意外退出了！**

---

**修复日期：** 2025-11-07  
**修复版本：** Final v3  
**问题：** 未知转义序列导致退出  
**解决：** 返回 ESC 而非 -1

