mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-17 22:07:42 +00:00
![]() ## Summary [Internal design document](https://www.notion.so/astral-sh/In-editor-settings-19e48797e1ca807fa8c2c91b689d9070?pvs=4) This PR expands `ruff.configuration` to allow inline configuration directly in the editor. For example: ```json { "ruff.configuration": { "line-length": 100, "lint": { "unfixable": ["F401"], "flake8-tidy-imports": { "banned-api": { "typing.TypedDict": { "msg": "Use `typing_extensions.TypedDict` instead" } } } }, "format": { "quote-style": "single" } } } ``` This means that now `ruff.configuration` accepts either a path to configuration file or the raw config itself. It's _mostly_ similar to `--config` with one difference that's highlighted in the following section. So, it can be said that the format of `ruff.configuration` when provided the config map is same as the one on the [playground] [^1]. ## Limitations <details><summary><b>Casing (<code>kebab-case</code> v/s/ <code>camelCase</code>)</b></summary> <p> The config keys needs to be in `kebab-case` instead of `camelCase` which is being used for other settings in the editor. This could be a bit confusing. For example, the `line-length` option can be set directly via an editor setting or can be configured via `ruff.configuration`: ```json { "ruff.configuration": { "line-length": 100 }, "ruff.lineLength": 120 } ``` #### Possible solution We could use feature flag with [conditional compilation](https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute) to indicate that when used in `ruff_server`, we need the `Options` fields to be renamed as `camelCase` while for other crates it needs to be renamed as `kebab-case`. But, this might not work very easily because it will require wrapping the `Options` struct and create two structs in which we'll have to add `#[cfg_attr(...)]` because otherwise `serde` will complain: ``` error: duplicate serde attribute `rename_all` --> crates/ruff_workspace/src/options.rs:43:38 | 43 | #[cfg_attr(feature = "editor", serde(rename_all = "camelCase"))] | ^^^^^^^^^^ ``` </p> </details> <details><summary><b>Nesting (flat v/s nested keys)</b></summary> <p> This is the major difference between `--config` flag on the command-line v/s `ruff.configuration` and it makes it such that `ruff.configuration` has same value format as [playground] [^1]. The config keys needs to be split up into keys which can result in nested structure instead of flat structure: So, the following **won't work**: ```json { "ruff.configuration": { "format.quote-style": "single", "lint.flake8-tidy-imports.banned-api.\"typing.TypedDict\".msg": "Use `typing_extensions.TypedDict` instead" } } ``` But, instead it would need to be split up like the following: ```json { "ruff.configuration": { "format": { "quote-style": "single" }, "lint": { "flake8-tidy-imports": { "banned-api": { "typing.TypedDict": { "msg": "Use `typing_extensions.TypedDict` instead" } } } } } } ``` #### Possible solution (1) The way we could solve this and make it same as `--config` would be to add a manual logic of converting the JSON map into an equivalent TOML string which would be then parsed into `Options`. So, the following JSON map: ```json { "lint.flake8-tidy-imports": { "banned-api": {"\"typing.TypedDict\".msg": "Use typing_extensions.TypedDict instead"}}} ``` would need to be converted into the following TOML string: ```toml lint.flake8-tidy-imports = { banned-api = { "typing.TypedDict".msg = "Use typing_extensions.TypedDict instead" } } ``` by recursively convering `"key": value` into `key = value` which is to remove the quotes from key and replacing `:` with `=`. #### Possible solution (2) Another would be to just accept `Map<String, String>` strictly and convert it into `key = value` and then parse it as a TOML string. This would also match `--config` but quotes might become a nuisance because JSON only allows double quotes and so it'll require escaping any inner quotes or use single quotes. </p> </details> ## Test Plan ### VS Code **Requires https://github.com/astral-sh/ruff-vscode/pull/702** **`settings.json`**: ```json { "ruff.lint.extendSelect": ["TID"], "ruff.configuration": { "line-length": 50, "format": { "quote-style": "single" }, "lint": { "unfixable": ["F401"], "flake8-tidy-imports": { "banned-api": { "typing.TypedDict": { "msg": "Use `typing_extensions.TypedDict` instead" } } } } } } ``` Following video showcases me doing the following: 1. Check diagnostics that it includes `TID` 2. Run `Ruff: Fix all auto-fixable problems` to test `unfixable` 3. Run `Format: Document` to test `line-length` and `quote-style` https://github.com/user-attachments/assets/0a38176f-3fb0-4960-a213-73b2ea5b1180 ### Neovim **`init.lua`**: ```lua require('lspconfig').ruff.setup { init_options = { settings = { lint = { extendSelect = { 'TID' }, }, configuration = { ['line-length'] = 50, format = { ['quote-style'] = 'single', }, lint = { unfixable = { 'F401' }, ['flake8-tidy-imports'] = { ['banned-api'] = { ['typing.TypedDict'] = { msg = 'Use typing_extensions.TypedDict instead', }, }, }, }, }, }, }, } ``` Same steps as in the VS Code test: https://github.com/user-attachments/assets/cfe49a9b-9a89-43d7-94f2-7f565d6e3c9d ## Documentation Preview https://github.com/user-attachments/assets/e0062f58-6ec8-4e01-889d-fac76fd8b3c7 [playground]: https://play.ruff.rs [^1]: This has one advantage that the value can be copy-pasted directly into the playground |
||
---|---|---|
.. | ||
assets | ||
docs | ||
resources/test/fixtures | ||
src | ||
tests | ||
Cargo.toml | ||
CONTRIBUTING.md | ||
README.md |
The Ruff Language Server
ruff server
is a language server that powers Ruff's editor integrations.
The job of the language server is to listen for requests from the client (in this case, the code editor of your choice) and call into Ruff's linter and formatter crates to construct real-time diagnostics or formatted code, which is then sent back to the client. It also tracks configuration files in your editor's workspace, and will refresh its in-memory configuration whenever those files are modified.
Refer to the documentation for more information on how to set up the language server with your editor and configure it to your liking.
Contributing
Contributions are welcome and highly appreciated. To get started, check out the contributing guidelines.
You can also join us on Discord.