# CRIEW Vim MVP 里程碑

本文档定义 `Code Preview` 编辑能力的 MVP 路线：先内联 Vim-like（VM1），再切出外部 Vim（VM2）。
详细交互原型见 `docs/specs/code-preview-vim-prototype.md`。

## 文档导航

- VM1：Code Preview 内联 Vim-like 模式（必须）
- VM2：切出外部 Vim 会话（增强）

## VM1：Code Preview 内联 Vim-like 模式（必须）

### 阶段目标

在不破坏现有默认键位的前提下，实现 `Code Preview` 内联编辑：
用户按 `e` 进入编辑态，按 Vim-like 方式修改并保存，再返回浏览态。

### 任务拆分

1. 编辑模式状态机
   - 新增 `Browse` / `VimNormal` / `VimInsert` / `VimCommand` 四态。
   - 编辑态下按键优先由编辑状态机处理。
   - 非编辑态下保持现有按键行为。
2. 进入与退出流程
   - `e` 仅在 `CodeBrowser + Source + 文件` 时进入编辑态。
   - 无效场景按 `e` 只提示，不切换模式。
   - `Esc` 在 `VimInsert` 回到 `VimNormal`，在 `VimNormal` 退出编辑态。
   - `:` 在 `VimNormal` 进入 `VimCommand`，`Esc` 可取消命令输入。
3. 文本缓冲区与光标
   - 读取选中文件到内存 buffer（按行存储）。
   - 维护光标行列与滚动位置。
   - 支持最小编辑动作（移动、插入、删除）。
4. 保存与命令模式
   - `s` 在 `VimNormal` 执行保存。
   - `:w` 保存，`:q` 退出，`:wq` 保存并退出。
   - `:q` 在 dirty 状态下拒绝退出并提示。
   - 不支持的 `:` 命令给出错误提示并返回 `VimNormal`。
5. 渲染与提示
   - `Code Preview` 编辑态展示模式与 dirty 状态。
   - `VimCommand` 显示底部命令行输入。
   - 浏览态和编辑态切换后 UI 渲染稳定，无残影。
6. 测试补齐
   - 覆盖模式切换、键位分流、保存成功/失败路径。
   - 覆盖 `:w`、`:q`、`:wq` 与非法命令路径。
   - 增加回归测试，确认默认键位在非编辑态不变。

### 交付物

- `src/ui/tui.rs` 中内联 Vim-like 编辑状态机。
- 最小可用编辑能力（`NORMAL/INSERT/COMMAND` + 保存 + 退出）。
- 最小 `:` 命令能力（`:w`、`:q`、`:wq`）。
- 对应单元测试与回归测试。
- 快捷键说明更新（至少在 help 或 footer 体现 `e`/编辑态键位）。

### 验收标准

1. 默认模式下现有键位行为保持不变，无冲突。
2. 仅按 `e` 才进入内联编辑模式。
3. 编辑态支持：移动、插入、删除、保存、退出。
4. 命令模式支持 `:w`、`:q`、`:wq`，并符合 dirty 规则。
5. 保存后文件落盘成功，预览区域显示新内容。
6. 无效场景与失败场景均有明确状态提示。

### 退出条件

- 功能实现完成并通过 `cargo test`。
- 手工验证通过：
  - 选中文件 -> `e` -> 编辑 -> `s` 保存 -> `Esc` 退出 -> 预览更新。
  - 选中文件 -> `e` -> `:w`/`:q`/`:wq` 路径均可按预期工作。
  - 非文件场景按 `e` -> 仅提示，不进入编辑态。
- 文档与帮助文案已同步。

### 风险与缓解

- 风险：内联编辑会与现有全局按键冲突。
  - 缓解：通过明确模式状态机做键位分流，仅在编辑态接管 Vim 键。
- 风险：文本编辑实现不完整，边界行为不稳定。
  - 缓解：先限制 MVP 命令集，优先覆盖核心路径和边界测试。
