diff --git a/crates/ruff_server/README.md b/crates/ruff_server/README.md index dc4700f43fc5b..de9254d0d0264 100644 --- a/crates/ruff_server/README.md +++ b/crates/ruff_server/README.md @@ -1,6 +1,4 @@ -## The Ruff Language Server - -Welcome! +# The Ruff Language Server `ruff server` is a language server that powers Ruff's editor integrations. @@ -9,68 +7,12 @@ and call into Ruff's linter and formatter crates to construct real-time diagnost 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. -### Setup - -We have specific setup instructions depending on your editor. If you don't see your editor on this list and would like a -setup guide, please open an issue. - -If you're transferring your configuration from [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp), regardless of -editor, there are several settings which have changed or are no longer available. See the [migration guide](docs/MIGRATION.md) for -more. - -#### VS Code - -Install the Ruff extension from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff). - -As this server is still in Beta, you will need to enable the "Native Server" extension setting, either in the settings -UI: - -![A screenshot showing an enabled "Native Server" extension setting in the VS Code settings view](assets/nativeServer.png) - -Or in your `settings.json`: - -```json -{ - "ruff.nativeServer": true -} -``` - -From there, you can configure Ruff to format Python code on-save with: - -```json -{ - "[python]": { - "editor.formatOnSave": true, - "editor.defaultFormatter": "charliermarsh.ruff" - } -} -``` - -For more, see [_Configuring VS Code_](https://github.com/astral-sh/ruff-vscode?tab=readme-ov-file#configuring-vs-code) -in the Ruff extension documentation. - -By default, the extension will run against the `ruff` binary that it discovers in your environment. If you don't have -`ruff` installed, the extension will fall back to a bundled version of the binary. - -#### Neovim - -See the [Neovim setup guide](docs/setup/NEOVIM.md). - -#### Helix - -See the [Helix setup guide](docs/setup//HELIX.md). - -#### Vim - -See the [Vim setup guide](docs/setup/VIM.md). - -#### Kate - -See the [Kate setup guide](docs/setup/KATE.md). +Refer to the [documentation](https://docs.astral.sh/ruff/editors/) for more information on +how to set up the language server with your editor and configure it to your liking. -### Contributing +## Contributing -If you're interested in contributing to `ruff server` - well, first of all, thank you! Second of all, you might find the -[**contribution guide**](CONTRIBUTING.md) to be a useful resource. +Contributions are welcome and highly appreciated. To get started, check out the +[**contributing guidelines**](https://docs.astral.sh/ruff/contributing/). -Finally, don't hesitate to reach out on [**Discord**](https://discord.com/invite/astral-sh) if you have questions. +You can also join us on [**Discord**](https://discord.com/invite/astral-sh). diff --git a/crates/ruff_server/docs/MIGRATION.md b/crates/ruff_server/docs/MIGRATION.md index 9b42ca0ee6616..18ee2ecd49fb0 100644 --- a/crates/ruff_server/docs/MIGRATION.md +++ b/crates/ruff_server/docs/MIGRATION.md @@ -1,85 +1,3 @@ ## Migrating From `ruff-lsp` -While `ruff server` supports the same feature set as [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp), migrating to -`ruff server` may require changes to your Ruff or language server configuration. - -> \[!NOTE\] -> -> The [VS Code extension](https://github.com/astral-sh/ruff-vscode) settings include documentation to indicate which -> settings are supported by `ruff server`. As such, this migration guide is primarily targeted at editors that lack -> explicit documentation for `ruff server` settings, such as Helix or Neovim. - -### Unsupported Settings - -Several `ruff-lsp` settings are not supported by `ruff server`. These are, as follows: - -- `format.args` -- `ignoreStandardLibrary` -- `interpreter` -- `lint.args` -- `lint.run` -- `logLevel` -- `path` - -Note that some of these settings, like `interpreter` and `path`, are still accepted by the VS Code extension. `path`, -in particular, can be used to specify a dedicated binary to use when initializing `ruff server`. But the language server -itself will no longer accept such settings. - -### New Settings - -`ruff server` introduces several new settings that `ruff-lsp` does not have. These are, as follows: - -- `configuration`: A path to a `ruff.toml` or `pyproject.toml` file to use for configuration. By default, Ruff will discover configuration for each project from the filesystem, mirroring the behavior of the Ruff CLI. -- `configurationPreference`: Used to specify how you want to resolve server settings with local file configuration. The following values are available: - - `"editorFirst"`: The default strategy - configuration set in the server settings takes priority over configuration set in `.toml` files. - - `"filesystemFirst"`: An alternative strategy - configuration set in `.toml` files takes priority over configuration set in the server settings. - - `"editorOnly"`: An alternative strategy - configuration set in `.toml` files is ignored entirely. -- `exclude`: Paths for the linter and formatter to ignore. See [the documentation](https://docs.astral.sh/ruff/settings/#exclude) for more details. -- `format.preview`: Enables [preview mode](https://docs.astral.sh/ruff/settings/#format_preview) for the formatter; enables unstable formatting. -- `lineLength`: The [line length](https://docs.astral.sh/ruff/settings/#line-length) used by the formatter and linter. -- `lint.select`: The rule codes to enable. Use `ALL` to enable all rules. See [the documentation](https://docs.astral.sh/ruff/settings/#lint_select) for more details. -- `lint.extendSelect`: Enables additional rule codes on top of existing configuration, instead of overriding it. Use `ALL` to enable all rules. -- `lint.ignore`: Sets rule codes to disable. See [the documentation](https://docs.astral.sh/ruff/settings/#lint_ignore) for more details. -- `lint.preview`: Enables [preview mode](https://docs.astral.sh/ruff/settings/#lint_preview) for the linter; enables unstable rules and fixes. - -Several of these new settings are replacements for the now-unsupported `format.args` and `lint.args`. For example, if -you've been passing `--select=` to `lint.args`, you can migrate to the new server by using `lint.select` with a -value of `[""]`. - -### Examples - -Let's say you have these settings in VS Code: - -```json -{ - "ruff.lint.args": "--select=E,F --line-length 80 --config ~/.config/custom_ruff_config.toml" -} -``` - -After enabling the native server, you can migrate your settings like so: - -```json -{ - "ruff.configuration": "~/.config/custom_ruff_config.toml", - "ruff.lineLength": 80, - "ruff.lint.select": ["E", "F"] -} -``` - -Similarly, let's say you have these settings in Helix: - -```toml -[language-server.ruff.config.lint] -args = "--select=E,F --line-length 80 --config ~/.config/custom_ruff_config.toml" -``` - -These can be migrated like so: - -```toml -[language-server.ruff.config] -configuration = "~/.config/custom_ruff_config.toml" -lineLength = 80 - -[language-server.ruff.config.lint] -select = ["E", "F"] -``` +This document has been moved to . diff --git a/crates/ruff_server/docs/setup/HELIX.md b/crates/ruff_server/docs/setup/HELIX.md index e41fb2b8bd275..b8e75fec75206 100644 --- a/crates/ruff_server/docs/setup/HELIX.md +++ b/crates/ruff_server/docs/setup/HELIX.md @@ -1,101 +1,3 @@ ## Helix Setup Guide for `ruff server` -First, open the language configuration file for Helix. On Linux and macOS, this will be at `~/.config/helix/languages.toml`, -and on Windows this will be at `%AppData%\helix\languages.toml`. - -Add the language server by adding: - -```toml -[language-server.ruff] -command = "ruff" -args = ["server", "--preview"] -``` - -Then, you'll register the language server as the one to use with Python. -If you don't already have a language server registered to use with Python, add this to `languages.toml`: - -```toml -[[language]] -name = "python" -language-servers = ["ruff"] -``` - -Otherwise, if you already have `language-servers` defined, you can simply add `"ruff"` to the list. For example, -if you already have `pylsp` as a language server, you can modify the language entry as follows: - -```toml -[[language]] -name = "python" -language-servers = ["ruff", "pylsp"] -``` - -> \[!NOTE\] -> Multiple language servers for a single language are only supported in Helix version [`23.10`](https://github.com/helix-editor/helix/blob/master/CHANGELOG.md#2310-2023-10-24) and later. - -Once you've set up the server, you should see diagnostics in your Python files. Code actions and other LSP features should also be available. - -![A screenshot showing an open Python file in Helix with highlighted diagnostics and a code action dropdown menu open](assets/SuccessfulHelixSetup.png) -*This screenshot is using `select=["ALL]"` for demonstration purposes.* - -If you want to, as an example, turn on auto-formatting, add `auto-format = true`: - -```toml -[[language]] -name = "python" -language-servers = ["ruff", "pylsp"] -auto-format = true -``` - -See the [Helix documentation](https://docs.helix-editor.com/languages.html) for more settings you can use here. - -You can pass settings into `ruff server` using `[language-server.ruff.config.settings]`. For example: - -```toml -[language-server.ruff.config.settings] -lineLength = 80 -[language-server.ruff.config.settings.lint] -select = ["E4", "E7"] -preview = false -[language-server.ruff.config.settings.format] -preview = true -``` - -By default, Ruff does not log anything to Helix. To enable logging, set the `RUFF_TRACE` environment variable -to either `messages` or `verbose`. - -```toml -[language-server.ruff] -command = "ruff" -args = ["server", "--preview"] -environment = { "RUFF_TRACE" = "messages" } -``` - -> \[!NOTE\] -> `RUFF_TRACE=verbose` does not enable Helix's verbose mode by itself. You'll need to run Helix with `-v` for verbose logging. - -To change the log level for Ruff (which is `info` by default), use the `logLevel` setting: - -```toml -[language-server.ruff] -command = "ruff" -args = ["server", "--preview"] -environment = { "RUFF_TRACE" = "messages" } - -[language-server.ruff.config.settings] -logLevel = "debug" -``` - -You can also divert Ruff's logs to a separate file with the `logFile` setting: - -```toml -[language-server.ruff] -command = "ruff" -args = ["server", "--preview"] -environment = { "RUFF_TRACE" = "messages" } - -[language-server.ruff.config.settings] -logLevel = "debug" -logFile = "~/.cache/helix/ruff.log" -``` - -The `logFile` path supports tildes and environment variables. +This document has been moved to . diff --git a/crates/ruff_server/docs/setup/KATE.md b/crates/ruff_server/docs/setup/KATE.md index 7b828121fc739..b0e87637e8d43 100644 --- a/crates/ruff_server/docs/setup/KATE.md +++ b/crates/ruff_server/docs/setup/KATE.md @@ -1,25 +1,3 @@ ## Kate Setup Guide for `ruff server` -1. Activate the [LSP Client plugin](https://docs.kde.org/stable5/en/kate/kate/plugins.html#kate-application-plugins). -1. Setup LSP Client [as desired](https://docs.kde.org/stable5/en/kate/kate/kate-application-plugin-lspclient.html). -1. Finally, add this to `Settings` -> `Configure Kate` -> `LSP Client` -> `User Server Settings`: - -```json -{ - "servers": { - "python": { - "command": ["ruff", "server", "--preview"], - "url": "https://github.com/astral-sh/ruff", - "highlightingModeRegex": "^Python$", - "settings": {} - } - } -} -``` - -See [LSP Client documentation](https://docs.kde.org/stable5/en/kate/kate/kate-application-plugin-lspclient.html) for more details -on how to configure the server from there. - -> \[!IMPORTANT\] -> -> Kate's LSP Client plugin does not support multiple servers for the same language. +This document has been moved to . diff --git a/crates/ruff_server/docs/setup/NEOVIM.md b/crates/ruff_server/docs/setup/NEOVIM.md index d055c58e1a1da..e47810686f042 100644 --- a/crates/ruff_server/docs/setup/NEOVIM.md +++ b/crates/ruff_server/docs/setup/NEOVIM.md @@ -1,94 +1,3 @@ ## Neovim Setup Guide for `ruff server` -### Using `nvim-lspconfig` - -1. Install [`nvim-lspconfig`](https://github.com/neovim/nvim-lspconfig). -1. Setup `nvim-lspconfig` with the [suggested configuration](https://github.com/neovim/nvim-lspconfig/tree/master#suggested-configuration). -1. Finally, add this to your `init.lua`: - -```lua -require('lspconfig').ruff.setup {} -``` - -See [`nvim-lspconfig`'s server configuration guide](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#ruff) for more details -on how to configure the server from there. - -> \[!IMPORTANT\] -> -> If you have the older language server (`ruff-lsp`) configured in Neovim, make sure to disable it to prevent any conflicts. - -#### Tips - -If you're using Ruff alongside another LSP (like Pyright), you may want to defer to that LSP for certain capabilities, -like `textDocument/hover`: - -```lua -local on_attach = function(client, bufnr) - if client.name == 'ruff' then - -- Disable hover in favor of Pyright - client.server_capabilities.hoverProvider = false - end -end - -require('lspconfig').ruff.setup { - on_attach = on_attach, -} -``` - -If you'd like to use Ruff exclusively for linting, formatting, and import organization, you can disable those -capabilities for Pyright: - -```lua -require('lspconfig').pyright.setup { - settings = { - pyright = { - -- Using Ruff's import organizer - disableOrganizeImports = true, - }, - python = { - analysis = { - -- Ignore all files for analysis to exclusively use Ruff for linting - ignore = { '*' }, - }, - }, - }, -} -``` - -By default, Ruff will not show any logs. To enable logging in Neovim, you'll need to set the `RUFF_TRACE` environment variable -to either `messages` or `verbose`: - -```lua -require('lspconfig').ruff.setup { - cmd_env = { RUFF_TRACE = "messages" } -} -``` - -You can set the log level in `settings`: - -```lua -require('lspconfig').ruff.setup { - cmd_env = { RUFF_TRACE = "messages" }, - init_options = { - settings = { - logLevel = "debug", - } - } -} -``` - -It's also possible to divert Ruff's logs to a separate file with the `logFile` setting: - -```lua -require('lspconfig').ruff.setup { - cmd_env = { RUFF_TRACE = "messages" }, - init_options = { - settings = { - logLevel = "debug", - logFile = "~/.local/state/nvim/ruff.log" - } - } -} -``` - -The `logFile` path supports tildes and environment variables. +This document has been moved to . diff --git a/crates/ruff_server/docs/setup/VIM.md b/crates/ruff_server/docs/setup/VIM.md index 5723243f2b2d2..0e583d3f07169 100644 --- a/crates/ruff_server/docs/setup/VIM.md +++ b/crates/ruff_server/docs/setup/VIM.md @@ -1,41 +1,3 @@ ## Vim Setup Guide for `ruff server` -### Using `vim-lsp` - -1. Install [`vim-lsp`](https://github.com/prabirshrestha/vim-lsp). -1. Setup `vim-lsp` [as desired](https://github.com/prabirshrestha/vim-lsp?tab=readme-ov-file#registering-servers). -1. Finally, add this to your `.vimrc`: - -```vim -if executable('ruff') - au User lsp_setup call lsp#register_server({ - \ 'name': 'ruff', - \ 'cmd': {server_info->['ruff', 'server', '--preview']}, - \ 'allowlist': ['python'], - \ 'workspace_config': {}, - \ }) -endif -``` - -See the `vim-lsp` [documentation](https://github.com/prabirshrestha/vim-lsp/blob/master/doc/vim-lsp.txt) for more -details on how to configure the language server. - -> \[!IMPORTANT\] -> -> If Ruff's legacy language server (`ruff-lsp`) is configured in Vim, be sure to disable it to prevent any conflicts. - -#### Tips - -If you're using Ruff alongside another LSP (like Pyright), you may want to defer to that LSP for certain capabilities, -like `textDocument/hover` by adding the following to the function `s:on_lsp_buffer_enabled()`: - -```vim -function! s:on_lsp_buffer_enabled() abort - " add your keybindings here (see https://github.com/prabirshrestha/vim-lsp?tab=readme-ov-file#registering-servers) - - let l:capabilities = lsp#get_server_capabilities('ruff') - if !empty(l:capabilities) - let l:capabilities.hoverProvider = v:false - endif -endfunction -``` +This document has been moved to . diff --git a/crates/ruff_server/docs/setup/assets/SuccessfulHelixSetup.png b/crates/ruff_server/docs/setup/assets/SuccessfulHelixSetup.png deleted file mode 100644 index ff21894cbfc3b..0000000000000 Binary files a/crates/ruff_server/docs/setup/assets/SuccessfulHelixSetup.png and /dev/null differ diff --git a/docs/.gitignore b/docs/.gitignore index 9df24a132a260..ec6ed14e2bb3f 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,5 +1,5 @@ -contributing.md -index.md -rules.md -rules/ -settings.md +/contributing.md +/index.md +/rules.md +/rules/ +/settings.md diff --git a/docs/editors/features.md b/docs/editors/features.md new file mode 100644 index 0000000000000..3ce5ff4d7ff92 --- /dev/null +++ b/docs/editors/features.md @@ -0,0 +1,105 @@ +# Features + +This section provides a detailed overview of the features provided by the Ruff Language Server. + +## Diagnostic Highlighting + +Provide diagnostics for your Python code in real-time. + + + +## Dynamic Configuration + +The server dynamically refreshes the diagnostics when a configuration file is changed in the +workspace, whether it's a `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file. + +The server relies on the file watching capabilities of the editor to detect changes to these files. +If an editor does not support file watching, the server will not be able to detect +changes to the configuration file and thus will not refresh the diagnostics. + + + +## Formatting + +Provide code formatting for your Python code. The server can format an entire document or a specific +range of lines. + +The VS Code extension provides the `Ruff: Format Document` command to format an entire document. +In VS Code, the range formatting can be triggered by selecting a range of lines, right-clicking, and +selecting `Format Selection` from the context menu. + + + +## Code Actions + +Code actions are context-sensitive suggestions that can help you fix issues in your code. They are +usually triggered by a shortcut or by clicking a light bulb icon in the editor. The Ruff Language +Server provides the following code actions: + +- Apply a quick fix for a diagnostic that has a fix available (e.g., removing an unused import). +- Ignore a diagnostic with a `# noqa` comment. +- Apply all quick fixes available in the document. +- Organize imports in the document. + + + +You can even run these actions on-save. For example, to fix all issues and organize imports on save +in VS Code, add the following to your `settings.json`: + +```json +{ + "[python]": { + "editor.codeActionsOnSave": { + "source.fixAll.ruff": "explicit", + "source.organizeImports.ruff": "explicit" + } + } +} +``` + +### Fix Safety + +Ruff's automatic fixes are labeled as "safe" and "unsafe". By default, the "Fix all" action will not +apply unsafe fixes. However, unsafe fixes can be applied manually with the "Quick fix" action. +Application of unsafe fixes when using "Fix all" can be enabled by setting `unsafe-fixes = true` in +your Ruff configuration file. + +See the [Ruff fix documentation](https://docs.astral.sh/ruff/linter/#fix-safety) for more details on +how fix safety works. + +## Hover + +The server can provide the rule documentation when focusing over a NoQA code in the comment. +Focusing is usually hovering with a mouse, but can also be triggered with a shortcut. + + + +## Jupyter Notebook + +Similar to Ruff's CLI, the Ruff Language Server fully supports Jupyter Notebook files with all the +capabilities available to Python files. + + + + diff --git a/docs/editors/index.md b/docs/editors/index.md new file mode 100644 index 0000000000000..f0f193be21d7b --- /dev/null +++ b/docs/editors/index.md @@ -0,0 +1,27 @@ +# Editor Integrations + +Ruff can be integrated with various editors and IDEs to provide a seamless development experience. +This section provides instructions on [how to set up Ruff with your editor](./setup.md) and [configure it to your +liking](./settings.md). + +## Language Server Protocol + +The editor integration is mainly powered by the Ruff Language Server which implements the +[Language Server Protocol](https://microsoft.github.io/language-server-protocol/). The server is +written in Rust and is available as part of the `ruff` CLI via `ruff server`. It is a single, common +backend built directly into Ruff, and a direct replacement for [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp), +our previous language server. You can read more about `ruff server` in the +[`v0.4.5` blog post](https://astral.sh/blog/ruff-v0.4.5). + +The server supports surfacing Ruff diagnostics, providing Code Actions to fix them, and +formatting the code using Ruff's built-in formatter. Currently, the server is intended to be used +alongside another Python Language Server in order to support features like navigation and +autocompletion. + +The Ruff Language Server was available first in Ruff [v0.4.5](https://astral.sh/blog/ruff-v0.4.5) +in beta and stabilized in Ruff [v0.5.3](https://github.com/astral-sh/ruff/releases/tag/0.5.3). + +!!! note + This is the documentation for Ruff's built-in language server written in Rust (`ruff server`). + If you are looking for the documentation for the `ruff-lsp` language server, please refer to the + [README](https://github.com/astral-sh/ruff-lsp) of the `ruff-lsp` repository. diff --git a/docs/editors/migration.md b/docs/editors/migration.md new file mode 100644 index 0000000000000..b9db53e729035 --- /dev/null +++ b/docs/editors/migration.md @@ -0,0 +1,81 @@ +# Migrating from `ruff-lsp` + +While `ruff server` supports the same feature set as [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp), migrating to +`ruff server` may require changes to your Ruff or language server configuration. + +!!! note + The [VS Code extension](https://github.com/astral-sh/ruff-vscode) settings include documentation to indicate which + settings are supported by `ruff server`. As such, this migration guide is primarily targeted at editors that lack + explicit documentation for `ruff server` settings, such as Helix or Neovim. + +## Unsupported Settings + +Several `ruff-lsp` settings are not supported by `ruff server`. These are, as follows: + +- `format.args` +- `ignoreStandardLibrary` +- `interpreter` +- `lint.args` +- `lint.run` +- `path` + +!!! note + Some of these settings, like `interpreter` and `path`, are still accepted by the VS Code + extension. `path`, in particular, can be used to specify a dedicated binary to use when + initializing `ruff server`. But the language server itself will no longer accept such settings. + +## New Settings + +`ruff server` introduces several new settings that `ruff-lsp` does not have. These are, as follows: + +- [`configuration`](settings.md#configuration) +- [`configurationPreference`](settings.md#configurationpreference) +- [`exclude`](settings.md#exclude) +- [`format.preview`](settings.md#format_preview) +- [`lineLength`](settings.md#linelength) +- [`lint.select`](settings.md#select) +- [`lint.extendSelect`](settings.md#extendselect) +- [`lint.ignore`](settings.md#ignore) +- [`lint.preview`](settings.md#lint_preview) + +Several of these new settings are replacements for the now-unsupported `format.args` and `lint.args`. For example, if +you've been passing `--select=` to `lint.args`, you can migrate to the new server by using `lint.select` with a +value of `[""]`. + +## Examples + +Let's say you have these settings in VS Code: + +```json +{ + "ruff.lint.args": "--select=E,F --line-length 80 --config ~/.config/custom_ruff_config.toml" +} +``` + +After enabling the native server, you can migrate your settings like so: + +```json +{ + "ruff.configuration": "~/.config/custom_ruff_config.toml", + "ruff.lineLength": 80, + "ruff.lint.select": ["E", "F"] +} +``` + +Similarly, let's say you have these settings in Helix: + +```toml +[language-server.ruff.config.lint] +args = "--select=E,F --line-length 80 --config ~/.config/custom_ruff_config.toml" +``` + +These can be migrated like so: + +```toml +[language-server.ruff.config] +configuration = "~/.config/custom_ruff_config.toml" +lineLength = 80 + +[language-server.ruff.config.lint] +select = ["E", "F"] +``` diff --git a/docs/editors/settings.md b/docs/editors/settings.md new file mode 100644 index 0000000000000..47e1401bbec7d --- /dev/null +++ b/docs/editors/settings.md @@ -0,0 +1,571 @@ +# Settings + +The Ruff Language Server provides a set of configuration options to customize its behavior +along with the ability to use an existing `pyproject.toml` or `ruff.toml` file to configure the +linter and formatter. This is done by providing these settings while initializing the server. +VS Code provides a UI to configure these settings, while other editors may require manual +configuration. The [setup](./setup.md) section provides instructions on where to place these settings +as per the editor. + +## Top-level + +### `configuration` + +Path to a `ruff.toml` or `pyproject.toml` file to use for configuration. + +By default, Ruff will discover configuration for each project from the filesystem, mirroring the +behavior of the Ruff CLI. + +**Default value**: `null` + +**Type**: `string` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.configuration": "~/path/to/ruff.toml" + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + configuration = "~/path/to/ruff.toml" + } + } + } + ``` + +### `configurationPreference` + +The strategy to use when resolving settings across VS Code and the filesystem. By default, editor +configuration is prioritized over `ruff.toml` and `pyproject.toml` files. + +- `"editorFirst"`: Editor settings take priority over configuration files present in the workspace. +- `"filesystemFirst"`: Configuration files present in the workspace takes priority over editor + settings. +- `"editorOnly"`: Ignore configuration files entirely i.e., only use editor settings. + +**Default value**: `"editorFirst"` + +**Type**: `"editorFirst" | "filesystemFirst" | "editorOnly"` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.configurationPreference": "filesystemFirst" + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + configurationPreference = "filesystemFirst" + } + } + } + ``` + +### `exclude` + +A list of file patterns to exclude from linting and formatting. See [the +documentation](https://docs.astral.sh/ruff/settings/#exclude) for more details. + +**Default value**: `null` + +**Type**: `string[]` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.exclude": ["**/tests/**"] + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + exclude = ["**/tests/**"] + } + } + } + ``` + +### `lineLength` + +The line length to use for the linter and formatter. + +**Default value**: `null` + +**Type**: `int` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.lineLength": 100 + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + lineLength = 100 + } + } + } + ``` + +### `fixAll` + +Whether to register the server as capable of handling `source.fixAll` code actions. + +**Default value**: `true` + +**Type**: `bool` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.fixAll": false + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + fixAll = false + } + } + } + ``` + +### `organizeImports` + +Whether to register the server as capable of handling `source.organizeImports` code actions. + +**Default value**: `true` + +**Type**: `bool` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.organizeImports": false + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + organizeImports = false + } + } + } + ``` + +### `showSyntaxErrors` + +_New in Ruff [v0.5.0](https://astral.sh/blog/ruff-v0.5.0#changes-to-e999-and-reporting-of-syntax-errors)_ + +Whether to show syntax error diagnostics. + +**Default value**: `true` + +**Type**: `bool` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.showSyntaxErrors": false + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + showSyntaxErrors = false + } + } + } + ``` + +### `logLevel` + +The log level to use for the server. + +**Default value**: `"info"` + +**Type**: `"trace" | "debug" | "info" | "warn" | "error"` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.logLevel": "debug" + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + logLevel = "debug" + } + } + } + ``` + +### `logFile` + +Path to the log file to use for the server. + +If not set, logs will be written to stderr. + +**Default value**: `null` + +**Type**: `string` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.logFile": "~/path/to/ruff.log" + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + logFile = "~/path/to/ruff.log" + } + } + } + ``` + +## `codeAction` + +Enable or disable code actions provided by the server. + +### `disableRuleComment.enable` + +Whether to display Quick Fix actions to disable rules via `noqa` suppression comments. + +**Default value**: `true` + +**Type**: `bool` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.codeAction.disableRuleComment.enable": false + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + codeAction = { + disableRuleComment = { + enable = false + } + } + } + } + } + ``` + +### `fixViolation.enable` + +Whether to display Quick Fix actions to autofix violations. + +**Default value**: `true` + +**Type**: `bool` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.codeAction.fixViolation.enable": false + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + codeAction = { + fixViolation = { + enable = false + } + } + } + } + } + ``` + +## `lint` + +Settings specific to the Ruff linter. + +### `enable` {: #lint_enable } + +Whether to enable linting. Set to `false` to use Ruff exclusively as a formatter. + +**Default value**: `true` + +**Type**: `bool` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.lint.enable": false + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + lint = { + enable = false + } + } + } + } + ``` + +### `preview` {: #lint_preview } + +Whether to enable Ruff's preview mode when linting. + +**Default value**: `null` + +**Type**: `bool` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.lint.preview": true + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + lint = { + preview = true + } + } + } + } + ``` + +### `select` + +Rules to enable by default. See [the documentation](https://docs.astral.sh/ruff/settings/#lint_select). + +**Default value**: `null` + +**Type**: `string[]` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.lint.select": ["E", "F"] + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + lint = { + select = {"E", "F"} + } + } + } + } + ``` + +### `extendSelect` + +Rules to enable in addition to those in [`lint.select`](#select). + +**Default value**: `null` + +**Type**: `string[]` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.lint.extendSelect": ["W"] + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + lint = { + extendSelect = {"W"} + } + } + } + } + ``` + +### `ignore` + +Rules to disable by default. See [the documentation](https://docs.astral.sh/ruff/settings/#lint_ignore). + +**Default value**: `null` + +**Type**: `string[]` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.lint.ignore": ["E4", "E7"] + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + lint = { + ignore = {"E4", "E7"} + } + } + } + } + ``` + +### `extendIgnore` + +Rules to disable in addition to those in [`lint.ignore`](#ignore). + +**Default value**: `null` + +**Type**: `string[]` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.lint.extendIgnore": ["W1"] + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + lint = { + extendIgnore = {"W1"} + } + } + } + } + ``` + +## `format` + +Settings specific to the Ruff formatter. + +### `preview` {: #format_preview } + +Whether to enable Ruff's preview mode when formatting. + +**Default value**: `null` + +**Type**: `bool` + +**Example usage**: + +=== "VS Code" + ```json + { + "ruff.format.preview": true + } + ``` + +=== "Neovim" + ```lua + require('lspconfig').ruff.setup { + init_options = { + settings = { + format = { + preview = true + } + } + } + } + ``` + +## VS Code specific + +The extension provides additional settings to control the behavior of the Ruff extension in VS Code. +The detailed documentation for these settings can be found in the UI of the settings editor in VS +Code. + +Refer to the [VS Code extension documentation](https://github.com/astral-sh/ruff-vscode#settings) +for more information. diff --git a/docs/editors/setup.md b/docs/editors/setup.md new file mode 100644 index 0000000000000..9cf6475bd75e6 --- /dev/null +++ b/docs/editors/setup.md @@ -0,0 +1,363 @@ +# Setup + +We have specific setup instructions depending on your editor of choice. If you don't see your editor on this +list and would like a setup guide, please open an issue. + +If you're transferring your configuration from [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp), +regardless of editor, there are several settings which have changed or are no longer available. See +the [migration guide](./migration.md) for more. + +!!! note + The setup instructions provided below are on a best-effort basis. If you encounter any issues + while setting up the Ruff in an editor, please [open an issue](https://github.com/astral-sh/ruff/issues/new) + for assistance and help in improving this documentation. + +!!! tip + Regardless of the editor, it is recommended to disable the older language server + ([`ruff-lsp`](https://github.com/astral-sh/ruff-lsp)) to prevent any conflicts. + +## VS Code + +Install the Ruff extension from the [VS Code +Marketplace](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff). It is +recommended to have the Ruff extension version `2024.32.0` or later to get the best experience with +the Ruff Language Server. + +For more documentation on the Ruff extension, refer to the +[README](https://github.com/astral-sh/ruff-vscode/blob/main/README.md) of the extension repository. + +## Neovim + +The [`nvim-lspconfig`](https://github/neovim/nvim-lspconfig) plugin can be used to configure the +Ruff Language Server in Neovim. To set it up, install +[`nvim-lspconfig`](https://github/neovim/nvim-lspconfig) plugin, set it up as per the +[configuration](https://github.com/neovim/nvim-lspconfig#configuration) documentation, and add the +following to your `init.lua`: + +```lua +require('lspconfig').ruff.setup({ + init_options = { + settings = { + -- Ruff language server settings go here + } + } +}) +``` + +If you're using Ruff alongside another language server (like Pyright), you may want to defer to that +language server for certain capabilities, like [`textDocument/hover`](./features.md#hover): + +```lua +vim.api.nvim_create_autocmd("LspAttach", { + group = vim.api.nvim_create_augroup('lsp_attach_disable_ruff_hover', { clear = true }), + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client == nil then + return + end + if client.name == 'ruff' then + -- Disable hover in favor of Pyright + client.server_capabilities.hoverProvider = false + end + end, + desc = 'LSP: Disable hover capability from Ruff', +}) +``` + +If you'd like to use Ruff exclusively for linting, formatting, and organizing imports, you can disable those +capabilities for Pyright: + +```lua +require('lspconfig').pyright.setup { + settings = { + pyright = { + -- Using Ruff's import organizer + disableOrganizeImports = true, + }, + python = { + analysis = { + -- Ignore all files for analysis to exclusively use Ruff for linting + ignore = { '*' }, + }, + }, + }, +} +``` + +By default, Ruff will not show any logs. To enable logging in Neovim, you'll need to set the +`RUFF_TRACE` environment variable to either `messages` or `verbose`, and use the +[`logLevel`](./settings.md#loglevel) setting to change the log level: + +```lua +require('lspconfig').ruff.setup { + cmd_env = { RUFF_TRACE = "messages" } + init_options = { + settings = { + logLevel = "debug", + } + } +} +``` + +By default, this will write logs to stderr which will be available in Neovim's LSP client log file +(`:lua vim.print(vim.lsp.get_log_path())`). It's also possible to divert these logs to a separate +file with the [`logFile`](./settings.md#logfile) setting. + +## Vim + +The [`vim-lsp`](https://github.com/prabirshrestha/vim-lsp) plugin can be used to configure the Ruff Language Server in Vim. +To set it up, install [`vim-lsp`](https://github.com/prabirshrestha/vim-lsp) plugin and register the server using the following +in your `.vimrc`: + +```vim +if executable('ruff') + au User lsp_setup call lsp#register_server({ + \ 'name': 'ruff', + \ 'cmd': {server_info->['ruff', 'server']}, + \ 'allowlist': ['python'], + \ 'workspace_config': {}, + \ }) +endif +``` + +See the `vim-lsp` +[documentation](https://github.com/prabirshrestha/vim-lsp/blob/master/doc/vim-lsp.txt) for more +details on how to configure the language server. + +If you're using Ruff alongside another LSP (like Pyright), you may want to defer to that LSP for certain capabilities, +like [`textDocument/hover`](./features.md#hover) by adding the following to the function `s:on_lsp_buffer_enabled()`: + +```vim +function! s:on_lsp_buffer_enabled() abort + " add your keybindings here (see https://github.com/prabirshrestha/vim-lsp?tab=readme-ov-file#registering-servers) + + let l:capabilities = lsp#get_server_capabilities('ruff') + if !empty(l:capabilities) + let l:capabilities.hoverProvider = v:false + endif +endfunction +``` + +Ruff is also available as part of the [coc-pyright](https://github.com/fannheyward/coc-pyright) +extension for [coc.nvim](https://github.com/neoclide/coc.nvim). + +
+With the ALE plugin for Vim or Neovim. + +```vim +" Linter +let g:ale_linters = { "python": ["ruff"] } +" Formatter +let g:ale_fixers = { "python": ["ruff-format"] } +``` + +
+ +
+Ruff can also be integrated via efm language server in just a few lines. +
+ +Following is an example config for efm to use Ruff for linting and formatting Python files: + +```yaml +tools: + python-ruff: + lint-command: "ruff check --stdin-filename ${INPUT} --output-format concise --quiet -" + lint-stdin: true + lint-formats: + - "%f:%l:%c: %m" + format-command: "ruff format --stdin-filename ${INPUT} --quiet -" + format-stdin: true +``` + +
+ +
+With the conform.nvim plugin for Neovim. +
+ +```lua +require("conform").setup({ + formatters_by_ft = { + python = { + -- To fix auto-fixable lint errors. + "ruff_fix", + -- To run the Ruff formatter. + "ruff_format", + -- To organize the imports. + "ruff_organize_imports", + }, + }, +}) +``` + +
+ +
+With the nvim-lint plugin for Neovim. + +```lua +require("lint").linters_by_ft = { + python = { "ruff" }, +} +``` + +
+ +## Helix + +Open the [language configuration file](https://docs.helix-editor.com/languages.html#languagestoml-files) for +Helix and add the language server as follows: + +```toml +[language-server.ruff] +command = "ruff" +args = ["server"] +``` + +Then, you'll register the language server as the one to use with Python. If you don't already have a +language server registered to use with Python, add this to `languages.toml`: + +```toml +[[language]] +name = "python" +language-servers = ["ruff"] +``` + +Otherwise, if you already have `language-servers` defined, you can simply add `"ruff"` to the list. For example, +if you already have `pylsp` as a language server, you can modify the language entry as follows: + +```toml +[[language]] +name = "python" +language-servers = ["ruff", "pylsp"] +``` + +!!! note + Support for multiple language servers for a language is only available in Helix version + [`23.10`](https://github.com/helix-editor/helix/blob/master/CHANGELOG.md#2310-2023-10-24) and later. + +If you want to, as an example, turn on auto-formatting, add `auto-format = true`: + +```toml +[[language]] +name = "python" +language-servers = ["ruff", "pylsp"] +auto-format = true +``` + +See the [Helix documentation](https://docs.helix-editor.com/languages.html) for more settings you can use here. + +You can pass settings into `ruff server` using `[language-server.ruff.config.settings]`. For example: + +```toml +[language-server.ruff.config.settings] +lineLength = 80 + +[language-server.ruff.config.settings.lint] +select = ["E4", "E7"] +preview = false + +[language-server.ruff.config.settings.format] +preview = true +``` + +By default, Ruff does not log anything to Helix. To enable logging, set the `RUFF_TRACE` environment +variable to either `messages` or `verbose`, and use the [`logLevel`](./settings.md#loglevel) setting to change +the log level: + +```toml +[language-server.ruff] +command = "ruff" +args = ["server"] +environment = { "RUFF_TRACE" = "messages" } + +[language-server.ruff.config.settings] +logLevel = "debug" +``` + +You can also divert Ruff's logs to a separate file with the [`logFile`](./settings.md#logfile) setting. + +!!! note + Setting `RUFF_TRACE=verbose` does not enable Helix's verbose mode by itself. You'll need to run + Helix with `-v` for verbose logging. + +## Kate + +1. Activate the [LSP Client plugin](https://docs.kde.org/stable5/en/kate/kate/plugins.html#kate-application-plugins). +1. Setup LSP Client [as desired](https://docs.kde.org/stable5/en/kate/kate/kate-application-plugin-lspclient.html). +1. Finally, add this to `Settings` -> `Configure Kate` -> `LSP Client` -> `User Server Settings`: + +```json +{ + "servers": { + "python": { + "command": ["ruff", "server"], + "url": "https://github.com/astral-sh/ruff", + "highlightingModeRegex": "^Python$", + "settings": {} + } + } +} +``` + +See [LSP Client documentation](https://docs.kde.org/stable5/en/kate/kate/kate-application-plugin-lspclient.html) for more details +on how to configure the server from there. + +!!! important + Kate's LSP Client plugin does not support multiple servers for the same language. + +## Sublime Text + +To use Ruff with Sublime Text, install Sublime Text's [LSP](https://github.com/sublimelsp/LSP) +and [LSP-ruff](https://github.com/sublimelsp/LSP-ruff) package. + +## PyCharm + +### Via External Tool + +Ruff can be installed as an [External Tool](https://www.jetbrains.com/help/pycharm/configuring-third-party-tools.html) +in PyCharm. Open the Preferences pane, then navigate to "Tools", then "External Tools". From there, +add a new tool with the following configuration: + +![Install Ruff as an External Tool](https://user-images.githubusercontent.com/1309177/193155720-336e43f0-1a8d-46b4-bc12-e60f9ae01f7e.png) + +Ruff should then appear as a runnable action: + +![Ruff as a runnable action](https://user-images.githubusercontent.com/1309177/193156026-732b0aaf-3dd9-4549-9b4d-2de6d2168a33.png) + +### Via third-party plugin + +Ruff is also available as the [Ruff](https://plugins.jetbrains.com/plugin/20574-ruff) plugin on the +IntelliJ Marketplace (maintained by [@koxudaxi](https://github.com/koxudaxi)). + +## Emacs + +Ruff is available as [`flymake-ruff`](https://melpa.org/#/flymake-ruff) on MELPA: + +```elisp +(require 'flymake-ruff) +(add-hook 'python-mode-hook #'flymake-ruff-load) +``` + +Ruff is also available as [`emacs-ruff-format`](https://github.com/scop/emacs-ruff-format): + +```elisp +(require 'ruff-format) +(add-hook 'python-mode-hook 'ruff-format-on-save-mode) +``` + +Alternatively, it can be used via the [Apheleia](https://github.com/radian-software/apheleia) formatter library, by setting this configuration: + +```emacs-lisp +;; Replace default (black) to use ruff for sorting import and formatting. +(setf (alist-get 'python-mode apheleia-mode-alist) + '(ruff-isort ruff)) +(setf (alist-get 'python-ts-mode apheleia-mode-alist) + '(ruff-isort ruff)) +``` + +## TextMate + +Ruff is also available via the [`textmate2-ruff-linter`](https://github.com/vigo/textmate2-ruff-linter) +bundle for TextMate. diff --git a/docs/integrations.md b/docs/integrations.md index 15e3fdda8ac7b..ff18d3df0fdbd 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -1,327 +1,5 @@ # Integrations -## VS Code (Official) - -Download the [Ruff VS Code extension](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff), -which supports fix actions, import sorting, and more. - -![Ruff VS Code extension](https://user-images.githubusercontent.com/1309177/205175763-cf34871d-5c05-4abf-9916-440afc82dbf8.gif) - -## pre-commit - -Ruff can be used as a [pre-commit](https://pre-commit.com) hook via [`ruff-pre-commit`](https://github.com/astral-sh/ruff-pre-commit): - -```yaml -- repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.5.2 - hooks: - # Run the linter. - - id: ruff - # Run the formatter. - - id: ruff-format -``` - -To enable lint fixes, add the `--fix` argument to the lint hook: - -```yaml -- repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.5.2 - hooks: - # Run the linter. - - id: ruff - args: [ --fix ] - # Run the formatter. - - id: ruff-format -``` - -To run the hooks over Jupyter Notebooks too, add `jupyter` to the list of allowed filetypes: - -```yaml -- repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.5.2 - hooks: - # Run the linter. - - id: ruff - types_or: [ python, pyi, jupyter ] - args: [ --fix ] - # Run the formatter. - - id: ruff-format - types_or: [ python, pyi, jupyter ] -``` - -When running with `--fix`, Ruff's lint hook should be placed _before_ Ruff's formatter hook, and -_before_ Black, isort, and other formatting tools, as Ruff's fix behavior can output code changes -that require reformatting. - -When running without `--fix`, Ruff's formatter hook can be placed before or after Ruff's lint hook. - -(As long as your Ruff configuration avoids any [linter-formatter incompatibilities](formatter.md#conflicting-lint-rules), -`ruff format` should never introduce new lint errors, so it's safe to run Ruff's format hook _after_ -`ruff check --fix`.) - -## Language Server Protocol (Official) - -Ruff supports the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) -via the [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp) Python package, available on -[PyPI](https://pypi.org/project/ruff-lsp/). - -[`ruff-lsp`](https://github.com/astral-sh/ruff-lsp) enables Ruff to be used with any editor that -supports the Language Server Protocol, including [Neovim](https://github.com/astral-sh/ruff-lsp#example-neovim), -[Sublime Text](https://github.com/astral-sh/ruff-lsp#example-sublime-text), Emacs, and more. - -For example, to use `ruff-lsp` with Neovim, install `ruff-lsp` from PyPI along with -[`nvim-lspconfig`](https://github.com/neovim/nvim-lspconfig). Then, set up the Neovim LSP client -using the [suggested configuration](https://github.com/neovim/nvim-lspconfig/tree/master#configuration) -(`:h lspconfig-keybindings`). Finally, configure `ruff-lsp` in your `init.lua`: - -```lua --- Configure `ruff-lsp`. --- See: https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#ruff_lsp --- For the default config, along with instructions on how to customize the settings -require('lspconfig').ruff_lsp.setup { - init_options = { - settings = { - -- Any extra CLI arguments for `ruff` go here. - args = {}, - } - } -} -``` - -Upon successful installation, you should see Ruff's diagnostics surfaced directly in your editor: - -![Code Actions available in Neovim](https://user-images.githubusercontent.com/1309177/208278707-25fa37e4-079d-4597-ad35-b95dba066960.png) - -To use `ruff-lsp` with other editors, including Sublime Text and Helix, see the [`ruff-lsp` documentation](https://github.com/astral-sh/ruff-lsp#setup). - -## Language Server Protocol (Unofficial) - -Ruff is also available as the [`python-lsp-ruff`](https://github.com/python-lsp/python-lsp-ruff) -plugin for [`python-lsp-server`](https://github.com/python-lsp/python-lsp-server), both of which are -installable from PyPI: - -```shell -pip install python-lsp-server python-lsp-ruff -``` - -The LSP server can then be used with any editor that supports the Language Server Protocol. - -For example, to use `python-lsp-ruff` with Neovim, add something like the following to your -`init.lua`: - -```lua -require'lspconfig'.pylsp.setup { - settings = { - pylsp = { - plugins = { - ruff = { - enabled = true - }, - pycodestyle = { - enabled = false - }, - pyflakes = { - enabled = false - }, - mccabe = { - enabled = false - } - } - } - }, -} -``` - -## Vim & Neovim - -Ruff can be integrated into any editor that supports the Language Server Protocol via [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp) -(see: [Language Server Protocol](#language-server-protocol-official)), including Vim and Neovim. - -It's recommended that you use [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp), the -officially supported LSP server for Ruff. To use `ruff-lsp` with Neovim, install `ruff-lsp` from -PyPI along with [`nvim-lspconfig`](https://github.com/neovim/nvim-lspconfig). Then, add something -like the following to your `init.lua`: - -```lua --- See: https://github.com/neovim/nvim-lspconfig/tree/54eb2a070a4f389b1be0f98070f81d23e2b1a715#suggested-configuration -local opts = { noremap=true, silent=true } -vim.keymap.set('n', 'e', vim.diagnostic.open_float, opts) -vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts) -vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts) -vim.keymap.set('n', 'q', vim.diagnostic.setloclist, opts) - --- Use an on_attach function to only map the following keys --- after the language server attaches to the current buffer -local on_attach = function(client, bufnr) - -- Enable completion triggered by - vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') - - -- Mappings. - -- See `:help vim.lsp.*` for documentation on any of the below functions - local bufopts = { noremap=true, silent=true, buffer=bufnr } - vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts) - vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts) - vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts) - vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts) - vim.keymap.set('n', '', vim.lsp.buf.signature_help, bufopts) - vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, bufopts) - vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, bufopts) - vim.keymap.set('n', 'wl', function() - print(vim.inspect(vim.lsp.buf.list_workspace_folders())) - end, bufopts) - vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, bufopts) - vim.keymap.set('n', 'rn', vim.lsp.buf.rename, bufopts) - vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, bufopts) - vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts) - vim.keymap.set('n', 'f', function() vim.lsp.buf.format { async = true } end, bufopts) -end - --- Configure `ruff-lsp`. --- See: https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#ruff_lsp --- For the default config, along with instructions on how to customize the settings -require('lspconfig').ruff_lsp.setup { - on_attach = on_attach, - init_options = { - settings = { - -- Any extra CLI arguments for `ruff` go here. - args = {}, - } - } -} -``` - -Ruff is also available as part of the [coc-pyright](https://github.com/fannheyward/coc-pyright) -extension for `coc.nvim`. - -
-With the ALE plugin for (Neo)Vim. - -```vim -let g:ale_linters = { "python": ["ruff"] } -let g:ale_fixers = { -\ "python": ["black", "ruff"], -\} -``` - -
- -
- -Ruff can also be integrated via - - efm - -in just a - - few lines. - - -
- -```yaml -tools: - python-ruff: &python-ruff - lint-command: "ruff check --config ~/myconfigs/linters/ruff.toml --quiet ${INPUT}" - lint-stdin: true - lint-formats: - - "%f:%l:%c: %m" - format-command: "ruff check --stdin-filename ${INPUT} --config ~/myconfigs/linters/ruff.toml --fix --exit-zero --quiet -" - format-stdin: true -``` - -
- -
- -With the conform.nvim plugin for Neovim. - -
- -```lua -require("conform").setup({ - formatters_by_ft = { - python = { - -- To fix lint errors. - "ruff_fix", - -- To run the Ruff formatter. - "ruff_format", - }, - }, -}) -``` - -
- -
- -With the nvim-lint plugin for Neovim. - - -```lua -require("lint").linters_by_ft = { - python = { "ruff" }, -} -``` - -
- -## PyCharm (External Tool) - -Ruff can be installed as an [External Tool](https://www.jetbrains.com/help/pycharm/configuring-third-party-tools.html) -in PyCharm. Open the Preferences pane, then navigate to "Tools", then "External Tools". From there, -add a new tool with the following configuration: - -![Install Ruff as an External Tool](https://user-images.githubusercontent.com/1309177/193155720-336e43f0-1a8d-46b4-bc12-e60f9ae01f7e.png) - -Ruff should then appear as a runnable action: - -![Ruff as a runnable action](https://user-images.githubusercontent.com/1309177/193156026-732b0aaf-3dd9-4549-9b4d-2de6d2168a33.png) - -## PyCharm (Unofficial) - -Ruff is also available as the [Ruff](https://plugins.jetbrains.com/plugin/20574-ruff) plugin on the -IntelliJ Marketplace (maintained by @koxudaxi). - -## Emacs (Unofficial) - -Ruff is available as [`flymake-ruff`](https://melpa.org/#/flymake-ruff) on MELPA: - -```elisp -(require 'flymake-ruff) -(add-hook 'python-mode-hook #'flymake-ruff-load) -``` - -Ruff is also available as [`emacs-ruff-format`](https://github.com/scop/emacs-ruff-format): - -```elisp -(require 'ruff-format) -(add-hook 'python-mode-hook 'ruff-format-on-save-mode) -``` - -Alternatively, it can be used via the [Apheleia](https://github.com/radian-software/apheleia) formatter library, by setting this configuration: - -```emacs-lisp -;; Replace default (black) to use ruff for sorting import and formatting. -(setf (alist-get 'python-mode apheleia-mode-alist) - '(ruff-isort ruff)) -(setf (alist-get 'python-ts-mode apheleia-mode-alist) - '(ruff-isort ruff)) -``` - -## TextMate (Unofficial) - -Ruff is also available via the [`textmate2-ruff-linter`](https://github.com/vigo/textmate2-ruff-linter) -bundle for TextMate. - -## mdformat (Unofficial) - -[mdformat](https://mdformat.readthedocs.io/en/stable/users/plugins.html#code-formatter-plugins) is -capable of formatting code blocks within Markdown. The [`mdformat-ruff`](https://github.com/Freed-Wu/mdformat-ruff) -plugin enables mdformat to format Python code blocks with Ruff. - ## GitHub Actions GitHub Actions has everything you need to run Ruff out-of-the-box: @@ -392,3 +70,64 @@ For example, to run `ruff check --select B ./src` using Ruff version `0.0.259`: args: check --select B src: "./src" ``` + +## pre-commit + +Ruff can be used as a [pre-commit](https://pre-commit.com) hook via [`ruff-pre-commit`](https://github.com/astral-sh/ruff-pre-commit): + +```yaml +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.5.2 + hooks: + # Run the linter. + - id: ruff + # Run the formatter. + - id: ruff-format +``` + +To enable lint fixes, add the `--fix` argument to the lint hook: + +```yaml +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.5.2 + hooks: + # Run the linter. + - id: ruff + args: [ --fix ] + # Run the formatter. + - id: ruff-format +``` + +To run the hooks over Jupyter Notebooks too, add `jupyter` to the list of allowed filetypes: + +```yaml +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.5.2 + hooks: + # Run the linter. + - id: ruff + types_or: [ python, pyi, jupyter ] + args: [ --fix ] + # Run the formatter. + - id: ruff-format + types_or: [ python, pyi, jupyter ] +``` + +When running with `--fix`, Ruff's lint hook should be placed _before_ Ruff's formatter hook, and +_before_ Black, isort, and other formatting tools, as Ruff's fix behavior can output code changes +that require reformatting. + +When running without `--fix`, Ruff's formatter hook can be placed before or after Ruff's lint hook. + +(As long as your Ruff configuration avoids any [linter-formatter incompatibilities](formatter.md#conflicting-lint-rules), +`ruff format` should never introduce new lint errors, so it's safe to run Ruff's format hook _after_ +`ruff check --fix`.) + +## `mdformat` + +[mdformat](https://mdformat.readthedocs.io/en/stable/users/plugins.html#code-formatter-plugins) is +capable of formatting code blocks within Markdown. The [`mdformat-ruff`](https://github.com/Freed-Wu/mdformat-ruff) +plugin enables mdformat to format Python code blocks with Ruff. diff --git a/scripts/generate_mkdocs.py b/scripts/generate_mkdocs.py index 5085f4400b82e..897a14da26649 100644 --- a/scripts/generate_mkdocs.py +++ b/scripts/generate_mkdocs.py @@ -8,7 +8,7 @@ import shutil import subprocess from pathlib import Path -from typing import NamedTuple +from typing import NamedTuple, Sequence import mdformat import yaml @@ -22,6 +22,8 @@ class Section(NamedTuple): title: str filename: str generated: bool + # If subsections is present, the `filename` and `generated` value is unused. + subsections: Sequence[Section] | None = None SECTIONS: list[Section] = [ @@ -30,6 +32,18 @@ class Section(NamedTuple): Section("Installing Ruff", "installation.md", generated=False), Section("The Ruff Linter", "linter.md", generated=False), Section("The Ruff Formatter", "formatter.md", generated=False), + Section( + "Editors", + "", + generated=False, + subsections=[ + Section("Editor Integration", "editors/index.md", generated=False), + Section("Setup", "editors/setup.md", generated=False), + Section("Features", "editors/features.md", generated=False), + Section("Settings", "editors/settings.md", generated=False), + Section("Migrating from ruff-lsp", "editors/migration.md", generated=False), + ], + ), Section("Configuring Ruff", "configuration.md", generated=False), Section("Preview", "preview.md", generated=False), Section("Rules", "rules.md", generated=True), @@ -108,7 +122,7 @@ def main() -> None: Path("docs").mkdir(parents=True, exist_ok=True) # Split the README.md into sections. - for title, filename, generated in SECTIONS: + for title, filename, generated, _ in SECTIONS: if not generated: continue @@ -180,7 +194,19 @@ def main() -> None: ) # Add the nav section to mkdocs.yml. - config["nav"] = [{section.title: section.filename} for section in SECTIONS] + config["nav"] = [] + for section in SECTIONS: + if section.subsections is None: + config["nav"].append({section.title: section.filename}) + else: + config["nav"].append( + { + section.title: [ + {subsection.title: subsection.filename} + for subsection in section.subsections + ] + } + ) with Path("mkdocs.generated.yml").open("w+", encoding="utf8") as fp: yaml.safe_dump(config, fp)