mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-29 20:20:57 +00:00
fix(lsp): improve C++/Java/Python language server support
Key changes: 1. Remove LspLanguageDetector — LSP is now fully config-driven via .lsp.json or extensions. No more auto-detected built-in presets that fail when the server binary is missing. 2. Add ensureDocumentOpen — send textDocument/didOpen before every document-level LSP request (definitions, references, hover, documentSymbol, implementations, prepareCallHierarchy, diagnostics, codeActions). This fixes the root cause of most methods returning empty results (Issue #2106, #1873). 3. Add retry mechanism for slow servers — when a freshly opened document yields empty results on non-TypeScript servers (jdtls, clangd, pylsp), wait 2s and retry once. This mirrors the existing retry logic in workspaceSymbols. 4. Handle LSP 3.17 WorkspaceSymbol format — location.range is now optional in normalizeSymbolResult, fixing jdtls workspace symbol responses that omit the range field. 5. Improve workspace symbol warmup — for non-TypeScript servers, open a workspace file before the first workspace/symbol request and retry on empty results after a warmup delay. 6. Track warmup-opened URIs — warmupTypescriptServer now returns the opened URI, which is registered with ensureDocumentOpen to prevent duplicate didOpen notifications. Closes #2106, closes #1873 Made-with: Cursor
This commit is contained in:
parent
38caa0b218
commit
c1004d0e99
13 changed files with 2391 additions and 449 deletions
|
|
@ -4,7 +4,7 @@ Qwen Code provides native Language Server Protocol (LSP) support, enabling advan
|
|||
|
||||
## Overview
|
||||
|
||||
LSP support in Qwen Code works by connecting to language servers that understand your code. When you work with TypeScript, Python, Go, or other supported languages, Qwen Code can automatically start the appropriate language server and use it to:
|
||||
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
|
||||
|
|
@ -21,7 +21,7 @@ LSP is an experimental feature in Qwen Code. To enable it, use the `--experiment
|
|||
qwen --experimental-lsp
|
||||
```
|
||||
|
||||
For most common languages, Qwen Code will automatically detect and start the appropriate language server if it's installed on your system.
|
||||
LSP servers are configuration-driven. You must define them in `.lsp.json` (or via extensions) for Qwen Code to start them.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
|
|
@ -33,6 +33,8 @@ You need to have the language server for your programming language installed:
|
|||
| 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
|
||||
|
||||
|
|
@ -57,30 +59,71 @@ You can configure language servers using a `.lsp.json` file in your project root
|
|||
}
|
||||
```
|
||||
|
||||
### 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 (must be in PATH) |
|
||||
| `extensionToLanguage` | object | Maps file extensions to language identifiers |
|
||||
| Option | Type | Description |
|
||||
| --------- | ------ | ------------------------------------------------- |
|
||||
| `command` | string | Command to start the LSP server (must be in PATH) |
|
||||
|
||||
#### Optional Fields
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
| ----------------------- | -------- | --------- | ------------------------------------------------------ |
|
||||
| `args` | string[] | `[]` | Command line arguments |
|
||||
| `transport` | string | `"stdio"` | Transport type: `stdio` or `socket` |
|
||||
| `env` | object | - | Environment variables |
|
||||
| `initializationOptions` | object | - | LSP initialization options |
|
||||
| `settings` | object | - | Server settings via `workspace/didChangeConfiguration` |
|
||||
| `workspaceFolder` | string | - | Override workspace folder |
|
||||
| `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 |
|
||||
| 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
|
||||
|
||||
|
|
@ -269,7 +312,7 @@ LSP servers are only started in trusted workspaces by default. This is because l
|
|||
|
||||
### Trust Controls
|
||||
|
||||
- **Trusted Workspace**: LSP servers start automatically
|
||||
- **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 or configure trusted folders in settings.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue