跳到内容

配置 Ruff

Ruff 可以通过 pyproject.tomlruff.toml.ruff.toml 文件进行配置。

无论您是将 Ruff 用作代码检查工具 (linter)、代码格式化工具 (formatter) 还是两者并用,其底层的配置策略和语义都是相同的。

有关可用配置选项的完整列表,请参阅 设置 (Settings)

如果未指定,Ruff 的默认配置等同于

[tool.ruff]
# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".git-rewrite",
    ".hg",
    ".ipynb_checkpoints",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pyenv",
    ".pytest_cache",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    ".vscode",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "site-packages",
    "venv",
]

# Same as Black.
line-length = 88
indent-width = 4

# Assume Python 3.10
target-version = "py310"

[tool.ruff.lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
# McCabe complexity (`C901`) by default.
select = ["E4", "E7", "E9", "F"]
ignore = []

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[tool.ruff.format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"

# Enable auto-formatting of code examples in docstrings. Markdown,
# reStructuredText code/literal blocks and doctests are all supported.
#
# This is currently disabled by default, but it is planned for this
# to be opt-out in the future.
docstring-code-format = false

# Set the line length limit used when formatting code snippets in
# docstrings.
#
# This only has an effect when the `docstring-code-format` setting is
# enabled.
docstring-code-line-length = "dynamic"
# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".git-rewrite",
    ".hg",
    ".ipynb_checkpoints",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pyenv",
    ".pytest_cache",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    ".vscode",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "site-packages",
    "venv",
]

# Same as Black.
line-length = 88
indent-width = 4

# Assume Python 3.10
target-version = "py310"

[lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
# McCabe complexity (`C901`) by default.
select = ["E4", "E7", "E9", "F"]
ignore = []

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"

# Enable auto-formatting of code examples in docstrings. Markdown,
# reStructuredText code/literal blocks and doctests are all supported.
#
# This is currently disabled by default, but it is planned for this
# to be opt-out in the future.
docstring-code-format = false

# Set the line length limit used when formatting code snippets in
# docstrings.
#
# This only has an effect when the `docstring-code-format` setting is
# enabled.
docstring-code-line-length = "dynamic"

例如,以下配置会将 Ruff 配置为

[tool.ruff.lint]
# 1. Enable flake8-bugbear (`B`) rules, in addition to the defaults.
select = ["E4", "E7", "E9", "F", "B"]

# 2. Avoid enforcing line-length violations (`E501`)
ignore = ["E501"]

# 3. Avoid trying to fix flake8-bugbear (`B`) violations.
unfixable = ["B"]

# 4. Ignore `E402` (import violations) in all `__init__.py` files, and in selected subdirectories.
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["E402"]
"**/{tests,docs,tools}/*" = ["E402"]

[tool.ruff.format]
# 5. Use single quotes in `ruff format`.
quote-style = "single"
[lint]
# 1. Enable flake8-bugbear (`B`) rules, in addition to the defaults.
select = ["E4", "E7", "E9", "F", "B"]

# 2. Avoid enforcing line-length violations (`E501`)
ignore = ["E501"]

# 3. Avoid trying to fix flake8-bugbear (`B`) violations.
unfixable = ["B"]

# 4. Ignore `E402` (import violations) in all `__init__.py` files, and in selected subdirectories.
[lint.per-file-ignores]
"__init__.py" = ["E402"]
"**/{tests,docs,tools}/*" = ["E402"]

[format]
# 5. Use single quotes in `ruff format`.
quote-style = "single"

代码检查插件配置以子部分的形式表示,例如

[tool.ruff.lint]
# Add "Q" to the list of enabled codes.
select = ["E4", "E7", "E9", "F", "Q"]

[tool.ruff.lint.flake8-quotes]
docstring-quotes = "double"
[lint]
# Add "Q" to the list of enabled codes.
select = ["E4", "E7", "E9", "F", "Q"]

[lint.flake8-quotes]
docstring-quotes = "double"

Ruff 支持 pyproject.tomlruff.toml.ruff.toml 文件。这三种文件实现相同的架构(但在 ruff.toml.ruff.toml 版本中,省略了 [tool.ruff] 头部和 tool.ruff 部分前缀)。

有关可用配置选项的完整列表,请参阅 设置 (Settings)

配置文件发现

ESLint 类似,Ruff 支持分层配置。这意味着目录层级中“最接近”的配置文件将用于处理每个单独的文件,且配置文件中的所有路径(如 exclude 全局匹配模式、src 路径)均相对于包含该配置文件的目录进行解析。

这些规则有几个例外情况

  1. 在为给定路径定位“最接近”的 pyproject.toml 文件时,Ruff 会忽略任何缺少 [tool.ruff] 部分的 pyproject.toml 文件。
  2. 如果直接通过 --config 传递配置文件,这些设置将应用于所有被分析的文件,并且该配置文件中的任何相对路径(如 exclude 全局匹配模式或 src 路径)都将相对于当前工作目录进行解析。
  3. 如果文件系统中未找到配置文件,Ruff 将退回使用默认配置。如果存在用户特定的配置文件 ${config_dir}/ruff/pyproject.toml,则会使用该文件代替默认配置。其中 ${config_dir} 通过 etcetera 的基础策略确定,并且所有相对路径同样相对于当前工作目录进行解析。
  4. 任何在命令行中提供的支持配置文件的设置(例如通过 --select)都将覆盖每个已解析配置文件中的设置。

ESLint 不同,Ruff 不会跨配置文件合并设置;相反,它使用“最接近”的配置文件,并忽略所有父级配置文件。作为对这种隐式级联的替代,Ruff 支持 extend 字段,它允许您从另一个配置文件继承设置,如下所示

[tool.ruff]
# Extend the `pyproject.toml` file in the parent directory...
extend = "../pyproject.toml"

# ...but use a different line length.
line-length = 100
# Extend the `ruff.toml` file in the parent directory...
extend = "../ruff.toml"

# ...but use a different line length.
line-length = 100

上述所有规则同样适用于 pyproject.tomlruff.toml.ruff.toml 文件。如果 Ruff 在同一目录中检测到多个配置文件,.ruff.toml 的优先级高于 ruff.toml,而 ruff.toml 的优先级高于 pyproject.toml

推断 Python 版本

当没有任何已发现的配置指定 target-version 时,Ruff 将尝试退回并使用与附近 pyproject.tomlrequires-python 字段兼容的最低版本。此行为的规则如下

  1. 如果直接传递配置文件,Ruff 不会尝试推断缺失的 target-version
  2. 如果在文件系统层级中找到了配置文件,Ruff 将从与该配置文件位于同一目录中的 pyproject.toml 文件的 requires-python 字段中推断缺失的 target-version
  3. 如果我们使用 ${config_dir}/ruff/pyproject.toml 中的用户级配置,则当前工作目录的祖先目录中找到的第一个 pyproject.toml 文件中的 requires-python 字段,其优先级高于用户级配置中的 target-version
  4. 如果未找到任何配置文件,Ruff 将从当前工作目录的祖先目录中找到的第一个 pyproject.toml 文件中的 requires-python 字段推断 target-version

请注意,在最后两种情况下,Ruff 的行为可能会根据调用它时的工作目录而有所不同。

Python 文件发现

当在命令行中传入路径时,Ruff 会自动发现该路径下的所有 Python 文件,并考虑每个目录配置文件中的 excludeextend-exclude 设置。

通过将 exclude 设置限定在工具特定的配置表中,也可以选择性地将文件排除在代码检查或格式化之外。例如,以下配置将阻止 ruff 格式化 .pyi 文件,但仍会将其包含在代码检查中

[tool.ruff.format]
exclude = ["*.pyi"]
[format]
exclude = ["*.pyi"]

默认情况下,Ruff 还会跳过任何通过 .ignore.gitignore.git/info/exclude 以及全局 gitignore 文件忽略的文件(参见:respect-gitignore)。

直接传递给 ruff 的文件无论上述条件如何,始终会被分析,除非同时启用了 force-exclude(通过 CLI 或配置文件)。例如,如果未启用 force-excluderuff check /path/to/excluded/file.py 总是会对 file.py 进行检查。

默认包含规则

默认情况下,Ruff 会发现匹配 *.py*.pyi*.ipynbpyproject.toml 的文件。在 预览 (preview) 模式下,Ruff 默认还会发现 *.pyw 文件。

要对具有其他文件扩展名的文件进行检查或格式化,请使用 extend-include 设置。您也可以使用 include 设置来更改默认选择。

[tool.ruff]
include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py"]
include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py"]

警告

提供给 include 的路径必须匹配具体文件。例如,include = ["src"] 将会失败,因为它匹配的是一个目录。

Jupyter Notebook 发现

Ruff 内置支持检查和格式化 Jupyter Notebooks,从 0.6.0 及更高版本开始,默认会对它们进行检查和格式化。

如果您更倾向于只对 Jupyter Notebook 文件进行检查或只进行格式化,可以使用特定于部分的 exclude 选项。例如,以下配置将只检查而不格式化 Jupyter Notebook 文件

[tool.ruff.format]
exclude = ["*.ipynb"]
[format]
exclude = ["*.ipynb"]

反之,以下配置将只格式化而不检查 Jupyter Notebook 文件

[tool.ruff.lint]
exclude = ["*.ipynb"]
[lint]
exclude = ["*.ipynb"]

您可以通过更新 extend-exclude 设置来完全禁用 Jupyter Notebook 支持

[tool.ruff]
extend-exclude = ["*.ipynb"]
extend-exclude = ["*.ipynb"]

如果您想针对 Jupyter Notebook 文件专门忽略某些规则,可以使用 per-file-ignores 设置来实现

[tool.ruff.lint.per-file-ignores]
"*.ipynb" = ["T20"]
[lint.per-file-ignores]
"*.ipynb" = ["T20"]

某些规则在应用于 Jupyter Notebook 文件时表现不同。例如,应用于 .py 文件时,module-import-not-at-top-of-file (E402) 规则会检测文件顶部的导入,但对于 Notebook,它会检测单元格 (cell) 顶部的导入。对于给定的规则,其文档会明确说明当应用于 Jupyter Notebook 文件时,该规则是否具有不同的行为。

命令行界面

某些配置选项可以通过命令行上的专用标志提供或覆盖。这包括与规则启用/禁用、文件发现、日志级别等相关的选项

$ ruff check path/to/code/ --select F401 --select F403 --quiet

所有其他配置选项都可以使用 --config 标志通过命令行进行设置,详情如下。

--config 命令行标志

--config 标志有两个用途。它最常用于指定您希望 Ruff 使用的配置文件,例如

$ ruff check path/to/directory --config path/to/ruff.toml

然而,--config 标志也可以用于使用 TOML <KEY> = <VALUE> 键值对来提供任意的配置设置覆盖。这在您希望覆盖没有专用命令行标志的配置设置时非常有用。

在下面的示例中,--config 标志是从命令行覆盖 dummy-variable-rgx 配置设置的唯一方法,因为该设置没有专用的 CLI 标志。per-file-ignores 设置也可以通过 --per-file-ignores 专用标志进行覆盖,但使用 --config 来覆盖它也是可以的

$ ruff check path/to/file --config path/to/ruff.toml --config "lint.dummy-variable-rgx = '__.*'" --config "lint.per-file-ignores = {'some_file.py' = ['F841']}"

传递给 --config 的配置选项的解析方式与 ruff.toml 文件中的配置选项相同。因此,Ruff 代码检查器特有的选项需要以 lint. 为前缀(例如使用 --config "lint.dummy-variable-rgx = '__.*'" 而不是简单地使用 --config "dummy-variable-rgx = '__.*'"),Ruff 格式化工具特有的选项需要以 format. 为前缀。

如果某个特定的配置选项同时被专用标志和 --config 标志覆盖,则专用标志具有优先权。在此示例中,允许的最大行长度将被设置为 90,而不是 100

$ ruff format path/to/file --line-length=90 --config "line-length=100"

指定 --config "line-length=90" 将覆盖 Ruff 检测到的所有配置文件中的 line-length 设置,包括在子目录中发现的配置文件。在这方面,指定 --config "line-length=90" 的效果与指定 --line-length=90 相同,后者同样会覆盖 Ruff 检测到的所有配置文件中的 line-length 设置,无论特定的配置文件位于何处。

完整命令行界面

请参阅 ruff help 以获取 Ruff 顶层命令的完整列表

Ruff: An extremely fast Python linter and code formatter.

Usage: ruff [OPTIONS] <COMMAND>

Commands:
  check    Run Ruff on the given files or directories
  rule     Explain a rule (or all rules)
  config   List or describe the available configuration options
  linter   List all supported upstream linters
  clean    Clear any caches in the current directory and any subdirectories
  format   Run the Ruff formatter on the given files or directories
  server   Run the language server
  analyze  Run analysis over Python source code
  version  Display Ruff's version
  help     Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help (see more with '--help')
  -V, --version  Print version

Log levels:
  -v, --verbose  Enable verbose logging
  -q, --quiet    Print diagnostics, but nothing else
  -s, --silent   Disable all logging (but still exit with status code "1" upon
                 detecting diagnostics)

Global options:
      --config <CONFIG_OPTION>
          Either a path to a TOML configuration file (`pyproject.toml` or
          `ruff.toml`), or a TOML `<KEY> = <VALUE>` pair (such as you might
          find in a `ruff.toml` configuration file) overriding a specific
          configuration option. Overrides of individual settings using this
          option always take precedence over all configuration files, including
          configuration files that were also specified using `--config`
      --isolated
          Ignore all configuration files
      --color <WHEN>
          Control when colored output is used [possible values: auto, always,
          never]

For help with a specific command, see: `ruff help <command>`.

或者 ruff help check 以了解更多关于代码检查命令的信息

Run Ruff on the given files or directories

Usage: ruff check [OPTIONS] [FILES]...

Arguments:
  [FILES]...  List of files or directories to check, or `-` to read from stdin
              [default: .]

Options:
      --fix
          Apply fixes to resolve lint violations. Use `--no-fix` to disable or
          `--unsafe-fixes` to include unsafe fixes
      --unsafe-fixes
          Include fixes that may not retain the original intent of the code.
          Use `--no-unsafe-fixes` to disable
      --show-fixes
          Show an enumeration of all fixed lint violations. Use
          `--no-show-fixes` to disable
      --diff
          Avoid writing any fixed files back; instead, output a diff for each
          changed file to stdout, and exit 0 if there are no diffs. Implies
          `--fix-only`
  -w, --watch
          Run in watch mode by re-running whenever files change
      --fix-only
          Apply fixes to resolve lint violations, but don't report on, or exit
          non-zero for, leftover violations. Implies `--fix`. Use
          `--no-fix-only` to disable or `--unsafe-fixes` to include unsafe
          fixes
      --ignore-noqa
          Ignore any `# noqa` comments
      --output-format <OUTPUT_FORMAT>
          Output serialization format for violations. The default serialization
          format is "full" [env: RUFF_OUTPUT_FORMAT=] [possible values:
          concise, full, json, json-lines, junit, grouped, github, gitlab,
          pylint, rdjson, azure, sarif]
  -o, --output-file <OUTPUT_FILE>
          Specify file to write the linter output to (default: stdout) [env:
          RUFF_OUTPUT_FILE=]
      --target-version <TARGET_VERSION>
          The minimum Python version that should be supported [possible values:
          py37, py38, py39, py310, py311, py312, py313, py314, py315]
      --preview
          Enable preview mode; checks will include unstable rules and fixes.
          Use `--no-preview` to disable
      --extension <EXTENSION>
          List of mappings from file extension to language (one of `python`,
          `ipynb`, `pyi`). For example, to treat `.ipy` files as IPython
          notebooks, use `--extension ipy:ipynb`
      --statistics
          Show counts for every rule with at least one violation
      --add-noqa[=<REASON>]
          Enable automatic additions of `noqa` directives to failing lines.
          Optionally provide a reason to append after the codes
      --show-files
          See the files Ruff will be run against with the current settings
      --show-settings
          See the settings Ruff will use to lint a given Python file
  -h, --help
          Print help (see more with '--help')

Rule selection:
      --select <RULE_CODE>
          Comma-separated list of rule codes to enable (or ALL, to enable all
          rules)
      --ignore <RULE_CODE>
          Comma-separated list of rule codes to disable
      --extend-select <RULE_CODE>
          Like --select, but adds additional rule codes on top of those already
          specified
      --per-file-ignores <PER_FILE_IGNORES>
          List of mappings from file pattern to code to exclude
      --extend-per-file-ignores <EXTEND_PER_FILE_IGNORES>
          Like `--per-file-ignores`, but adds additional ignores on top of
          those already specified
      --fixable <RULE_CODE>
          List of rule codes to treat as eligible for fix. Only applicable when
          fix itself is enabled (e.g., via `--fix`)
      --unfixable <RULE_CODE>
          List of rule codes to treat as ineligible for fix. Only applicable
          when fix itself is enabled (e.g., via `--fix`)
      --extend-fixable <RULE_CODE>
          Like --fixable, but adds additional rule codes on top of those
          already specified

File selection:
      --exclude <FILE_PATTERN>
          List of paths, used to omit files and/or directories from analysis
      --extend-exclude <FILE_PATTERN>
          Like --exclude, but adds additional files and directories on top of
          those already excluded
      --respect-gitignore
          Respect file exclusions via `.gitignore` and other standard ignore
          files. Use `--no-respect-gitignore` to disable
      --force-exclude
          Enforce exclusions, even for paths passed to Ruff directly on the
          command-line. Use `--no-force-exclude` to disable

Miscellaneous:
  -n, --no-cache
          Disable cache reads [env: RUFF_NO_CACHE=]
      --cache-dir <CACHE_DIR>
          Path to the cache directory [env: RUFF_CACHE_DIR=]
      --stdin-filename <STDIN_FILENAME>
          The name of the file when passing it through stdin
  -e, --exit-zero
          Exit with status code "0", even upon detecting lint violations
      --exit-non-zero-on-fix
          Exit with a non-zero status code if any files were modified via fix,
          even if no lint violations remain

Log levels:
  -v, --verbose  Enable verbose logging
  -q, --quiet    Print diagnostics, but nothing else
  -s, --silent   Disable all logging (but still exit with status code "1" upon
                 detecting diagnostics)

Global options:
      --config <CONFIG_OPTION>
          Either a path to a TOML configuration file (`pyproject.toml` or
          `ruff.toml`), or a TOML `<KEY> = <VALUE>` pair (such as you might
          find in a `ruff.toml` configuration file) overriding a specific
          configuration option. Overrides of individual settings using this
          option always take precedence over all configuration files, including
          configuration files that were also specified using `--config`
      --isolated
          Ignore all configuration files
      --color <WHEN>
          Control when colored output is used [possible values: auto, always,
          never]

或者 ruff help format 以了解更多关于格式化命令的信息

Run the Ruff formatter on the given files or directories

Usage: ruff format [OPTIONS] [FILES]...

Arguments:
  [FILES]...  List of files or directories to format, or `-` to read from stdin
              [default: .]

Options:
      --check
          Avoid writing any formatted files back; instead, exit with a non-zero
          status code if any files would have been modified, and zero otherwise
      --diff
          Avoid writing any formatted files back; instead, exit with a non-zero
          status code and the difference between the current file and how the
          formatted file would look like
      --extension <EXTENSION>
          List of mappings from file extension to language (one of `python`,
          `ipynb`, `pyi`). For example, to treat `.ipy` files as IPython
          notebooks, use `--extension ipy:ipynb`
      --target-version <TARGET_VERSION>
          The minimum Python version that should be supported [possible values:
          py37, py38, py39, py310, py311, py312, py313, py314, py315]
      --preview
          Enable preview mode; enables unstable formatting. Use `--no-preview`
          to disable
      --output-format <OUTPUT_FORMAT>
          Output serialization format for violations, when used with `--check`.
          The default serialization format is "full" [env: RUFF_OUTPUT_FORMAT=]
          [possible values: concise, full, json, json-lines, junit, grouped,
          github, gitlab, pylint, rdjson, azure, sarif]
  -h, --help
          Print help (see more with '--help')

Miscellaneous:
  -n, --no-cache
          Disable cache reads [env: RUFF_NO_CACHE=]
      --cache-dir <CACHE_DIR>
          Path to the cache directory [env: RUFF_CACHE_DIR=]
      --stdin-filename <STDIN_FILENAME>
          The name of the file when passing it through stdin
      --exit-non-zero-on-format
          Exit with a non-zero status code if any files were modified via
          format, even if all files were formatted successfully

File selection:
      --respect-gitignore
          Respect file exclusions via `.gitignore` and other standard ignore
          files. Use `--no-respect-gitignore` to disable
      --exclude <FILE_PATTERN>
          List of paths, used to omit files and/or directories from analysis
      --force-exclude
          Enforce exclusions, even for paths passed to Ruff directly on the
          command-line. Use `--no-force-exclude` to disable

Format configuration:
      --line-length <LINE_LENGTH>  Set the line-length

Editor options:
      --range <RANGE>  When specified, Ruff will try to only format the code in
                       the given range.
                       It might be necessary to extend the start backwards or
                       the end forwards, to fully enclose a logical line.
                       The `<RANGE>` uses the format
                       `<start_line>:<start_column>-<end_line>:<end_column>`.

Log levels:
  -v, --verbose  Enable verbose logging
  -q, --quiet    Print diagnostics, but nothing else
  -s, --silent   Disable all logging (but still exit with status code "1" upon
                 detecting diagnostics)

Global options:
      --config <CONFIG_OPTION>
          Either a path to a TOML configuration file (`pyproject.toml` or
          `ruff.toml`), or a TOML `<KEY> = <VALUE>` pair (such as you might
          find in a `ruff.toml` configuration file) overriding a specific
          configuration option. Overrides of individual settings using this
          option always take precedence over all configuration files, including
          configuration files that were also specified using `--config`
      --isolated
          Ignore all configuration files
      --color <WHEN>
          Control when colored output is used [possible values: auto, always,
          never]

Shell 自动补全

Ruff 支持大多数 shell 的自动补全。特定于 shell 的补全脚本可以通过 ruff generate-shell-completion <SHELL> 生成,其中 <SHELL> 可以是 bashelvishfigfishpowershellzsh

提示

您可以运行 echo $SHELL 来帮助您确定您的 shell。

要为 Ruff 启用 shell 自动补全,请运行以下命令之一

echo 'eval "$(ruff generate-shell-completion bash)"' >> ~/.bashrc
echo 'eval "$(ruff generate-shell-completion zsh)"' >> ~/.zshrc
echo 'ruff generate-shell-completion fish | source' > ~/.config/fish/completions/ruff.fish
echo 'eval (ruff generate-shell-completion elvish | slurp)' >> ~/.elvish/rc.elv
if (!(Test-Path -Path $PROFILE)) {
  New-Item -ItemType File -Path $PROFILE -Force
}
Add-Content -Path $PROFILE -Value '(& ruff generate-shell-completion powershell) | Out-String | Invoke-Expression'

然后重新启动 shell 或加载 shell 配置文件。