Zed 配置 Swift / iOS 开发

Zed 配置 Swift / iOS 开发笔记

记录日期:2026-07-13

本文记录在 macOS 上使用 Zed 开发 Swift / iOS 项目的配置、原理,以及本次 import UIKit 无法跳转问题的定位过程。

1. 目标

在 Zed 中获得基础 Swift / iOS 开发能力:

  • Swift 语法高亮、补全和错误诊断
  • Cmd+Click 跳转项目内和系统框架中的定义
  • 使用 Zed Task 构建、测试和运行 Swift 项目

Zed 是编辑器,不负责理解完整的 Swift 编译环境。Swift 语义分析由 SourceKit-LSP 负责;Xcode 工程还需要向 SourceKit-LSP 提供真实的编译参数。

2. 整体工作原理

text 复制代码
Zed
 │  LSP 协议:补全、诊断、跳转定义
 ▼
SourceKit-LSP
 │  需要知道 Swift 文件如何被 Xcode 编译
 ▼
xcode-build-server
 │  提供 workspace、scheme、SDK、target、framework、index store
 ▼
Xcode 工程 + .compile 编译数据库
配置/工具 作用 与跳转的关系
Swift Zed 扩展 Swift 语法和 SourceKit-LSP 注册 必需
SourceKit-LSP Swift 语义分析、补全、诊断、跳转 直接负责
settings.json 告诉 Zed 启动哪个 LSP 只负责启动
buildServer.json 指定 Xcode 工程和 scheme 必需
.compile 保存真实 Swift 编译参数 最关键
Index.noindex/DataStore Xcode 的符号索引 影响跨文件跳转
tasks.json 构建、测试、运行任务 与跳转无关
keymap.json 任务快捷键 与跳转无关

3. 本次环境

text 复制代码
Zed                  1.10.3
Xcode                26.5 (Build 17F42)
Swift                6.3.2
xcode-build-server   1.3.0

检查工具链:

bash 复制代码
xcode-select -p
xcrun --find sourcekit-lsp
xcodebuild -version
swift --version

sourcekit-lsp 应来自当前 Xcode:

text 复制代码
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp

如果当前 Xcode 选择错误:

bash 复制代码
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

4. 安装 Swift 支持

4.1 Swift Zed 扩展

打开 Swift 文件后,Zed 会使用 Swift 扩展。当前扩展配置中注册了:

toml 复制代码
[language_servers.sourcekit-lsp]
language = "Swift"

扩展文件位于:

text 复制代码
~/Library/Application Support/Zed/extensions/installed/swift/extension.toml

4.2 安装 xcode-build-server

bash 复制代码
brew install xcode-build-server

它不是 Swift 编译器,也不是另一个 LSP;它负责把 Xcode 工程的编译信息转给 SourceKit-LSP。

5. Zed 全局设置

配置文件:

text 复制代码
~/.config/zed/settings.json

本次的关键配置:

jsonc 复制代码
{
  "lsp": {
    "sourcekit-lsp": {
      "binary": {
        "path": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp"
      }
    }
  },
  "languages": {
    "Swift": {
      "enable_language_server": true,
      "language_servers": ["sourcekit-lsp"],
      "formatter": "language_server",
      "format_on_save": "on",
      "tab_size": 2
    }
  }
}

配置项说明:

  • binary.path:指定使用哪个 SourceKit-LSP。它只解决"启动哪个 LSP",不包含 Xcode 工程编译参数。
  • enable_language_server:开启 Swift 的补全、诊断和跳转能力。
  • language_servers:指定 Swift 使用扩展注册的 sourcekit-lsp
  • formatter:使用语言服务器格式化代码。
  • format_on_save:保存时自动格式化;和跳转无关。
  • tab_size:编辑器缩进宽度;和编译、LSP 无关。

JSONC 注意事项

Zed 设置文件支持注释,但本机配置曾因尾逗号导致解析失败。配置解析失败时,Zed 可能继续运行,但部分设置会被忽略。当前配置已经整理为没有尾逗号的 JSONC。

6. Xcode 工程配置

本项目 iOS 工程目录:

text 复制代码
/Users/zzb/AndroidStudioProjects/coowise2/demos/ios

进入目录:

bash 复制代码
cd /Users/zzb/AndroidStudioProjects/coowise2/demos/ios

6.1 生成 buildServer.json

bash 复制代码
xcode-build-server config \
  -workspace CoowiseDemoVideo.xcworkspace \
  -scheme DemoCoowise

它会记录 workspace、DerivedData、scheme 等信息,但不会保证已经拥有每个 Swift 文件的完整编译命令。

