Looking to write your own extension for Zed? You've come to the right place!
Extensions are currently capable of extending Zed in the following ways:
Extensions may provide Tree-sitter grammars that allow Zed to parse different kinds of syntax.
These are typically used in conjunction with languages.
Extensions may provide languages to extend Zed with support for a particular language.
Currently this is used for things like syntax highlighting and outlining.
Extensions may also provide language servers for use with languages.
Extensions may provide themes to change the look of Zed.
A Zed extension is a Git repository that contains an extension.toml
:
id = "my-extension"
name = "My extension"
version = "0.0.1"
schema_version = 1
authors = ["Your Name <[email protected]>"]
description = "My cool extension"
repository = "https://github.com/your-name/my-zed-extension"
Extensions may contain any combination of grammars, languages, and themes. For example, you can have an extension that provides both a grammar and a language, or one that just provides a theme.
If your extension contains grammars, you can denote the provided grammars in your extension.toml
like so:
[grammars.gleam]
repository = "https://github.com/gleam-lang/tree-sitter-gleam"
commit = "58b7cac8fc14c92b0677c542610d8738c373fa81"
The repository
field must specify a repository where the Tree-sitter grammar should be loaded from, and the commit
field must contain the SHA of the Git commit to use.
The languages
directory in an extension should contain one or more directories containing languages.
To provide language server support your extension can integrate against the Zed extension API.
Create a Rust library at the root of your extension repository.
Your Cargo.toml
should look like this:
[package]
name = "my-extension"
version = "0.0.1"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
zed_extension_api = "0.0.6"
Make sure to use the latest version of the zed_extension_api
available on crates.io.
In the src/lib.rs
file in your Rust crate you will need to define a struct for your extension and implement the Extension
trait, as well as use the register_extension!
macro to register your extension:
use zed_extension_api as zed;
struct MyExtension {
// ... state
}
impl zed::Extension for MyExtension {
// ...
}
zed::register_extension!(MyExtension);
Finally, add an entry to your extension.toml
with the name of your language server and the language it applies to:
[language_servers.some-language]
name = "My Extension LSP"
language = "Some Language"
For more examples on providing language servers via extensions, take a look at the extensions available in the Zed repository.
The themes
directory in an extension should contain one or more theme files.
Each theme file should adhere to the JSON schema specified at https://zed.dev/schema/themes/v0.1.0.json
.
See this blog post for more details about creating themes.
To test your extension locally, you can open up the extensions view with the zed: extensions
command and then click on the Install Dev Extension
button.
This will open a file dialog where you can locate and select the directory in which your extension resides.
Zed will then build your extension and load it.
To publish an extension, open a PR to this repo.
In your PR do the following:
- Add your extension as a Git submodule within the
extensions/
directory - Add a new entry to
extensions.toml
containing your extension:[my-extension] submodule = "extensions/my-extension" version = "0.0.1"
- Run
pnpm sort-extensions
to ensureextensions.toml
and.gitmodules
are sorted
Once your PR is merged, the extension will be packaged and published to the Zed extension registry.
To update an extension, open a PR to this repo.
In your PR do the following:
- Update the extension's submodule to that commit of the new version.
- Update the
version
field for the extension inextensions.toml
- Make sure the
version
matches the one set inextension.json
at the particular commit.
If you'd like to automate this process, there is a community GitHub Action you can use.