Zed Weekly: #20

September 18th, 2023


This week I've finally been closing in on the end of this moving / linking channels mini-project. Surprisingly, this has taken as long and has almost as large as adding chat*! At this point I've written about a half dozen DAG representation transformations for each of the database, server memory, the network, client memory, client UI, and test helpers ;-;. Thankfully, it's a lot of fun to be able to work with these Computer science concepts in the Real World.

Also, next week I'm going to be at Strange Loop! Feel free to @ us on twitter if you're going to be there too and want to meet up!

(* 3200 net LOC changed for moving channels vs. 3000 net LOC changed for chat)


The nasty hints' panic bug with hints took a few days of fixing and more dives into coordinate management code, but thanks to Antonio's help it's over and we have a fix and more randomized tests for new highlights. As a bonus, the whole hint thing should work even faster now.

The rest of the time was dedicated to prettier integration: editor now has a basic integration for local development with prettier and is able to detect project's prettier or install its own, potentially managing the plugins needed for certain languages. I'm currently working on a prettier wrapper that should allow us to speed up the formatting process and there's more to work on, such as remote development — hopefully, no more hint bugs to distract me during next week.


This week, we got the last of the major PRs related to our Semantic Index in, notably implementing semantic search in modified open buffers. With this out of the way, I've begun work on an evaluation framework for testing our engine automatically, allowing us to iterate and make confident engine decisions over time. Beyond this, Antonio and I started work on integrating the Semantic Index into our inline code assistant. Currently, we are only leveraging context from the existing open file when informing our inline AI generation. The hope is that with the Semantic Index, the inline assistant will have full knowledge of your working codebase when making edits or generating new code.


Auto-complete docs have continued to progress, with a bit of code reshuffling we have markdown rendering

Autocomplete docs markdown rendering
Autocomplete docs markdown rendering

I've also spent plenty of time fixing some LSP status bugs with Antonio, investigated some language server installation problems with Piotr, and helped lay out some exploratory brainstorming for some future big work.


This week, I built an initial chat system for Zed channels. This will allow us to have asynchronous, text-based conversations about code, in which comments can be attached to specific lines of code. For now, the chat is very simple. Next, we'll need to build a concept of mentions, and notifications for new messages.


I've been heads down exploring the new way we'll be building UI for Zed going forward in gpui. Up until this point we've been using a mix of gpui code and a custom typescript app to compile styles. Recently we've been building up a Tailwind-like system for styling components in gpui.

So far it has been really great for rapidly prototyping UI and I'm really excited for the potential it holds for unlocking much faster iteration on UI in Zed.

For example, if we wanted to create an Avatar component, we could do something like this:

#[derive(Element, Clone)]
pub struct Avatar {
    src: ArcCow<'static, str>,
    shape: Shape,
pub fn avatar(src: impl Into<ArcCow<'static, str>>) -> Avatar {
    Avatar {
        src: src.into(),
        shape: Shape::Circle,
impl Avatar {
    pub fn shape(mut self, shape: Shape) -> Self {
        self.shape = shape;
    fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
        let theme = theme(cx);
        let mut img = img();
        if self.shape == Shape::Circle {
            img = img.rounded_full();
        } else {
            img = img.rounded_md();

Then if we wanted a circle avatar we could do something like this:


If we wanted an avatar with a rounded rectangle shape instead we could just add a shape method:


Forgive any poor quality Rust here, I'm still learning! 🙈

This is just a small example of what's possible with this new system. I'll try to do a larger write up on how we are using this system to rewrite the Zed UI and it's implications sometime in the future.

Until then, I'll be immersing myself in the world of Rust! Coming from pretty much only a Typescript background the learning curve is pretty brutal but it has been rewarding so far.

Until next week!


I've been focusing on enhancing our capability to analyze groups of churned users in our analytics, so we can gain clearer insights into which specific development areas require improvements. Previously, we had some methods to investigate how certain features were being used, and whether users of these features had left Zed. However, we lacked an effective way to compare these groups with one another or with the overall churned user population. It is a bit of a large task, but it feels like we will learn a good amount from it.


This week, I landed a "replace in buffer" feature, collaborated on the UX with Max and Nate. I also tracked down the source of a bug where, with some keyboard layouts (notably Chinese, Japanese, and Korean), some users experienced random characters being inserted on their behalf. As it turns out, Conrad had a similar issue with Portuguese layouts, so we're going to pair up to knock that one off the list, as it looks similar to the one I've already fixed. Other than that, I made minor adjustments to the command palette sorting order and paired with Julia on LSP's getting stuck updating - without much luck just yet, though. In the following week, I will continue addressing these QoL improvements. I also want to eventually get into "replace in project search," though it needs a bit more thought around the expected behavior than "replace in buffer."