6.2 生成 .compile

使用完整的 Xcode 编译日志:

bash 复制代码
xcodebuild \
  -workspace CoowiseDemoVideo.xcworkspace \
  -scheme DemoCoowise \
  -sdk iphonesimulator \
  -destination 'generic/platform=iOS Simulator' \
  clean build -verbose \
  2>&1 | tee /tmp/coowise-xcodebuild.log >/dev/null

解析日志:

bash 复制代码
xcode-build-server parse /tmp/coowise-xcodebuild.log

会生成或更新:

text 复制代码
demos/ios/.compile
demos/ios/buildServer.json

.compile 中应该出现类似参数:

text 复制代码
-sdk .../iPhoneSimulator26.5.sdk
-target arm64-apple-ios15.0-simulator
-I .../Build/Products/Debug-iphonesimulator
-F .../Build/Products/Debug-iphonesimulator
-index-store-path .../Index.noindex/DataStore

不要手工编辑 .compile。切换 Xcode、SDK、scheme、Debug/Release、架构或依赖后,应重新构建并解析日志。

7. UIKit 无法跳转的根因

最初的 .compile 实际内容是:

json 复制代码
[]

没有真实编译参数时,xcode-build-server 退回到默认推断,并给 SourceKit-LSP 传入了:

text 复制代码
-sdk .../MacOSX.sdk

UIKit 是 iOS / iOS Simulator SDK 的模块,不是 macOS SDK 的模块,因此 SourceKit-LSP 报错:

text 复制代码
no such module 'UIKit'

结果就是:

  • import UIKit 无法正确解析
  • UIViewControllerUILabel 无法跳转
  • 项目内跨文件类型无法跳转
  • 当前文件内的简单声明可能仍然可以跳转

重新解析 iOS 编译日志后,.compile 使用了 iPhoneSimulator26.5.sdkapple-ios15.0-simulator 和正确的 index store,SourceKit-LSP 已经可以跳转 UIKitUIViewControllerUILabelDemoThemeMineViewController

真正解决问题的关键是:

text 复制代码
正确的 .compile 编译数据库
+
正确的 iPhone Simulator SDK
+
重启 SourceKit-LSP

import UIKit 和具体类型

UIKit 是模块名,不是普通项目源文件。跳转时可能进入生成的:

text 复制代码
UIKit.swiftinterface

验证配置时,建议优先点击:

swift 复制代码
final class MineViewController: UIViewController {
    let label = UILabel()
}

分别测试 UIViewControllerUILabel 和项目内的 DemoTheme

8. Zed Task 配置

配置文件:

text 复制代码
~/.config/zed/tasks.json

8.1 Swift Build

作用:构建 iOS Demo 工程。

json 复制代码
{
  "label": "Swift Build",
  "command": "xcodebuild",
  "args": [
    "-workspace", "CoowiseDemoVideo.xcworkspace",
    "-scheme", "DemoCoowise",
    "-configuration", "Debug",
    "-sdk", "iphonesimulator",
    "-destination", "generic/platform=iOS Simulator",
    "build"
  ],
  "cwd": "$ZED_WORKTREE_ROOT/demos/ios",
  "env": {
    "DEVELOPER_DIR": "/Applications/Xcode.app/Contents/Developer"
  }
}

8.2 Swift Test

作用:运行 Swift Package 测试。

json 复制代码
{
  "label": "Swift Test",
  "command": "swift",
  "args": ["test"],
  "cwd": "$ZED_WORKTREE_ROOT/sdk/ios"
}

8.3 Swift Run

作用:运行 Swift Package executable。

json 复制代码
{
  "label": "Swift Run",
  "command": "swift",
  "args": ["run"],
  "cwd": "$ZED_WORKTREE_ROOT/native/ios-screen-capture"
}

这些 Task 只负责构建、测试和运行,与 LSP 跳转没有直接关系。

9. 快捷键配置

配置文件:

text 复制代码
~/.config/zed/keymap.json

本次绑定:

快捷键 任务
Cmd+Shift+B Swift Build
Cmd+Shift+T Swift Test
Cmd+Shift+R Swift Run
Space S B Swift Build,Vim normal 模式
Space S T Swift Test,Vim normal 模式
Space S R Swift Run,Vim normal 模式

快捷键只是调用 Task,不参与 LSP 跳转。

10. 本地排除规则

以下两个文件包含本机绝对路径,不适合提交:

text 复制代码
demos/ios/.compile
demos/ios/buildServer.json

当前已经写入本机 Git 排除文件:

text 复制代码
.git/info/exclude

