Copilot x Zed

April 20th, 2023

Co-authored with ChatGPT and Copilot

At Zed, we've been captivated by the new AI tooling as much as everyone else. So we asked ourselves, how quickly can we bring these new tools to our users? After a few weeks of hustle, we're excited to announce that GitHub Copilot is now available in Zed! Copilot is a code generation tool that uses machine learning to help you write code faster. You can use it to generate code snippets, functions, and entire files making it a breeze to bring your ideas to life.

Copilot should be available immediately (in Zed v0.82) through a status bar icon in the lower right of the screen. Click the icon to login using your existing copilot subscrition.

If you'd rather not have Copilot at all, you can disable it by adding "features": {"copilot": false } to your settings file.

Here's Copilot in action:

A demo of Zed's Copilot integration.

Read on for how we integrated Copilot into Zed!

First, we had to actually get access to Copilot. As of this writing, there is no official GitHub API to interact with Copilot. However, thanks to the open-source Neovim plugin, we have access to an undocumented, minified LSP server that handles interacting with GitHub for us. Zed already has built-in support for LSP servers, so getting access to Copilot was as simple as downloading the Copilot LSP from the Neovim plugin repository. Special thanks to TerminalFi, a Zed community member, for their LSP-copilot Sublime Text plugin, which provided a specification for the custom messages available.

Once we had the LSP, we needed to add UI for the authentication process. We already have the machinery in Zed to acquire a GitHub auth token. But the Copilot LSP was built for Neovim's text-based interface; it manages its own OAuth token internally using a device code. However, this challenge led us to introduce a Modal UI in Zed, which can pop up as a separate window – opening up possibilities for future enhancements like releasing a standalone terminal!

Finally, we needed a way of showing the suggestion text. As we mentioned in the CRDT blog post we maintain an in-memory representation of the entire history of edits to the document as a sequence of operations called a Buffer. But storing and editing text are only the very basics of a code editor. We also need code folding, tab expansion, line wrapping, etc. These are all provided by a DisplayMap which maintains indexes into the edit sequence for each of these features. For Copilot, we added 'suggestions', which allow us to splice multi-line text with custom styling into the buffer. The DisplayMap is also subjected to extensive, randomized testing that ensures that all combinations of these features work together.

With all the pieces in place, we spent a few weeks on internal preview builds fine-tuning Copilot's behavior. Balancing its visual and mental burden was crucial, as an over-eager Copilot could be counterproductive and cause conflicts with pre-existing features like LSP autocomplete. We introduced settings to disable Copilot per language, added a 75ms debounce before suggesting text, and prioritized the language's real LSP over Copilot when conflicts arose.

And that's how we successfully integrated Copilot into Zed! We're excited to see how this new feature will enhance the coding experience for our users. Give it a try, and let us know what you think!