# python-lsp-ruff
[](https://pypi.org/project/python-lsp-ruff)
[](https://anaconda.org/conda-forge/python-lsp-ruff)
[](https://github.com/python-lsp/python-lsp-ruff/actions/workflows/python.yml)
`python-lsp-ruff` is a plugin for `python-lsp-server` that adds **linting**, **code actions** and **formatting** capabilities that are provided by [ruff](https://github.com/charliermarsh/ruff),
an extremely fast Python linter and formatter written in Rust.
Note that `ruff>0.4.5` ships with a built-in LSP server (and `ruff-lsp` before that), which allows linting, formatting and code actions.
In contrast, this implementation adds `ruff` as a plugin for `pylsp` in addition to `pylsp`'s other functionalities (go-to support, ...).
## Install
In the same `virtualenv` as `python-lsp-server`:
```shell
pip install python-lsp-ruff
```
There also exists an [AUR package](https://aur.archlinux.org/packages/python-lsp-ruff).
### When using ruff before version 0.1.0
Ruff version `0.1.0` introduced API changes that are fixed in Python LSP Ruff `v1.6.0`. To continue with `ruff<0.1.0` please use `v1.5.3`, e.g. using `pip`:
```sh
pip install "ruff<0.1.0" "python-lsp-ruff==1.5.3"
```
## Usage
This plugin will disable `pycodestyle`, `pyflakes`, `mccabe`, `autopep8`, and `yapf` by default, unless they are explicitly enabled in the client configuration.
When `python-lsp-ruff` is enabled, all linting diagnostics and formatting capabilities will be provided by `ruff`.
Any codes given in the `format` option will only be marked as `fixable` for ruff during the formatting operation, the user has to make sure that these codes are also in the list of codes that ruff checks!
## Configuration
Configuration options can be passed to the python-language-server. If a `pyproject.toml`
file is present in the project, `python-lsp-ruff` will ignore specific options (see below).
The plugin follows [python-lsp-server's configuration](https://github.com/python-lsp/python-lsp-server/#configuration).
This example configuration using for `neovim` shows the possible options:
Lua
```lua
pylsp = {
plugins = {
ruff = {
enabled = true, -- Enable the plugin
formatEnabled = true, -- Enable formatting using ruffs formatter
executable = "", -- Custom path to ruff
config = "", -- Custom config for ruff to use
extendSelect = { "I" }, -- Rules that are additionally used by ruff
extendIgnore = { "C90" }, -- Rules that are additionally ignored by ruff
format = { "I" }, -- Rules that are marked as fixable by ruff that should be fixed when running textDocument/formatting
severities = { ["D212"] = "I" }, -- Optional table of rules where a custom severity is desired
unsafeFixes = false, -- Whether or not to offer unsafe fixes as code actions. Ignored with the "Fix All" action
unfixable = { "F401" }, -- Rules that are excluded when checking the code actions (including the "Fix All" action)
-- Rules that are ignored when a pyproject.toml or ruff.toml is present:
lineLength = 88, -- Line length to pass to ruff checking and formatting
exclude = { "__about__.py" }, -- Files to be excluded by ruff checking
select = { "F" }, -- Rules to be enabled by ruff
ignore = { "D210" }, -- Rules to be ignored by ruff
perFileIgnores = { ["__init__.py"] = "CPY001" }, -- Rules that should be ignored for specific files
preview = false, -- Whether to enable the preview style linting and formatting.
targetVersion = "py310", -- The minimum python version to target (applies for both linting and formatting).
},
}
}
```
JSON
```
{
"pylsp": {
"plugins": {
"ruff": {
"enabled": true,
"formatEnabled": true,
"executable": "",
"config": "",
"extendSelect": [ "I" ],
"extendIgnore": [ "C90"],
"format": [ "I" ],
"severities": {
"D212": "I"
},
"unsafeFixes": false,
"unfixable": [ "F401" ],
"lineLength": 88,
"exclude": ["__about__.py"],
"select": ["F"],
"ignore": ["D210"],
"perFileIgnores": {
"__init__.py": "CPY001"
},
"preview": false,
"targetVersion": "py310"
}
}
}
}
```
For more information on the configuration visit [Ruff's homepage](https://beta.ruff.rs/docs/configuration/).
### Custom severities
By default, all diagnostics are marked as warning, except for `"E999"` and all error codes starting with `"F"`, which are displayed as errors.
This default can be changed through the `pylsp.plugins.ruff.severities` option, which takes the error code as a key and any of
`"E"`, `"W"`, `"I"` and `"H"` to be displayed as errors, warnings, information and hints, respectively.
For more information on the diagnostic severities please refer to
[the official LSP reference](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticSeverity).
With `v2.0.0` it is also possible to use patterns to match codes. Rules match if the error code starts with the given pattern. If multiple patterns match the error code, `python-lsp-ruff` chooses the one with the most amount of matching characters.
## Code formatting
With `python-lsp-ruff>1.6.0` formatting is done using [ruffs own formatter](https://docs.astral.sh/ruff/formatter/) by default.
Formatting using ruff can be explicitly disabled by setting `formatEnabled = false` in the LSP settings.
Additional rules that should be fixed during the `textDocument/formatting` request can be added with the `format` option.
Coming from previous versions the only change is that `isort` rules are **not** applied by default.
To enable sorting of imports using ruff's isort functionality, add `"I"` to the list of `format` rules.
## Code actions
`python-lsp-ruff` supports code actions as given by possible fixes by `ruff`. `python-lsp-ruff` also supports [unsafe fixes](https://docs.astral.sh/ruff/linter/#fix-safety).
Fixes considered unsafe by `ruff` are marked `(unsafe)` in the code action.
The `Fix all` code action *only* consideres safe fixes.
## Debugging
The log level can be set via the `cmd` option of `pylsp`:
```lua
vim.lsp.config("pylsp", {
cmd = {"pylsp", "-vvv", "--log-file", "/tmp/lsp.log"},
settings = {
pylsp = {
plugins = {
ruff = {
enabled = true,
},
}
}
}
})
```