Zed Weekly: #24

Joseph Lyons

Joseph Lyons

October 20th, 2023


This week I've landed a handful of changes all over the place:

  • Zed now handles nested git repositories a bit better. Previously we were always respecting all .gitignore files encountered on a path from the worktree root to the filesystem root. This proved a bit cumbersome for users who've set up a "global" git repository for their dotfiles in $HOME directory; the fix was rather simple, as we now bail out on the first .gitignore file whose sibling directory is .git.
  • My favourite kind of issues are ones related to the inability to type out some characters on particular keyboard layout. This time around, it turned out that „true quotes” cannot be typed out in Zed with American keyboard layouts. Thankfully, this time around, it was not up to the language integrations intercepting the keystroke, but rather the collision on the keybind; it turns out that we've set Copilot's Suggest Next and Suggest Previous action keybinds to the same key combination as that of true quotes. Whoops! We've kept the keybinds in place, propagating the keystroke if there's no Copilot action to be taken.
  • I've collaborated a bit with Max on chat notifications (though I was more of a listener really, as I did not touch that part of codebase yet) - in the process, I've added highlights of mentions in chat messages.
  • I've sketched out a rudimentary CONTRIBUTING.md for Zed that we can build upon in the future. I plan to focus a bit more on the quality of our code documentation over the next few weeks.


This week was mostly a deep dive into adding "guests" to calls. A guest can follow participants, and chat; but cannot share their own projects, screens or microphones. The idea is that we can provide an industry-specific twitch-like experience for working on codebases, to help spread the word about Zed.

That said, I did have some time to work on one of Zed's most fun, and most long-standing bugs...

Previously, when you hit up it would count the number of UTF-8 bytes since the start of the current line, and move the cursor after that number of UTF-8 bytes in the line above. Those of you who have read anything about unicode will know that is "naïve" to say the least. Users had rightly complained that it Just Does Not Work.

@Julia and I explored a number of approaches to fixing this: we could do a bit better by counting code-points instead of bytes, or a lot better by counting grapheme clusters instead of code-points. But unfortunately even grapheme clusters still have problems:

  • on modern systems, your font selection is just a preference. When rendering text, if your font doesn't contain the character you need (commonly Emoji) then it will be rendered using a different font (commonly "Apple Color Emoji"). These guest characters will have different widths.
  • even in nominally-Monospace fonts, there's a distinction between single-width characters ("abcd") and double-width characters ("漢字"). We could account for this using some Unicode lookup tables (which is how terminal emulators work), but as the Unicode rules change regularly, and not all font authors follow them exactly, there are still edge-cases to consider.
  • if you have chose a non-Monospace font, then all bets are off...

So instead, Julia proposed that we could re-use the text-layout engines outputs to figure this out. We already had code to figure out which character corresponded to your mouse position when you clicked, so we refactored it, spent some time making it faster, fixing rounding errors, etc. And now (once this is merged), hitting up and down will do what your eyes expect it to do!


I spent most of the week cleaning up various things in our ui crate. We're getting close to the point where other folks will start building out UI using the new patterns, so I want to make sure that things are neat and consistent for them. As part of this, I started documenting our various style helpers, including references to the Tailwind docs with which they correspond.

I also had the chance to pair with Conrad on implementing a command to toggle Vim mode. For someone like me who isn't a huge Vim user, but occasionally wants to dip their toes in, it will be nice to have the ability to enable or disable Vim mode without having to modify settings.json each time!


I spent a few days this week getting Tailwind CSS autocomplete working in a few more languages such as Svelte, PHP/Blade, Ruby/ERB, and Elixir/HEEX. In the process, I got to learn quite a bit about those various ecosystems while setting up test projects and configuring them to work in VSCode, so I had something to compare behavior to. It was a bit time-consuming, but quite interesting and important to validate that things worked as expected.


I am slowly narrowing my search around outdated diagnostics in the panel — alas, the bug is tricky to reproduce, as it requires special files opened after special events with LSP server in a certain state, and nothing about those 3 parts is fully clear. Right now, planting more logs so that we could catch and comprehend it better on the next occurrence: I have a few theories which are hard to prove or refute otherwise. Meanwhile, keeping myself occupied with bugfixing, some pop up more when I'm trying to break diagnostics, so it's a good chance to deal with them too.

And while it's still is more of a concept, things start to form around the remote terminal sharing: me and Mikayla had a great chance to pair in person, hacking through alacritty's inner code and preparing everything for inner Zed changes. One remarkable thing to me was how Zed is great even if your parther sits 10 cm to the left of you: with all the collab features, you don't need to try and squeeze two people into a single laptop anymore! So you can follow a person in Zed, do your own code lookups in another tab and discuss things live, periodically jumping into specific code places to help — pretty much what I'd do collaborating remotely anyway, but even faster in person.


Pretty exciting week for AI @ Zed, as we shipped a new button in the Inline Assist "Retrieve Context". If selected, this button will provide the inline assistant with relevant context from the repository. This now allows the inline assistant to understand your repository, and provide grounded and relevant answers from your repository when needed. This is the second feature that will make it out to stable leveraging the Semantic Index, and while a pretty simple first step is already pretty impressive.

The remainder of the week was spent focusing on improving prompt ergonomics with prompt templates, and working towards a multi-stage planning agent for the inline assist. I'll likely have more to say on the planning agent, as we get closer to shipping, and instead of walking you through some of the work on prompt ergonomics, here is the inline assistant walking you through how some of our new prompt templating code works:

Inline assistant walking through improved prompt ergonomics