茱莉亚 (Julia)
本周我终于成功将自动补全文档合并到主分支。在处理这个问题的同时,我还顺便解决了我们长期以来在补全功能方面打字性能不佳的问题。
显示自动补全主要有两个阶段:请求和过滤。当用户开始打字时,我们还没有任何补全建议,我们必须向语言服务器请求一个列表,这就是请求阶段。一旦我们有了列表,我们就可以进行模糊排序和修剪,以删除多余的项目并将最接近的匹配项排到列表顶部,这被称为过滤。
仅仅一个请求是不够的,我们需要持续地重新请求最准确的列表,因为随着用户继续打字,服务器提供的内容可能会发生变化。然而,在我们等待服务器响应的同时,重新过滤我们已有的列表可能很有用,可以根据用户进一步的打字进行重新排序。这应该能提供更流畅的体验并隐藏一些延迟。
不幸的是,在进行重新过滤时,我们阻塞了 UI 线程,直到过滤完成,导致卡顿和输入延迟增加。因此,我们还等待过滤完成后才请求新的补全列表副本,这进一步加剧了与语言服务器通信(尤其是在网络上)的固有延迟。这种情况本不应该发生,因为过滤 API 明确地在我们的后台工作线程组中执行工作。
棘手的是,即使一个子系统将繁重的工作卸载到后台工作程序并通过异步正确协调,更高级别的调用站点仍然可能滥用它,而这里正是这种情况。重新过滤被触发,它将该工作移动到后台,并等待它;然后我们获取结果 Future 并阻塞整个线程,直到它返回。简而言之,整个 UI 线程在等待后台线程完成过滤时停止工作。
经过一番努力,我重新配置了补全菜单的状态,允许多工作程序同步,并设置了重新过滤以不阻塞并与重新请求竞争。这允许重新过滤在重新请求需要一段时间时改善体验,但不会过度干扰。重新请求新列表将不再等待重新过滤完成,有望降低延迟。此外,在打字时有许多补全项时,UI 不会卡顿或停顿。
马歇尔
本周我的一个主要重点是完成我上周末开始的迁移工作,将所有 UI 组件迁移到最新版本的 GPUI。以前我们是针对旧的快照进行构建的,而自那时以来,GPUI 中发生了一些更大的基础性更改。
我很高兴地报告,我们新的 UI 工作现在完全运行在最新版本的 GPUI 上。
随着我开始积极使用这个新版本的 GPUI,我一直在与 Nathan 和 Antonio 密切合作,随着我们越来越接近实际使用,继续完善它。
本周还对我们构建 UI 故事的方式进行了一些更改,以改善处理 UI 组件的体验。
以前,组件的故事保存在 storybook crate 中,而组件定义本身则位于 ui crate 中。这种分离意味着需要在这两个 crate 之间进行大量的来回切换。
现在,我们在每个组件的模块中都有一个单独的 stories 模块,允许我们将故事直接与它们对应的组件一起定义
// icon.rs
#[cfg(feature = "stories")]
pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
use crate::Story;
#[derive(Element, Default)]
pub struct IconStory {}
impl IconStory {
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
let icons = Icon::iter();
Story::container(cx)
.child(Story::title_for::<_, IconElement>(cx))
.child(Story::label(cx, "All Icons"))
.child(div().flex().gap_3().children(icons.map(IconElement::new)))
}
}
}内特
这周,我既休假了一周,又被感冒打倒了好几天,所以除了 gpui2ui 的工作仍在继续之外,没什么太多可说的了。
我们正在与许多 UI 元素实现视觉一致,并在某些地方(尤其是在项目面板和协作面板等地方)比旧 UI 取得了改进。由共享组件构建的元素使 UI 统一和重构变得更快。
希望在接下来的几周里,我能开始分享一些视觉效果,并讨论我们正在进行的改进,以实现更好的对比度、更多的主题自定义、可伸缩的 UI 等。(并非所有这些都将与新 UI 同时发布,但为实现它们而进行的基础工作将使它们很快更容易完成。)
此外,我一直在我的个人项目中编写大量的 Rust 代码,以便更熟悉该语言和生态系统。我已经开始在 TypeScript 环境中感到想要回到 Rust 的冲动,而这里的其他人则因此而得意洋洋😤
Piotr
正如我在上一个 Zed 周刊条目中承诺的那样,本周我主要致力于 Vue.js 集成。它将在下周三(10 月 18 日)的预览版中发布。除此之外,我还对 Rust 异步函数的补全功能进行了小幅修复。
康拉德
正在 Zed 的协作方面努力:我们如何让人们更容易地与我们协作开发 Zed 本身,并提高协作工具的质量?
我花了大量时间与 Apple 的 Entitlements 搏斗,结果是,我想我们现在可以发布 Universal Links 了(所以将来会有一个链接直接带你到 Zed,而无需通过网站跳转)。
接下来是频道对公共开放:允许人们参与,但不能控制通话。这里的大部分工作是定义它应该如何表现,但实现起来并不像预期的那么简单,因为 Zed 目前允许权限沿着频道树级联。
马克斯
本周,我修复了跟随功能中的一些错误,这些错误是我上周在泛化跟随功能工作方式的过程中引入的。
我也一直在为 Zed 开发一个通知面板,这样我们就可以在 Zed 的聊天中添加 @-提及功能,被提及的用户将有一个地方查看通知。
基里尔
本周是多项工作的一个良好收尾
-
由于回溯(通过尝试 beta 版 XCode 解决)和 curl(最终我自己修复了 https://github.com/alexcrichton/curl-rust/issues/524)的问题已解决,Zed 项目现在可以升级到 macOS Sonoma 了。
-
我发现并修复了一个诊断指示器 bug,现在它可以根据 LSP 服务器通知正确更新。它困扰了我一段时间,但花了一些时间才理解其出现模式。具有讽刺意味的是,修复此问题反而突显了 rust-analyzer 的假阳性诊断问题,是时候尝试找出一个孤立的例子,甚至可能修复语言服务器本身了。
-
最后,Prettier 集成的第一个版本将随下一个预览版发布。它的目标是覆盖所有现有语言(因此,与 Tailwind 和 Svelte 的插件一起工作),在协作场景中工作,从项目的 package.json 中检测项目的 Prettier,或者提供默认的 Prettier,以及其他一些小功能。让我们看看覆盖范围有多好。
内森
下周我将前往意大利与 Antonio 并肩工作。再下一周,全公司将在博洛尼亚召开秋季峰会。我的目标是让新版本的 GPUI 准备就绪,以便每个人都能共同完成过渡。
这周有点模糊,但亮点包括优化视图在其他视图中的嵌套方式,以及将元素与在帧之间持久存在的状态关联起来的能力。GPUI 的核心前提是文档对象模型是无状态的。我们可以添加缓存以节省能源,但我们设计的框架能够以最小的延迟重新渲染整个窗口。
这种无状态性在元素需要有状态时带来了挑战,例如实现点击处理程序时。点击被定义为在同一元素上鼠标按下和鼠标抬起,但如果在鼠标按下时发生视图更新,我们需要记住哪个元素被点击了。为了支持这一点,我们要求有状态的元素与标识符相关联。起初这似乎很烦人,但我后来意识到 React 要求子元素具有 id 以进行高效的差异比较。我们不需要差异比较,因为我们是无状态的,但另一方面,我们需要任何需要状态的元素的标识符。这似乎是一个值得的权衡。
GPUI 2 剩下的主要组件是焦点和键盘处理、拖放、滚动、IME,以及一个使用自定义逻辑以避免布局屏幕外元素的列表组件。能够从网络平台中汲取最佳想法,同时又拥有我们所需低级控制以使其快速运行,这真是太棒了。