第100章 Zed 编辑器 Python 开发指南(第100章)
Zed 原生支持 Python。
- Tree-sitter:tree-sitter-python
- Language Server:
- 调试适配器:debugpy
安装 Python
开始之前,你需要先安装好 Zed 和 Python。
第 1 步:安装 Python
Zed 不内置 Python 运行时,需要你自行安装,可以从以下方式中选择:
- uv(推荐)
curl -LsSf https://astral.sh/uv/install.sh | sh
详情请参阅 Astral 的安装指南。
- Homebrew:
brew install python
- Python.org 安装包:从 python.org/downloads 下载最新版本。
第 2 步:验证 Python 安装
确认 Python 已安装并可在终端中使用:
python3 --version
你应该会看到类似 Python 3.x.x 的输出。
在 Zed 中打开第一个 Python 项目
Zed 和 Python 都安装好后,打开一个包含 Python 代码的文件夹即可开始工作。
第 1 步:用 Zed 打开 Python 项目
启动 Zed,在菜单栏选择 File > Open Folder,或者在终端中运行:
zed path/to/your/project
Zed 会通过内置的 tree-sitter-python 解析器自动识别 .py 文件,无需安装插件或手动配置。
第 2 步:使用集成终端(可选)
Zed 自带集成终端,位于底部面板。若 Zed 检测到项目正在使用 虚拟环境,在新建的终端中会自动激活该环境。你可以通过 detect_venv 设置项来配置这一行为。
在 Zed 中配置 Python 语言服务器
Zed 内置了多个 Python 语言服务器。默认情况下,basedpyright 是主要的语言服务器,而 Ruff 用于代码格式化和静态检查。
其他内置的语言服务器包括:
- ty—Astral 推出的一款新兴语言服务器,以高性能著称。
- Pyright—basedpyright 的基石。
- PyLSP—基于插件的语言服务器,可集成
pycodestyle、autopep8和yapf等工具。
这些服务器默认处于禁用状态,但可以在设置中启用。
你可以在设置中({#kb zed::OpenSettings})通过“语言 > Python”选项来配置语言服务器,或者在设置文件中添加以下配置:
{
"languages": {
"Python": {
"language_servers": [
// 启用 ty,禁用 basedpyright,
// 并启用其他所有已注册的语言服务器(ruff, pylsp, pyright)。
"ty",
"!basedpyright",
"..."
]
}
}
}
有关启用和禁用语言服务器的更多信息,请参阅:使用语言服务器。
Basedpyright
自 Zed v0.204.0 版本起,basedpyright 成为 Zed 的主要 Python 语言服务器。它提供导航(跳转到定义/查找所有引用)和类型检查等核心语言服务器功能。与 Pyright 相比,它增加了对更多语言服务器功能(如内嵌提示)及检查规则的支持。
需要注意的是,基于默认的 basedpyright 配置,其类型检查模式为 recommended;但 Zed 默认将其设置为较宽松的 standard 模式,以与 Pyright 的行为保持一致。你可以通过在 pyrightconfig.json 或 pyproject.toml 中设置 typeCheckingMode 来覆盖 Zed 的默认值,从而指定项目的类型检查模式。更多内容请继续阅读关于 basedpyright 配置的详细说明。
Basedpyright 配置
basedpyright 从两种不同来源读取配置项:
- 语言服务器设置(即“工作区配置”):这类设置必须针对特定编辑器进行配置(在 Zed 中通过
settings.json实现),但会对该编辑器中打开的所有项目生效。 - 配置文件(
pyrightconfig.json、pyproject.toml):这类配置独立于编辑器,仅对其所在的项目生效。
通常的规则是:仅在编辑器中使用 basedpyright 时相关的选项,必须设置在语言服务器设置中;而即使作为命令行工具运行也相关的选项,则必须设置在配置文件中。内嵌提示(inlay hints)相关的设置属于前者,诊断类别设置则属于后者。
下文提供了这两种配置类型的示例。关于可用选项的完整列表,请参阅 basedpyright 文档中关于语言服务器设置和配置文件的部分。
语言服务器设置
在 Zed 中,basedpyright 的语言服务器设置可以在 settings.json 的 lsp 部分进行配置。
例如,若想要:
- 诊断工作区中的所有文件,而非默认的仅诊断当前打开的文件
- 禁用函数参数的内嵌提示
可以使用以下配置:
{
"lsp": {
"basedpyright": {
"settings": {
"basedpyright": {
"analysis": {
"diagnosticMode": "workspace",
"inlayHints": {
"callArgumentNames": false
}
}
}
}
}
}
}
为了兼容旧配置,Zed 也支持在 settings 中将 basedpyright.analysis 作为顶层键。
配置文件
basedpyright 会从 pyrightconfig.json 配置文件以及 pyproject.toml 清单中的 [tool.basedpyright] 和 [tool.pyright] 段读取项目级配置。如果两处都存在配置,pyrightconfig.json 会覆盖 pyproject.toml。
下面是一个 pyrightconfig.json 示例,它让 basedpyright 使用 strict 类型检查模式,并且不对 __pycache__ 目录下的任何文件发出诊断:
{
"typeCheckingMode": "strict",
"ignore": ["**/__pycache__"]
}
PyLSP
python-lsp-server(通常称为 PyLSP)默认集成了许多外部工具(autopep8、mccabe、pycodestyle、yapf),另一些则是可选的,需要显式启用并配置(flake8、pylint)。
详情请参阅 Python Language Server Configuration。
虚拟环境
虚拟环境可以为特定项目固定 Python 版本和一组依赖,并与同一台机器上的其他项目相互隔离。Zed 内置了对虚拟环境的发现、配置和激活支持,其基础是与具体语言无关的 toolchain(工具链) 概念。
注意,如果你装有全局 Python,它同样会被 Zed 视为一个工具链。
创建虚拟环境
如果项目尚未配置虚拟环境,可以按以下命令创建一个:
python3 -m venv .venv
或者,如果你使用的是 uv,首次运行 uv sync 时会自动创建虚拟环境。
Zed 如何使用 Python 工具链
Zed 会以以下方式使用你项目选定的 Python 工具链:
- 内置的 language server 会自动配置为该工具链 Python 解释器的路径,若适用,还会包含虚拟环境路径。这很重要,因为它能确保依赖项解析正常。(目前,扩展提供的 language server 尚不支持这种自动配置。)
- Python 任务(如 pytest 测试)会使用工具链中的 Python 解释器运行。
- 如果工具链是虚拟环境,在 Zed 集成终端中启动新 shell 时,会自动执行该环境的激活脚本,让你方便地访问选定的 Python 解释器和依赖集。
- 如果当前激活的虚拟环境中已安装内置 language server,则会使用其二进制文件,而非 Zed 自动安装的私有版本。debugpy 也遵循此规则。
选择工具链
对于大多数项目,Zed 会自动选择正确的 Python 工具链。在包含多个虚拟环境的复杂项目中,可能需手动覆盖此选择。你可以使用工具链选择器,从 Zed 发现的列表中选择工具链;若列表中未包含所需工具链,可手动指定其路径。
代码格式化与 Lint 检查
Zed 使用 Ruff 对 Python 代码进行格式化和 lint 检查。具体而言,它通过 ruff server 子命令将 Ruff 作为 LSP server 运行。
配置格式化
Zed 中的格式化遵循两阶段流水线:首先执行格式化时的 code actions(code_actions_on_format),然后运行配置的 formatter。
在 Settings({#kb zed::OpenSettings})的 Languages > Python 下配置格式化,或在你的 settings 文件中添加:
{
"languages": {
"Python": {
"code_actions_on_format": {
"source.organizeImports.ruff": true
},
"formatter": {
"language_server": {
"name": "ruff"
}
}
}
}
}
这两个阶段相互独立。例如,如果你更喜欢用 Black 进行代码格式化,但想保留 Ruff 的导入排序功能,只需更改格式化阶段的配置即可。
在设置中({#kb zed::OpenSettings})的 Languages > Python 下进行配置,或者添加到你的设置文件中:
{
"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}", "-"]
}
}
}
}
}
如果你想完全切换到其他工具,并防止 Ruff 修改你的代码,除了更改格式化器,还必须在 code_actions_on_format 部分中显式地将 source.organizeImports.ruff 设置为 false。
若要禁止保存时触发任何格式化操作,可以禁用 Python 文件的保存时格式化功能。
在设置中({#kb zed::OpenSettings})的 Languages > Python 下进行配置,或者添加到你的设置文件中:
{
"languages": {
"Python": {
"format_on_save": "off"
}
}
}
配置 Ruff
与 basedpyright 类似,当在 Zed 中使用 Ruff 时,它从 Zed 的语言服务器设置和配置文件(ruff.toml)中读取选项。与 basedpyright 不同,Ruff 的所有选项都可以在这两个位置配置。因此,决定在哪里放置 Ruff 配置的关键在于你的需求:如果希望配置在不同项目间共享但专用于 Zed,应使用语言服务器设置;如果希望配置专用于特定项目但适用于所有 Ruff 调用,应使用 ruff.toml。
下面是在 Zed 的 settings.json 中通过语言服务器设置,禁用 Zed 中所有 Ruff lint(同时仍保留 Ruff 作为格式化工具)的示例:
{
"lsp": {
"ruff": {
"initialization_options": {
"settings": {
"exclude": ["*"]
}
}
}
}
}
下面是一个包含 lint 和格式化配置的 ruff.toml 示例,改编自 Ruff 官方文档:
[lint]
# 不强制检查行长违规(`E501`)
ignore = ["E501"]
[format]
# 格式化时使用单引号。
quote-style = "single"
更多细节请参阅 Ruff 文档中关于配置文件、语言服务器设置以及完整选项列表的说明。
嵌入式语言高亮
Zed 支持为 Python 字符串中嵌入的代码提供语法高亮,只需在前面加一条标注语言名称的注释即可。
# sql
query = "SELECT * FROM users"
#sql
query = """
SELECT *
FROM users
"""
result = func( #sql
"SELECT * FROM users"
)
调试
Zed 通过 debugpy 适配器支持 Python 调试。你可以零配置直接启动,也可以在 .zed/debug.json 中定义自定义启动配置。
零配置启动调试
Zed 能自动检测可调试的 Python 入口点。按下 F4(或在命令面板中运行 debugger: start),即可查看当前项目可用的调试选项。 支持以下场景:
- Python 脚本
- 模块
- pytest 测试
Zed 底层使用 debugpy,但无需手动配置适配器。
定义自定义调试配置
如果需要可复用的调试配置,可以在项目根目录创建 .zed/debug.json 文件,这样能更精细地控制 Zed 如何运行和调试你的代码。
调试当前文件
[
{
"label": "Python Active File",
"adapter": "Debugpy",
"program": "$ZED_FILE",
"request": "launch"
}
]
该配置运行编辑器中当前打开的文件。
调试 Flask 应用
对于使用 Flask 的项目,可以定义完整的启动配置:
.venv/
app/
init.py
main.py
routes.py
templates/
index.html
static/
style.css
requirements.txt
……可以使用以下配置:
[
{
"label": "Python: Flask",
"adapter": "Debugpy",
"request": "launch",
"module": "app",
"cwd": "$ZED_WORKTREE_ROOT",
"env": {
"FLASK_APP": "app",
"FLASK_DEBUG": "1"
},
"args": [
"run",
"--reload", // 启用 Flask 重载器,监听文件变更
"--debugger" // 启用 Flask 调试器
],
"autoReload": {
"enable": true
},
"jinja": true,
"justMyCode": true
}
]
这些配置项可组合使用,以便针对 Web 服务器、测试运行器或自定义脚本调整体验。
调试 Django 应用
对于使用 Django 且结构类似下列示例的项目:
my_django_project/
manage.py
…
my_django_app/
migrations/
templates/
models.py
urls.py
…
……可以使用以下配置:
[
{
"label": "Python: Django",
"adapter": "Debugpy",
"request": "launch",
"program": "manage.py",
"args": ["runserver"],
"django": true
}
]
故障排除
Zed 中 Python 相关的问题通常涉及虚拟环境、语言服务器或工具配置。
解决语言服务器启动问题
如果语言服务器无响应,或诊断、自动补全等功能不可用:
- 查看 Zed 日志(使用 {#action zed::OpenLog} 操作),查找与正在使用的语言服务器相关的错误。如果语言服务器完全无法启动,这里通常会提供有用的信息。
- 使用语言服务器日志视图了解受影响语言服务器的生命周期。可通过 {#action dev::OpenLanguageServerLogs} 操作,或点击状态栏中的闪电图标并选择语言服务器来访问该视图。此视图中最有用的数据包括:
- “服务器日志”,显示语言服务器输出的任何错误
- “服务器信息”,显示语言服务器启动的相关详情
- 检查
settings.json或pyrightconfig.json的语法是否正确。 - 重启 Zed 以重新初始化语言服务器连接,或使用 {#action editor::RestartLanguageServer} 操作尝试重启语言服务器。
如果语言服务器无法解析导入,且正在使用虚拟环境,请确保在选择器中选中了正确的环境。可通过“服务器信息”视图确认 Zed 发送给语言服务器的虚拟环境——查看末尾的 * Configuration 部分即可。