3f5abf5084ddb7fe2b87e4c44fdfa1a6ec17cac6
39861
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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 |
||
|
|
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 |
||
|
|
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> |
||
|
|
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 |
||
|
|
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 |
||
|
|
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`. |
||
|
|
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>
|
||
|
|
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. |
||
|
|
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 |
||
|
|
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 |
||
|
|
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
|
||
|
|
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. |
||
|
|
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>
|
||
|
|
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. |
||
|
|
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. |
||
|
|
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> |
||
|
|
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> |
||
|
|
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. |
||
|
|
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> |
||
|
|
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. |
||
|
|
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
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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. |
||
|
|
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> |
||
|
|
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 |
||
|
|
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 ... |
||
|
|
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 |
||
|
|
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. |
||
|
|
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.  --- Release Notes: - Fixed Git Panel keybindings matching the Changes tab while the History tab is active. |
||
|
|
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.
|
||
|
|
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 |
||
|
|
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 |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
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. |
||
|
|
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> |
||
|
|
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 |
||
|
|
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 |
||
|
|
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 ... |
||
|
|
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> |
||
|
|
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%) |
||
|
|
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 |
||
|
|
bfad3a6108 |
docs: Document focus_follows_mouse (#63646)
Release Notes: - N/A |
||
|
|
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> |
||
|
|
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 ... |
||
|
|
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 |
||
|
|
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 ... |