Zed 又度过了忙碌的一周。我们的搜索功能正在获得一项重要的更新,WebAssembly 扩展也已启动,我们正在接近发布新的协作频道功能。
凯尔
本周主要集中在重新设计搜索用户界面,以整合我们一直在开发的语义搜索功能。Piotr 和我已将用户界面调整到感觉非常流畅和直观的状态,我们希望它能比以前的用户界面有所改进。除此之外,我们还进行了一些关于 Zed 未来人工智能的小范围探索,并扩展了我们的检索引擎以整合重排序模型。
Piotr
本周我与 Kyle 一起重新设计了搜索用户界面。它很可能成为下周预览版的一部分。在接下来的一周,我还计划将用户界面更改应用到缓冲区搜索中。
约瑟夫
本周,我构建了一些图表,以显示已停止使用 Zed 的用户最常打开的文件类型,旨在获取更多关于人们在 Zed 中尝试使用哪些语言的数据点。我与 Julia 就还可以构建哪些图表进行了头脑风暴,这些图表将有助于更好地描绘我们流失用户正在寻找什么。除了社区工作和一些图表制作,我还向 Zed 提交了一些小的 PR;其中一个为编辑器添加了 convert to {upper,lower} case 命令(感谢 Julia 的帮助)。下周,我计划继续为流失用户构建图表,并且可能会探索构建一个本地工具来汇总用户反馈。
Nathan & Antonio
Antonio 和我本周最感兴趣的工作是两个 CRDB 存储库之间的同步。我们最初的版本依赖于交换向量时间戳,其中包含每个副本 ID 的单调递增计数器。我们使用它来快速确定客户端缺少服务器哪些操作,反之亦然。由于这些时间戳会随着每个副本 ID 的增长而增长,因此这种方法意味着我们需要集中分配副本 ID,并在给定副本上维护状态以跟踪其 ID,这会带来操作复杂性。
所以我们决定在理论层面投入更多精力,寻找一种不依赖于向量时间戳的同步策略。最终,存储库的状态是从一组按 Lamport 时间戳排序的操作中派生出来的,这样新操作往往会聚集在操作历史的右侧。
在探索了几种不同的方法后,我们正在形成一种解决方案,该方案涉及确定客户端和服务器之间操作序列的共享前缀的长度。我们使用 Bromberg 关联哈希函数以及我们的通用 B-树数据结构,以 O(log(n)) 的时间复杂度计算任何操作范围的摘要。当客户端发起同步时,它们会发送覆盖多个范围的摘要。从客户端发送的最大范围开始,服务器查看连续更小的范围,直到找到匹配的摘要。这就是公共前缀。匹配范围和下一个匹配范围之间的尺寸差异决定了我们潜在的超调……公共前缀可能更大,但我们没有足够的分辨率来知道。
如果潜在错误小于我们的最大值,我们只需发送共享前缀之后的所有操作。有些操作可能已经在客户端上,但这没关系。如果潜在错误超过我们的最大值,我们可以执行额外的往返以细化答案。这一切都是为了在往返延迟和发送冗余操作的成本之间取得平衡。
我还致力于用 GPUI 表达 UI 布局,它真的开始成形了。这是我正在进行的一个测试的摘录
fn test_layout(cx: &mut TestAppContext) {
let window = cx.add_window(|_| {
view(|_| {
let theme = rose_pine::dawn();
column()
.width(auto())
.height(auto())
.justify(1.)
.child(
row()
.width(auto())
.height(rems(10.))
.fill(theme.foam)
.justify(1.)
.child(row().width(rems(10.)).height(auto()).fill(theme.gold)),
)
.child(row())
});
});
// ...
}许多框架使用宏 DSL,但我认为存在复杂性权衡。我真的很喜欢用纯 Rust 表达 UI 的想法,到目前为止,我认为这种函数链式方法是合理的。
马克斯
本周,Mikayla 和我继续致力于 Zed 的频道新功能,用于构建协作。我们现在有一个用于管理频道和成员资格的用户界面,它大部分功能已经完成,但比较粗糙。下周,我们将完成其样式设计,并希望将其发布到预览频道。
米凯拉
本周,我们为频道功能构建了所有核心用户界面和交互!我和 Max 在开发此功能方面玩得很开心,我们很高兴看到它如此迅速地整合在一起。随着我们接近内部 MVP,我想稍微谈谈我们是如何以及为何构建此功能的。
从根本上说,频道是人们组织工作地点和内容的一种方式。就像我们的实际工作一样,频道可以按主题分层组织成一个大致的选择,我们设想如下:
- #zed
- #livestreaming
- #public-channels
- #channels-core
- #search-and-replace
- #design
- #wasm
点击任何一个频道都会立即启动 Zed 通话,并将您在该频道中的存在广播给任何其他已加入的人。有点像 Slack 的临时讨论,但结构更丰富,而且(目前)没有文本聊天。
但我们的工作并非纯粹的层次结构,它不能总是清晰地分离成单独的主题,而且我们经常与其他团队和项目协作。为了适应这一现实,我们将频道数据结构建模为 DAG(有向无环图),允许您根据需要将事物链接在一起。例如,我们使用 LiveKit 来支持我们的麦克风和屏幕共享,因此您可以想象我们两个组织之间有一个共享频道
#zed
- > #livestreaming
- #search-and-replace
- #design
- #livekit 🔗
- #screen-sharing
- #web-rtc
或者你可以有一个特定功能的交叉关注点
#zed
- > #livestreaming
- #search-and-replace
- #replace-design
- #design
- #replace-design
- > #livekit
或者你可以将你的频道组织成团队和项目
- #crdb-industries
- #design
- #alpha
- #lamport-timestamps
- #branches
- #repository-synchronization
- #november
- #gpui-layout
- #branches
- #repository-synchronization
仍然觉得树形结构太受限制?创建一个新频道,然后按照你想要的方式组织它们!
- #my-freelance-design-business
- > #crdb-industries/#design
- > #zed/#design
支撑这种灵活性的是,频道具有两个基本属性:任何频道的权限都会通过减法干扰级联到所有子频道,并且未经拥有权限的人邀请,不可能“向上”移动 DAG。这意味着,例如,如果我们要开始使用这些频道发布直播,我们可以为此创建一个 #public 频道。
#zed
- > #livestreaming
- > #search-and-replace
- > #design
- > #livekit 🔗
- #public
- #linux-support
- #windows-support
在这个 #public 频道中,我们可以指定社区成员为版主,或者生成一个只读链接。而且我们做所有这些都不必担心 #public 频道中的人可以访问 Zed 的任何内容。
下周,我将讨论我们如何实现此功能的一些技术细节。
(请注意,我所说的一切都可能发生变化,我们仍在尝试什么感觉合适以及什么效果最好 :D)
茱莉亚 (Julia)
我们一直想做的一件重要事情是让用户能够为 Zed 添加自定义语言支持。由于涉及的复杂性,我们已经推迟了一段时间,但本周我得到了开始着手这项工作的许可。我们目前只开始添加自定义语言服务器,因为这将让我们在添加可扩展的 tree-sitter 语法支持之前解决一堆 WASM 相关问题。这意味着我本周有机会阅读和试验了一堆很酷的 WebAssembly 内容。还有很多工作要做,但我对我们的前进方向感到兴奋!