Setup | Ruff (original) (raw)
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, regardless of editor, there are several settings which have changed or are no longer available. See the migration guide 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 issuefor assistance and help in improving this documentation.
Tip
Regardless of the editor, it is recommended to disable the older language server (ruff-lsp) to prevent any conflicts.
VS Code
Install the Ruff extension from the VS Code Marketplace. 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 theREADME of the extension repository.
Neovim
The nvim-lspconfig plugin can be used to configure the Ruff Language Server in Neovim. To set it up, installnvim-lspconfig plugin, set it up as per theconfiguration documentation, and add the following to your init.lua
:
[](#%5F%5Fcodelineno-0-1)require('lspconfig').ruff.setup({ [](#%5F%5Fcodelineno-0-2) init_options = { [](#%5F%5Fcodelineno-0-3) settings = { [](#%5F%5Fcodelineno-0-4) -- Ruff language server settings go here [](#%5F%5Fcodelineno-0-5) } [](#%5F%5Fcodelineno-0-6) } [](#%5F%5Fcodelineno-0-7)})
[](#%5F%5Fcodelineno-1-1)vim.lsp.config('ruff', { [](#%5F%5Fcodelineno-1-2) init_options = { [](#%5F%5Fcodelineno-1-3) settings = { [](#%5F%5Fcodelineno-1-4) -- Ruff language server settings go here [](#%5F%5Fcodelineno-1-5) } [](#%5F%5Fcodelineno-1-6) } [](#%5F%5Fcodelineno-1-7)}) [](#%5F%5Fcodelineno-1-8) [](#%5F%5Fcodelineno-1-9)vim.lsp.enable('ruff')
Note
If the installed version of nvim-lspconfig
includes the changes fromneovim/nvim-lspconfig@70d1c2c, you will need to use Ruff version 0.5.3
or later.
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:
[](#%5F%5Fcodelineno-2-1)vim.api.nvim_create_autocmd("LspAttach", { [](#%5F%5Fcodelineno-2-2) group = vim.api.nvim_create_augroup('lsp_attach_disable_ruff_hover', { clear = true }), [](#%5F%5Fcodelineno-2-3) callback = function(args) [](#%5F%5Fcodelineno-2-4) local client = vim.lsp.get_client_by_id(args.data.client_id) [](#%5F%5Fcodelineno-2-5) if client == nil then [](#%5F%5Fcodelineno-2-6) return [](#%5F%5Fcodelineno-2-7) end [](#%5F%5Fcodelineno-2-8) if client.name == 'ruff' then [](#%5F%5Fcodelineno-2-9) -- Disable hover in favor of Pyright [](#%5F%5Fcodelineno-2-10) client.server_capabilities.hoverProvider = false [](#%5F%5Fcodelineno-2-11) end [](#%5F%5Fcodelineno-2-12) end, [](#%5F%5Fcodelineno-2-13) desc = 'LSP: Disable hover capability from Ruff', [](#%5F%5Fcodelineno-2-14)})
If you'd like to use Ruff exclusively for linting, formatting, and organizing imports, you can disable those capabilities for Pyright:
[](#%5F%5Fcodelineno-3-1)require('lspconfig').pyright.setup { [](#%5F%5Fcodelineno-3-2) settings = { [](#%5F%5Fcodelineno-3-3) pyright = { [](#%5F%5Fcodelineno-3-4) -- Using Ruff's import organizer [](#%5F%5Fcodelineno-3-5) disableOrganizeImports = true, [](#%5F%5Fcodelineno-3-6) }, [](#%5F%5Fcodelineno-3-7) python = { [](#%5F%5Fcodelineno-3-8) analysis = { [](#%5F%5Fcodelineno-3-9) -- Ignore all files for analysis to exclusively use Ruff for linting [](#%5F%5Fcodelineno-3-10) ignore = { '*' }, [](#%5F%5Fcodelineno-3-11) }, [](#%5F%5Fcodelineno-3-12) }, [](#%5F%5Fcodelineno-3-13) }, [](#%5F%5Fcodelineno-3-14)}
By default, the log level for Ruff is set to info
. To change the log level, you can set thelogLevel setting:
[](#%5F%5Fcodelineno-4-1)require('lspconfig').ruff.setup { [](#%5F%5Fcodelineno-4-2) init_options = { [](#%5F%5Fcodelineno-4-3) settings = { [](#%5F%5Fcodelineno-4-4) logLevel = 'debug', [](#%5F%5Fcodelineno-4-5) } [](#%5F%5Fcodelineno-4-6) } [](#%5F%5Fcodelineno-4-7)}
By default, Ruff 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 setting.
To view the trace logs between Neovim and Ruff, set the log level for Neovim's LSP client to debug
:
[](#%5F%5Fcodelineno-5-1)vim.lsp.set_log_level('debug')
With the conform.nvim plugin for Neovim.
[](#%5F%5Fcodelineno-6-1)require("conform").setup({ [](#%5F%5Fcodelineno-6-2) formatters_by_ft = { [](#%5F%5Fcodelineno-6-3) python = { [](#%5F%5Fcodelineno-6-4) -- To fix auto-fixable lint errors. [](#%5F%5Fcodelineno-6-5) "ruff_fix", [](#%5F%5Fcodelineno-6-6) -- To run the Ruff formatter. [](#%5F%5Fcodelineno-6-7) "ruff_format", [](#%5F%5Fcodelineno-6-8) -- To organize the imports. [](#%5F%5Fcodelineno-6-9) "ruff_organize_imports", [](#%5F%5Fcodelineno-6-10) }, [](#%5F%5Fcodelineno-6-11) }, [](#%5F%5Fcodelineno-6-12)})
With the nvim-lint plugin for Neovim.
[](#%5F%5Fcodelineno-7-1)require("lint").linters_by_ft = { [](#%5F%5Fcodelineno-7-2) python = { "ruff" }, [](#%5F%5Fcodelineno-7-3)}
With the ALE plugin for Neovim or Vim. Neovim (using Lua):
[](#%5F%5Fcodelineno-8-1)-- Linters [](#%5F%5Fcodelineno-8-2)vim.g.ale_linters = { python = { "ruff" } } [](#%5F%5Fcodelineno-8-3)-- Fixers [](#%5F%5Fcodelineno-8-4)vim.g.ale_fixers = { python = { "ruff", "ruff_format" } }
Vim (using Vimscript):
[](#%5F%5Fcodelineno-9-1)" Linters [](#%5F%5Fcodelineno-9-2)let g:ale_linters = { "python": ["ruff"] } [](#%5F%5Fcodelineno-9-3)" Fixers [](#%5F%5Fcodelineno-9-4)let g:ale_fixers = { "python": ["ruff", "ruff_format"] }
For the fixers, ruff
will run ruff check --fix
(to fix all auto-fixable problems) whereas ruff_format
will run ruff format
.
Vim
The vim-lsp plugin can be used to configure the Ruff Language Server in Vim. To set it up, install vim-lsp plugin and register the server using the following in your .vimrc
:
[](#%5F%5Fcodelineno-10-1)if executable('ruff') [](#%5F%5Fcodelineno-10-2) au User lsp_setup call lsp#register_server({ [](#%5F%5Fcodelineno-10-3) \ 'name': 'ruff', [](#%5F%5Fcodelineno-10-4) \ 'cmd': {server_info->['ruff', 'server']}, [](#%5F%5Fcodelineno-10-5) \ 'allowlist': ['python'], [](#%5F%5Fcodelineno-10-6) \ 'workspace_config': {}, [](#%5F%5Fcodelineno-10-7) \ }) [](#%5F%5Fcodelineno-10-8)endif
See the vim-lsp
documentation 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 by adding the following to the function s:on_lsp_buffer_enabled()
:
[](#%5F%5Fcodelineno-11-1)function! s:on_lsp_buffer_enabled() abort [](#%5F%5Fcodelineno-11-2) " add your keybindings here (see https://github.com/prabirshrestha/vim-lsp?tab=readme-ov-file#registering-servers) [](#%5F%5Fcodelineno-11-3) [](#%5F%5Fcodelineno-11-4) let l:capabilities = lsp#get_server_capabilities('ruff') [](#%5F%5Fcodelineno-11-5) if !empty(l:capabilities) [](#%5F%5Fcodelineno-11-6) let l:capabilities.hoverProvider = v:false [](#%5F%5Fcodelineno-11-7) endif [](#%5F%5Fcodelineno-11-8)endfunction
Ruff is also available as part of the coc-pyrightextension for coc.nvim.
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:
[](#%5F%5Fcodelineno-12-1)tools: [](#%5F%5Fcodelineno-12-2) python-ruff: [](#%5F%5Fcodelineno-12-3) lint-command: "ruff check --stdin-filename ${INPUT} --output-format concise --quiet -" [](#%5F%5Fcodelineno-12-4) lint-stdin: true [](#%5F%5Fcodelineno-12-5) lint-formats: [](#%5F%5Fcodelineno-12-6) - "%f:%l:%c: %m" [](#%5F%5Fcodelineno-12-7) format-command: "ruff format --stdin-filename ${INPUT} --quiet -" [](#%5F%5Fcodelineno-12-8) format-stdin: true
Helix
Open the language configuration file for Helix and add the language server as follows:
[](#%5F%5Fcodelineno-13-1)[language-server.ruff] [](#%5F%5Fcodelineno-13-2)command = "ruff" [](#%5F%5Fcodelineno-13-3)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
:
[](#%5F%5Fcodelineno-14-1)[[language]] [](#%5F%5Fcodelineno-14-2)name = "python" [](#%5F%5Fcodelineno-14-3)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:
[](#%5F%5Fcodelineno-15-1)[[language]] [](#%5F%5Fcodelineno-15-2)name = "python" [](#%5F%5Fcodelineno-15-3)language-servers = ["ruff", "pylsp"]
Note
Support for multiple language servers for a language is only available in Helix version23.10 and later.
If you want to, as an example, turn on auto-formatting, add auto-format = true
:
[](#%5F%5Fcodelineno-16-1)[[language]] [](#%5F%5Fcodelineno-16-2)name = "python" [](#%5F%5Fcodelineno-16-3)language-servers = ["ruff", "pylsp"] [](#%5F%5Fcodelineno-16-4)auto-format = true
See the Helix documentation for more settings you can use here.
You can pass settings into ruff server
using [language-server.ruff.config.settings]
. For example:
[](#%5F%5Fcodelineno-17-1)[language-server.ruff.config.settings] [](#%5F%5Fcodelineno-17-2)lineLength = 80 [](#%5F%5Fcodelineno-17-3) [](#%5F%5Fcodelineno-17-4)[language-server.ruff.config.settings.lint] [](#%5F%5Fcodelineno-17-5)select = ["E4", "E7"] [](#%5F%5Fcodelineno-17-6)preview = false [](#%5F%5Fcodelineno-17-7) [](#%5F%5Fcodelineno-17-8)[language-server.ruff.config.settings.format] [](#%5F%5Fcodelineno-17-9)preview = true
By default, the log level for Ruff is set to info
. To change the log level, you can set thelogLevel setting:
[](#%5F%5Fcodelineno-18-1)[language-server.ruff] [](#%5F%5Fcodelineno-18-2)command = "ruff" [](#%5F%5Fcodelineno-18-3)args = ["server"] [](#%5F%5Fcodelineno-18-4) [](#%5F%5Fcodelineno-18-5)[language-server.ruff.config.settings] [](#%5F%5Fcodelineno-18-6)logLevel = "debug"
You can also divert Ruff's logs to a separate file with the logFile setting.
To view the trace logs between Helix and Ruff, pass in the -v
(verbose) flag when starting Helix:
Kate
- Activate the LSP Client plugin.
- Setup LSP Client as desired.
- Finally, add this to
Settings
->Configure Kate
->LSP Client
->User Server Settings
:
[](#%5F%5Fcodelineno-20-1){ [](#%5F%5Fcodelineno-20-2) "servers": { [](#%5F%5Fcodelineno-20-3) "python": { [](#%5F%5Fcodelineno-20-4) "command": ["ruff", "server"], [](#%5F%5Fcodelineno-20-5) "url": "https://github.com/astral-sh/ruff", [](#%5F%5Fcodelineno-20-6) "highlightingModeRegex": "^Python$", [](#%5F%5Fcodelineno-20-7) "settings": {} [](#%5F%5Fcodelineno-20-8) } [](#%5F%5Fcodelineno-20-9) } [](#%5F%5Fcodelineno-20-10)}
See LSP Client documentation 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. As a workaround, you can use the python-lsp-serveralong with the python-lsp-ruff plugin to use Ruff alongside another language server. Note that this setup won't use the server settingsbecause the python-lsp-ruff plugin uses theruff
executable and not the language server.
Sublime Text
To use Ruff with Sublime Text, install Sublime Text's LSPand LSP-ruff package.
PyCharm
Via External Tool
Ruff can be installed as an External Toolin PyCharm. Open the Preferences pane, then navigate to "Tools", then "External Tools". From there, add a new tool with the following configuration:
Ruff should then appear as a runnable action:
Via third-party plugin
Ruff is also available as the Ruff plugin on the IntelliJ Marketplace (maintained by @koxudaxi).
Emacs
Ruff can be utilized as a language server via Eglot, which is in Emacs's core. To enable Ruff with automatic formatting on save, use the following configuration:
[](#%5F%5Fcodelineno-21-1)(add-hook 'python-mode-hook 'eglot-ensure) [](#%5F%5Fcodelineno-21-2)(with-eval-after-load 'eglot [](#%5F%5Fcodelineno-21-3) (add-to-list 'eglot-server-programs [](#%5F%5Fcodelineno-21-4) '(python-mode . ("ruff" "server"))) [](#%5F%5Fcodelineno-21-5) (add-hook 'after-save-hook 'eglot-format))
Ruff is available as flymake-ruff on MELPA:
[](#%5F%5Fcodelineno-22-1)(require 'flymake-ruff) [](#%5F%5Fcodelineno-22-2)(add-hook 'python-mode-hook #'flymake-ruff-load)
Ruff is also available as emacs-ruff-format:
[](#%5F%5Fcodelineno-23-1)(require 'ruff-format) [](#%5F%5Fcodelineno-23-2)(add-hook 'python-mode-hook 'ruff-format-on-save-mode)
Alternatively, it can be used via the Apheleia formatter library, by setting this configuration:
[](#%5F%5Fcodelineno-24-1);; Replace default (black) to use ruff for sorting import and formatting. [](#%5F%5Fcodelineno-24-2)(setf (alist-get 'python-mode apheleia-mode-alist) [](#%5F%5Fcodelineno-24-3) '(ruff-isort ruff)) [](#%5F%5Fcodelineno-24-4)(setf (alist-get 'python-ts-mode apheleia-mode-alist) [](#%5F%5Fcodelineno-24-5) '(ruff-isort ruff))
TextMate
Ruff is also available via the textmate2-ruff-linterbundle for TextMate.
Zed
Ruff is available as an extension for the Zed editor. To install it:
- Open the command palette with
Cmd+Shift+P
- Search for "zed: extensions"
- Search for "ruff" in the extensions list and click "Install"
To configure Zed to use the Ruff language server for Python files, add the following to your settings.json
file:
[](#%5F%5Fcodelineno-25-1){ [](#%5F%5Fcodelineno-25-2) "languages": { [](#%5F%5Fcodelineno-25-3) "Python": { [](#%5F%5Fcodelineno-25-4) "language_servers": ["ruff"] [](#%5F%5Fcodelineno-25-5) // Or, if there are other language servers you want to use with Python [](#%5F%5Fcodelineno-25-6) // "language_servers": ["pyright", "ruff"] [](#%5F%5Fcodelineno-25-7) } [](#%5F%5Fcodelineno-25-8) } [](#%5F%5Fcodelineno-25-9)}
To configure the language server, you can provide the server settingsunder the lsp.ruff.initialization_options.settings key:
[](#%5F%5Fcodelineno-26-1){ [](#%5F%5Fcodelineno-26-2) "lsp": { [](#%5F%5Fcodelineno-26-3) "ruff": { [](#%5F%5Fcodelineno-26-4) "initialization_options": { [](#%5F%5Fcodelineno-26-5) "settings": { [](#%5F%5Fcodelineno-26-6) // Ruff server settings goes here [](#%5F%5Fcodelineno-26-7) "lineLength": 80, [](#%5F%5Fcodelineno-26-8) "lint": { [](#%5F%5Fcodelineno-26-9) "extendSelect": ["I"], [](#%5F%5Fcodelineno-26-10) } [](#%5F%5Fcodelineno-26-11) } [](#%5F%5Fcodelineno-26-12) } [](#%5F%5Fcodelineno-26-13) } [](#%5F%5Fcodelineno-26-14) } [](#%5F%5Fcodelineno-26-15)}
Note
Support for multiple formatters for a given language is only available in Zed version0.146.0
and later.
You can configure Ruff to format Python code on-save by registering the Ruff formatter and enabling the format_on_save setting:
Zed 0.146.0+
[](#%5F%5Fcodelineno-27-1){ [](#%5F%5Fcodelineno-27-2) "languages": { [](#%5F%5Fcodelineno-27-3) "Python": { [](#%5F%5Fcodelineno-27-4) "language_servers": ["ruff"], [](#%5F%5Fcodelineno-27-5) "format_on_save": "on", [](#%5F%5Fcodelineno-27-6) "formatter": [ [](#%5F%5Fcodelineno-27-7) { [](#%5F%5Fcodelineno-27-8) "language_server": { [](#%5F%5Fcodelineno-27-9) "name": "ruff" [](#%5F%5Fcodelineno-27-10) } [](#%5F%5Fcodelineno-27-11) } [](#%5F%5Fcodelineno-27-12) ] [](#%5F%5Fcodelineno-27-13) } [](#%5F%5Fcodelineno-27-14) } [](#%5F%5Fcodelineno-27-15)}
You can configure Ruff to fix lint violations and/or organize imports on-save by enabling thesource.fixAll.ruff
and source.organizeImports.ruff
code actions respectively:
Zed 0.146.0+
[](#%5F%5Fcodelineno-28-1){ [](#%5F%5Fcodelineno-28-2) "languages": { [](#%5F%5Fcodelineno-28-3) "Python": { [](#%5F%5Fcodelineno-28-4) "language_servers": ["ruff"], [](#%5F%5Fcodelineno-28-5) "format_on_save": "on", [](#%5F%5Fcodelineno-28-6) "formatter": [ [](#%5F%5Fcodelineno-28-7) { [](#%5F%5Fcodelineno-28-8) "code_actions": { [](#%5F%5Fcodelineno-28-9) // Fix all auto-fixable lint violations [](#%5F%5Fcodelineno-28-10) "source.fixAll.ruff": true, [](#%5F%5Fcodelineno-28-11) // Organize imports [](#%5F%5Fcodelineno-28-12) "source.organizeImports.ruff": true [](#%5F%5Fcodelineno-28-13) } [](#%5F%5Fcodelineno-28-14) } [](#%5F%5Fcodelineno-28-15) ] [](#%5F%5Fcodelineno-28-16) } [](#%5F%5Fcodelineno-28-17) } [](#%5F%5Fcodelineno-28-18)}
Taken together, you can configure Ruff to format, fix, and organize imports on-save via the following settings.json
:
Note
For this configuration, it is important to use the correct order of the code action and formatter language server settings. The code actions should be defined before the formatter to ensure that the formatter takes care of any remaining style issues after the code actions have been applied.
Zed 0.146.0+
[](#%5F%5Fcodelineno-29-1){ [](#%5F%5Fcodelineno-29-2) "languages": { [](#%5F%5Fcodelineno-29-3) "Python": { [](#%5F%5Fcodelineno-29-4) "language_servers": ["ruff"], [](#%5F%5Fcodelineno-29-5) "format_on_save": "on", [](#%5F%5Fcodelineno-29-6) "formatter": [ [](#%5F%5Fcodelineno-29-7) { [](#%5F%5Fcodelineno-29-8) "code_actions": { [](#%5F%5Fcodelineno-29-9) "source.organizeImports.ruff": true, [](#%5F%5Fcodelineno-29-10) "source.fixAll.ruff": true [](#%5F%5Fcodelineno-29-11) } [](#%5F%5Fcodelineno-29-12) }, [](#%5F%5Fcodelineno-29-13) { [](#%5F%5Fcodelineno-29-14) "language_server": { [](#%5F%5Fcodelineno-29-15) "name": "ruff" [](#%5F%5Fcodelineno-29-16) } [](#%5F%5Fcodelineno-29-17) } [](#%5F%5Fcodelineno-29-18) ] [](#%5F%5Fcodelineno-29-19) } [](#%5F%5Fcodelineno-29-20) } [](#%5F%5Fcodelineno-29-21)}