# Snow CLI 使用文档——LSP 配置与用法

欢迎使用 Snow CLI！在终端中进行 Agentic 编程。

## 什么是 LSP

LSP（Language Server Protocol）是一套通用协议，用来让“语言服务器”向编辑器/工具提供能力，例如：

- 跳转到定义（Go to Definition）
- 符号提取（Outline / Document Symbols）
- 悬浮信息（Hover）
- 查找引用（References）
- 补全（Completion）

## Snow CLI 中的 LSP 用途

Snow CLI 会在部分代码搜索能力中优先尝试使用 LSP；当 LSP 不可用或超时失败时，会自动回退到正则/文本搜索（不会阻塞使用）。

目前 Snow CLI 的 LSP 主要用于增强以下内置工具：

- `ace-search`（action=`find_definition`）：优先用 LSP 做“跳转到定义”；失败则回退到正则搜索
- `ace-search`（action=`file_outline`）：优先用 LSP 抽取“文件符号大纲”；失败则回退到正则搜索

注意：

- LSP 调用有内部超时（默认 3 秒）。项目较大或语言服务器冷启动时可能触发超时，从而回退到正则搜索。
- 某些语言服务器（例如 OmniSharp）强烈依赖准确的光标位置参数；建议在调用时提供 `contextFile + line + column`（见下文）。

## 配置文件位置与加载机制

LSP 配置文件位置：`~/.snow/lsp-config.json`

加载机制：

1. 当 Snow CLI 首次需要使用 LSP 时，会尝试读取 `~/.snow/lsp-config.json`。
2. 若文件不存在，会自动创建一个默认配置文件，并使用内置默认服务列表。
3. 配置在进程内会缓存；修改配置后建议重启 Snow CLI 以确保重新加载。

## 配置文件格式

支持两种格式：

### 格式 1（推荐）：带 schemaVersion

```json
{
	"schemaVersion": 1,
	"servers": {
		"typescript": {
			"command": "typescript-language-server",
			"args": ["--stdio"],
			"fileExtensions": [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
			"installCommand": "npm install -g typescript-language-server typescript",
			"initializationOptions": {}
		}
	}
}
```

### 格式 2（兼容）：直接写 servers 映射

```json
{
	"typescript": {
		"command": "typescript-language-server",
		"args": ["--stdio"],
		"fileExtensions": [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]
	}
}
```

## 配置项说明

每个语言服务器配置项包含：

- `command`（必填）：启动语言服务器的命令（要求可在 PATH 中被找到）
- `args`（必填）：启动参数数组
- `fileExtensions`（必填）：该语言服务器处理的文件扩展名列表（用于按文件后缀匹配语言）
- `installCommand`（可选）：安装提示命令（仅用于提示/记录，不会被 Snow CLI 自动执行）
- `initializationOptions`（可选）：会透传到 LSP `initialize` 请求的 `initializationOptions`

重要说明：

- 配置文件采用“整体校验、整体生效”的策略：只要任意一个 server 的必填字段缺失/类型不正确，整份配置会被视为无效并回退到默认配置。
- 语言选择基于文件后缀（`.ts`、`.py` 等）；请确保 `fileExtensions` 覆盖你项目里实际的文件类型。

## 默认内置服务器（首次创建配置文件时会写入）

默认包含的语言键（可自行修改/增删）：

- `typescript`：`typescript-language-server --stdio`
- `python`：`pylsp`
- `go`：`gopls`
- `rust`：`rust-analyzer`
- `java`：`jdtls`
- `csharp`：`csharp-ls`

提示：不同平台安装方式不同；以你本机的安装方式为准，核心要求是 `command` 能在终端中被找到。

## 安装与验证（Windows 示例）

Snow CLI 在 Windows 下会使用 `where <command>` 判断语言服务器是否已安装并在 PATH 可用。

你可以先自行验证：

```cmd
where typescript-language-server
where pylsp
where gopls
where rust-analyzer
where jdtls
where csharp-ls
```

常见安装方式示例：

1. TypeScript / JavaScript

```cmd
npm install -g typescript-language-server typescript
```

2. Python

```cmd
python -m pip install python-lsp-server
```

3. Go

```cmd
go install golang.org/x/tools/gopls@latest
```

如果你不想安装某个语言的 LSP，可在配置里删除对应语言键或移除其扩展名（这样会直接回退到正则搜索）。

## 通过 ACE 工具使用 LSP（用法说明）

### 1) 跳转到定义：`ace-search`（action=`find_definition`）

当你提供 `contextFile` 时，Snow CLI 会优先尝试用 LSP 获取定义位置；否则会直接使用正则搜索。

推荐提供光标位置信息：

- `line`：0 基索引（第一行是 0）
- `column`：0 基索引（第一列是 0）

例如：如果你在 IDE 中看到“第 34 行，第 7 列”，通常需要传 `line=33`、`column=6`。

### 2) 文件大纲：`ace-search`（action=`file_outline`）

对单文件提取符号列表时，Snow CLI 会优先用 LSP 取 `documentSymbol`，失败则回退到正则搜索。

建议：

- 对大文件/大项目，优先使用 `ace-search`（action=`file_outline`）获取概要，再按需要继续深入。

## 常见问题

### 1. 配置改了但不生效

- 确认已保存 `~/.snow/lsp-config.json`
- 重启 Snow CLI（配置会缓存）

### 2. LSP 总是回退到正则搜索

常见原因：

- 语言服务器未安装或不在 PATH（Windows 可用 `where <command>` 验证）
- `fileExtensions` 未覆盖实际文件后缀
- 语言服务器启动较慢触发超时（默认 3 秒）

### 3. 定位不准 / 跳转结果不对

- 确保调用 `ace-search`（action=`find_definition`）时提供 `contextFile + line + column`
- 如果 `symbolName` 在当前文件出现多次，且未提供行列信息，系统会尝试用“首次出现位置”推断，可能不准确
