|
| 1 | +# Language Configuration Guide |
| 2 | + |
| 3 | +In the `lsp-client` SDK, language-specific configurations are primarily defined through the `LanguageConfig` class. This configuration determines how the client identifies files of a specific language, locates project roots, and interacts with the Language Server. |
| 4 | + |
| 5 | +## LanguageConfig |
| 6 | + |
| 7 | +`LanguageConfig` is an immutable configuration class defined in `lsp_client.client.lang`. it contains the following core fields: |
| 8 | + |
| 9 | +- **kind (`lsp_type.LanguageKind`)**: |
| 10 | + Specifies the type of programming language (e.g., `Python`, `Rust`, `Go`, `TypeScript`). This typically corresponds to the language identifier in the LSP protocol. |
| 11 | +- **suffixes (`list[str]`)**: |
| 12 | + A list of file extensions associated with the language (e.g., `[".py", ".pyi"]`). The client uses these suffixes to determine if a file belongs to this language. |
| 13 | +- **project_files (`list[str]`)**: |
| 14 | + A list of "marker" files used to identify the project root directory (e.g., `["pyproject.toml", "Cargo.toml", "package.json"]`). When the client attempts to determine the root directory for a file, it searches upwards recursively for directories containing these files. |
| 15 | +- **exclude_files (`list[str]`)**: |
| 16 | + A list of marker files indicating that a directory should _not_ be considered a project root. |
| 17 | + |
| 18 | +## Project Root Discovery |
| 19 | + |
| 20 | +The client determines the project root by searching upwards from the given file path until a valid project root is found or the system root is reached. This discovery is based on the `project_files` and `exclude_files` defined in the `LanguageConfig`. |
| 21 | + |
| 22 | +The `LanguageConfig` class provides a `find_project_root(path: Path)` method that combines `suffixes`, `project_files`, and `exclude_files` for precise detection. |
| 23 | + |
| 24 | +## Client Language Attributes |
| 25 | + |
| 26 | +The `Client` base class includes several general configurations related to language processing and server interaction: |
| 27 | + |
| 28 | +- **`sync_file` (bool, default `True`)**: |
| 29 | + Whether to automatically synchronize file content with the server. If enabled, the client automatically sends `textDocument/didOpen` and `textDocument/didClose` notifications when using the `open_files` context manager. |
| 30 | +- **`initialization_options` (dict)**: |
| 31 | + Custom options passed to the server during the `initialize` request. Most Language Servers require specific configurations here to function correctly. |
| 32 | +- **`request_timeout` (float, default `5.0`)**: |
| 33 | + The timeout in seconds for LSP requests. |
| 34 | + |
| 35 | +## Example: Defining a Custom Language Client |
| 36 | + |
| 37 | +To support a new language, you typically inherit from `Client` (or a base class like `PythonClientBase`) and implement the `get_language_config` method: |
| 38 | + |
| 39 | +```python |
| 40 | +from pathlib import Path |
| 41 | +from typing import override |
| 42 | +from lsp_client.client.abc import Client |
| 43 | +from lsp_client.client.lang import LanguageConfig |
| 44 | +from lsp_client.utils.types import lsp_type |
| 45 | + |
| 46 | +class MyNewLanguageClient(Client): |
| 47 | + @override |
| 48 | + def get_language_config(self) -> LanguageConfig: |
| 49 | + return LanguageConfig( |
| 50 | + kind=lsp_type.LanguageKind.PlainText, # Replace with actual language kind |
| 51 | + suffixes=[".mylang"], |
| 52 | + project_files=["my_project.config"] |
| 53 | + ) |
| 54 | + |
| 55 | + # Other abstract methods like create_default_servers must also be implemented |
| 56 | +``` |
0 commit comments