# 终端搜索 - 双模式搜索引擎

> 在可见缓冲区和完整会话历史中快速查找内容，支持正则表达式和高级选项。

## 🎯 核心功能

OxideTerm 提供两种搜索模式：

| 模式 | 搜索范围 | 速度 | 用途 |
|------|---------|------|------|
| **Visible Buffer** | 当前屏幕可见内容 | 极快（实时） | 快速定位最近输出 |
| **Deep History** | 完整会话历史（默认 30,000 行，可配置至 100,000） | 快速（异步） | 查找历史命令和输出 |

---

## 🚀 快速开始

### 打开搜索栏

**快捷键**：
- Windows: `Ctrl+Shift+F`
- Linux: `Ctrl+F`
- macOS: `⌘F`

**或者**：
- 右键菜单 → "Search"
- 顶部菜单 → "Edit" → "Find"

### 基本搜索

1. 按下 `Ctrl+Shift+F` (Win) / `Ctrl+F` (Lin) 或 `⌘F`
2. 输入搜索词（例如：`error`）
3. 搜索结果会实时高亮显示
4. 使用 `Enter` / `Shift+Enter` 在匹配项间导航

---

## 🎨 搜索界面

### 界面布局

```
┌──────────────────────────────────────────────────────────┐
│  [Visible Buffer] [Deep History]                    [×] │
├──────────────────────────────────────────────────────────┤
│  🔍 Search terminal output...          2/15  [↑] [↓] [×│
├──────────────────────────────────────────────────────────┤
│  □ Aa (Case)  □ .* (Regex)  □Word (Whole Word)          │
└──────────────────────────────────────────────────────────┘
```

### 组件说明

| 组件 | 功能 |
|------|------|
| **模式标签** | 切换 Visible Buffer / Deep History |
| **搜索输入框** | 输入搜索词 |
| **匹配计数** | 显示当前位置/总匹配数（例如：`2/15`） |
| **导航按钮** | `↑` 上一个，`↓` 下一个 |
| **选项复选框** | 大小写、正则、整词匹配 |

---

## 📍 Visible Buffer 模式

### 工作原理

在当前屏幕**可见的终端输出**（利用 xterm.js 的 SearchAddon）中进行搜索。

**特点**：
- ✅ **实时高亮**：输入即搜索（150ms 防抖）
- ✅ **极快速度**：毫秒级响应
- ✅ **黄色高亮**：匹配项会以黄色背景高亮显示
- ✅ **当前项橙色**：当前选中的匹配项以橙色背景显示

### 使用方法

#### 1. 普通搜索

```
输入：error
结果：匹配所有包含 "error" 的行（不区分大小写）
```

#### 2. 大小写敏感

```
启用 "Aa" 选项
输入：Error
结果：仅匹配 "Error"，不匹配 "error" 或 "ERROR"
```

#### 3. 整词匹配

```
启用 "Word" 选项
输入：test
结果：匹配 "test runs"，不匹配 "testing"
```

#### 4. 正则表达式

```
启用 ".*" 选项
输入：^Error:.*timeout
结果：匹配以 "Error:" 开头并包含 "timeout" 的行
```

### 导航

| 操作 | 快捷键 |
|------|--------|
| **下一个匹配** | `Enter` 或点击 `↓` |
| **上一个匹配** | `Shift+Enter` 或点击 `↑` |
| **关闭搜索** | `Esc` |

### 性能

- **匹配上限**：默认 1000 个匹配项
- **超出提示**：显示 `1000+ matches`（表示实际更多）
- **建议**：如果匹配过多，添加更具体的搜索词

---

## 🗄️ Deep History 模式

### 工作原理

在**完整会话历史**（后端滚动缓冲区，默认最多 30,000 行，可在设置中配置至最高 100,000 行）中进行搜索。

**特点**：
- ✅ **搜索全部历史**：包括已滚动出屏幕的内容
- ✅ **异步执行**：使用 `spawn_blocking` 避免阻塞
- ✅ **结果列表**：显示所有匹配项的行号和内容
- ✅ **点击跳转**：点击结果直接跳转到对应位置

### 使用方法

#### 1. 切换到 Deep History 模式

点击搜索栏顶部的 **Deep History** 标签

#### 2. 执行搜索

```
输入搜索词（例如：npm install）
按 Enter 或点击 "Search" 按钮
等待搜索完成（通常 < 100ms）
```

#### 3. 查看结果

```
┌──────────────────────────────────────────────────────────┐
│  15 matches (45ms)                                       │
├──────────────────────────────────────────────────────────┤
│  Line 1234                                               │
│  npm install react-dom                                   │
├──────────────────────────────────────────────────────────┤
│  Line 2456                                               │
│  npm install success  talled 23 packages                │
├──────────────────────────────────────────────────────────┤
│  ...                                                     │
└──────────────────────────────────────────────────────────┘
```

#### 4. 跳转到匹配位置

点击任意结果行，终端会自动滚动到对应位置并高亮显示该行。

### 搜索示例

#### 查找历史命令

```
搜索：^git commit
结果：找到所有以 "git commit" 开头的命令
```

#### 查找错误日志

```
搜索：ERROR|FATAL
结果：找到所有包含 "ERROR" 或 "FATAL" 的行
```

#### 查找 IP 地址

```
启用 ".*" 选项
搜索：\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
结果：找到所有 IPv4 地址
```

### 结果限制

- **最多显示**：前 100 个匹配项
- **总数显示**：底部提示总匹配数（例如：`Showing first 100 of 456 matches`）
- **优化建议**：使用更精确的搜索词减少匹配数

---

## 🔧 搜索选项

### 1. Case Sensitive (Aa)

**作用**：区分大小写

```
未启用（默认）:
  搜索 "error" → 匹配 "error", "Error", "ERROR"
  
启用:
  搜索 "error" → 仅匹配 "error"
```

### 2. Regular Expression (.*)

**作用**：使用正则表达式模式匹配

```
未启用（默认）:
  搜索 "file.txt" → 精确匹配 "file.txt"（. 被转义）
  
启用:
  搜索 "file.txt" → 匹配 "file.txt", "fileXtxt"（. 匹配任意字符）
```

#### 常用正则模式

| 模式 | 说明 | 示例 |
|------|------|------|
| `^xxx` | 行首匹配 | `^Error:` 匹配以 "Error:" 开头的行 |
| `xxx$` | 行尾匹配 | `success$` 匹配以 "success" 结尾的行 |
| `a\|b` | 或运算 | `ERROR\|FATAL` 匹配包含 "ERROR" 或 "FATAL" |
| `\d+` | 数字 | `port \d+` 匹配 "port 3000", "port 8080" |
| `\w+` | 单词字符 | `user_\w+` 匹配 "user_admin", "user_123" |
| `.*` | 任意字符 | `start.*end` 匹配 "start" 和 "end" 之间的任意内容 |

### 3. Whole Word (Word)

**作用**：仅匹配完整单词

```
未启用（默认）:
  搜索 "test" → 匹配 "test", "testing", "contest"
  
启用:
  搜索 "test" → 仅匹配独立的 "test"
```

**单词边界规则**：
- 空格、标点、行首/行尾都属于单词边界
- 例如：`"test"`, ` test-run`, `(test)` 都会匹配

---

## ⚡ 性能与优化

### Visible Buffer 性能

| 指标 | 数值 |
|------|------|
| **响应时间** | < 5ms（实时） |
| **最大匹配** | 1000 个 |
| **搜索范围** | 当前可见缓冲区（通常 1000-5000 行） |

### Deep History 性能

| 指标 | 数值 |
|------|------|
| **搜索速度** | ~50-100ms（100,000 行） |
| **后端引擎** | Rust Regex（高性能） |
| **异步执行** | `spawn_blocking`（不阻塞 UI） |
| **默认历史** | 30,000 行（`DEFAULT_MAX_LINES`，可配置至 100,000） |

### 优化建议

1. **使用具体搜索词**：避免通用词（如 "the", "a"）
2. **启用整词匹配**：减少误匹配
3. **使用锚点**：`^` 和 `$` 限制匹配位置
4. **避免过于复杂的正则**：可能影响性能

---

## 🎯 使用场景

### 场景 1：查找错误日志

**需求**：在大量输出中定位错误

```
步骤：
1. 切换到 Deep History
2. 启用 Regex 选项
3. 搜索：^(ERROR|FATAL):
4. 查看结果列表，点击跳转
```

### 场景 2：查找最近的 Git 提交

**需求**：找到刚才执行的 git commit 命令

