mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 14:52:01 +00:00
2 commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
![]() |
a184dc68f5
|
Implement client setting initialization and resolution for ruff server (#10764)
## Summary When a language server initializes, it is passed a serialized JSON object, which is known as its "initialization options". Until now, `ruff server` has ignored those initialization options, meaning that user-provided settings haven't worked. This PR is the first step for supporting settings from the LSP client. It implements procedures to deserialize initialization options into a settings object, and then resolve those settings objects into concrete settings for each workspace. One of the goals for user settings implementation in `ruff server` is backwards compatibility with `ruff-lsp`'s settings. We won't support all settings that `ruff-lsp` had, but the ones that we do support should work the same and use the same schema as `ruff-lsp`. These are the existing settings from `ruff-lsp` that we will continue to support, and which are part of the settings schema in this PR: | Setting | Default Value | Description | |----------------------------------------|---------------|----------------------------------------------------------------------------------------| | `codeAction.disableRuleComment.enable` | `true` | Whether to display Quick Fix actions to disable rules via `noqa` suppression comments. | | `codeAction.fixViolation.enable` | `true` | Whether to display Quick Fix actions to autofix violations. | | `fixAll` | `true` | Whether to register Ruff as capable of handling `source.fixAll` actions. | | `lint.enable` | `true` | Whether to enable linting. Set to `false` to use Ruff exclusively as a formatter. | | `organizeImports` | `true` | Whether to register Ruff as capable of handling `source.organizeImports` actions. | To be clear: this PR does not implement 'support' for these settings, individually. Rather, it constructs a framework for these settings to be used by the server in the future. Notably, we are choosing *not* to support `lint.args` and `format.args` as settings for `ruff server`. This is because we're now interfacing with Ruff at a lower level than its CLI, and converting CLI arguments back into configuration is too involved. We will have support for linter and formatter specific settings in follow-up PRs. We will also 'hook up' user settings to work with the server in follow up PRs. ## Test Plan ### Snapshot Tests Tests have been created in `crates/ruff_server/src/session/settings/tests.rs` to ensure that deserialization and settings resolution works as expected. ### Manual Testing Since we aren't using the resolved settings anywhere yet, we'll have to add a few printing statements. We want to capture what the resolved settings look like when sent as part of a snapshot, so modify `Session::take_snapshot` to be the following: ```rust pub(crate) fn take_snapshot(&self, url: &Url) -> Option<DocumentSnapshot> { let resolved_settings = self.workspaces.client_settings(url, &self.global_settings); tracing::info!("Resolved settings for document {url}: {resolved_settings:?}"); Some(DocumentSnapshot { configuration: self.workspaces.configuration(url)?.clone(), resolved_client_capabilities: self.resolved_client_capabilities.clone(), client_settings: resolved_settings, document_ref: self.workspaces.snapshot(url)?, position_encoding: self.position_encoding, url: url.clone(), }) } ``` Once you've done that, build the server and start up your extension testing environment. 1. Set up a workspace in VS Code with two workspace folders, each one having some variant of Ruff file-based configuration (`pyproject.toml`, `ruff.toml`, etc.). We'll call these folders `folder_a` and `folder_b`. 2. In each folder, open up `.vscode/settings.json`. 3. In folder A, use these settings: ```json { "ruff.codeAction.disableRuleComment": { "enable": true } } ``` 4. In folder B, use these settings: ```json { "ruff.codeAction.disableRuleComment": { "enable": false } } ``` 5. Finally, open up your VS Code User Settings and un-check the `Ruff > Code Action: Disable Rule Comment` setting. 6. When opening files in `folder_a`, you should see logs that look like this: ``` Resolved settings for document <file>: ResolvedClientSettings { fix_all: true, organize_imports: true, lint_enable: true, disable_rule_comment_enable: true, fix_violation_enable: true } ``` 7. When opening files in `folder_b`, you should see logs that look like this: ``` Resolved settings for document <file>: ResolvedClientSettings { fix_all: true, organize_imports: true, lint_enable: true, disable_rule_comment_enable: false, fix_violation_enable: true } ``` 8. To test invalid configuration, change `.vscode/settings.json` in either folder to be this: ```json { "ruff.codeAction.disableRuleComment": { "enable": "invalid" }, } ``` 10. You should now see these error logs: ``` <time> [info] <duration> ERROR ruff_server::session::settings Failed to deserialize initialization options: data did not match any variant of untagged enum InitializationOptions. Falling back to default client settings... <time> [info] <duration> WARN ruff_server::server No workspace settings found for file:///Users/jane/testbed/pandas <duration> WARN ruff_server::server No workspace settings found for file:///Users/jane/foss/scipy ``` 11. Opening files in either folder should now print the following configuration: ``` Resolved settings for document <file>: ResolvedClientSettings { fix_all: true, organize_imports: true, lint_enable: true, disable_rule_comment_enable: true, fix_violation_enable: true } ``` |
||
![]() |
0c84fbb6db
|
ruff server - A new built-in LSP for Ruff, written in Rust (#10158)
<!-- Thank you for contributing to Ruff! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary This PR introduces the `ruff_server` crate and a new `ruff server` command. `ruff_server` is a re-implementation of [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp), written entirely in Rust. It brings significant performance improvements, much tighter integration with Ruff, a foundation for supporting entirely new language server features, and more! This PR is an early version of `ruff_lsp` that we're calling the **pre-release** version. Anyone is more than welcome to use it and submit bug reports for any issues they encounter - we'll have some documentation on how to set it up with a few common editors, and we'll also provide a pre-release VSCode extension for those interested. This pre-release version supports: - **Diagnostics for `.py` files** - **Quick fixes** - **Full-file formatting** - **Range formatting** - **Multiple workspace folders** - **Automatic linter/formatter configuration** - taken from any `pyproject.toml` files in the workspace. Many thanks to @MichaReiser for his [proof-of-concept work](https://github.com/astral-sh/ruff/pull/7262), which was important groundwork for making this PR possible. ## Architectural Decisions I've made an executive choice to go with `lsp-server` as a base framework for the LSP, in favor of `tower-lsp`. There were several reasons for this: 1. I would like to avoid `async` in our implementation. LSPs are mostly computationally bound rather than I/O bound, and `async` adds a lot of complexity to the API, while also making harder to reason about execution order. This leads into the second reason, which is... 2. Any handlers that mutate state should be blocking and run in the event loop, and the state should be lock-free. This is the approach that `rust-analyzer` uses (also with the `lsp-server`/`lsp-types` crates as a framework), and it gives us assurances about data mutation and execution order. `tower-lsp` doesn't support this, which has caused some [issues](https://github.com/ebkalderon/tower-lsp/issues/284) around data races and out-of-order handler execution. 3. In general, I think it makes sense to have tight control over scheduling and the specifics of our implementation, in exchange for a slightly higher up-front cost of writing it ourselves. We'll be able to fine-tune it to our needs and support future LSP features without depending on an upstream maintainer. ## Test Plan The pre-release of `ruff_server` will have snapshot tests for common document editing scenarios. An expanded test suite is on the roadmap for future version of `ruff_server`. |