排除规则:

gitignore 复制代码
/demos/ios/.compile
/demos/ios/buildServer.json

它们会继续留在本机并供 Zed 使用,但不会出现在 git status 中,也不会影响团队共享的 .gitignore

如果删除了这两个文件,需要重新执行第 6 节的生成命令。

11. 日常验证流程

11.1 验证 SourceKit-LSP 路径

bash 复制代码
xcrun --find sourcekit-lsp

11.2 验证 Xcode 工程可以构建

bash 复制代码
cd /Users/zzb/AndroidStudioProjects/coowise2/demos/ios
xcodebuild \
  -workspace CoowiseDemoVideo.xcworkspace \
  -scheme DemoCoowise \
  -sdk iphonesimulator \
  -destination 'generic/platform=iOS Simulator' \
  build -quiet

11.3 验证 Swift Package 测试

bash 复制代码
cd /Users/zzb/AndroidStudioProjects/coowise2/sdk/ios
swift test --quiet

11.4 重启 Zed 语言服务器

在 Zed 中执行:

text 复制代码
Cmd + Shift + P
→ editor: restart language server

如果刚更新了 .compile,这一步很重要,因为编译参数通常在语言服务器启动时读取。

12. 常见问题排查

没有补全、诊断和跳转

依次检查:

  1. Swift 扩展是否安装
  2. settings.json 是否解析失败
  3. xcrun --find sourcekit-lsp 是否指向当前 Xcode
  4. Zed 是否启用了 Swift language server
  5. 是否重启过 language server

出现 no such module 'UIKit'

检查 .compile 中是否出现:

text 复制代码
iPhoneSimulator.platform
iPhoneSimulator26.5.sdk
apple-ios...-simulator

如果出现的是 MacOSX.platformMacOSX.sdk,说明 SourceKit-LSP 使用了错误的 macOS 编译上下文,需要重新执行第 6.2 节。

同文件可以跳转,跨文件不能跳转

通常说明 SourceKit-LSP 启动了,但没有正确的项目编译参数或 index store。检查:

  • .compile 是否为空
  • buildServer.json 的 scheme 是否正确
  • indexStorePath 是否存在
  • .compile 中是否包含目标 Swift 文件

改了 SDK 或 scheme 后跳转又失效

重新生成完整编译日志并解析:

bash 复制代码
cd /Users/zzb/AndroidStudioProjects/coowise2/demos/ios
xcodebuild \
  -workspace CoowiseDemoVideo.xcworkspace \
  -scheme DemoCoowise \
  -sdk iphonesimulator \
  -destination 'generic/platform=iOS Simulator' \
  clean build -verbose \
  2>&1 | tee /tmp/coowise-xcodebuild.log >/dev/null

xcode-build-server parse /tmp/coowise-xcodebuild.log

然后重启 Zed language server。

13. 必需配置和可选配置总结

最小必需配置

  • Xcode
  • Swift Zed 扩展
  • SourceKit-LSP
  • settings.json 中启用 Swift language server
  • Xcode 工程的 buildServer.json
  • 正确生成的 .compile

方便开发但不影响跳转的配置

  • tasks.json
  • keymap.json
  • formatter
  • format_on_save
  • Swift Build / Test / Run 快捷键

核心经验

text 复制代码
LSP 能启动,不代表 LSP 了解项目。

能否跳转,取决于 SourceKit-LSP 是否拿到了与 Xcode 一致的编译上下文。

14. 参考资料

相关推荐
北冥you鱼3 小时前
Go-Ethereum (Geth) 最佳实践:从部署到生产环境优化
开发语言·后端·golang
这不小天嘛10 小时前
JAVA八股——J集合篇
java·开发语言
AOwhisky10 小时前
Python 学习笔记(第一期与第二期)——基础语法——核心知识点自测与详解
开发语言·笔记·python·学习·云原生·运维开发
喜欢的名字被抢了13 小时前
Python实战:SQLAlchemy ORM与FastAPI项目集成
开发语言·python·sql·教程·fastapi
从零开始的代码生活_15 小时前
C++ 内存管理:从内存分区到 new/delete 底层原理
开发语言·c++·后端
wabs66615 小时前
关于单调栈【力扣739.每日温度的思考】
java·开发语言
AOwhisky15 小时前
Python 学习笔记(第三期)——流程控制核心知识点自测与详解
开发语言·笔记·python·学习·云原生·运维开发·流程控制
逆向编程16 小时前
Socket异常连接自动清理方案
开发语言
va学弟17 小时前
Java 网络通信编程(10):Channel 和 Selector
java·开发语言