```
步骤：
1. 使用 Visible Buffer
2. 搜索：git commit
3. 按 Shift+Enter 向上导航
```

### 场景 3：提取所有 IP 地址

**需求**：从日志中找到所有 IP 地址

```
步骤：
1. 切换到 Deep History
2. 启用 Regex 选项
3. 搜索：\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
4. 查看结果列表
```

### 场景 4：查找端口号

**需求**：找到服务器监听的端口

```
步骤：
1. 使用 Visible Buffer
2. 启用 Regex 选项
3. 搜索：port \d+
4. 快速定位到最近的端口输出
```

---

## 🐛 故障排查

### Q: 搜索没有结果但确定存在？

A: 可能的原因：
- **大小写问题**：关闭 "Aa" 选项
- **超出可见范围**：切换到 Deep History 模式
- **正则语法错误**：检查正则表达式是否正确
- **已经滚出缓冲区**：如果历史超过 30,000 行（默认值，可在设置中调整 maxLines），早期内容可能被丢弃

### Q: Deep History 搜索很慢？

A: 可能的原因：
- **复杂正则**：简化正则表达式
- **大量匹配**：添加更具体的搜索词
- **历史过大**：清理会话或重启

建议：使用更精确的搜索模式

### Q: Visible Buffer 显示 "1000+ matches"？

A: 匹配数超过上限（性能保护）

解决方案：
- 添加更具体的搜索词
- 使用整词匹配
- 使用正则锚点（^ 或 $）

### Q: 正则表达式报错？

A: 查看搜索栏底部的错误提示

常见错误：
- `[invalid(` → 括号不匹配
- `*` 在行首 → 量词使用错误
- `\q` → 无效转义序列

---

## 🔑 快捷键参考

| 操作 | Windows/Linux | macOS |
|------|---------------|-------|
| **打开搜索** | `Ctrl+Shift+F` (Win) / `Ctrl+F` (Lin) | `⌘F` |
| **关闭搜索** | `Esc` | `Esc` |
| **下一个匹配** | `Enter` | `Enter` |
| **上一个匹配** | `Shift+Enter` | `Shift+Enter` |
| **执行 Deep Search** | `Enter`（Deep 模式） | `Enter`（Deep 模式） |

---

## 🛠️ 高级技巧

### 1. 组合搜索选项

```
启用：Regex + Case Sensitive + Whole Word
搜索：\bError\b
效果：仅匹配完整的 "Error" 单词（区分大小写）
```

### 2. 使用捕获组高亮

```
启用 Regex
搜索：(ERROR|WARN|INFO):\s*(.*)
效果：匹配日志级别和消息，整行高亮
```

### 3. 负向查找（排除）

```
启用 Regex
搜索：^(?!.*DEBUG).*ERROR
效果：匹配包含 "ERROR" 但不包含 "DEBUG" 的行
```

### 4. 多行模式

```
启用 Regex
搜索：function.*\{
效果：查找函数定义（简化示例）
```

---

## 📊 技术细节

### 后端搜索引擎

**实现**：`src-tauri/src/session/search.rs`

```rust
pub struct SearchOptions {
    query: String,
    case_sensitive: bool,
    regex: bool,
    whole_word: bool,
}

pub fn search_lines(lines: &[TerminalLine], options: SearchOptions) -> SearchResult {
    // 使用 Rust regex crate
    // spawn_blocking 异步执行
    // 返回所有匹配项
}
```

**优势**：
- ✅ Rust Regex 高性能
- ✅ 异步执行不阻塞 UI
- ✅ 支持 Unicode 和复杂模式

### 前端集成

**实现**：`src/components/terminal/SearchBar.tsx`

```typescript
// Visible Buffer: xterm.js SearchAddon
const searchAddon = new SearchAddon();
terminal.loadAddon(searchAddon);
searchAddon.findNext(query, { ...options });

// Deep History: layered archive search
const { search_id } = await invoke('start_terminal_history_search', { sessionId, options });

try {
  let cursor = 0;

  while (true) {
    const page = await invoke('get_terminal_history_search_results', { searchId: search_id, cursor });
    cursor = page.next_cursor;

    if (page.done) {
      break;
    }
  }
} finally {
  await invoke('cancel_terminal_history_search', { searchId: search_id });
}
```

---

*文档版本: v1.10.0 | 最后更新: 2026-04-12*
