qwen-code/docs/users/features/lsp.md
2026-04-26 21:32:16 +08:00

408 lines
13 KiB
Markdown

# Language Server Protocol (LSP) Support
Qwen Code provides native Language Server Protocol (LSP) support, enabling advanced code intelligence features like go-to-definition, find references, diagnostics, and code actions. This integration allows the AI agent to understand your code more deeply and provide more accurate assistance.
## Overview
LSP support in Qwen Code works by connecting to language servers that understand your code. Once you configure servers via `.lsp.json` (or extensions), Qwen Code can start them and use them to:
- Navigate to symbol definitions
- Find all references to a symbol
- Get hover information (documentation, type info)
- View diagnostic messages (errors, warnings)
- Access code actions (quick fixes, refactorings)
- Analyze call hierarchies
## Quick Start
LSP is an experimental feature in Qwen Code. To enable it, use the `--experimental-lsp` command line flag:
```bash
qwen --experimental-lsp
```
LSP servers are configuration-driven. You must define them in `.lsp.json` (or via extensions) for Qwen Code to start them.
### Prerequisites
You need to have the language server for your programming language installed:
| Language | Language Server | Install Command |
| --------------------- | -------------------------- | ------------------------------------------------------------------------------ |
| TypeScript/JavaScript | typescript-language-server | `npm install -g typescript-language-server typescript` |
| Python | pylsp | `pip install python-lsp-server` |
| Go | gopls | `go install golang.org/x/tools/gopls@latest` |
| Rust | rust-analyzer | [Installation guide](https://rust-analyzer.github.io/manual.html#installation) |
| C/C++ | clangd | Install LLVM/clangd via your package manager |
| Java | jdtls | Install JDTLS and a JDK |
## Configuration
### .lsp.json File
You can configure language servers using a `.lsp.json` file in your project root. Each top-level key is a language identifier, and its value is the server configuration object.
**Basic format:**
```json
{
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"],
"extensionToLanguage": {
".ts": "typescript",
".tsx": "typescriptreact",
".js": "javascript",
".jsx": "javascriptreact"
}
}
}
```
### C/C++ (clangd) configuration
Dependencies:
- clangd (LLVM) must be installed and available in PATH.
- A compile database (`compile_commands.json`) or `compile_flags.txt` is required for accurate results.
Example:
```json
{
"cpp": {
"command": "clangd",
"args": [
"--background-index",
"--clang-tidy",
"--header-insertion=iwyu",
"--completion-style=detailed"
]
}
}
```
### Java (jdtls) configuration
Dependencies:
- JDK installed and available in PATH (`java`).
- JDTLS installed and available in PATH (`jdtls`).
Example:
```json
{
"java": {
"command": "jdtls",
"args": ["-configuration", ".jdtls-config", "-data", ".jdtls-workspace"]
}
}
```
### Configuration Options
#### Required Fields
| Option | Type | Description |
| --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `command` | string | Command to start the LSP server. Supports bare command names resolved via `PATH` (e.g. `clangd`) and absolute paths (e.g. `/opt/llvm/bin/clangd`) |
#### Optional Fields
| Option | Type | Default | Description |
| ----------------------- | -------- | --------- | ------------------------------------------------------- |
| `args` | string[] | `[]` | Command line arguments |
| `transport` | string | `"stdio"` | Transport type: `stdio`, `tcp`, or `socket` |
| `env` | object | - | Environment variables |
| `initializationOptions` | object | - | LSP initialization options |
| `settings` | object | - | Server settings via `workspace/didChangeConfiguration` |
| `extensionToLanguage` | object | - | Maps file extensions to language identifiers |
| `workspaceFolder` | string | - | Override workspace folder (must be within project root) |
| `startupTimeout` | number | `10000` | Startup timeout in milliseconds |
| `shutdownTimeout` | number | `5000` | Shutdown timeout in milliseconds |
| `restartOnCrash` | boolean | `false` | Auto-restart on crash |
| `maxRestarts` | number | `3` | Maximum restart attempts |
| `trustRequired` | boolean | `true` | Require trusted workspace |
### TCP/Socket Transport
For servers that use TCP or Unix socket transport:
```json
{
"remote-lsp": {
"transport": "tcp",
"socket": {
"host": "127.0.0.1",
"port": 9999
},
"extensionToLanguage": {
".custom": "custom"
}
}
}
```
## Available LSP Operations
Qwen Code exposes LSP functionality through the unified `lsp` tool. Here are the available operations:
For location-based operations (`goToDefinition`, `findReferences`, `hover`, `goToImplementation`, and `prepareCallHierarchy`), you can either provide an exact `filePath` + `line` + `character`, or provide `symbolName` and let Qwen Code resolve the symbol position through workspace symbol search first.
### Code Navigation
#### Go to Definition
Find where a symbol is defined.
```
Operation: goToDefinition
Parameters:
- filePath + line + character: Exact source position (1-based), or
- symbolName: Symbol name to resolve automatically
```
#### Find References
Find all references to a symbol.
```
Operation: findReferences
Parameters:
- filePath + line + character: Exact source position (1-based), or
- symbolName: Symbol name to resolve automatically
- includeDeclaration: Include the declaration itself (optional)
```
#### Go to Implementation
Find implementations of an interface or abstract method.
```
Operation: goToImplementation
Parameters:
- filePath + line + character: Exact source position (1-based), or
- symbolName: Symbol name to resolve automatically
```
### Symbol Information
#### Hover
Get documentation and type information for a symbol.
```
Operation: hover
Parameters:
- filePath + line + character: Exact source position (1-based), or
- symbolName: Symbol name to resolve automatically
```
#### Document Symbols
Get all symbols in a document.
```
Operation: documentSymbol
Parameters:
- filePath: Path to the file
```
#### Workspace Symbol Search
Search for symbols across the workspace.
```
Operation: workspaceSymbol
Parameters:
- query: Search query string
- limit: Maximum results (optional)
```
### Call Hierarchy
#### Prepare Call Hierarchy
Get the call hierarchy item at a position.
```
Operation: prepareCallHierarchy
Parameters:
- filePath + line + character: Exact source position (1-based), or
- symbolName: Symbol name to resolve automatically
```
#### Incoming Calls
Find all functions that call the given function.
```
Operation: incomingCalls
Parameters:
- callHierarchyItem: Item from prepareCallHierarchy
```
#### Outgoing Calls
Find all functions called by the given function.
```
Operation: outgoingCalls
Parameters:
- callHierarchyItem: Item from prepareCallHierarchy
```
### Diagnostics
#### File Diagnostics
Get diagnostic messages (errors, warnings) for a file.
```
Operation: diagnostics
Parameters:
- filePath: Path to the file
```
#### Workspace Diagnostics
Get all diagnostic messages across the workspace.
```
Operation: workspaceDiagnostics
Parameters:
- limit: Maximum results (optional)
```
### Code Actions
#### Get Code Actions
Get available code actions (quick fixes, refactorings) at a location.
```
Operation: codeActions
Parameters:
- filePath: Path to the file
- line: Start line number (1-based)
- character: Start column number (1-based)
- endLine: End line number (optional, defaults to line)
- endCharacter: End column (optional, defaults to character)
- diagnostics: Diagnostics to get actions for (optional)
- codeActionKinds: Filter by action kind (optional)
```
Code action kinds:
- `quickfix` - Quick fixes for errors/warnings
- `refactor` - Refactoring operations
- `refactor.extract` - Extract to function/variable
- `refactor.inline` - Inline function/variable
- `source` - Source code actions
- `source.organizeImports` - Organize imports
- `source.fixAll` - Fix all auto-fixable issues
## Security
LSP servers are only started in trusted workspaces by default. This is because language servers run with your user permissions and can execute code.
### Trust Controls
- **Trusted Workspace**: LSP servers start if configured
- **Untrusted Workspace**: LSP servers won't start unless `trustRequired: false` is set in the server configuration
To mark a workspace as trusted, use the `/trust` command.
### Per-Server Trust Override
You can override trust requirements for specific servers in their configuration:
```json
{
"safe-server": {
"command": "safe-language-server",
"args": ["--stdio"],
"trustRequired": false,
"extensionToLanguage": {
".safe": "safe"
}
}
}
```
## Troubleshooting
### Server Not Starting
1. **Verify `--experimental-lsp` flag**: Make sure you're using the flag when starting Qwen Code
2. **Check if the server is installed**: Run the command manually (e.g. `clangd --version`) to verify
3. **Check the command**: The server binary must be in your system `PATH`, or specified as an absolute path (e.g. `/opt/llvm/bin/clangd`). Relative paths that escape the workspace are blocked
4. **Check workspace trust**: The workspace must be trusted for LSP (use `/trust`)
5. **Check logs**: Look for `[LSP]` entries in the debug log (see Debugging section below)
6. **Check the process**: Run `ps aux | grep <server-name>` to verify the server process is running
### Slow Performance
1. **Large projects**: Consider excluding `node_modules` and other large directories
2. **Server timeout**: Increase `startupTimeout` in server configuration for slow servers
### No Results
1. **Server not ready**: The server may still be indexing. For C/C++ projects with clangd, ensure `--background-index` is in the args and a `compile_commands.json` (or `compile_flags.txt`) exists in the project root or a parent directory. Use `--compile-commands-dir=<path>` if it is in a build subdirectory
2. **File not saved**: Save your file for the server to pick up changes
3. **Wrong language**: Check if the correct server is running for your language
4. **Check the process**: Run `ps aux | grep <server-name>` to verify the server is actually running
### Debugging
LSP debug logs are automatically written to session log files in `~/.qwen/debug/`. To check LSP-related entries:
```bash
# View the latest session log
grep '\[LSP\]' ~/.qwen/debug/latest
# Common error messages to look for:
# "command path is unsafe" → relative path escapes workspace, use absolute path or add to PATH
# "command not found" → server binary not installed or not in PATH
# "requires trusted workspace" → run /trust first
```
You can also verify the server process is running:
```bash
ps aux | grep clangd # or typescript-language-server, jdtls, etc.
```
## Extension LSP Configuration
Extensions can provide LSP server configurations through the `lspServers` field in their `plugin.json`. This can be either an inline object or a path to a `.lsp.json` file. Qwen Code loads these configs when the extension is enabled. The format is the same language-keyed layout used in project `.lsp.json` files.
## Best Practices
1. **Install language servers globally**: This ensures they're available in all projects
2. **Use project-specific settings**: Configure server options per project when needed via `.lsp.json`
3. **Keep servers updated**: Update your language servers regularly for best results
4. **Trust wisely**: Only trust workspaces from trusted sources
## FAQ
### Q: How do I enable LSP?
Use the `--experimental-lsp` flag when starting Qwen Code:
```bash
qwen --experimental-lsp
```
### Q: How do I know which language servers are running?
Check the debug log for `[LSP]` entries (`grep '\[LSP\]' ~/.qwen/debug/latest`), or verify the process directly with `ps aux | grep <server-name>`.
### Q: Can I use multiple language servers for the same file type?
Yes, but only one will be used for each operation. The first server that returns results wins.
### Q: Does LSP work in sandbox mode?
LSP servers run outside the sandbox to access your code. They're subject to workspace trust controls.