- 风险：命令模式解析歧义导致行为不一致。
  - 缓解：MVP 只接受白名单命令（`w`/`q`/`wq`），其余一律报错。

### 非目标（VM1 不做）

- 完整 Vim 命令集、宏、寄存器、插件。
- Neovim 嵌入协议（msgpack-rpc）与生态整合。
- 多文件 buffer、split 窗口、复杂命令行模式（含 `:g`、`:s` 等）。

## VM2：切出外部 Vim 会话（增强）

### 阶段目标

在保持 VM1 内联编辑能力的基础上，支持从 `Code Preview` 切出到外部 Vim，
利用完整 Vim 生态完成复杂编辑，并在退出后自动回到 CRIEW。

### 任务拆分

1. 触发入口与前置校验
   - 在 `CodeBrowser + Source + 文件` 场景提供外部 Vim 入口（建议 `E` 或 `:vim`）。
   - 当前无文件时拒绝启动并给出状态提示。
   - 若内联 buffer 为 dirty，要求先保存（`:w`）再启动外部 Vim。
2. 编辑器选择与启动策略
   - 编辑器优先级：`VISUAL` -> `EDITOR` -> `vim`。
   - 允许为后续配置预留 `[ui].external_editor`，VM2 可先不开放用户配置。
   - 以当前选中文件路径作为启动参数。
3. TUI 切换与终端恢复
   - 启动前执行 `disable_raw_mode()` + `LeaveAlternateScreen`。
   - 前台启动外部编辑器（继承 stdin/stdout/stderr）。
   - 编辑器退出后执行 `EnterAlternateScreen` + `enable_raw_mode()` 恢复 TUI。
4. 返回后的状态同步
   - 外部 Vim 退出后重新读取文件并刷新 `Code Preview`。
   - 更新状态栏：成功、失败、退出码/信号摘要。
   - 保持用户上下文（页面、焦点、选中文件）不丢失。
5. 测试补齐
   - 为编辑器选择与触发条件补充单元测试。
   - 为终端切换流程做可测试抽象（避免单测真实拉起 vim）。
   - 补充回归测试，确认未触发 VM2 时现有键位无变化。

### 交付物

- `src/ui/tui.rs` 外部 Vim 启动入口（键位或命令入口）。
- 终端切换与恢复逻辑（含异常路径）。
- 外部 Vim 退出后的文件重载与预览刷新。
- 对应测试与文档说明（help/快捷键文案）。

### 验收标准

1. 在目标文件上触发 VM2 可成功拉起外部 Vim。
2. 外部 Vim 退出后能稳定回到 CRIEW，终端状态正常。
3. 返回后 `Code Preview` 显示外部编辑后的最新内容。
4. dirty 状态下触发 VM2 会被阻止并提示先保存。
5. 启动失败或异常退出时，状态信息可追踪且不导致 TUI 卡死。

### 退出条件

- 功能实现完成并通过 `cargo test`。
- 手工验证通过：
  - 选中文件 -> 触发 VM2 -> 外部编辑 -> 退出 -> 预览更新。
  - dirty 文件触发 VM2 -> 被拒绝并提示保存。
  - 编辑器启动失败路径 -> 能回到可操作 TUI。
- 文档与帮助文案已同步。

### 风险与缓解

- 风险：不同终端/平台下 alt screen 与 raw mode 恢复失败。
  - 缓解：把切换流程收敛到统一封装，逐步恢复并捕获每一步错误。
- 风险：外部编辑器路径/环境变量不一致导致启动失败。
  - 缓解：固定优先级回退链，失败时输出明确诊断信息。
- 风险：外部编辑期间文件被其他进程修改导致状态不一致。
  - 缓解：外部编辑返回后强制重新加载文件，以磁盘内容为准。

### 非目标（VM2 不做）

- 在 VM2 阶段实现 Neovim RPC 嵌入。
- 支持多文件批量外部会话管理。
- 针对不同编辑器做参数适配矩阵（仅保证 vim 兼容路径）。
