docs: Update the formatting section for Python (#48904)

I have added the `code_actions_on_format` setting. I also temporarily
removed the mention of `"formatter": null`. Based on our findings in
#48600, its current behavior is inconsistent, so I've omitted it for now
to avoid confusing users. I will add it back once the underlying issue
is fixed (likely in a subsequent PR).

Closes #48600.

- [ ] Tests or screenshots needed?
- [x] Code Reviewed
- [x] Manual QA

Release Notes:

- N/A

---------

Co-authored-by: Kunall Banerjee <hey@kimchiii.space>
This commit is contained in:
Xin ZhaoandKunall Banerjee authored and GitHub committed 2026-02-11 08:33:41 +00:00
1 parent 38800907cc
commit 8f707653c2
1 file changed
+46 -21
+46 -21
View File
@@ -190,11 +190,54 @@ For most projects, Zed will automatically select the right Python toolchain. In
## Code Formatting & Linting
Zed provides the [Ruff](https://docs.astral.sh/ruff/) formatter and linter for Python code. (Specifically, Zed runs Ruff as an LSP server using the `ruff server` subcommand.) Both formatting and linting are enabled by default, including format-on-save.
Zed uses [Ruff](https://github.com/astral-sh/ruff) for formatting and linting Python code. Specifically, it runs Ruff as an LSP server using the `ruff server` subcommand.
### Configuring formatting
### Configuring Formatting
You can disable format-on-save for Python files in your `settings.json`:
Formatting in Zed follows a two-phase pipeline: first, code actions on format (`code_actions_on_format`) are executed, followed by the configured formatter:
```json [settings]
{
"languages": {
"Python": {
"code_actions_on_format": {
"source.organizeImports.ruff": true
},
"formatter": {
"language_server": {
"name": "ruff"
}
}
}
}
}
```
These two phases are independent. For example, if you prefer [Black](https://github.com/psf/black) for code formatting, but want to keep Ruff's import sorting, you only need to change the formatter phase:
```json [settings]
{
"languages": {
"Python": {
"code_actions_on_format": {
// Phase 1: Ruff still handles organize imports
"source.organizeImports.ruff": true
},
"formatter": {
// Phase 2: Black handles formatting
"external": {
"command": "black",
"arguments": ["--stdin-filename", "{buffer_path}", "-"]
}
}
}
}
}
```
To completely switch to another tool and prevent Ruff from modifying your code at all, you must explicitly set `source.organizeImports.ruff` to false in the `code_actions_on_format` section, in addition to changing the formatter.
To prevent any formatting actions when you save, you can disable format-on-save for Python files in your `settings.json`:
```json [settings]
{
@@ -206,24 +249,6 @@ You can disable format-on-save for Python files in your `settings.json`:
}
```
Alternatively, you can use the `black` command-line tool for Python formatting, while keeping Ruff enabled for linting:
```json [settings]
{
"languages": {
"Python": {
"formatter": {
"external": {
"command": "black",
"arguments": ["--stdin-filename", "{buffer_path}", "-"]
}
}
// Or use `"formatter": null` to disable formatting entirely.
}
}
}
```
### Configuring Ruff
Like basedpyright, Ruff reads options from both Zed's language server settings and configuration files (`ruff.toml`) when used in Zed. Unlike basedpyright, _all_ options can be configured in either of these locations, so the choice of where to put your Ruff configuration comes down to whether you want it to be shared between projects but specific to Zed (in which case you should use language server settings), or specific to one project but common to all Ruff invocations (in which case you should use `ruff.toml`).