## File: README.md

# Zed

[](https://zed.dev)
[](https://github.com/zed-industries/zed/actions/workflows/run_tests.yml)

Welcome to Zed, a high-performance, multiplayer code editor from the creators of [Atom](https://github.com/atom/atom) and [Tree-sitter](https://github.com/tree-sitter/tree-sitter).

---

### Installation

On macOS, Linux, and Windows you can [download Zed directly](https://zed.dev/download) or install Zed via your local package manager ([macOS](https://zed.dev/docs/installation#macos)/[Linux](https://zed.dev/docs/linux#installing-via-a-package-manager)/[Windows](https://zed.dev/docs/windows#package-managers)).

Other platforms are not yet available:

- Web ([tracking discussion](https://github.com/zed-industries/zed/discussions/26195))

### Developing Zed

- [Building Zed for macOS](./docs/src/development/macos.md)
- [Building Zed for Linux](./docs/src/development/linux.md)
- [Building Zed for Windows](./docs/src/development/windows.md)

### Contributing

See [CONTRIBUTING.md](./CONTRIBUTING.md) for ways you can contribute to Zed.

Also... we're hiring! Check out our [jobs](https://zed.dev/jobs) page for open roles.

### Licensing

Zed source code is licensed primarily under GPL-3.0-or-later, with Apache-2.0 components where marked.

License information for third party dependencies must be correctly provided for CI to pass.

We use [`cargo-about`](https://github.com/EmbarkStudios/cargo-about) to automatically comply with open source licenses. If CI is failing, check the following:

- Is it showing a `no license specified` error for a crate you've created? If so, add `publish = false` under `[package]` in your crate's Cargo.toml.
- Is the error `failed to satisfy license requirements` for a dependency? If so, first determine what license the project has and whether this system is sufficient to comply with this license's requirements. If you're unsure, ask a lawyer. Once you've verified that this system is acceptable add the license's SPDX identifier to the `accepted` array in `script/licenses/zed-licenses.toml`.
- Is `cargo-about` unable to find the license for a dependency? If so, add a clarification field at the end of `script/licenses/zed-licenses.toml`, as specified in the [cargo-about book](https://embarkstudios.github.io/cargo-about/cli/generate/config.html#crate-configuration).

## Sponsorship

Zed is developed by **Zed Industries, Inc.**, a for-profit company.

If you’d like to financially support the project, you can do so via GitHub Sponsors.
Sponsorships go directly to Zed Industries and are used as general company revenue.
There are no perks or entitlements associated with sponsorship.

---

## File: .cloudflare/README.md

We have two cloudflare workers that let us serve some assets of this repo
from Cloudflare.

- `open-source-website-assets` is used for `install.sh`
- `docs-proxy` is used for `https://zed.dev/docs`

During docs deployments, both of these (and the files they depend on) are uploaded to Cloudflare.

### Deployment

These functions are deployed by the docs deployment workflows. Worker Rules in Cloudflare intercept requests to zed.dev and proxy them to the appropriate workers.

### Testing

You can use [wrangler](https://developers.cloudflare.com/workers/cli-wrangler/install-update) to test these workers locally, or to deploy custom versions.

---

## File: crates/vim/README.md

This contains the code for Zed's Vim emulation mode.

Vim mode in Zed is supposed to primarily "do what you expect": it mostly tries to copy vim exactly, but will use Zed-specific functionality when available to make things smoother. This means Zed will never be 100% vim compatible, but should be 100% vim familiar!

The backlog is maintained in the `#vim` channel notes.

## Testing against Neovim

If you are making a change to make Zed's behavior more closely match vim/nvim, you can create a test using the `NeovimBackedTestContext`.

For example, the following test checks that Zed and Neovim have the same behavior when running `*` in visual mode:

```rust
#[gpui::test]
async fn test_visual_star_hash(cx: &mut gpui::TestAppContext) {
    let mut cx = NeovimBackedTestContext::new(cx).await;

    cx.set_shared_state("ˇa.c. abcd a.c. abcd").await;
    cx.simulate_shared_keystrokes(["v", "3", "l", "*"]).await;
    cx.assert_shared_state("a.c. abcd ˇa.c. abcd").await;
}
```

To keep CI runs fast, by default the neovim tests use a cached JSON file that records what neovim did (see crates/vim/test_data),
but while developing this test you'll need to run it with the neovim flag enabled:

```sh
cargo test -p vim --features neovim test_visual_star_hash
```

This will run your keystrokes against a headless neovim and cache the results in the test_data directory. Note that neovim must be installed and reachable on your $PATH in order to run the feature.


## Testing zed-only behavior

Zed does more than vim/neovim in their default modes. The `VimTestContext` can be used instead. This lets you test integration with the language server and other parts of zed's UI that don't have a NeoVim equivalent.

---

## File: crates/theme_importer/README.md

# Zed Theme Importer

```sh
cargo run -p theme_importer -- dark-plus-syntax-color-theme.json --output output-theme.json
```

---

## File: crates/terminal_view/README.md

# Terminal View

## Design Notes

This crate is split into two conceptual halves:
- The terminal.rs file and the src/mappings/ folder, these contain the code for interacting with terminal emulator backends and maintaining the pty event loop. Some behavior in this file is constrained by terminal protocols and standards. The Zed init function is also placed here.
- Everything else. These other files integrate the `Terminal` struct created in terminal.rs into the rest of GPUI. The main entry point for GPUI is the terminal_view.rs file and the modal.rs file.

ttys are created externally, and so can fail in unexpected ways. However, GPUI currently does not have an API for models than can fail to instantiate. `TerminalBuilder` solves this by using Rust's type system to split tty instantiation into a 2 step process: first attempt to create the file handles with `TerminalBuilder::new()`, check the result, then call `TerminalBuilder::subscribe(cx)` from within a model context.

The TerminalView struct abstracts over failed and successful terminals, passing focus through to the associated view and allowing clients to build a terminal without worrying about errors.

## Backend Boundary

`terminal.rs` exposes backend-neutral domain types such as terminal content, cells, modes, points, ranges, scroll commands, vi motions, hyperlinks, and search matches. UI code should depend on those types instead of importing backend-specific terminal types directly.

The current implementation is still Alacritty-backed, but the abstraction boundary keeps backend details concentrated in the terminal crate:

- `terminal_view` renders `TerminalContent` and dispatches backend-neutral actions.
- Panels and tools use terminal-domain types for mode, cursor, range, hyperlink, and search behavior.
- Backend-specific conversions stay near the terminal event loop and render snapshot code.

This keeps the user-facing terminal behavior unchanged while making future backend experiments reviewable as backend implementations instead of UI-wide refactors.

## Input

There are currently many distinct paths for getting keystrokes to the terminal:

1. Terminal specific characters and bindings. Things like ctrl-a mapping to ASCII control character 1, ANSI escape codes associated with the function keys, etc. These are caught with a raw key-down handler in the element and are processed immediately. This is done with the `try_keystroke()` method on Terminal

2. GPU Action handlers. GPUI clobbers a few vital keys by adding bindings to them in the global context. These keys are synthesized and then dispatched through the same `try_keystroke()` API as the above mappings

3. IME text. When the special character mappings fail, we pass the keystroke back to GPUI to hand it to the IME system. This comes back to us in the `View::replace_text_in_range()` method, and we then send that to the terminal directly, bypassing `try_keystroke()`.

4. Pasted text has a separate pathway.

Generally, there's a distinction between 'keystrokes that need to be mapped' and 'strings which need to be written'. I've attempted to unify these under the '.try_keystroke()' API and the `.input()` API (which try_keystroke uses) so we have consistent input handling across the terminal

---

## File: crates/schema_generator/README.md

# Zed Schema Generator

Prints various Zed schemas to stdout.

## Usage

```sh
cargo run -p schema_generator -- --help

cargo run -p schema_generator -- theme
cargo run -p schema_generator -- icon_theme
```

---

## File: crates/livekit_api/vendored/protocol/README.md

# LiveKit Protocol

This is a vendored copy of the [LiveKit protocol](https://github.com/livekit/protocol).

Vendored at [`8645a138fb2ea72c4dab13e739b1f3c9ea29ac84`](https://github.com/livekit/protocol/tree/8645a138fb2ea72c4dab13e739b1f3c9ea29ac84).

---

## File: crates/inspector_ui/README.md

# Inspector

This is a tool for inspecting and manipulating rendered elements in Zed. It is only available in debug builds. Use the `dev::ToggleInspector` action to toggle inspector mode and click on UI elements to inspect them.

# Current features

* Picking of elements via the mouse, with scroll wheel to inspect occluded elements.

* Temporary manipulation of the selected element.

* Layout info for `Div`.

* Both Rust and JSON-based style manipulation of `Div` style. The rust style editor only supports argumentless `Styled` and `StyledExt` method calls.

* Navigation to code that constructed the element.

# Known bugs

## JSON style editor undo history doesn't get reset

The JSON style editor appends to its undo stack on every change of the active inspected element.

I attempted to fix it by creating a new buffer and setting the buffer associated with the `json_style_buffer` entity. Unfortunately this doesn't work because the language server uses the `version: clock::Global` to figure out the changes, so would need some way to start the new buffer's text at that version.

```
        json_style_buffer.update(cx, |json_style_buffer, cx| {
            let language = json_style_buffer.language().cloned();
            let file = json_style_buffer.file().cloned();

            *json_style_buffer = Buffer::local("", cx);

            json_style_buffer.set_language(language, cx);
            if let Some(file) = file {
                json_style_buffer.file_updated(file, cx);
            }
        });
```

# Future features

* Action and keybinding for entering pick mode.

* Ability to highlight current element after it's been picked.

* Info and manipulation of element types other than `Div`.

* Indicate when the picked element has disappeared.

* To inspect elements that disappear, it would be helpful to be able to pause the UI.

* Hierarchy view?

## Methods that take arguments in Rust style editor

Could use TreeSitter to parse out the fluent style method chain and arguments. Tricky part of this is completions - ideally the Rust Analyzer already being used by the developer's Zed would be used.

## Edit original code in Rust style editor

Two approaches:

1. Open an excerpt of the original file.

2. Communicate with the Zed process that has the repo open - it would send the code for the element. This seems like a lot of work, but would be very nice for rapid development, and it would allow use of rust analyzer.

With both approaches, would need to record the buffer version and use that when referring to source locations, since editing elements can cause code layout shift.

## Source location UI improvements

* Mode to navigate to source code on every element change while picking.

* Tracking of more source locations - currently the source location is often in a ui component. Ideally this would have a way for the components to indicate that they are probably not the source location the user is looking for.

  - Could have `InspectorElementId` be `Vec<(ElementId, Option<Location>)>`, but if there are multiple code paths that construct the same element this would cause them to be considered different.

  - Probably better to have a separate `Vec<Option<Location>>` that uses the same indices as `GlobalElementId`.

## Persistent modification

Currently, element modifications disappear when picker mode is started. Handling this well is tricky. Potential features:

* Support modifying multiple elements at once. This requires a way to specify which elements are modified - possibly wildcards in a match of the `InspectorElementId` path. This might default to ignoring all numeric parts and just matching on the names.

* Show a list of active modifications in the UI.

* Support for modifications being partial overrides instead of snapshots. A trickiness here is that multiple modifications may apply to the same element.

* The code should probably distinguish the data that is provided by the element and the modifications from the inspector. Currently these are conflated in element states.

If support is added for editing original code, then the logical selector in this case would be just matches of the source path.

# Code cleanups

## Consider removing special side pane rendering

Currently the inspector has special rendering in the UI, but maybe it could just be a workspace item.

## Pull more inspector logic out of GPUI

Currently `crates/gpui/inspector.rs` and `crates/inspector_ui/inspector.rs` are quite entangled.  It seems cleaner to pull as much logic a possible out of GPUI.

## Cleaner lifecycle for inspector state viewers / editors

Currently element state inspectors are just called on render. Ideally instead they would be implementors of some trait like:

```
trait StateInspector: Render {
    fn new(cx: &mut App) -> Task<Self>;
    fn element_changed(inspector_id: &InspectorElementId, window: &mut Window, cx: &mut App);
}
```

See `div_inspector.rs` - it needs to initialize itself, keep track of its own loading state, and keep track of the last inspected ID in its render function.

---

## File: crates/gpui/docs/contexts.md

# Contexts

GPUI makes extensive use of _context parameters_ (typically named `cx`) to provide access to application state and services. These contexts are references passed to functions, enabling interaction with global state, windows, entities, and system services.

---

## `App`

The root context granting access to the application's global state. This context owns all entities' data and can be used to read or update the data referenced by an `Entity<T>`.

## `Context<T>`

A context provided when interacting with an `Entity<T>`, with additional methods related to that specific entity such as notifying observers and emitting events. This context dereferences into `App`, meaning any function which can take an `App` reference can also take a `Context<T>` reference, allowing you to access the application's global state.

## `AsyncApp` and `AsyncWindowContext`

Whereas the above contexts are always passed to your code as references, you can call `to_async` on the reference to create an async context, which has a static lifetime and can be held across `await` points in async code. When you interact with entities with an async context, the calls become fallible, because the context may outlive the window or even the app itself.

## `TestAppContext`

These are similar to the async contexts above, but they panic if you attempt to access a non-existent app or window, and they also contain other features specific to tests.

---

# Non-Context Core Types

## `Window`

Provides access to the state of an application window. This type has a root view (an `Entity` implementing `Render`) which it can read/update, but since it is not a context, you must pass a `&mut App` (or a context which dereferences to it) to do so, along with other functions interacting with global state. You can obtain a `Window` from an `WindowHandle` by calling `WindowHandle::update`.

## `Entity<T>`

A handle to a structure requiring state. This data is owned by the `App` and can be accessed and modified via references to contexts. If `T` implements `Render`, then the entity is sometimes referred to as a view. Entities can be observed by other entities and windows, allowing a closure to be called when `notify` is called on the entity's `Context`.