Configure PyCharm and Neovim to ensure your develpment environment is consistent and your code style matches, regardless of which editor your choose.
Why?
A linter is a tool used in software development to analyze source code for errors, bugs, and stylistic issues. It helps improve code quality by flagging problems before the code is executed. Linters are essential for maintaining coding standards and ensuring that code is clean and maintainable.
When we program in python, although IDEs claim to follow PEP8, the reality is that PEP8 is a style guide, not a single software configuration.
Since I usually use PyCharm and Neovim as python IDEs, I, sometimes, encounter minor formatting style differences. These small differences slightly break the consistency between files/files projects and end up costing me some time to fix.
Ruff
PyCharm saves its configuration in the .idea/ folder or in its global settings. Neovim looks for standard configuration files in the project root. For consistency between linters, ideally both should read the same source of truth.
Ruff is currently the de facto standard because it replaces almost a dozen tools (flake8, isort, pydocstyle, etc.) and is faster because it’s written in Rust.
The plan is to keep Pyright for type analysis (where it excels) and add Ruff for linting and automatic formatting.
First off, let’s install Ruff:
pipx install ruff
Now, we uninstall python-lsp-server
pipx uninstall python-lsp-server
Create a common python standard
As we mentioned before, to ensure both IDEs behave the same, they should read the same font. To force both IDEs to follow the same rules, we need to configure our Ruff settings.
Configuring ruff
Ruff follows a specific hierarchy to resolve settings. It searches for a configuration file in the current directory and continues up the parent directories until it finds one.
Global Configuration (User-wide)
To apply rules to every Python project on your machine (as a fallback when no project-specific file exists), use the following directory: ~/.config/ruff/ with one of the following filenames:
settings.toml(Recommended)ruff.toml.ruff.toml
My settings.toml:
Do not use the [tool.ruff] header. Write properties directly at the root of the file.
Project Configuration
To apply rules to a specific project, place the file in the project’s root directory:
pyproject.toml(must use [tool.ruff] header and sections)ruff.tomlor.ruff.toml(direct properties, no headers)
My pyproject.toml:
Folder-Specific Configuration (Nested)
To override or extend rules for a specific subdirectory (e.g., allowing assert only in /tests or changing line lengths in /scripts), place a file inside that folder.
ruff.tomlor.ruff.toml
Configure Neovim
Instead of pylsp (which is heavier), the ideal solution is to use the new Ruff server.
Let’s add the following sections to our init.vim:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
local lspconfig = require('lspconfig')
lspconfig.ruff.setup({
on_attach = function(client, bufnr)
client.server_capabilities.hoverProvider = false
end,
})
lspconfig.pyright.setup({
settings = {
pyright = {
disableOrganizeImports = true,
},
python = {
analysis = {
ignore = { '*' },
},
},
},
})
Configure PyCharm
Starting in 2025.3, JetBrains included Ruff as a “Core” tool (native) through the Python LSP plugin (enabled by default).
To configure Ruff: Go to Settings (Ctrl+Alt+S) > Python > Tools > Ruff:
Select the
Enablecheckbox to start configuringRuffsettings.Interpreter mode: PyCharm searches for a
Ruffexecutable installed in your interpreter. To install theRuffpackage for the selected interpreter, clickInstall Ruff.Path mode: PyCharm searches for a
Ruffexecutable in$PATH. If the executable is not found, you can specify the path by clicking theBrowse...icon.Select which
Ruffoptions should be enabled.
JetBrains doc:
Thanks for reading! :)