Commit Graph
39861 Commits
Author SHA1 Message Date
Kirill Bulatov 3f5abf5084 Fix projects leaking via agents panel (#63765)
When working with multiple windows, one agent worked in the external
hard drive's directory.
After finishing working on that external dir, I've closed the entire
window (the other one, unrelated, remained) only to discover I cannot
unmount the external hard drive.

Investigated, and seems that that manual `ref_count` is buggy — replaced
that with `WeakEntry` for both agent and ACP parts.
Also added leaked project logging into reliability.

Release Notes:

- Fixed projects leaking via agents panel
2026-09-04 18:14:56 +00:00
Jakub Konka b601a0e716 gpui_web: Disable native canvas touch callouts (#63775)
On iOS, WebKit presents a native touch callout when a user long-presses
a canvas. For GPUI Web this selected the full application canvas while
GPUI independently selected the intended word, producing two pairs of
selection handles, a native edit menu, and haptic feedback.

Set `-webkit-touch-callout: none` on the canvas created by `gpui_web`.
GPUI already owns touch gesture recognition on this surface, so WebKit
should not provide a competing canvas interaction.

Tested with:

- `cargo fmt --check --package gpui_web`
- `RUSTC_BOOTSTRAP=1 cargo check -p gpui_web --target
wasm32-unknown-unknown`
- A Delta Web WASM build using the local Zed checkout
- Manual verification on an iPhone that long-press word selection no
longer selects the full canvas

Release Notes:

- N/A
2026-09-04 18:14:18 +00:00
shxmblesandKirill Bulatov 5b6ba0375d Add disable_ai check for "Agent Panel" MenuItem (#63580)
# Objective

- Removes Agent Panel menu item when AI disabled toggle is on.
- Fixes #63497

## Solution

- Use the global DisableAiSettings - disable_ai check in `app_menus.rs`.
To keep the order the same I
1. Check the disable AI setting
2. If true push to the `view_items` vec![]
3.  Extend the vec![] with the remaining Menu Items and Separators. 

## Testing

This can be tested visually:
 1. Open Zed with AI settings enabled 
 2. Click View when Zed is focused
3. Noting where Agent Panel is on the list and to make sure clicking it
opens up the Agent Panel.
 4. Open settings 
 5. Navigate to AI settings
 6. Toggle disable AI on
 7. Click View 
 
Expected: Agent Panel is gone from the menu. The opposite is also
expected.
 
- This was tested on macOS 26.6.2 (25G83).

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [] Tests cover the new/changed behavior 
To keep this PR simple, I did not add any testing to this, as there were
no tests in this file already.
- [x] Performance impact has been considered and is acceptable

## Showcase
<details>
  <summary>Click to view showcase</summary>




https://github.com/user-attachments/assets/50db44ac-6c11-4101-a064-fd4e3b285620



</details>

---

Release Notes:

- Fixed Agent Panel appearing in the "View" menu when disable AI
settings is on.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-04 17:19:04 +00:00
Ayush 078d171ebc google_ai: Add Gemini 3.8 Flash (#63643)
# Objective

Add Gemini 3.8 Flash to Zed's built-in Google AI provider so it can be
selected from the model dropdown.

  ## Solution

Register `gemini-3.8-flash` with its 1 million token context window, 64k
output limit, and Low, Medium, and High thinking levels. Medium is the
default, and Low is used when thinking is disabled because the model
rejects Minimal.

Add tests covering the model metadata, serialization, token limits,
thinking levels, and disabled-thinking behavior.

  ## Testing

  Tested on Windows using Rust 1.98 GNU:

  - `cargo test -p google_ai` — 23 passed
  - `cargo fmt --all --check`
- `cargo +stable-x86_64-pc-windows-gnu clippy -p google_ai --release
--all-targets --all-features -- --deny warnings`

Reviewers can run `cargo test -p google_ai`. The pinned MSVC toolchain
was not tested locally because `link.exe` was unavailable.

  ## Self-Review Checklist:

  - [x] I've reviewed my own diff for quality, security, and reliability
  - [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
  - [x] Tests cover the new/changed behavior
  - [x] Performance impact has been considered and is acceptable

  ---

Release Notes:

- Added Gemini 3.8 Flash to the Google AI models
2026-09-04 16:24:18 +00:00
Jakub Konka 3c1fc637ad ui: Expose keybinding visibility (#63770)
`KeyBinding::set_default_visibility` lets applications suppress
keybinding labels, but the current visibility value is private to
`KeyBinding::render`. Applications that compose related modifier hints
from lower-level UI elements cannot follow the same presentation policy.

Expose the existing visibility query without changing its behavior. This
lets those callers omit their complete hint, including accompanying text
and spacing, while sharing the same application-wide source of truth.

Release Notes:

- N/A
2026-09-04 16:21:48 +00:00
Vlad Gaevsky d081bbb7e1 settings_json: Locate a key by its own range, not by scanning quotes (#62949)
`replace_value_in_json_text` spelled a newly inserted key with
hand-written quotes, so a key carrying a `"` or a `\` produced invalid
JSON. The removal and rename paths then could not find such a key again:
both walked backwards to the nearest raw `"`, which lands inside an
escape, and ate the neighbouring entry while leaving JSON that still
parses.

The parser already hands back the key's byte range, so the three sites
use it, and serde for the spelling, the way key lookup and the
nested-construction path always did.

Worth knowing beyond the escaping: `update_value_in_json_text` pushes
every map key into the key path verbatim, so any settings map whose keys
are not authored by hand reaches this. Most are typed by the user, but
`favorite_config_option_values` is keyed by a `SessionConfigId` that an
ACP agent supplies over the protocol.

Tests cover insertion into a single-line and a multi-line object,
removal and rename, all with a key carrying a quote and a backslash.

Release Notes:

- Fixed a settings key containing a quote or a backslash corrupting
`settings.json`.
2026-09-04 15:28:40 +00:00
Jake NelsonandKirill Bulatov 1aab982b0a workspace: Add configurable window title formatting (#54379)
## Summary
- Add `window_title_format` and `window_title_separator` settings for
customizing the window title
- Expose `${projectName}`, `${fileName}`, `${filePath}`,
`${relativePath}`, `${fileStem}`, `${remoteName}`, `${remoteHost}`,
`${appName}`, and `${separator}` as the native Zed window-title
variables
- Keep the collab `↗/↙` indicator hard-appended
- Translate VS Code `window.title` / `window.titleSeparator` aliases
into Zed's canonical variables during settings import, including
`${appName}` passthrough support and mapping VS Code's
`${activeEditorMedium}` onto Zed's `${relativePath}`
- Gate path-, remote-, and release-channel-derived lookups on whether
the active template references the corresponding variable, so the
default template avoids the extra work and still uses the existing
`last_window_title` cache to skip redundant platform updates

An alternative approach is at #49638. I went with `${variable}` names
over `$ZED_*`, canonical Zed variable names with VS Code aliases handled
at import time, kept `${separator}` as the only structural token, and
left `${dirty}` out of scope.

## Implementation reasoning and notes

### Variables considered but not included
- **collab/shared indicator variable**: kept hard-appended instead.
Folding it into the template would need whitespace/separator logic the
other variables don't need, and I'd rather not bake those semantics in
without a concrete need for it.
- **dirty variable**: The glyph choice and interaction with OS-level
edited indicators (like macOS's titlebar dot via `set_window_edited`)
felt like a separate design call I wasn't confident making here.

A separator-style config for each of collab/shared/dirty would solve the
above, but I didn't want to add too many additional settings initially.

### Performance
`update_window_title` is on a hot path, so two short-circuits apply:
- Path-, remote-, and release-channel-derived lookups (`absolute_path`,
relative-path string, `file_stem`, `remote_connection_options`,
`ReleaseChannel::try_global`) are gated on `template.contains(...)` via
`WindowTitleNeeds::from_template`, so the default template avoids the
extra work.
- The existing `last_window_title` cache still skips the platform call
when the rendered title is unchanged.

## Screenshots

Settings Editor entries for `window_title_format` and
`window_title_separator`:
<img width="774" height="324" alt="Settings Editor screenshot"
src="https://github.com/user-attachments/assets/b3378ec7-5649-4de3-9de6-164a42bce3fd"
/>

Customized Zed window titles in AltTab app switcher (remote, local,
empty):
<img width="774" height="324" alt="AltTab app switcher screenshot"
src="https://github.com/user-attachments/assets/a189945e-fc68-41b9-aab9-6dc04d5ef4ab"
/>

## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Closes #14534

Release Notes:

- Added configurable window title formatting with `window_title_format`
/ `window_title_separator`, including `${appName}` / `${remoteName}` /
`${remoteHost}` variables and VS Code `window.title` import support

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-04 13:48:58 +00:00
Kirill Bulatov f659fcc000 terminal_view: Do not treat AltGr character input as a meta sequence on Windows (#63707)
Follow-up to https://github.com/zed-industries/zed/pull/62891
Fixes #63703


https://github.com/user-attachments/assets/5eb198ef-2958-4a43-a2fb-fb0d3a96f642

Release Notes:

- Fixed AltGr / diacritic input being swallowed by the integrated
terminal on Windows.
2026-09-04 12:54:18 +00:00
Lena 62e1aadb2c Handle reopened PRs on the community PR board (#63755)
The particular edge case that is covered here is closing a community PR,
then labeling it with an `area:`, and _then_ reopening it.

Release Notes:

- N/A
2026-09-04 12:47:05 +00:00
Kirill Bulatov 5d1147a6e4 Stop canonicalizing LSP locations before worktree lookup (#63754)
Closes
https://github.com/zed-industries/zed/pull/61392#issuecomment-5538772188
Follow-up to https://github.com/zed-industries/zed/pull/61392



https://github.com/user-attachments/assets/6c745474-6b6e-4cfa-b1b6-87e9631973bf


Not every language server wants to deal with the canonicalized paths,
some (e.g. gopls) can resolve them themselves, and keep sending
symlinked paths over the LSP — canonicalizing them means we will break
out of the current worktree and open odd singleton files instead.

Release Notes:

- Fixed goToDefinition opening out-of-worktree entries
2026-09-04 12:15:49 +00:00
Lena 5889a27ff2 Consolidate GitHub helpers for community scripts (#63198)
It's been fun for a while to have the same function calling GitHub API
in every single script, but we're going to have fun in different ways
now.

This one's for you, @MrSubidubi! 🥂 

## Testing

I've ran the things that had `--dry-run` locally and nothing blew up,
but the ultimate smoke test will be carried out in production.

---

Release Notes:

- N/A
2026-09-04 11:40:05 +00:00
Ibrahim Khan 08e135dbfa vim: Continue multiline comments with o (#63751)
# Objective

In Vim mode, pressing `o` to open a line inside a documentation-style
block comment preserves indentation but drops the `* ` prefix.

The behavior for pressing Return is already correct as it continues this
prefix in the next line.

This change makes both actions behave consistently.

Fixes #55049

## Solution

Make Vim’s `o` and `O` commands copy documentation-comment prefixes such
as `* ` onto the new line. This happens only when the current line is
parsed as a comment.

Also added regression coverage for this and folded it into the existing
`test_o_comment` test.

## Testing

- `CC=clang CXX=clang++ cargo test -p vim test_o_comment -- --nocapture`
- `CC=clang CXX=clang++ cargo test -p vim`
- `CC=clang CXX=clang++ cargo test -p multi_buffer`
- `cargo fmt --all -- --check`
- `CC=clang CXX=clang++ ./script/clippy -p vim -p multi_buffer`
- Tested on Linux aarch64.

## Self-Review Checklist:

- [x] I reviewed the diff for quality, security, and reliability
- [x] Unsafe blocks, if any, have justifying comments
- [x] The content adheres to the Zed UI standards
- [x] Tests cover the changed behavior
- [x] Performance impact is acceptable

---

Release Notes:

- Fixed Vim `o` comment continuation in C-style multiline comments.
2026-09-04 11:09:15 +00:00
Manoj skandChristopher Biscardi 3ffeb868ae project_panel: Show path tooltip on hover (#63299)
# Objective

The project panel doesn't show a file or folder's actual location on
disk anywhere in the UI — you have to rely on the tab title or context
menu ("Copy Path") to find out where a file actually lives, which is
especially unclear for files with the same name in different folders, or
when a project has multiple worktrees.

## Solution
- Adds a tooltip to each file/folder row in the project panel that shows
the entry's path on hover, with the home directory abbreviated to `~`
(via the existing `PathExt::compact()` utility, consistent with how
paths are already displayed elsewhere, e.g. the Recent Projects list).

## Testing

- Manually tested by hovering over files and folders at various nesting
depths in the project panel and confirming the tooltip shows the correct
path.
- Tested with a project both inside and outside the home directory to
confirm the `~` substitution only applies when appropriate.
- Confirmed existing row behavior (selection, click-to-open,
drag-and-drop, right-click context menu) is unaffected by the added
tooltip.
- Reviewers: hover over any row in the project panel and confirm the
tooltip appears after the normal hover delay and shows the expected
path.
- Tested on macOS only — haven't verified on Linux/Windows.

## Self-Review Checklist:

- [ ] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

## Showcase

<img width="1512" height="871" alt="image"
src="https://github.com/user-attachments/assets/ec86f9ab-0a8e-40f7-b783-8a115203f11d"
/>


- Help others understand the result of this PR by showcasing your
awesome work!
- If this PR includes a visual change, consider adding a screenshot,
GIF, or video
- A before/after comparison is very useful for changes to existing
features!

While a showcase should aim to be brief and digestible, you can use a
toggleable section to save space on longer showcases:

<details>
  <summary>Click to view showcase</summary>

My super cool demos here

</details>

---

Release Notes:

- Added a tooltip showing the file path when hovering over files and
folders in the project panel.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-09-04 11:05:53 +00:00
Josh Kent cac6725147 markdown_preview: Group settings and add automatic preview opening (#63462)
## Objective

Markdown preview appearance settings are split between root theme
settings and
`markdown_preview`, and Markdown files always open as source editors
even when a user primarily
wants the rendered preview.

## Solution

- Group the Markdown preview font settings under `markdown_preview`,
migrate their legacy keys
across supported settings scopes, and update defaults, Settings UI, and
documentation.
- Add `markdown_preview.open_markdown_files_in_preview`, defaulting to
false. When enabled, clean
Markdown opens are replaced by a rendered preview while preserving dirty
editors, temporary-tab
behavior, pane activation and focus, targeted navigation, workspace
restoration, and the escape
  back to source.

## Testing

- Manually verified on macOS that enabling the setting opens Markdown
files as preview-only.
- `cargo test -p markdown_preview` (three consecutive runs)
- `cargo test -p migrator nest_markdown_preview`
- `cargo test -p settings_content`
- `cargo check -p markdown -p markdown_preview -p migrator -p settings
-p settings_content -p settings_ui -p theme_settings -p workspace`
- `./script/clippy -p gpui_apple -p markdown -p markdown_preview -p
migrator -p settings -p settings_content -p settings_ui -p
theme_settings -p workspace --features gpui_apple/runtime_shaders`
- `cargo fmt --all -- --check`
- `git diff --check`

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Recordings


https://github.com/user-attachments/assets/032ab36d-f934-4ef7-aa18-53f3955a7df8


https://github.com/user-attachments/assets/dc872265-2fe0-45ac-95eb-ff820d3a8164

Release Notes:

- Added a setting to open Markdown files directly in preview mode and
grouped Markdown preview settings together.
2026-09-04 10:54:29 +00:00
itsfuad 48628b1970 Show progress while cloning repositories (#63239)
## Summary

- Reuse the existing Zed clone activity indicator, which previously
showed only a static `Cloning <URL>` message.
- Add filesystem job updates so the existing indicator can change while
a job is running.
- Stream exact `git clone --progress` messages into that indicator
without maintaining a phase allowlist.
- Preserve the final Git stderr message when cloning fails.


https://github.com/user-attachments/assets/a9b8cbfd-b87f-4d83-a24b-992eb1c4de1f

## Testing

- `cargo test -p fs git_clone_progress::tests -- --nocapture`
- `CCACHE_DISABLE=1 ./script/clippy -p fs -p activity_indicator`
- Manually cloned a repository and verified live Git progress in the
activity indicator.

Release Notes:

- Improved repository cloning by showing live Git progress in the
activity indicator.
2026-09-04 10:39:14 +00:00
Xiaobo LiuandMrSubidubi 83ffa665ed panel: Remove unused panel crate (#63742)
# Objective

remove unused crate

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- N/A

---------

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: MrSubidubi <finn@zed.dev>
2026-09-04 10:08:26 +00:00
Radhi RashoandMrSubidubi 184971d11d title_bar: Hide organization section when signed out (#63728)
# Objective

- Fixes #63433
- Currently, when there is no logged in user, the Organization menu item
shows up even though it should not.

## Solution

- This PR simply does an early return when there is no logged in user,
which skips the logic to add the organization header into the menu drop
down.

## Testing

- Open a Zed window
- Sign out of Zed
- Click the menu bar chevron (top-right corner) and ensure that the
Organization Menu item (like in image below is not there anymore.
- Login to make sure it does display properly when a user is logged in. 
- I tested this on a Windows Machine as I use that for development, but
I believe the reproduction steps should be the same across Operating
Systems. I don't have access to other operating systems, so that might
be something that I'd need the communities help with to make sure
everything is working properly.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments - Not Applicable
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior - Not Applicable.
- [ ] Performance impact has been considered and is acceptable - Not
applicable

## Showcase

Before: Image is from the Original issue
<img width="438" height="458" alt="image"
src="https://github.com/user-attachments/assets/c4852e86-1b68-42d8-ad79-68904214eed7"
/>

After:

https://github.com/user-attachments/assets/520f2564-36da-433b-9339-8c0210695ee0

---

Release Notes:

- Fixed issue where "Organization" section in dropdown menu was being
rendered empty when no user was logged in.

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-09-04 09:32:29 +00:00
Ali 153405b4cb editor: Preserve the trailing newline when converting case (#63463)
# Objective
Case conversion commands deleted the newline at the end of the
selection,
merging the selected line into the line below it.

To reproduce:

1. A buffer with two lines:

   ```
   hello world
   goodbye
   ```

2. Put the cursor on line 1 and run `editor: select line` — this selects
   `hello world\n`, newline included.
3. Run `editor: convert to upper camel case`.

Before: `HelloWorldgoodbye`, one line. After: `HelloWorld` / `goodbye`.

## Testing

Added a regression test to `test_manipulate_text`.


Release Notes:
- Fixed the case conversion commands deleting the line break when the
selection
  ended at the start of the next line.
2026-09-04 08:25:51 +00:00
CainandChristopher Biscardi 326a5f026a editor: Add optional cursor movement animation (#63195)
# Objective

Add an optional smooth cursor movement animation to make cursor position
changes easier to follow, especially during larger jumps and
multi-cursor editing.

Related to #4991.

## Solution

- Add a new `cursor_animation.enabled` editor setting, disabled by
default.
- Animate local bar and block cursors using a damped spring while
preserving momentum during rapid cursor movement.
- Support multiple local cursors independently.
- Continue using the cursor color provided by the active theme.
- Snap immediately when scrolling, resizing, or other viewport changes
would make interpolation misleading.
- Respect the `reduce_motion` setting.
- Request animation frames only while an enabled cursor animation is
active.

Enabling the feature causes additional editor redraws while the cursor
is moving, so it is opt-in and the performance cost is mentioned in the
setting documentation.

### Attribution

The cursor spring physics and four-corner deformation algorithm are
adapted from
[vscode-neovide-cursor](https://github.com/LengineerC/vscode-neovide-cursor),
which is available under the MIT License and inspired by Neovide.

The implementation adapts the algorithm to Zed's editor and GPUI
architecture, including viewport handling, selection state
reconciliation, multi-cursor support, theme integration, and
reduced-motion behavior. The attribution and license information are
also retained in the source file.

## Testing

Automated checks run on Windows:

- `cargo fmt --all --check`
- `cargo test -p editor cursor_animation --lib`
  - 15 cursor animation tests passed.

The tests cover:

- Spring convergence.
- Short and long cursor movements.
- Mid-animation retargeting and momentum preservation.
- Multiple independent cursors.
- Selection replacement and state cleanup.
- Viewport and scroll changes.
- Invalid or unusually large timing values.
- Supported cursor shapes.

To test manually:

1. Add the following to the settings file:

   ```json
   "cursor_animation": {
     "enabled": true
   }
   ```

2. Move the cursor using typing, arrow keys, mouse clicks, and
multi-cursor actions.
3. Toggle the setting off and confirm that cursor rendering immediately
returns to its normal behavior.

Manual testing was performed on Windows and Linux using a release build
from this exact PR branch.

Verified that:

- Cursor animation is disabled by default.
- Enabling `cursor_animation.enabled` is hot-reloaded without restarting
Zed.
- Disabling the setting immediately restores the original cursor
behavior.
- Cursor movement remains responsive during typing, keyboard navigation,
and mouse navigation.

This exact PR branch has not yet been manually tested on macOS.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase


https://github.com/user-attachments/assets/17450529-491e-4982-b539-c46e3d5df467

---

Release Notes:

- Added an optional cursor movement animation setting.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-09-04 07:36:22 +00:00
Som b536d5369d editor: Keep deleted git-gutter marker visible at small custom widths (#63434)
# Objective

- Fixes #62923.
- When `gutter.git_gutter_width` is set to a small `Custom` value (e.g.
`{"custom": 6.0}`), the deleted-line marker becomes disproportionately
small. It is nearly invisible in the reporter's screenshots, while
added/modified markers scale acceptably.

## Solution

- The deleted marker's `Default` arm uses a `0.35 * line_height` base;
the strip's `Default` arm uses `0.275 * line_height`. That 27% larger
base is what keeps the pill-shaped deleted marker visible next to the
rectangular added/modified strips.
- The `Custom(N)` arm previously used `N` for both branches, dropping
the boost. This PR routes the deleted-empty case through a new
`deleted_marker_base_width(setting, line_height)` helper that applies a
single `DELETED_MARKER_WIDTH_RATIO = 0.35 / 0.275` constant to both
arms.
- Default-mode pixels are byte-identical because `floor(0.275 * lh *
0.35/0.275)` reduces to `floor(0.35 * lh)`. Custom-mode gains the same
1.273× multiplier the default has always had.

## Testing

- Added a pure `#[test] fn test_deleted_marker_base_width` covering
three invariants:
- `Default` at `line_height = 22.0` returns `7px`, identical to the
previous default arm.
- `Custom(6.0)` at `line_height = 22.0` returns a width greater than 6.0
(visibility preserved).
- `Custom(0.0)` returns `0.0`, so the width-0 render path is unchanged.
- Verified locally on Windows: `cargo fmt --all -- --check`, `cargo
check -p editor`, and `cargo clippy -p editor --all-targets -- -D
warnings` all exit 0.
- I have not visually verified the rendered marker on macOS or Linux. A
reviewer with the reporter's setup (`git_gutter_width: {"custom": 6.0}`
on macOS) can confirm the pill stays visible.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Fixed the deleted git-gutter marker becoming nearly invisible when
`git_gutter_width` is set to a small custom pixel value.
2026-09-04 07:35:34 +00:00
Daniel Shneyder aa11d12a93 markdown: Apply heading level text styles to the shaped text (#63465)
# Objective

Follow-up to #63118. That PR set the preview's headings to semibold and
gave h6 a muted color through `heading_level_styles`, and the PR body
says as much, but neither actually rendered. Headings in the preview
came out at the base weight and color, which you can see in the after
screenshot on that PR: every heading is regular while the bold body text
and the table header cells are heavy.

I found this while looking into @Arcitec's report on #63118 about bold
not rendering with SF Pro. That one turned out to be a different bug: SF
Pro is a variable font, and the Linux text system does not pass the
requested weight through to it. It is tracked in #60155 and #62832 has a
fix up for it, so this PR does not touch it.

## Solution

`apply_heading_style` wrote the per-level style onto the heading div
only. The div's text style reaches layout, which is why the font sizes
worked, but the text runs are shaped from `MarkdownElementBuilder`'s
style stack, and nothing ever pushed the level style onto that stack. So
weight and color were dropped on the floor.

The fix pulls the level lookup out into `heading_level_style` and has
`push_markdown_heading` refine the heading's run text style with it
before pushing, alongside the existing div refinement. No style values
change anywhere. The agent panel's level styles only set font size, so
its rendering is identical before and after; I checked.

## Testing

- `cargo test -p markdown` and `./script/clippy` are clean.
- Smoke tested the preview on Linux with a document covering h1 to h6,
headings containing bold, italic, code, and links, a wrapping heading,
lists, blockquotes, tables, and code blocks. Headings are now semibold,
h6 is muted, sizes and h1/h2 borders are unchanged.
- Checked the agent panel with a reply containing headings, bold, a
list, and a table: unchanged.
- No new test. The test platform's text system is a no-op that returns
the same `FontId` for every font, so an assertion on run weight could
not fail.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments (there are none)
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior (see Testing for why not)
- [x] Performance impact has been considered and is acceptable

## Showcase

Before is `main` at 6dc2206180, which already includes #63118, so the
only difference is the heading weight and the h6 color.

| Before | After |
|--------|-------|
| <img width="1933" height="2101" alt="zed_before"
src="https://github.com/user-attachments/assets/b84d536a-235d-45bf-9b38-34027accc091"
/> | <img width="1933" height="2101" alt="zed_after"
src="https://github.com/user-attachments/assets/27d90afd-93c9-4118-96c8-f849b1ad096d"
/> |

Release Notes:

- Fixed Markdown preview headings not rendering at their configured
weight.
2026-09-04 07:28:43 +00:00
Coinleft LFTandKirill Bulatov fe56c3cac4 Redact environment secrets from dev container docker exec logs (#63606)
# Objective

Fixes #63569

`run_docker_command` Debug-formatted the whole `docker exec` command, so
every `-e NAME=VALUE` pair forwarded into a dev container was written to
`Zed.log` in plaintext: once at DEBUG, and again in the error message
that `remote_client.rs` logs at ERROR on a failed reconnect.

## Solution

Render the command with `redact_arguments`, which replaces the value of
every `-e NAME=VALUE` argument with `<redacted>` before the arguments
are flattened, and pass the remaining arguments and stderr through
`util::redact::redact_command`.
Validate `containerEnv` and `remoteEnv` keys in `spawn_dev_container`
before any container is reused or built, because an empty key produced
`-e =VALUE`, which the Docker CLI rejects while echoing the value
verbatim to stderr.
Skip invalid names in `remote` as well, since `remote_env` is also
rehydrated from the workspace database.
The shared predicate lives in `util::redact::is_valid_environment_name`.

The DEBUG line now logs the redacted command and exit status only; the
previous stdout and stderr byte dumps are gone.

## Testing

`cargo test -p remote -p dev_container --lib`.
Unit tests cover redaction of forwarded env, argument boundaries,
assignments inside program arguments and stderr, invalid-name skipping
and rejection, and the podman CLI.

Release Notes:

- Fixed dev container environment variables being logged in full

---------

Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2026-09-04 03:02:13 +00:00
Bowen XuandKirill Bulatov e9f5215b42 gpui_web: Update example to use run_embedded() instead of run() (#63235)
# Objective

- Make the gpui_web example run correctly

## Solution

- The gpui_web example uses `run()`, which should be replaced with
`run_embedded()`; otherwise, the page will be blank.

## Testing

- I tested it locally.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

**_Before:_**
<img width="1730" height="1527" alt="before"
src="https://github.com/user-attachments/assets/1935a2a0-7509-4bd6-bdba-6538a37de375"
/>
<br/><br/>

**_After:_**
<img width="1730" height="1527" alt="after"
src="https://github.com/user-attachments/assets/564aef15-7c1e-4978-a95d-07ad4fd680e4"
/>

<br/><br/>
Release Notes:

- Fixed the `gpui_web` example.

---------

Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2026-09-04 01:35:56 +00:00
342bafafee Send session headers on all OpenCode requests (#63702)
Fixes https://github.com/zed-industries/zed/issues/63672

OpenCode Go now requires the `x-opencode-session` header on every model
request. Zed previously sent the header only when a request already had
a thread ID, so inline assistance, terminal assistance, and other
standalone requests could omit it and risk rejection.

This change makes the OpenCode provider add the header to every request.
Existing thread and assist session IDs are reused when available.
Standalone requests receive a generated non-empty ID. Thread title and
summary requests now carry the thread ID so related requests keep the
same session scope.

The change also adds tests for missing, empty, and invalid IDs, plus a
wire-level test that verifies the header reaches the HTTP client. The
provider test file stays separate so the implementation remains under
1,000 lines.

Testing:

- `cargo fmt --all -- --check`
- Focused OpenCode, thread summary, and thread title tests
- `cargo check -p agent_ui -p sidebar`
- `GITHUB_ACTIONS=1 ./script/clippy -p language_models`
- `git diff --check`

Release Notes:

- Fixed OpenCode Go requests that could fail when Zed omitted the
session header.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-09-03 18:29:10 +00:00
Richard Feldman c41a5fa028 Treat OpenAI 404 responses as transient (#63705)
OpenAI can return HTTP 404 during temporary service disruptions, but
language model errors currently classify that status as permanently
missing. Treat OpenAI 404 responses as transient while leaving other
providers unchanged, and expose the shared transient classification so
retry executors can consume it directly instead of inferring it from a
first-attempt delay.

Release Notes:

- Improved recovery when OpenAI temporarily returns HTTP 404 errors.
2026-09-03 16:46:06 +00:00
tidelyandMrSubidubi 32a0e6b48b settings_ui: Fix layout issues with recently created GitHub accounts (#63630)
# Objective

Fixes #62169

Accounts which are marked "too young" have layout issues within the LLM
settings. Example provided in the linked issue.

## Solution

Allow the provider controls to shrink to the available width instead of
retaining their content width. Also make the young-account configuration
fill that width so the warning wraps correctly without collapsing the
provider description.

I think the "Upgrade to Pro" looks a little stretched now, but I don't
know how to fix it without allocating even more space for the already
large setting section. Could we possibly shorten the 30-day requirement
explanation? Regardless, it's much better than what it was before :D

## Testing

- I added a debug selector to be able to write a regression test for
layout issues. Since the UI may change, the tests only enforce the rough
layout.
- Compiled with `too_young_account` being `true` and `false`, checking
that the UI looks okay.


## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
  <summary>Click to view showcase</summary>

Before:

<img width="639" height="678" alt="image"
src="https://github.com/user-attachments/assets/45ed32b0-8987-49d1-8bbd-a12f7917570a"
/>


After:

<img width="640" height="225" alt="image"
src="https://github.com/user-attachments/assets/bb39a847-7d36-4597-b16d-6a6ccb872817"
/>

</details>

---

Release Notes:

- Fixed layout issues in settings when using recently created GitHub
accounts

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-09-03 15:16:07 +00:00
Tom Houlé b7e762128b cloud_api: Add notification update message (#63695)
Allow Cloud to send notification invalidations. Add
`NotificationsUpdated` to the `cloud_api_types` protocol and handle it
explicitly as a no-op in the existing user and LLM token listeners.

Release Notes:

- N/A
2026-09-03 14:38:23 +00:00
Cameron Mcloughlin 7211b33bd4 gpui: Add Hitbox::is_hovered_at (#63696)
Adds `Hitbox::is_hovered_at` to improve touch selection on delta web

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-09-03 14:36:51 +00:00
Lena 2707b08b13 Add issue upvotes to the community PR board (#63692)
We already had the PR's upvotes (all the positive reactions,
deduplicated by user); this commit adds the issue-closed-by-the-PR's
upvotes (deduplicated against the PR's upvoters too). The code got even
uglier because I'm trying to avoid extra API calls.

Release Notes:

- N/A
2026-09-03 13:28:03 +00:00
Chara 07301a1aea agent_ui: Wrap long ask_user options (#63656)
# Objective

Fixes #62955

Long `ask_user` option labels are currently truncated with an ellipsis,
which can hide part of the response text.

## Solution

Remove truncation from the shared elicitation option label so it uses
the label's default multiline wrapping. This affects both single- and
multi-select options without changing selection behavior.

## Testing

- `cargo fmt --all -- --check`
- `cargo test -p agent_ui -- --nocapture` — 429 passed, 0 failed
- `cargo build -j 2 -p zed --bin zed`
- Manually reproduced the issue using a long `ask_user` option label.
- Verified that the complete label wraps without an ellipsis at wide and
narrow panel widths.

---

Release Notes:

- Fixed long `ask_user` options being truncated instead of wrapping.
2026-09-03 13:24:32 +00:00
$H!NDGEKYUME c2f6ece4e2 Add a history list key context to the Git panel (#63689)
# Objective

The Git Panel exposes the `ChangesList` key context while its list is
focused, including when the History tab is active. This causes
Changes-only keybindings to match in History and provides no context for
History-specific bindings.

This is a fresh submission of the revised change from #63669, as
requested in that PR's discussion.

Fixes #61012

## Solution

Select the list key context from the active Git Panel tab. Changes
exposes `ChangesList`, while History exposes `HistoryList`. The shared
`GitPanel` and `menu` contexts remain unchanged.

Preserve compatible keyboard behavior by sharing navigation,
confirmation, and cancellation bindings between `ChangesList` and
`HistoryList` on macOS, Linux, Windows, and Vim. File, staging, restore,
and commit-editor bindings remain exclusive to `ChangesList`.

Extend the dispatch-context test to verify that the list contexts are
mutually exclusive and absent while the commit editor is focused.

## Testing

- `cargo fmt --package git_ui -- --check`
- `./script/check-keymaps`
- `git diff --check`
- `cargo test -p git_ui test_dispatch_context_with_focus_states --
--nocapture`
- `cargo test -p git_ui` (153 passed)
- `cargo build -p zed`
- Manually verified on macOS that History reports `HistoryList` without
`ChangesList`, arrow navigation selects commits, and Enter opens the
selected commit
- Linux and Windows keymaps were updated and checked, but not manually
exercised on those platforms

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

The Keyboard Context view shows `GitPanel`, `menu`, and `HistoryList`
while the History tab is focused. `ChangesList` is absent.

![Keyboard Context view showing the HistoryList
context](https://github.com/user-attachments/assets/63422131-b16d-4d30-997c-17aec7924011)

---

Release Notes:

- Fixed Git Panel keybindings matching the Changes tab while the History
tab is active.
2026-09-03 12:55:21 +00:00
Albert Bogusz 998775e60d git_ui: Fix git::FileHistory action in diff views (#63539)
# Objective

The `git::FileHistory` action ("View File History") silently does
nothing when a diff view is the active item (single-file or multibuffer
project diff).

## Solution

Diff views wrap their inner `Editor` and expose it via `act_as`, but
`resolve_file_history_target` used a strict `active_item_as::<Editor>`
downcast, which returns `None` for these wrappers. Resolve through
`act_as` instead.

## Testing

Added a regression test which opens a `ProjectDiff`, dispatches
`git::FileHistory`, and asserts the file's history graph opens. I've
verified it fails without the `act_as` fix, and confirmed the fix
manually (see Showcase).

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

Left is before, right is after:


https://github.com/user-attachments/assets/39972bdf-b24f-4583-afd7-d6eb5226f50f

---

Release Notes:

- Fixed viewing a file's Git history when in a diff view.
2026-09-03 12:09:00 +00:00
itsfuad 6a115bc241 git: Separate revisions from paths in git commands (#63666)
Closes #63665

A branch whose name also matches a path in the working tree, such as a
branch `docs/rewrite` in a repository that also has a `docs/rewrite`
directory, was passed to git as a bare argument, so git could not tell
the revision from the path:

```
fatal: ambiguous argument 'docs/rewrite': both revision and filename
```

The git panel's History tab showed "Failed to load commit history",
commit search returned no results, branch diff failed, and opening a
commit by ref failed.

The revision lists are now terminated with `--`.

That also required moving `--no-ext-diff` in `build_command`. It was
appended after the caller's arguments, so once a terminator was present
it landed past the separator and git read it as a pathspec. The diff
then came back empty with exit status 0 and no error, which broke three
existing `merge_base_worktree` tests. It now goes directly after the
subcommand, where it cannot fall past a terminator. This also means it
is no longer swallowed as a pathspec by `diff_stat`, which already ended
its arguments with `--` and a path list.

`git merge-base` takes no pathspec, so it was never ambiguous and is
unchanged.

This also fixes the `fatal: ambiguous argument` error reported in
#61186. That report additionally shows an `error: invalid option:
--merge-base` failure when the base branch does not exist locally, which
is a separate problem and is not addressed here.

### Tests

Three regression tests, one per affected surface, each building a
repository whose branch name matches a directory. All three fail on
`main` with the ambiguity error. A fourth test pins that every
revision-taking `LogSource` terminates its revision list, and that
`LogSource::Path`, which states its own separator, does not gain a
second one.

`cargo test -p git`: 76 passed. Clippy and `cargo fmt` clean.

### Before

<img width="542" height="950" alt="Screenshot From 2026-09-03 09-15-13"
src="https://github.com/user-attachments/assets/c54577c7-5066-4cdd-a03c-c67c6803ad33"
/>


### After

<img width="386" height="471" alt="Screenshot From 2026-09-03 10-08-42"
src="https://github.com/user-attachments/assets/b985bb16-60a2-4f50-ad2a-609c6a126bfb"
/>

Release Notes:

- Fixed the git panel's History tab, commit search, branch diff, and
opening a commit by ref failing when the branch name matches a path in
the working tree
2026-09-03 11:14:41 +00:00
Matei Oprea 2163e928aa remote_servers: Dismiss picker on Open Folder click (#63628)
# Objective

- Clicking "Open folder" on a remote server entry in the remote projects
picker did not close the picker itself. The picker was staying
underneath the new opened modal for folder/project picker.

## Solution

- Emit `DismissEvent` immediately when `RemoteMatch::OpenFolder` is
confirmed. This mirrors the existing pattern in
`open_remote_project_entry` which already dismisses immediately before
proceeding with the async connect flow.

## Testing

- Did you test these changes? If so, how?
- Are there any parts that need more testing?
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable


Release Notes:

- Fixed the remote projects picker not closing when opening a folder on
a remote server
2026-09-03 11:04:20 +00:00
Dmitry IvanishkinandKirill Bulatov fad8515a7a git_graph: Show time in commit details (#62679)
# Objective

The Git Graph list shows the full commit timestamp in its constrained
date column, while the more spacious commit details view only shows the
calendar date. Include the time in the details view so it does not
provide less information than the graph itself.

## Solution

Reuse the existing `format_timestamp` helper from the Git Graph `Date`
column when rendering the selected commit details. This gives both views
the same local date and time format without a separate formatting path.

## Testing

- `cargo check -p git_ui`

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Improved Git Graph commit details to show the same full commit
timestamp as the `Date` column.

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-03 09:47:23 +00:00
Smit BarmaseandKirill Bulatov d4424eec68 which_key: Add a pending key binding indicator (#63343)
This PR makes Zed's one-second key binding delay visible.

Say both ctrl-w and ctrl-w left have bindings. After you press ctrl-w,
Zed waits to see whether left follows. The PR shows that wait in the
status bar with a countdown. Hovering the indicator shows which bindings
can still match.

It also adds a setting to hide the indicator. It does not change how Zed
resolves key bindings.

<img height="100" alt="dyn-db84a840272e2f6250a3f527a59b1efd"
src="https://github.com/user-attachments/assets/e42c6a6c-4677-499f-a1d3-835960ebb21a"
/>
<br/>
<img height="100" alt="dyn-8012278d030b41bc8ebfae1540504eff"
src="https://github.com/user-attachments/assets/250928d5-f913-40f0-9068-00ccb5cdf59f"
/>
<br/>
<img height="100" alt="file-5e6ffa90944faa294e7870f471b4e65b"
src="https://github.com/user-attachments/assets/c250e6eb-a269-4e2c-a5a0-0be9b5006f99"
/>

Release Notes:

- Added a status bar countdown for pending multi-stroke key bindings.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-03 09:35:53 +00:00
Smit Barmase a47324bb2b gpui: Add an option to keep hover listeners active after keyboard input (#63614)
While working on https://github.com/zed-industries/zed/pull/63343, I ran
into a problem with the pending key binding indicator. Hovering pauses
its countdown, but pressing the next key made `on_hover` report false
even though the mouse had not moved. The countdown then resumed while
the pointer was still over the indicator.

`on_hover` currently follows GPUI's normal hover rules. GPUI clears
hover after keyboard input so the item under a stationary mouse does not
interfere with keyboard navigation, for example list popover navigation
with keyboard.

This PR adds `HoverListenerMode` and `hover_listener_mode`. Callers that
need to track the pointer across key presses can opt in like this:

```rs
div()
    .hover_listener_mode(HoverListenerMode::InputModalityIndependent)
    .on_hover(|is_hovered, window, cx| {
          // ...
      })
```

`InputModalityAware` remains the default.

Release Notes:

- N/A
2026-09-03 09:35:52 +00:00
denizdogan 9441364cf1 Fix Keymap Editor "Search by Keystrokes" shortcut shadowed by the text finder (#63376)
# Objective

Fixes #62361.

In the Keymap Editor, focus lands on the "Filter action names" input,
which is wrapped in a `BufferSearchBar` key context
(`crates/keymap_editor/src/keymap_editor.rs`). Its `cmd-alt-f →
text_finder::Toggle` binding (added in #60677) shadows the
`KeymapEditor` context's `cmd-alt-f →
keymap_editor::ToggleKeystrokeSearch`, because `BufferSearchBar` sits
deeper in the focus stack — so `cmd-alt-f` in the filter opens the file
finder instead of toggling "Search by Keystrokes". Same collision on
Linux (`ctrl-alt-f`); Windows is unaffected (it uses `alt-f`).

## Solution

Add a `KeymapEditor > BufferSearchBar` binding mapping the chord back to
`keymap_editor::ToggleKeystrokeSearch`, in `default-macos.json` and
`default-linux.json`. It's more specific than the plain
`BufferSearchBar` binding and placed after the `KeymapEditor` block, so
it wins the same-depth tie-break (gpui precedence: depth, then
definition order) — restoring the shortcut inside the Keymap Editor
without affecting the global text finder.

I gave the `KeymapEditor` binding precedence rather than rebinding
"Search by Keystrokes" to a non-conflicting default (e.g. `cmd-alt-k`),
since it's less invasive and doesn't change a documented default. Happy
to switch to the rebind if the team prefers.

## Testing

Built and ran locally on macOS: opened the Keymap Editor (`cmd-k
cmd-s`), pressed `cmd-alt-f` with focus in the filter → "Search by
Keystrokes" toggles instead of opening the file finder; confirmed the
file finder still works normally in a regular editor. `cargo test -p zed
keymap` passes (validates the bundled keymaps parse and all actions
resolve).

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Tests cover the new/changed behavior (bundled-keymap validation
exercises the new binding; runtime behavior manually verified — no logic
to unit-test in a default-keymap change)

_Unsafe blocks / UI standards / performance: N/A for a keymap default
change._


Release Notes:

- Fixed the Keymap Editor's "Search by Keystrokes" shortcut (`cmd-alt-f`
/ `ctrl-alt-f`) being shadowed by the file finder.
2026-09-03 08:45:58 +00:00
Vlad GaevskyandMrSubidubi d0699ca1d6 gpui: Snap recomputed padding to the device pixel grid before clamping scroll (#62296)
# Objective

Follow-up to #62135, taking the approach suggested there: fix the error
at its
source in GPUI instead of hiding it in the scrollbar.

At fractional rem sizes (`py_1` at an odd UI font size), a container
whose
content fits becomes scrollable by a sub-pixel amount, and every
uniform-list
picker grows a full-height scrollbar thumb for that phantom range.

## Solution

Taffy lays boxes out with every authored length snapped to the device
pixel grid
(`to_taffy`), and the final bounds are snapped again after layout.
However,
`Interactivity::clamp_scroll_position` recomputed the padding from the
raw style
with no snapping at all, so the padded content size exceeded the snapped
bounds
by up to half a device pixel, far past the existing two-decimal
float-noise
rounding, and `scroll_max` came out positive.

The fix snaps the recomputed padding with the same `pixel_snap` helper
the rest
of the pipeline uses, so both operands of the subtraction sit on the
same grid
and the phantom range never comes into existence.

Two neighbouring cases are deliberately left out to keep this scoped,
both are
follow-up candidates: percentage-based padding resolves inside Taffy
without
pre-snapping, so a discrepancy is still theoretically possible there;
and
`ListState::max_scroll_offset` (the older `list()` element) has no
rounding
protection at all.

## Testing

- New regression test: a 50px container with `py(4.25)` padding and a
child that
fits exactly. It fails on main (`max_offset` comes out at 0.5px) and
passes
  with the fix; verified in both directions.
- Full gpui suite: 241 tests pass.
- Reviewers can see the original symptom by opening any picker at a UI
font
size that makes `py_1` fractional in device pixels: a spurious
full-height
scrollbar thumb appears on main and is gone with this change. The math
is
  logical-pixel only, so the behavior is platform-independent.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable (one
pixel-snap
per padding edge per clamp, negligible against existing per-frame layout
work)

cc @MrSubidubi

Release Notes:

- Fixed containers becoming scrollable by a sub-pixel amount, with a
phantom
  full-height scrollbar thumb, at fractional UI font sizes.

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-09-02 23:15:40 +00:00
Finn Evers 946dab8c11 extension_cli: Error on unrecognized files and queries in language directories (#63080)
This ensures that we do not copy over resources we do not need for
languages. We enforce this at this stage so that potential contributors
to these extensions do not think these files might be needed for the
given language.

Release Notes:

- N/A
2026-09-02 22:45:15 +00:00
kai-xlr 443318ef01 agent_ui: Hide manage skills command when AI is disabled (#63598)
# Objective

Fixes #63495

When `"disable_ai": true` is set, `agent: manage skills` still appears
in the command palette. The action was exposed by the `else` branch of
the `disable_ai` check in `update_command_palette_filter`, which called
`show_action_types` on it — overriding the `hide_namespace("agent")`
applied when AI is disabled.

## Solution

Moved `filter.hide_action_types(&manage_skills_action)` out of the
conditional so it applies regardless of the `disable_ai` setting. Skills
are surfaced through the settings UI now, so the command should never
appear in the palette.

Added test coverage in `test_agent_command_palette_visibility`:
- Asserts `ManageSkills` is hidden even when AI is enabled (the
invariant).
- Asserts `ManageSkills`, `OpenSkillCreator`, and `NewThread` are hidden
when AI is disabled.

## Testing

- `cargo test -p agent_ui` (398 passed)
- `./script/clippy -p agent_ui`
- `cargo fmt --check`
- Manual verification: set `"disable_ai": true`, open the command
palette, filter `agent` — `agent: manage skills` should be absent.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments (no unsafe blocks)
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Fixed `agent: manage skills` still appearing in the command palette
when AI is disabled
2026-09-02 20:56:51 +00:00
Cameron Mcloughlin 81808cb5db gpui: Add TouchDragEvent API (#63645)
Adds `TouchDragEvent` and coresponding APIs. This allows web/touch-based
code to capture long press events without having to go through
scroll-like APIs

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-09-02 20:28:07 +00:00
Shuhei KadowakiandKirill Bulatov 8482496a16 lsp: Honor dynamic LSP document selectors (#59243)
Zed previously discarded the documentSelector from dynamically
registered textDocument capabilities and treated those capabilities as
applicable to every buffer attached to the server. This could route
requests for documents outside a registration selector.

Track dynamic textDocument registrations by method and registration ID,
and use their selectors when routing local requests, checking
capabilities, and deriving completion triggers. Static capabilities
continue to apply to every attached buffer. Language and URI scheme
matching are supported, while unsupported pattern matching remains
fail-open.

Keep document color, symbol, link, code lens, and folding range caches
aligned with the selector-aware server set so incapable or non-matching
servers do not leave caches perpetually incomplete.

Require an advertised diagnostic provider before sending pull diagnostic
requests, and add integration coverage for selector-aware dynamic
completion registration and trigger updates.

---

Release Notes:

- Improved language server request routing to respect dynamically
registered document selectors.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-02 19:54:04 +00:00
Kirill Bulatov 9be65a8dfe Strip local symbols from macOS and Linux release bundles (#63429)
Not sure if this PR is 100% good, since it removes symbols from local
traces, leaving addresses only — but this what Windows seem to do
already, and we have those symbols on Sentry to restore from, which were
needed to normally read Linux perf traces already (see `perf.zip` in
https://github.com/zed-industries/zed/issues/59689#issuecomment-5452720248)

On the upside, uncompressed binaries' are now ~100MB less, which is a
lot — hence decided to open the PR for the review

-------------------

Strips debug info and local symbols from shipped macOS and Linux
binaries, matching what Windows already does with PDBs: `bundle-mac` now
always runs `dsymutil` before a new `strip -x` step, and `bundle-linux`
adds `--discard-all` plus `zed.dbg`/`remote_server.dbg` extraction via
`--only-keep-debug`.

Sentry uploads are unchanged and precede stripping.

The macOS binary UUID and the GNU build id survive stripping, so
user-provided traces stay recoverable without rebuilding at the
reporter's commit: `sample` output resolves via `atos` against the
archived `zed.dwarf`, and `perf.data` via `perf buildid-cache` against
the Sentry-archived binary.

zed binary:
macOS (2026-08-29 nightly): 420478976 -> 316503984 bytes (-24.7%,
-104.0MB)
Linux (v1.17.2 aarch64): 439417448 -> 336967256 bytes (-23.3%, -102.5MB)
Downloads shrink far less, symbols compress ~7:1: the macOS DMG loses
only ~15MB.

Release Notes:

- Improved installed size on macOS and Linux by stripping debug symbols
from release binaries (roughly -25%)
2026-09-02 19:38:12 +00:00
Kirill Bulatov 8b32975a05 Fix workspace diagnostics polling (#63336)
Closes https://github.com/zed-industries/zed/issues/62391

Workspace diagnostics were polled incorrectly:

* Workspace pulls were cancelled and re-sent every 120s.
Pyright-family servers hold the request open forever and re-analyze the
whole workspace on every new one, so the retry loop leaked memory; the
request is now kept open (long-poll), as the spec recommends.

* No re-trigger after a server closed a workspace pull.
ty closes the request when diagnostics change and expects the client to
re-pull
 
* `ServerCancelled` / `retriggerRequest` was ignored.
The spec defaults cancellation data to `{ retriggerRequest: true }`, so
these errors now retrigger workspace pulls and retry document pulls
instead of failing them.

* LSP error codes were erased with `anyhow!(message)`
Errors now carry a typed `lsp::ResponseError` through the chain,
replacing four copies of `ends_with(...)` matching against
rust-analyzer's literal message texts.

* Workspace partial results were not tied to their request.
Stale or numeric-token `$/progress` reports were applied as current data
and could poison `previousResultIds` until a server restart; reports are
now matched against the exact in-flight token.

* `interFileDependencies` was never read.
Every edit re-pulled all other open buffers even for servers declaring
no inter-file dependencies (e.g. ruff); cross-buffer pulls are now gated
on that capability.

* Cross-buffer pulls were unpaced.
All open buffers were pulled back-to-back after each edit debounce; they
are now paced at one document per 500ms.

* The failure valve killed workspace pulls permanently.
51 hard errors over a server's lifetime silently stopped its workspace
pulls until restart

* Concurrent refresh waiters could be dropped instantly.
The capacity-1 refresh channel resolved a second concurrent waiter to
`false` immediately, and request errors dropped queued refreshes;
waiters now queue and carry over to the retried pull.

Release Notes:

- Fixed basedpyright memory leak caused by incorrect workspace
diagnostics polling
2026-09-02 19:12:35 +00:00
Finn Evers bfad3a6108 docs: Document focus_follows_mouse (#63646)
Release Notes:

- N/A
2026-09-02 18:54:48 +00:00
Kaj KowalskiandKirill Bulatov cdee8dd547 Properly clear diagnostics data for stopped servers (#63460)
# Objective

Diagnostics published by a language server survive the buffer being
detached from that server, so a file keeps showing errors from a server
that is no longer reading it.

To reproduce:

1. Install the [GitHub Actions
extension](https://zed.dev/extensions/github-actions).
2. Open a composite action definition,
`.github/actions/<name>/action.yml`.
3. Select the GitHub Actions language for it in the language selector.
That server validates the file as a workflow, so it reports `on` and
`jobs` as missing and `inputs`, `outputs` and `runs` as unexpected.
4. Select YAML again, since GitHub Actions was not what you wanted here.
5. The errors are still there. `editor: restart language servers` does
not clear them either. They go away only once the buffer is dropped, in
practice by switching to another project and back.

Two things keep them alive:

- `LocalLspStore::unregister_buffer_from_language_servers` drops the
snapshot bookkeeping and sends `didClose`, but never clears what that
server already published. `LspStore::set_language_for_buffer` calls it,
so a language change detaches the buffer while leaving the old verdict
on it.
- Restarting does not reach the server either.
`stop_local_language_servers_for_buffers` collects servers through
`language_server_ids_for_buffer`, evaluated against the language the
buffer has *now*. The old server no longer matches, so it is never
stopped, and it is typically still running legitimately for other files
in the project. Only `stop_local_language_server` clears diagnostics,
and it is never reached for that server.

## Solution

The first commit cleared the detached server's diagnostics inside
`unregister_buffer_from_language_servers`, on `didClose`. Review pointed
out that publishes are applied by path regardless of registration, so a
running server can legitimately describe a file that is no longer open
in it, and that this clearing also left `diagnostic_summaries` and the
worktree's per-path diagnostics stale.

The second commit reworks this. Detaching a buffer now only drops the
buffer's entry in `buffers_opened_in_servers` and the path's
pull-diagnostics result ids for the servers it left, two pieces of
per-server state that previously leaked. After the buffer is registered
with the servers of its new language, the server tree is rebuilt through
`refresh_server_tree`, the same pruning that runs on settings changes:
every server no registered buffer maps to any more is stopped through
`stop_local_language_server`, whose path already clears buffer
diagnostic sets, `diagnostic_summaries` and worktree diagnostics. A
detached server that other buffers still map to keeps running and keeps
everything it published. An earlier revision judged orphanhood by
`buffers_opened_in_servers`, which is only filled in once a server runs,
so it stopped servers that were still starting;
`test_context_completion_provider_mentions` caught that.

## Testing

Added `test_selecting_a_language_clears_the_old_servers_diagnostics`: a
Rust buffer gets a diagnostic from a fake server, the buffer is switched
to JavaScript, and afterwards both the buffer's diagnostics and the
project-level `diagnostic_summary` must be empty. It fails on `main`,
where the message survives the switch:

```text
< ["unused constant"]
> []
```

The test passes with the rework and fails without it. The `project` test
suite, `script/clippy` and style checks ran green on the reworked change
in CI. Tested on Linux; the change is platform independent.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

The buffer is back on YAML, as the status bar shows, while the workflow
schema's complaints from the GitHub Actions server are still on screen:
`on` and `jobs` reported missing, and `inputs`, `outputs` and `runs`
reported as unexpected values.

<img width="2514" height="2008" alt="Screenshot From 2026-08-30
21-52-12"
src="https://github.com/user-attachments/assets/040898a6-cc61-41b6-88c6-f346666e8e13"
/>

---

Release Notes:

- Fixed diagnostics from the previous language server staying on a file
after changing its language.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-02 18:23:56 +00:00
Cameron Mcloughlin bd46f70cfd gpui: Prevent touch mispredict jitter (#63638)
When scrolling, mispredicted touch events could cause scroll jitter. We
now ignore predictions that are "travelling the wrong direction".

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-09-02 18:23:32 +00:00
Shuhei Kadowaki e0c38940d5 lsp: Scope logs and status updates to their projects (#61221)
The language registry and LSP log store are shared by every workspace in
a Zed process. The LSP Logs selector enumerated the shared log store
without filtering by project, while each activity indicator consumed
global binary status updates. This exposed servers from other windows as
"Unknown worktree" entries and surfaced their startup failures or
timeouts in unrelated status bars.

Key each logged server by its owning project or LSP store together with
its process-local language server ID. Use that identity consistently
when adding, removing, streaming, selecting, opening, and reselecting
log entries so local, remote, SSH, and supplementary servers cannot
collide across ownership domains.

Model Copilot and other servers outside the project LSP store as
project-scoped supplementary servers, while matching SSH servers by
their owning LSP store.

Tag project-originated binary status updates with the owning LSP store
entity ID. Carry that source through extension worktree delegates and
every worktree-based WASM language-server call, then let each local LSP
store forward only statuses for its project. Activity indicators rely
solely on their project LSP store, and remote projects continue to
receive host statuses through the existing protocol path instead of
subscribing to local registry events.

Own each binary-status subscription task in its local LSP store and
unregister its broadcaster sender when the store is dropped, so closing
windows cannot leave detached status tasks or stale senders behind.

Add regression coverage for duplicate process-local server IDs across
ownership domains, filtering remote, supplementary, and SSH servers from
other projects, retaining servers owned by the current project or LSP
store, preserving extension status sources, and unregistering dropped
status subscriptions.

Release Notes:

- Fixed language servers from other projects appearing in the LSP Logs
view and their statuses showing in unrelated windows' status bars
2026-09-02 18:23:27 +00:00
Cameron Mcloughlin 1a1d00988e gpui_web: Drive IME mirror focus state from GPUI (#63629)
Previously, we manually synchronized the keyboard state in response to
tap events, but this meant that several common cases were unreliable.

Now, we use GPUI's focused element as the source of truth, and use
`sync_virtual_keyboard` in cases where they have gotten out of sync
(i.e. a user manually dismisses a keyboard while the input is still
focused).

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-09-02 18:23:07 +00:00