ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Ruff Language Server 功能全解析:诊断、动态配置、格式化、代码操作与 Notebook 支持

2026/9/12 17:37:10 拓冰建站 浏览量
Ruff Language Server 功能全解析:诊断、动态配置、格式化、代码操作与 Notebook 支持 Ruff Language Server 功能全解析诊断、动态配置、格式化、代码操作与 Notebook 支持【免费下载链接】ruffAn extremely fast Python linter and code formatter, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ru/ruff导读RuffRust 编写的极速 Python linter 与代码格式化器内置了基于 Language Server ProtocolLSP的语言服务器ruff server为 VS Code、Neovim、Helix、Zed 等编辑器提供实时的诊断高亮、动态配置热更新、文档/选区格式化、代码操作Code Actions与 Hover 规则文档等能力。本文以官方文档 docs/editors/features.md 为骨架逐项拆解 Ruff Language Server 的核心功能并结合 crates/ruff_server 源码揭示各功能背后的实现原理与调用链帮助你彻底理解并善用这些能力。一、诊断高亮Diagnostic HighlightingRuff Language Server 会实时为你的 Python 代码提供诊断信息并直接在编辑器中高亮显示无需手动触发或保存文件。从实现上看诊断的生成由 crates/ruff_server/src/lint.rs 中的check函数负责它根据文档的语言类型分发到check_pythonPython 源码或check_tomlpyproject.toml/ruff.toml随后通过ruff_linter::linter::check_path执行完整的 lint 流程。该流程依次完成解析源码parse_unchecked_source只解析一次构建Locator将行列位置映射到字节切片与Stylist探测当前代码风格提取# noqa、# isort: skip等指令extract_directives解析区间抑制注释Suppressions::from_tokens最终调用check_path生成诊断并将内部诊断转换为 LSP 诊断to_lsp_diagnostic。值得注意的实现细节诊断被统一标记为DIAGNOSTIC_NAME Ruff见 crates/ruff_server/src/lib.rs编辑器可据此过滤若文档被exclude/extend-exclude规则排除则直接返回空诊断列表语法错误默认也会被展示但可通过设置控制是否显示show_syntax_errors。二、动态配置Dynamic Configuration2.1 配置热更新的触发机制当工作区内出现配置文件的变更——无论是pyproject.toml、ruff.toml还是.ruff.toml——Ruff Language Server 都会动态刷新诊断无需重启语言服务器或重载编辑器窗口。这一能力依赖编辑器提供的**文件监听file watching**能力通过 LSP 的workspace/didChangeWatchedFiles通知实现。对应的处理器位于 crates/ruff_server/src/server/api/notifications/did_change_watched_files.rs它先调用session.reload_settings重载配置索引然后根据客户端能力分两条路径刷新诊断若客户端支持workspace/diagnosticRefresh拉取式诊断发送刷新请求让编辑器重新拉取否则对所有已打开的文本文档逐一重新发布诊断publish_diagnostics_for_documentNotebook 文档不受 pull 诊断支持与否的影响始终会主动重新发布诊断。2.2 配置解析与优先级配置的解析与缓存由 crates/ruff_server/src/session/index/ruff_settings.rs 中的RuffSettingsIndex完成。服务器启动或工作区变更时会构建索引解析顺序为工作区根目录之上的祖先目录配置工作区根目录本身的配置工作区目录树内部各子目录的配置通过并行WalkBuilder遍历遵守.gitignore与exclude规则。每个文档通过get方法在索引中找到最近的祖先目录对应的配置找不到则回退到 fallback 配置用户级配置或编辑器设置。关于编辑器内多来源配置的优先级官方文档在 docs/editors/settings.md 中给出了从高到低的顺序具体设置项编辑器中单独定义的lineLength、lint.select等ruff.configuration编辑器提供的配置文件路径或内联 JSON 配置项目配置文件项目目录中的ruff.toml/pyproject.toml。三种来源的合并逻辑在EditorConfigurationTransformerruff_settings.rs中实现同时受configurationPreferenceEditorFirst/FilesystemFirst/EditorOnly控制。2.3 重要提示如果编辑器不支持文件监听服务器将无法感知配置文件变更也就无法自动刷新诊断——这是官方文档明确指出的限制若在工作区内解析配置出错服务器会通过客户端展示错误消息并回退到默认配置具体错误信息记录在日志中。三、格式化Formatting3.1 整文档与选区格式化Ruff Language Server 提供对 Python 代码的格式化能力支持格式化整个文档或特定行区间。VS Code扩展提供Ruff: Format Document命令格式化整个文档选中若干行后右键选择Format Selection即可触发选区格式化。其他支持 LSP 的编辑器可通过标准textDocument/formatting与textDocument/rangeFormatting请求接入。底层实现在 crates/ruff_server/src/format.rsformat负责整文档格式化根据文档类型分发Python 走format_module_sourceMarkdown 走format_code_blocks见下文TOML 文件则明确不支持格式化format_range负责区间格式化内部调用ruff_python_formatter::format_range若源码存在语法错误格式化不会报错中断而是记录警告并返回未变更FormatResult::Unchanged。3.2 格式化后端FormatBackend源码中定义了两种格式化后端format.rs后端说明Internal默认使用 Ruff 内置格式化器格式化器版本与 LSP 版本保持一致Uv调用外部uv format命令格式化器版本可能与 LSP 版本不同使用Uv后端时服务器会将行宽、缩进样式、引号风格、行尾、尾随逗号、--preview等选项逐一转换成uv format的命令行参数见UvFormatCommand::build_command。该后端依赖本机已安装uv且版本支持uv format否则会返回明确错误。3.3 Markdown 代码块格式化Ruff 的格式化器同样可以格式化 Markdown 文件中的 Python 代码块。VS Code 扩展为 Markdown 文件提供Format Document命令格式化代码块时沿用与普通 Python 文件完全相同的设置。需要特别注意的边界行为Ruff不会格式化 Markdown 文件的其他任何部分标题、正文、表格等一概不动如果你希望 Ruff 与另一个 Markdown 格式化扩展共存需要在 VS Code 中将其中一个设为默认格式化器再用Format Document With...或Ruff: Format document手动运行另一个Ruff 不支持 Markdown 文件的区间格式化若开启了 format-on-save建议按下面方式显式指定保存模式。将 Ruff 设为 Markdown 默认格式化器写入settings.json{ [markdown]: { editor.defaultFormatter: charliermarsh.ruff } }由于不支持区间格式化format-on-save 建议同时指定file模式{ [markdown]: { editor.formatOnSave: true, editor.formatOnSaveMode: file } }底层实现在 crates/ruff_markdown/src/lib.rs 的format_code_blocks它定位 Markdown 中的围栏代码块将language信息通过SourceType::get_source_type_by_extension判断是否为 Python 方言如python、py、pyi对命中者执行去缩进dedent、格式化、再回缩indent后写回。3.4 与格式化相关的配置格式化行为完全复用 Ruff 的标准格式化配置例如line-length默认 88控制换行阈值indent-style/indent-width缩进风格空格或 Tab与宽度quote-style引号风格double/singleline-ending行尾风格format.skip-magic-trailing-comma是否保留魔幻尾随逗号preview是否启用预览版格式化规则。这些选项可直接写在pyproject.toml的[tool.ruff.format]或ruff.toml中服务器会随动态配置机制即时生效。四、代码操作Code Actions代码操作是上下文敏感的修复建议通常通过快捷键或编辑器中的灯泡图标触发。Ruff Language Server 提供以下代码操作详见 crates/ruff_server/src/server/api/requests/code_action.rsQuick Fix快速修复为带有修复方案的诊断应用修复例如移除未使用的导入F401NoQA 抑制通过# noqa注释忽略某条诊断操作标题形如Ruff (F401): Disable for this lineFix all修复全部应用文档中所有可自动修复的问题source.fixAll.ruffOrganize imports整理导入整理文档中的导入source.organizeImports.ruff。这些代码操作的 LSPCodeActionKind常量定义在 crates/ruff_server/src/lib.rs同时为 Notebook 提供了notebook.source.fixAll.ruff与notebook.source.organizeImports.ruff变体。4.1 保存时自动修复与整理导入你可以让这些操作在保存文件时自动执行。例如在 VS Code 中实现保存时修复全部问题并整理导入在settings.json中加入{ [python]: { editor.codeActionsOnSave: { source.fixAll.ruff: explicit, source.organizeImports.ruff: explicit } } }注意对于 Notebook 单元格source.fixAll与source.organizeImports会被服务器忽略避免每个单元格并行请求导致同一编辑被重复应用客户端应改用notebook.source.*变体源码注释中对此有明确说明。4.2 修复安全性Fix SafetyRuff 的自动修复被标记为safe安全与unsafe不安全两类默认情况下Fix all 不会应用 unsafe 修复unsafe 修复仍可通过Quick fix手动逐条应用若要让 Fix all 也包含 unsafe 修复在 Ruff 配置文件中设置unsafe-fixes true也可在命令行使用--unsafe-fixes见 docs/configuration.md。从源码看修复安全性通过fix.applicability()判断to_lsp_diagnostic会把该修复是否安全is_preferred写入诊断的data字段quick_fix据此决定修复是否标记为首选操作resolve_edit_for_fix_all在批量修复时会过滤 unsafe 修复。4.3 修复的延迟解析对于 Fix all 与 Organize imports若编辑器支持codeAction/resolve延迟编辑解析服务器会先返回不带编辑的 Code Action待编辑器发起 resolve 请求时再计算具体编辑见fix_all/organize_imports中对code_action_deferred_edit_resolution的分支处理以减少不必要的计算。五、HoverNoQA 规则文档当你将鼠标悬停或通过快捷键聚焦在# noqa注释中的规则代码上时Ruff Language Server 会展示该规则的文档。实现位于 crates/ruff_server/src/server/api/requests/hover.rs流程如下仅对 Python 文档生效Markdown、TOML 直接返回空先检查悬停行是否包含#注释避免无谓地解析整个文档定位光标处的注释 token再用rule_identifier_range_at_offset找出悬停处的规则标识符通过Rule::from_code或Rule::from_name解析出规则生成包含如下内容的 Markdown 悬停文本规则名与代码如F401 unused-import来源 linter如 Derived from thePyflakeslinter.修复可用性Always / Sometimes 等若为预览规则提示 This rule is in preview and is not stable.规则的完整解释rule.explanation()。若悬停处的标识符无法匹配到规则则会返回{identifier}: Rule not found的提示文本。六、Jupyter Notebook 支持与 Ruff CLI 一致Ruff Language Server完整支持 Jupyter Notebook 文件.ipynb并具备与普通 Python 文件相同的全部能力——诊断、格式化、代码操作等均可在 Notebook 中生效。自 Ruff 0.6.0 起原生语言服务器默认发现并 lint / 格式化.ipynb文件关于 Notebook 的发现与配置细节可参考 docs/configuration.md 中的 Jupyter Notebook discovery 小节从源码看服务器专门实现了did_open_notebook、did_change_notebook、did_close_notebook通知见 crates/ruff_server/src/server/api/notificationsNotebook 诊断会被映射到具体单元格cell_uri_by_index格式化与代码操作也提供了对应的notebook.source.*变体。七、使用前提与注意事项定位Ruff Language Server 内置于ruffCLI通过ruff server启动实现了 LSP 协议它于 Ruff v0.4.5 以 beta 形式推出并在 v0.5.3 稳定参见 docs/editors/index.md。旧版 Python 实现的ruff-lsp已被其取代。与其他 Python 语言服务器协同目前 Ruff Language Server 聚焦于诊断、修复与格式化导航、补全等能力需配合其他 Python 语言服务器如 Pylance、pyright、jedi-language-server共同使用。编辑器依赖动态配置刷新依赖编辑器的文件监听能力不支持文件监听的编辑器无法自动感知配置变更。格式化边界Markdown 仅格式化 Python 代码块且不支持区间格式化TOML 文件不支持格式化。结语Ruff Language Server 将 linter、formatter 与编辑器体验深度整合实时的诊断高亮、配置热更新、安全修复分级、NoQA 悬停文档以及完整的 Notebook 支持构成了一个围绕 Python 开发的高效闭环。通过结合 crates/ruff_server 源码你可以看到每个功能背后清晰的 LSP 请求/通知处理器与底层 lint、格式化调用链这也有助于你在遇到编辑器行为异常时快速定位问题如配置解析失败、uv 后端缺失、Notebook 修复重复应用等。【免费下载链接】ruffAn extremely fast Python linter and code formatter, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ru/ruff创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考