a103d8322b27501d2a20fd39fbbef946c5b6c5df
38912
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a103d8322b |
Improve docs AI readiness (#59577)
Context This PR makes the Zed docs easier for AI tools, search crawlers, and users to consume without changing the visible docs content. The current production docs are primarily optimized for browser navigation. They do not expose first-class Markdown URLs, an `llms.txt` index, page-level copy affordances, or machine-readable freshness metadata that let users and agents grab clean, current page content. Changes - Generate Markdown copies for docs pages during the mdBook postprocess step, including `/docs/index.md` as an alias for Getting Started. - Generate `/docs/llms.txt` from the mdBook chapter list, grouped by `SUMMARY.md` sections and annotated with page frontmatter descriptions. - Generate `/docs/sitemap.xml` with `<lastmod>` values for every docs page. - Emit machine-readable freshness metadata in HTML via `last-modified` and `article:modified_time` meta tags. - Generate Cloudflare Pages `_redirects` for `.html`, extensionless, and `.md` redirect variants, with channel-aware docs destinations. - Add discovery hints for agents and crawlers: `rel="llms.txt"`, `rel="alternate" type="text/markdown"`, and a short generated `llms.txt` directive in copied Markdown pages. - Update the docs proxy so `Accept: text/markdown`, `/docs.md`, and direct `.md` requests can resolve to the generated Markdown artifacts. - Move primary docs content earlier in the HTML source while preserving the visible layout, so crawlers and agent scorers encounter the article before sidebar chrome. - Move the existing copy-as-Markdown control from the top navigation into the page-title row, using the generated Markdown alternate link as the source of truth. - Split AI-discovery artifact generation out of `docs_preprocessor/src/main.rs` into a focused module. Best Practices Adopted - Use `llms.txt` as a concise navigation index, not a dump of full page content. - Link to absolute, canonical Markdown URLs from `llms.txt`. - Preserve the docs hierarchy in `llms.txt` instead of emitting a flat sitemap-like list. - Include short per-link descriptions from existing metadata rather than inventing summaries. - Keep `llms.txt`, Markdown copies, sitemap data, redirects, and freshness metadata generated from the same mdBook source to avoid drift. - Advertise Markdown alternates with standard HTML metadata and same-origin URLs. - Support both explicit Markdown URLs and content negotiation for clients that prefer Markdown. - Keep browser copy behavior pointed at generated Markdown alternate links instead of duplicating route inference in JavaScript. - Keep the copy-as-Markdown affordance in the page title row without duplicating header chrome controls. Validation - `cargo check -p docs_preprocessor` - `cargo test -p docs_preprocessor` - `./script/clippy -p docs_preprocessor` - `mdbook build ./docs --dest-dir=../target/deploy/docs/` - `node --check docs/theme/plugins.js` - `pnpm dlx prettier@3.5.0 docs/theme/plugins.js --check` - `git diff --check` - Local artifact checks confirmed generated Markdown pages, `llms.txt`, `sitemap.xml` lastmod values, HTML freshness metadata, Markdown alternate links, redirect targets, and preprocessed action/keybinding tags resolve as expected. - Worker URL rewrite mock covered `/docs/`, `/docs.md`, `/docs/index.md`, extensionless docs routes, `.html` routes, `/docs/llms.txt`, and `/docs/sitemap.xml`. - High-effort adversarial subagent review found blockers around channel-aware redirects, shallow-checkout date fallback, file size, duplicated Markdown path inference, and process spawning. Those were addressed. Remaining Notes - Local `python -m http.server` does not emulate Cloudflare Pages pretty URLs, `_redirects`, or the docs-proxy Worker, so full local `afdocs` still cannot prove content negotiation end to end. - Existing production remains unchanged until this PR is deployed through the docs workflow. - Production baseline `npx afdocs check https://zed.dev/docs/ --fixes --verbose` still reports the original failures before this PR is deployed: 12 passed, 8 failed, 3 skipped. Release Notes: - Improved docs AI-readiness by adding machine-readable discovery, Markdown access, and freshness metadata. --------- Co-authored-by: Katie Geer <katie@zed.dev> Co-authored-by: Ben Kunkle <ben@zed.dev> |
||
|
|
4f6d05dde0 |
Update wayland-backend to fix Wayland file dialog crash (#60621)
On Wayland, closing a window in the brief gap between requesting a portal file dialog and ashpd exporting the window's surface (used to parent the dialog) crashed Zed with `Unknown opcode 0 for object <anonymous>@0` ([ZED-9KB](https://zed-dev.sentry.io/issues/7568720776/)). When the export request fails because the surface is already dead, wayland-scanner's generated code silently returns an inert proxy, and ashpd's `Drop` impl later sends `destroy` on it — which wayland-backend 0.3.11 answers with a panic, because it looks up the request opcode before checking whether the object is null. wayland-backend 0.3.15 fixes this ([Smithay/wayland-rs#890](https://github.com/Smithay/wayland-rs/issues/890)) by returning an error instead, which the generated destructor discards, so the drop becomes a harmless no-op. This bumps the lockfile to 0.3.15 and raises the version floor in `gpui_linux` so the fix can't silently regress via a fresh lockfile. Closes FR-100 Release Notes: - Fixed a crash on Linux (Wayland) when a window was closed just as a file dialog was being opened. |
||
|
|
01d5096a3f |
gpui: Fix hover state not clearing when mouse leaves window (#60275)
# Objective Fix two gaps in element hover tracking at window boundaries. Hover was only re-evaluated on `MouseMove`, so when the pointer left the window no event fired `on_hover(false)` and the element stayed hovered. Symmetrically on Wayland, no `Motion` follows `Enter` until the pointer moves again, so hover was not established at the entry pixel. Both cases are easy to miss since most hover-styled elements don't sit flush against the window edge, but they surfaced while implementing layer_shell popups with input_regions, which should close when stop hovering. ## Solution The hover compare-and-fire logic in `div` is refactored into a shared `update_hover` closure, and a second listener on `MouseExitEvent` clears hover when the pointer leaves the window. It clears unconditionally because `MouseExited` doesn't update the tracked mouse position, so a hit test during that dispatch would still report the element as hovered. On Wayland, a `MouseMove` is synthesized at the entry position on `wl_pointer.enter`, mirroring the `MouseExited` already dispatched on `Leave`. ## Testing Tested manually on Wayland/Linux: hover on a window-edge element clears when the pointer leaves the window, and hover is established immediately when the pointer enters a surface with an element under the entry pixel. Not tested on other platforms. The `div` change relies on each platform's existing `MouseExited` dispatch: macOS and X11 emit it, so they get the exit fix too. Windows never dispatches `MouseExited` (`WM_MOUSELEAVE` only flips the window-level hover flag), so the stuck-hover case might remain there, unchanged from before. Before: https://github.com/user-attachments/assets/6af83bb3-de9d-40e2-a64c-bdefc98fc96d After: https://github.com/user-attachments/assets/721a9b5c-108a-499f-867e-da111836a34a Here is an example application to test this: ```rs #![cfg_attr(target_family = "wasm", no_main)] use gpui::{ App, Bounds, Context, Window, WindowBounds, WindowOptions, div, prelude::*, px, rgb, size, }; use gpui_platform::application; struct HoverExit { hovered: bool, } impl Render for HoverExit { fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement { // Fills the whole window so its edge is the window edge: moving the mouse // out of the window is what exercises the MouseExited path. div() .id("hover-exit") .size_full() .flex() .justify_center() .items_center() .text_xl() .text_color(rgb(0xffffff)) .bg(if self.hovered { rgb(0x585f58) } else { rgb(0x505050) }) .child(if self.hovered { "HOVERED" } else { "not hovered" }) .on_hover(cx.listener(|this, hovered, _, cx| { this.hovered = *hovered; cx.notify(); })) } } fn run_example() { application().run(|cx: &mut App| { let bounds = Bounds::centered(None, size(px(240.), px(160.0)), cx); cx.open_window( WindowOptions { window_bounds: Some(WindowBounds::Windowed(bounds)), app_id: Some("gpui-hover-exit".to_string()), ..Default::default() }, |_, cx| cx.new(|_| HoverExit { hovered: false }), ) .unwrap(); cx.activate(true); }); } #[cfg(not(target_family = "wasm"))] fn main() { run_example(); } #[cfg(target_family = "wasm")] #[wasm_bindgen::prelude::wasm_bindgen(start)] pub fn start() { gpui_platform::web_init(); run_example(); } ``` ## 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: - Fixed element hover state not clearing when the mouse leaves the window |
||
|
|
ae61c133f1 |
gpui_windows: Check composition attribute lookup (#60122)
Checks that SetWindowCompositionAttribute was found before transmuting and calling the function pointer, making the composition setup a no-op when the undocumented export is unavailable. Release Notes: - N/A |
||
|
|
636e764737 |
gpui: Add parent-anchored native popup windows (with wayland xdg_popup implementation only so far) (#60232)
# Objective gpui can't show UI that extends past the window it belongs to. Menus, dropdowns and tooltips are drawn as elements inside the window, so they clip at its edges. This PR adds a window kind for platform-native popups anchored to a parent window, as groundwork for real native menus, dropdowns and tooltips. ## Solution `WindowKind::AnchoredPopup(PopupOptions)` opens a popup positioned relative to a parent window. Instead of giving the popup an absolute position, you describe where it should go and the platform figures out the rest: - `parent`: the window to anchor to - `anchor_rect`: a rectangle in the parent, e.g. the button that opened the menu - `anchor` and `gravity`: which point of that rect to attach to, and which direction to grow - `constraint_adjustment`: what the platform may do if the popup would leave the screen (slide, flip, resize) - `grab`: menu behavior, the popup takes focus and is dismissed when clicking outside the app The popup's size comes from `WindowOptions::window_bounds`. This model mirrors Wayland's `xdg_positioner`, where the compositor owns positioning and the client can only describe intent. Since that's the most restrictive case, the other platforms can implement the same description later with simple math against screen bounds. Only Wayland is implemented so far, via `xdg_popup` on top of the existing surface implementation. Popups can be parented to toplevels, layer-shell surfaces (a menu opened from a panel) and other popups (nested menus). macOS, Windows, X11 and web reject the kind with `PopupNotSupportedError`, so callers can detect that and fall back to in-window popovers. Some Wayland details that might help during review: - Anchor rects are translated from gpui coordinates into the parent's window geometry space and clamped to it. A rect outside the geometry, or with zero size, is a fatal protocol error - Resizing a mapped popup goes through `xdg_popup.reposition` - Mouse press serials are now recorded on press only, not release. Compositors decline grabs and interactive moves that reference a release serial ## Testing Tested manually on Wayland with an example app: the menu opens anchored below its button, extends past the parent window, flips above the button near the bottom of the screen, and a grabbing popup is dismissed when clicking into another application. Nested menus were tested in one of my projects (ignore that they are ugly, that's just a prototype 😛): https://github.com/user-attachments/assets/2cd3e2e9-87f7-4b02-986f-48e5633e205c I also have a complete runnable example demonstrating it. I did not add it to the PR, because this might give the impression that `WindowKind::AnchoredPopup` are a complete implementation, despite only working on wayland so far: <details> <summary>Click to view example</summary> ```rust //! Example and manual test for platform-native popups (`WindowKind::AnchoredPopup`). //! //! A native popup is a real, parent-anchored window that can extend beyond its parent onto the //! screen, unlike gpui's in-window popovers. Run it, open the menu, and confirm the points listed //! in the window. On a platform without an implementation the button reports that popups are not //! supported instead of opening anything. //! //! Run with: cargo run -p gpui --example popup #![cfg_attr(target_family = "wasm", no_main)] use gpui::{ AnyWindowHandle, App, Bounds, Context, MouseButton, SharedString, Window, WindowBounds, WindowHandle, WindowKind, WindowOptions, div, point, popup::*, prelude::*, px, rgb, size, }; use gpui_platform::application; /// The trigger button, at a fixed position so the popup can anchor to a known rectangle. Real code /// would anchor to the measured bounds of whatever element opens the popup. const BUTTON_BOUNDS: Bounds<gpui::Pixels> = Bounds { origin: point(px(24.), px(24.)), size: size(px(200.), px(32.)), }; const POPUP_SIZE: gpui::Size<gpui::Pixels> = size(px(260.), px(320.)); struct Menu; impl Render for Menu { fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement { let item = |label: &str| { div() .id(label.to_string()) .px_3() .py_1() .rounded_sm() .hover(|this| this.bg(rgb(0x3a3a3a))) .cursor_pointer() .child(label.to_string()) .on_click(|_, window, _| window.remove_window()) }; div() .id("menu-root") .size_full() .p_1() .flex() .flex_col() .gap_0p5() .bg(rgb(0x2a2a2a)) .text_color(gpui::white()) .rounded_md() .border_1() .border_color(rgb(0x454545)) .child(item("Foo")) .child(item("Bar")) .child(item("Baz")) .child(item("Qux")) .child(item("Alice")) .child(item("Bob")) } } struct PopupExample { menu: Option<WindowHandle<Menu>>, status: SharedString, } impl Default for PopupExample { fn default() -> Self { Self { menu: None, status: "Click \"Open menu\" to open a native popup.".into(), } } } impl PopupExample { /// Closes the menu if it is open. Returns true if a menu was actually open. fn close_menu(&mut self, cx: &mut App) -> bool { match self.menu.take() { Some(menu) => menu .update(cx, |_, window, _| window.remove_window()) .is_ok(), None => false, } } fn toggle_menu(&mut self, parent: AnyWindowHandle, cx: &mut App) { if self.close_menu(cx) { return; } match open_menu(parent, cx) { Ok(menu) => { self.menu = Some(menu); self.status = "Menu open. Dismiss it by selecting an item, clicking elsewhere in \ this window, or clicking another application." .into(); } // A real application would fall back to an in-window popover here. Err(error) => { self.status = format!("Failed to open a native popup: {error}").into(); log::error!("failed to open popup: {error}"); } } } } impl Render for PopupExample { fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement { let bullet = |text: &str| div().child(format!("• {text}")); div() .id("root") .size_full() .bg(rgb(0xf7f7f7)) .text_color(rgb(0x222222)) // Same-app clicks don't auto-dismiss a grabbing popup (see `PopupOptions::grab`). .on_mouse_down( MouseButton::Left, cx.listener(|this, _, _window, cx| { this.close_menu(cx); }), ) .child( div() .size_full() .p_5() .pt(px(76.)) .flex() .flex_col() .gap_3() .child(div().text_xl().child("Native popup test")) .child(div().text_sm().child( "WindowKind::AnchoredPopup opens a real, parent-anchored window that can \ extend past this window onto the screen. Only some platforms implement \ it so far.", )) .child( div() .flex() .flex_col() .gap_1() .text_sm() .text_color(rgb(0x555555)) .child(div().child("Verify:")) .child(bullet("The menu opens anchored below the button.")) .child(bullet( "The menu extends past the bottom edge of this window.", )) .child(bullet( "Near the bottom of the screen, the menu flips above the button.", )) .child(bullet("Clicking another application dismisses the menu.")) .child(bullet( "Selecting an item or clicking in this window dismisses it.", )), ) .child( div() .text_sm() .text_color(rgb(0x333333)) .child(self.status.clone()), ), ) .child( div() .absolute() .left(BUTTON_BOUNDS.origin.x) .top(BUTTON_BOUNDS.origin.y) .w(BUTTON_BOUNDS.size.width) .h(BUTTON_BOUNDS.size.height) .flex() .items_center() .justify_center() .bg(rgb(0xffffff)) .border_1() .border_color(rgb(0xd0d0d0)) .rounded_md() .cursor_pointer() .id("open-menu") .active(|this| this.bg(rgb(0xeeeeee))) .child("Open menu ▾") // Open on mouse-down, not on click, so the grab is taken while the button is still held. .on_mouse_down( MouseButton::Left, cx.listener(|this, _, window, cx| { // Don't let the window handler above close the menu we are opening. cx.stop_propagation(); this.toggle_menu(window.window_handle(), cx); }), ), ) } } fn open_menu(parent: AnyWindowHandle, cx: &mut App) -> anyhow::Result<WindowHandle<Menu>> { cx.open_window( WindowOptions { titlebar: None, // Sizes the popup. The platform decides the position, so the origin is ignored. window_bounds: Some(WindowBounds::Windowed(Bounds { origin: point(px(0.), px(0.)), size: POPUP_SIZE, })), kind: WindowKind::AnchoredPopup(PopupOptions { parent, anchor_rect: BUTTON_BOUNDS, // Anchor to the button's bottom-left and grow down-right so the menu drops beneath it. anchor: PopupAnchor::BottomLeft, gravity: PopupGravity::BottomRight, // Slide horizontally and flip vertically if the menu would leave the screen. constraint_adjustment: PopupConstraintAdjustment::SLIDE_X | PopupConstraintAdjustment::FLIP_Y, offset: point(px(0.), px(4.)), // Grab input so the compositor dismisses the popup on clicks into other applications. grab: true, }), ..Default::default() }, |_, cx| cx.new(|_| Menu), ) } fn run_example() { application().run(|cx: &mut App| { cx.open_window( WindowOptions { window_bounds: Some(WindowBounds::Windowed(Bounds { origin: point(px(100.), px(100.)), size: size(px(420.), px(300.)), })), ..Default::default() }, |_, cx| cx.new(|_| PopupExample::default()), ) .unwrap(); cx.activate(true); }); } #[cfg(not(target_family = "wasm"))] fn main() { run_example(); } #[cfg(target_family = "wasm")] #[wasm_bindgen::prelude::wasm_bindgen(start)] pub fn start() { gpui_platform::web_init(); run_example(); } ``` </details> ## 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: - N/A |
||
|
|
bfd21aa8dc |
search: Bump fancy-regex dependency and enable CRLF mode (#55471)
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 #43396 Release Notes: - Project search now supports CRLF line endings correctly, as well as other regex features like subroutine calls |
||
|
|
2eeb3e9f47 |
Add support for format_on_save only changed lines (#49964)
## Summary Introduces `format_on_save` variants that format only modified lines, limiting formatting to lines changed since the last commit. This prevents massive diffs when editing legacy codebases. Aligns with VS Code's `editor.formatOnSaveMode` naming: - `"modifications"` — formats only git-diffed lines. Requires source control; skips formatting if no diff is available. - `"modifications_if_available"` — formats only git-diffed lines, falling back to full-file formatting for untracked files, when source control is unavailable, or when the LSP does not support range formatting. Also supports importing equivalent VS Code settings (`formatOnSaveMode`). This PR uses the range-based whitespace/newline infrastructure from the dependency PR above. ## Changes <details> <summary><b>New settings, modified ranges computation, VS Code import</b></summary> ### New settings (`language.rs`, `default.json`, `all-settings.md`) Two new `FormatOnSave` variants: `Modifications` and `ModificationsIfAvailable`. ### Modified ranges computation (`items.rs`) - `compute_format_decision()` — reads `format_on_save` setting across all buffers, determines whether to use ranged formatting (`Ranges`), full formatting (`Full`), or skip (`Skip`). - `compute_modified_ranges()` — extracts modified line ranges from git diff hunks via `BufferDiffSnapshot`. - `is_empty_range()` — helper to detect deletion-only hunks that produce no formatable content. The `save()` method calls `compute_format_decision()` and dispatches accordingly. ### Modifications mode in `lsp_store.rs` - Adds `FormatOnSave::Modifications | FormatOnSave::ModificationsIfAvailable` to the formatter selection match arm. - `ModificationsIfAvailable` falls back to full-file formatting when ranged formatting produces no results. ### VS Code settings import (`vscode_import.rs`, `settings_store.rs`) Imports `editor.formatOnSaveMode` mapping: - `"modifications"` → `FormatOnSave::Modifications` - `"modificationsIfAvailable"` → `FormatOnSave::ModificationsIfAvailable` - `"file"` → `FormatOnSave::On` </details> ## Tests - `test_modifications_format_on_save` — basic modifications mode formatting with dirty buffer - `test_modifications_format_no_changes` — clean buffer triggers no formatting - `test_modifications_format_lsp_no_range_support` — LSP without range formatting skips entirely for `Modifications` - `test_modifications_format_lsp_returns_empty_edits` — empty edits handled gracefully - `test_modifications_format_multiple_hunks` — two non-adjacent edits produce two separate range formatting requests --- 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 #16509 Depends on #53942 Release Notes: - Added `modifications` and `modifications_if_available` options to `format_on_save`, which format only git-changed lines instead of the entire file - When using modifications mode, `remove_trailing_whitespace_on_save` and `ensure_final_newline_on_save` are also scoped to changed lines, preventing unwanted diff jitter in legacy codebases - Added support for importing VS Code's `editor.formatOnSaveMode` setting --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
14efb2c376 |
Switch Guild board automation to role checks (#60606)
Outside collaborators can't be added to GitHub teams, team membership is restricted to org members. https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-outside-collaborators/adding-outside-collaborators-to-repositories-in-your-organization#:~:text=Outside%20collaborators%20cannot%20be%20added%20to%20a%20team%2C%20team%20membership%20is%20restricted%20to%20members%20of%20the%20organization Release Notes: - N/A |
||
|
|
c1a0f53792 |
Make editor::LineUp & editor::LineDown honor vertical_scroll_margin like vim::LineUp & vim::LineDown (#52057)
## Context This is an implementation of this feature: https://github.com/zed-industries/zed/discussions/49821 Although, I'd argue it's a bug fix, not a feature. Either way : This copies the window scroll logic from the `vim` mode versions with out all the extra logic for visual mode. Could refactor the common logic out of the vim code and make it common. But that seems like a bigger PR. Happy to take a stab at it if that's what you prefer. Could also add new commands for the new behavior if you prefer. I didn't do that, because it seems like more clutter in the commands, and my belief that the existing behavior is a bug. But happy to do that if you prefer. ## How to Review creates new function `scroll_screen_with_cursor_margin` in `scroll.rs` wires up editor::LineUp/LineDown to new function in `elements.rs` adds a test in `editor_tests.rs` ## Self-Review Checklist <!-- Check before requesting review: --> - [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 Release Notes: - editor::LineUp/LineDown commands now honor vertical_scroll_margin (same as vim::LineUp/LineDown) --------- Co-authored-by: Kirill Bulatov <mail4score@gmail.com> |
||
|
|
7e786c264c |
Fix worktree entry IDs for symlinked files (#57846)
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 #55792 Release Notes: - Fixed files in pnpm workspaces moving to symlinked `node_modules` paths after saving. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
2a69b52459 |
Bump Zed to v1.12.0 (#60600)
Release Notes: - N/A Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
3f135978df |
csv_preview: Add row filtering feature (#60339)
# Objective CSV feature needs row filtering feature by column values. This PR provides base implementation of it with barebones ui. > NOTE: Sleek UI with search & proper scrolling hanling is implemented in next PR. It's stacked on top to reduce review scope ## Solution - New `FilterEntry` / `FilterEntryState` model in `table_data_engine/filtering_by_column.rs` tracking per-column applied/candidate filter values - Filtering runs in the background (`feat: Implement background filtering`) so large CSVs don't block the UI thread while a filter is applied - Filter menu entries reflect live counts and support a configurable sort order (`FilterSortOrder`, added in `renderer/settings.rs` / `settings.rs`) - Filter/sort trigger buttons on column headers are hidden until hover, using `GradientFade` (new in `ui/src/components/gradient_fade.rs`) to fade content behind them ## Testing Filter chain tested on csv fixtures with multiple filters applied sequentially columns. ## Self-Review Checklist: (todo) - [ ] I've reviewed my own diff for quality, security, and reliability - [x] 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) (out of scope of this pr) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase <img width="664" height="249" alt="image" src="https://github.com/user-attachments/assets/0e9b0a91-1a27-4e0f-a8d4-fdce36735131" /> <img width="663" height="205" alt="image" src="https://github.com/user-attachments/assets/0428f5c6-6aaa-4891-b010-ca79803f6613" /> --- Release Notes: - Added initial row filtering UI & logic |
||
|
|
cf4a373230 |
Unify Render and RenderOnce into View (#58087)
This allows us to build powerful and flexible Input and TextArea components 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 Release Notes: - N/A --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
f1b91966fc |
agent_ui: Fix expanded message editor staying auto-height during streaming (#55916)
Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments (Unsafe: none) - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Summary When the agent is streaming output, expanding the message editor can appear to work (the container grows) but the input editor itself remains constrained to auto-height (only a few lines). Toggling minimize → expand makes it render correctly. This PR ensures the message editor stays in full mode while expanded, preventing automatic editor mode syncing on thread updates from overriding the user's explicit expand action during streaming. ## Steps to reproduce 1. Start an agent thread and send a message that causes streaming output 2. While streaming, click “Expand Message Editor” 3. Observe the input editor still shows only a few lines (auto-height) 4. Click “Minimize Message Editor” and then expand again; it becomes fully expanded ## Test plan - Start an agent thread and let it stream - Click “Expand Message Editor” while streaming - Verify the editor actually expands (not limited to the auto-height max lines) - Toggle minimize/expand multiple times during streaming; verify it remains correct ## Additional context Repro video: https://github.com/user-attachments/assets/6e328fa8-d431-456a-b70a-864ae617ea88 Release Notes: - Fixed message editor not fully expanding during agent generation --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> |
||
|
|
244a8d349c |
gpui: Add run_embedded and ApplicationHandle for externally driven run loops (#60574)
On ordinary platforms, `Platform::run` blocks for the lifetime of the app, and `Application::run`'s stack frame keeps the app state alive. Embedded platforms invert that: the run loop belongs to someone else. `Application::run_embedded` supports that shape: it starts the app exactly like `run()`, but returns an `ApplicationHandle` holding the strong app handle. Release Notes: - N/A |
||
|
|
883bb315fd |
editor: Use raw head selection for rename (#60594)
Follow up to https://github.com/zed-industries/zed/pull/55542, which reused the shifted offset for the rename input's *initial selection*, cutting it one character short. <img width="524" height="512" alt="image" src="https://github.com/user-attachments/assets/37032614-2cfd-4ad4-9005-f2eac57924a1" /> <img width="435" height="158" alt="image" src="https://github.com/user-attachments/assets/7b1b9c52-08d6-48ce-928a-873f6e175f65" /> --- Release Notes: - Fixed symbol rename in vim mode omitting the last character of the symbol out of the rename input's initial selection |
||
|
|
5df865937a |
acp_thread: Log error when checkpoint comparison fails (#59196)
`update_last_checkpoint` swallows `compare_checkpoints` errors with `.unwrap_or(true)`. The "Restore checkpoint" button silently disappears and nothing gets logged, which is what made the linked issue painful to track down in the first place. The sibling `update_last_checkpoint_if_changed` a few lines up already handles the same call with `.context(...).log_err()` and an early return, so I did the same here. On error the checkpoint's visibility is left alone instead of being forced to hidden. I didn't propagate the error because the task result gets `?`'d in `run_turn`'s cleanup, and failing there would leave the panel stuck in its generating state. Added a regression test that breaks the comparison mid-turn (recreating `.git` makes the fake repo forget its checkpoints) and asserts an already-visible checkpoint stays visible. It fails on main and passes with this change. The new log line shows up when it runs: `failed to compare checkpoints: invalid left checkpoint: ...` Closes #59100 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 Release Notes: - Fixed checkpoint comparison errors silently hiding the "Restore Checkpoint" button in the agent panel. Co-authored-by: pstemporowski <110726755+pstemporowski@users.noreply.github.com> Co-authored-by: Bennet Bo Fenner <bennet@zed.dev> |
||
|
|
8dcf9fd48c |
project_panel: Open files in a permanent tab on middle click (#60563)
# Objective Provide a means of quickly opening a permanent tab from project panel instead of a preview tab. Implements #51866 (_Middle click to open file in a new tab_ with 18×↑) which is also part of #31822 (_Middle Click Improvments_) titled "middle clicking on a file in the project panel should open the file in a non-transient state". With `preview_tabs.enable_preview_from_project_panel` enabled, a click in the project panel opens a preview tab, and there's no easy gesture to open a permanent one instead, simplest one currently being a double click. VS Code and VSCode-based editors recognize middle mouse click as a way to open a permanent tab since 2016 (microsoft/vscode#14453). ## Solution Wired up an `on_aux_click` handler for project panel entries: middle-clicking a file opens it in a permanent tab and focuses it, regardless of the preview tabs setting. Added a line to `docs/src/project-panel.md` to reflect the behavior. ## Testing - Manually tested on Windows: middle click opens a permanent tab, promotes an existing preview tab to a permanent one if already open, does nothing for directories - Haven't tested on macOS/Linux ## Self-Review Checklist: - [ ] 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 ## Showcase <details> <summary>Click to view showcase</summary> https://github.com/user-attachments/assets/2de5f23d-637f-4ffc-8d03-02dc11714af4 </details> --- Release Notes: - Added support for middle-clicking a file in the project panel to open it in a permanent tab instead of a preview tab |
||
|
|
b98c695f55 |
terminal: Open links with Cmd/Ctrl-click when mouse mode is enabled (#60067)
This fixes #56956. The terminal link-open gesture was split between `mouse_down` and `mouse_up`, but both halves only ran in the non-mouse-reporting path. When a foreground app enabled terminal mouse reporting, a secondary click on a URL or file path was forwarded to the PTY instead of opening the link. This changes secondary-click link handling so it checks for a hyperlink before mouse reporting on press, and completes the matching hyperlink open before mouse reporting on release. The event is only consumed when the click actually lands on the same link, so normal clicks in mouse-reporting TUIs continue to be forwarded as before. Validation: - `CARGO_BUILD_JOBS=1 cargo test -j1 -p terminal test_hyperlink_ctrl_click_same_position_in_mouse_mode` - `CARGO_BUILD_JOBS=1 cargo check -j1 -p terminal` Release Notes: - Improved terminal links: Cmd/Ctrl-click now opens links even when the application has mouse reporting enabled (e.g. vim, opencode, claude). Disable `terminal.open_links_in_mouse_mode` to forward these clicks to the application instead. --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> |
||
|
|
ce9720d61b |
grammars: Recognize Gentoo ebuild files as bash script (#59068)
The Gentoo `ebuild` file format is a subset of a bash script, see https://wiki.gentoo.org/wiki/Ebuild. 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 Closes #ISSUE Release Notes: - Changed `ebuild` files to be recognized as bash. Signed-off-by: gcarq <egger.m@protonmail.com> Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
b099024705 |
Fix typos and grammatical mistakes in docs (#59495)
# Objective - Describe the objective or issue this PR addresses. -> ** Typo and grammar fixes!** ## Solution ## Testing ## 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 --- Release Notes: - N/A |
||
|
|
1abef8fadf |
Suggest language extensions for untitled buffers (#55263)
Fixes #53527. ## Summary - Suggest `untitled.<extension>` when saving an untitled editor buffer with a selected non-Plain Text language. - Preserve the existing title-based suggestion for existing files, Plain Text buffers, and buffers without a language extension. - Add a regression test for an untitled Rust buffer suggesting `untitled.rs`. ## Testing - `mise exec rust@1.95.0 -- cargo fmt --check -p editor` - `mise exec rust@1.95.0 -- cargo test -p editor test_suggested_filename_uses_language_extension_for_untitled_buffer --lib` ## Suggested .rules additions None. Release Notes: - Fixed Save As suggestions for untitled buffers with a selected language. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
eb9b2b8341 |
go: Fix outline for methods with unnamed receivers (#58656)
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 This fixes Go outline extraction for methods whose receiver has no name, such as `func (v2) Method()`. These methods are now included in outline symbols, which also feed breadcrumbs and sticky scroll. Tested with: - `cargo test -p languages` - `cargo test -p grammars` - `./script/clippy -p languages` - `cargo fmt --check --package languages` Before: [before_cut.webm](https://github.com/user-attachments/assets/91eb5cb0-703a-4496-b0dd-5369c4c219fc) After: [after_cut.webm](https://github.com/user-attachments/assets/76d13d88-3671-4118-99fc-c073a6e64727) Release Notes: - Fixed Go methods with unnamed receivers not appearing in breadcrumbs and sticky scroll. Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
c09d59120c |
project: Fix content swap when an LSP rename also renames the file (#59104)
A "rename symbol" whose workspace edit also renames the file (a `TextDocumentEdit` followed by a `RenameFile` resource operation) only applied the text edit to the in-memory buffer. The on-disk file still held the pre-edit content, so the blind `fs.rename` moved stale bytes to the new path while the edited buffer was stranded at the old path, swapping the two files' contents. This persists a dirty buffer for the rename source before renaming, so the new file receives the edited content and the now-clean buffer can't be saved back to the old path. 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 Closes #59077 Release Notes: - Fixed a symbol rename that also renames the file swapping the contents of the old and new files |
||
|
|
f6385d12c7 |
Consistently use context() to preserve sources for anyhow errors (#59112)
When you use `anyhow::anyhow!("{error}")` to convert a preexisting error
to an `anyhow::Error`, the error source can be lost (depending on the
`Display` impl of the error). Anyhow errors can display the whole source
chain when printed. This commit makes us consistently use `context()`
instead to preserve the underlying error's source.
Release Notes:
- N/A
|
||
|
|
657962ab30 |
Use more .array_windows::<N>() (#58877)
- [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 The fight against entropy continues... Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
9efc6f5e16 |
Fix should_log_lsp_request_failure logic inversion (#57554)
Was trying to debug an r-a issue and ran into this. Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliabilityx - [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 #ISSUE Release Notes: - N/A or Added/Fixed/Improved ... Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
bb021d2004 |
workspace: Skip closed items that cannot be reopened (#56299)
Resolves https://github.com/zed-industries/zed/issues/55600 This diff fixes `pane::ReopenClosedItem` getting stuck when the closed-item stack contains entries that cannot be reopened, such as Project Search, untitled buffers, or Default Settings. Previously, `Workspace::navigate_history_impl` would pop the newest closed entry and stop if that item was no longer present in the pane and had no path recorded for reopening. That made `cmd- shift-t` appear to do nothing until enough attempts had consumed those unreopenable entries. With this change, closed-item navigation keeps scanning when it encounters an entry that cannot be activated or reopened by path. This preserves the current path-based reopening behavior for normal files, while avoiding no-op shortcuts caused by non-file items in the closed stack. This made me wonder whether or not we'd eventually want full reopen support for non-traditional items like Project Search or bundled settings editors. Supporting that properly would require storing item-specific restoration state, such as search query/options for Project Search or a bundled-file descriptor for Default Settings, and teaching closed-item navigation how to recreate those items from that state. Something definitely out of scope for this PR. | Before | After | | --- | --- | | <video src="https://github.com/user-attachments/assets/c7044423-4531-4857-84f2-4e9651826c6a" controls width="500" title="Before"></video> | <video src="https://github.com/user-attachments/assets/c89dcefb-1796-4cdf-bb21-f165145e678e" controls width="500" title="After"></video> | Release Notes: - Fixed reopening closed tabs getting stuck on closed items that cannot be reopened. |
||
|
|
057bd63412 |
editor: Decode escaped characters in hover popover links (#55973)
Decodes url escape sequences in hover preview `file:///` links like escaped spaces in the file path. I'm working on an LSP and happened to be working with some files in a directory with spaces. When adding Markdown links with `file:///` the `%20` escape for spaces was being included verbatim in the path that Zed tried to open. I'm reusing the lines from `markdown_preview_view.rs` for decoding. In the existing tests I don't see coverage for `file:///` links. If you'd like some tests for this can you point me to any examples to start from? 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) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed decoding spaces and other escaped characters in `file://` links used in hover popovers --------- Co-authored-by: dino <dinojoaocosta@gmail.com> |
||
|
|
dedf4cbfe8 |
cloud_api_client: Make send_authenticated_json_request public (#60562)
This PR makes the `send_authenticated_json_request` method on the `CloudApiClient` public. This way we can use it to make requests by external callers. The `build_request` method was also inlined into `send_authenticated_request` to make the contract simpler. Release Notes: - N/A |
||
|
|
f47073a215 |
bedrock: Add native support for Bedrock Mantle models (#60480)
Adds native support for AWS Bedrock's Mantle endpoint (`bedrock-mantle`), which serves models with no `Converse`/`Invoke` support on `bedrock-runtime`, such as GPT-5.5, GPT-5.4, and Grok 4.3 but more importantly **open-weight** models Closes #60471 ## What's changed - Renamed the existing `Model` enum in the `bedrock` crate to `ConverseModel`, and added a new `MantleModel` enum for Mantle-only models. Mantle models reuse the existing OpenAI-compatible Chat Completions/Responses request and response plumbing (`into_open_ai`/`into_open_ai_response`, `OpenAiEventMapper`/`OpenAiResponseEventMapper`) already used by the native OpenAI and OpenAI-compatible providers, rather than introducing new marshalling code. - Added a `BedrockMantleModel` language model that routes requests to the `bedrock-mantle` endpoint, dispatching to Chat Completions or the Responses API depending on the model. Mantle models appear in the model picker alongside Converse models under the same Bedrock provider. - Added region gating: `bedrock-mantle` is only available in a subset of AWS Regions, so using a Mantle model outside of them surfaces a clear error naming the current Region and the supported ones, instead of an opaque HTTP failure. - Implemented Bedrock bearer token authentication for Mantle requests: a configured Bedrock API key is used as-is, and every other auth method (IAM credentials, named profile, SSO, automatic) derives a short-term token by locally SigV4-presigning a `CallWithBearerToken` request. This requires no extra network round trip and no token caching, since re-signing locally is cheap. - Added a specific error for the 403 you get when your credentials have `bedrock:CallWithBearerToken` but not the separate `bedrock-mantle:CallWithBearerToken` permission Mantle models require, since this is the most common misconfiguration. - Added a `mantle_available_models` setting so custom models served through `bedrock-mantle` can be configured, the same way other providers support custom models via `available_models`. - Documented Mantle models and the new setting in the Amazon Bedrock section of [Use a Gateway](https://zed.dev/docs/ai/use-a-gateway#amazon-bedrock). ## Testing - Added unit tests covering: the local SigV4 bearer-token signing (including a byte-for-byte cross-check against a reference implementation), Mantle endpoint URL construction, the Mantle-supported-regions list, thinking-effort normalization, and the settings-to-model protocol mapping. - `cargo test -p bedrock -p language_models -p settings_content -p settings` passes. - `./script/clippy` passes with no new warnings. Release Notes: - Added native support for AWS Bedrock's Mantle endpoint, enabling GPT-5.5, GPT-5.4, and Grok 4.3 through the Amazon Bedrock provider. |
||
|
|
07fa666c4e |
language_extension: Hold LspStore weakly in LspAccess::ViaLspStore (#60558)
# Objective Fix a Windows CI flake in `extension_host extension_store_test::test_extension_store_with_test_extension`, which panicked in GPUI's leak detector with three leaked `LspStore` handles ([example run](https://github.com/zed-industries/zed/actions/runs/28871529605/job/85635418351)). ## Solution `LspAccess::ViaLspStore` held a strong `Entity<LspStore>`, cloned into three `ExtensionHostProxy` registrations by `language_extension::init`. The proxy sits inside an `Arc` cycle (proxy → `LanguageServerRegistryProxy` → `LanguageRegistry` → `ExtensionLspAdapter` → `WasmExtension` → `WasmHost` → proxy), so whenever an extension LSP adapter was registered at app-drop time, the cycle pinned the `LspStore` entity after its owning `Project` dropped. The flake was purely timing: extension reload toggles the adapter registration, and an unclean LSP pipe shutdown on Windows shifted teardown into the pinned window. `ViaLspStore` now holds a `WeakEntity<LspStore>`, upgraded at its sole use site (`remove_language_server`), skipping the stop task when the store is gone — matching the existing `ViaWorkspaces` semantics. A dead store is the expected terminal state after the owning project drops, so no error is logged or propagated. `Project`/`HeadlessProject` remain the sole long-term owners of `LspStore`, which is already the convention everywhere else (e.g. `json_schema_store`, the `lsp_store` message handlers). ## Testing - Ran `cargo nextest run -p extension_host extension_store_test::test_extension_store_with_test_extension` locally: passes. - The flake is timing-dependent (reproduced on Windows CI), so a local pass doesn't prove absence; the fix removes the only strong non-owner handle, which the leak detector reported. ## 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 --------- Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
042d22ce9c |
git_ui: Use pull request link from push output in push toast (#60522)
## Summary Fixes #60288 and #60454 . After a push, the push toast's "Create Pull Request" button fails with `Unsupported remote URL` when the repository's remote is not a plain, recognized host. This restores the pre-#53913 behavior as a fallback: use the create-PR/MR link that `git push` itself prints, and only build a URL from the provider registry when the push output had no link. ## Why this matters #53913 made the button always appear and changed `create_pull_request` to reconstruct the PR URL from the remote via `git::parse_git_remote_url` against the `GitHostingProviderRegistry`. When the remote is not recognized, parsing returns `None` and the action errors. This affects self-hosted GitLab/GitHub, an SSH-config host alias like `git@personal:owner/repo` (the duplicate #60076), and any non-standard host. Before #53913, the flow used the link git prints in the push output, which works regardless of host, so this is a regression for anyone not pushing to a plainly-recognized GitHub URL. ## Solution `git push` prints a `remote:` line with the hosting provider's create-PR/MR URL (GitHub: "Create a pull request for '\<branch>' on GitHub by visiting:", GitLab: "To create a merge request for \<branch>, visit:", Bitbucket: "Create pull request for \<branch>:"), and we already hold the push `RemoteCommandOutput`. - `remote_output.rs`: add `extract_pull_request_url`, which scans the push stderr for the first `http(s)` URL on a `remote:` line tied to a create-PR/MR prompt. It ignores unrelated URLs (for example the OpenSSH post-quantum warning line). - `git_panel.rs`: capture that URL in `show_remote_output` into `pending_pull_request_url`, and prefer it in `create_pull_request`, falling back to the existing provider construction only when the push output had no link. The cached URL is consumed once (`take()`) and cleared when the active repo, the active branch/head, or the pending remote operation changes, so a later `git: Create Pull Request` action never opens a stale URL from an earlier push. Recognized GitHub remotes are unaffected: they still get a link from the push output, with the provider path as the fallback. ## Testing Unit tests in `remote_output.rs` cover `extract_pull_request_url` for the GitHub, GitLab, and Bitbucket prompt formats, the no-link case (returns `None`, so the provider fallback runs), and an output containing an unrelated URL that must not be mistaken for the PR link. The existing remote-operation test also asserts the cached URL is cleared when a new operation starts. `cargo test -p git_ui remote_output` passes (5 tests). 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] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed "Create Pull Request" button in the toast shown after `git: push` failing for repositories on unrecognized Git hosts by using the link printed in the push output. - Fixed the button shown on the toast after `git: push` for GitLab branches with an existing merge request. It now shows "View Merge Request" and links to the existing merge request. --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: dino <dinojoaocosta@gmail.com> |
||
|
|
6a9bf6498f |
gpui_wgpu: Fix wgpu renderer teardown panic (#60160)
# Objective Opening and closing windows quickly on Linux could crash the renderer with a `GPU resources not available` panic. The `gpui_wgpu` renderer keeps its GPU resources in an `Option` that is cleared when a window is torn down, and also while device-loss recovery is pending. On Wayland the window's `Drop` releases those resources synchronously but defers unregistering the surface to a later task, so a compositor resize or transparency event can still reach the renderer in that short gap. `update_drawable_size` and `update_transparency` assumed the resources were always present and called an accessor that panics when they are not. I am not certain if there is a good case to reproduce this in zed, but I had encountered it in my own GPUI app. ## Solution Make `update_drawable_size` and `update_transparency` tolerate missing GPU resources by skipping the surface reconfiguration instead of panicking, matching how the rest of the renderer already guards this state. The requested size and alpha mode are still recorded before the guard, so they take effect if the renderer's resources are recreated, for example after device-loss recovery. ## Testing Tested on Linux with Wayland. - Reproduced by opening and closing windows quickly, which previously panicked with `GPU resources not available`. With this change the panic no longer occurs. This was reproducible on a debug build or a weak/slow device. ## 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 (not sure if worth mentioning): - Fixed a crash that could occur when opening and closing windows quickly on Linux Co-authored-by: Mikayla Maki <mikayla@zed.dev> |
||
|
|
aa7591f73f |
fs: Skip parent watch for poll watcher symlink targets (#57049)
# Problem Since the release of the new git UI, when `~/.gitconfig` on a remote server is a symlink pointing to a file on a virtual filesystem (a common setup when using [OrbStack](https://orbstack.dev/) on macOS), Zed fails to connect with "Timed out pinging remote client". # Cause When setting up a file watcher for gitconfig, `fs::watch()` reads the symlink target and adds its parent directory to the poll watcher. `notify::PollWatcher::watch()` does a full synchronous recursive directory scan at registration time to build an initial snapshot. If the parent is something like a Mac home directory mounted via virtiofs, that scan blocks the server's main thread long enough that it can't respond to the initial ping within the 5 second timeout. # Solution The fix I implemented for this was to skip the parent directory watch when using a poll watcher. As far as I can tell, it's redundant in the poll case since the poll watcher detects changes by periodically reading metadata at the registered path, so watching the parent doesn't add anything for change detection. From my limited testing this seems to work fine but if someone with more experience in this part of the codebase would like to weigh in, that would be very much appreciated. Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [ ] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [ ] Performance impact has been considered and is acceptable Release Notes: - Fixed remote SSH connections timing out when `~/.gitconfig` is a symlink to a file on a virtual filesystem |
||
|
|
846c40cf0d |
Add missing panels to View menu (#60356)
# Objective Ensure that all existing panels have corresponding menu items in the "View" menu. I was onboarding a friend to Zed yesterday that was having a hard time figuring out how to interact with the Agent. Although he did open the "View" menu, I noticed that the Agent panel item was missing from there, making it hard for new users to discover it exists. ## Solution * Add both "Agent Panel" and "Git Panel" entries to the menu items for the "View" app menu. * Update the action used for the "Terminal Panel" menu item from `terminal_panel::ToggleFocus` to `terminal_panel::Toggle` to ensure we display a shortcut for this menu item. * Another valid option would be to update the default keymap to use `terminal_panel::ToggleFocus` instead but that would probably break existing user's expectations that the default shortcut toggles the terminal panel, instead of toggling its focus. * Introduce `zed_actions::git_panel` to be able to extract its `ToggleFocus` action, following the existing pattern. ### Next Steps It's worth noting that, even though there's now an "Agent Panel" item mapped to the `assistant::ToggleFocus` action, its default keybinding is not displayed (at least on macOS), because of the way it's defined as `cmd-?` . Using `cmd-shift-/` instead doesn't work, so we'll likely have to update `MacKeyboardMapper` to allow mapping between shifted and unshifted keys equivalent, that is, when `?` is detected, it is able to determine that, in the user's layout that is the result of `shift-/`. ## Testing Manually tested, screenshots can be seen in the "Showcase" section. ## 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 - [ ] Performance impact has been considered and is acceptable ## Showcase <details> <summary>Before</summary> <img width="488" height="946" alt="CleanShot 2026-07-03 at 14 24 35@2x" src="https://github.com/user-attachments/assets/58b0497c-2929-4da3-86b6-a2e0ce0c5ca4" /> </details> <details> <summary>After</summary> <img width="524" height="1116" alt="CleanShot 2026-07-03 at 14 24 59@2x" src="https://github.com/user-attachments/assets/8e2c6320-97ad-4620-b595-182f6d0ded81" /> </details> --- Release Notes: - Added "Agent Panel" and "Git Panel" items to the "View" menu |
||
|
|
601690391b |
git: Load buffer git diff bases with a single batched git process (#59357)
# Objective Whenever the git repository state is updated on disk (e.g., via staging, committing, branch switching, or stashing), `reload_buffer_diff_bases` is scheduled to reload the diff for all active buffers. This causes 2 git processes to be spawned for each open file which can become noticeable when many files are open https://github.com/zed-industries/zed/blob/b2617baa21a83dfcbd8361e285bb2eba84e294ec/crates/project/src/git_store.rs#L5179 ## Solution This PR introduces `load_revisions` which uses a single `git cat-file --batch` command to compute the diff for all files in the same git process. This prevents the need to sequentially schedule 2 git subprocesses per open buffer. I also changed `load_index_text` and `load_commited_text` to rely on `load_revisions` which simplifies the code. ## Testing I added a unittest and manually verified that Zed now only runs a single `git cat-file --batch` command instead of 2 `git show` processes per open buffer. On macOS I viewed the currently running git processes using: ```shell sudo eslogger exec | jq --unbuffered -r ' select(.event.exec?.target?.executable?.path? | strings | contains("git")) | (.event.exec?.args? // []) | join(" ") ' ``` ## 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 /cc @Veykril Release Notes: - Reduced number of git processes for calculating diff of open buffers when the repo state changes on disk |
||
|
|
3f74307a26 |
git_ui: Show tags in Git panel history (#60534)
# Objective - Make Git Panel History show commit tags so release/version markers are visible without opening the full Git graph or commit details. ## Solution - Store commit history entries with both the commit SHA and tag names from existing git graph data. - Render tag names as muted chips next to the commit subject. - Limit visible tags to 3 per commit and show `+N` for additional tags. ## Testing - Ran `cargo check -p git_ui`. - Manually verified on Linux with `script/zed-local --stateful .`. - Confirmed tags appear in Git Panel History. ## 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 ## Showcase Git Panel History now shows commit tags inline as muted chips next to the commit subject. --- Release Notes: - Added tag labels to the Git Panel commit history. --------- Co-authored-by: Danilo Leal <daniloleal09@gmail.com> |
||
|
|
a820d6ee1f |
Update issue ranking script dependencies (#60345)
Release Notes: - N/A |
||
|
|
6da34ac148 |
git_graph: Add design adjustments (#60469)
This PR adds adjustments to the tree view, making it more consistent with all other tree view displays in the app (e.g., displaying indent guides, removing chevron toggle, etc.), and also fixes an issue where the commit message scrollbar was scrolling up with the message. Release Notes: - N/A |
||
|
|
c99df2bea6 |
project: Create LSP file watcher on the background (#60530)
Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
e9c324f710 |
acp: Show descriptions for elicitation options (#60527)
<img width="683" height="781" alt="image" src="https://github.com/user-attachments/assets/bcf1bc75-9bb4-4ddf-88d8-c09a4aa3f34b" /> Release Notes: - N/A |
||
|
|
4293014f8a |
Limit SVG Pixmap size to avoid GPUI texture allocation errors (#56468)
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) (Arguably no, but it's an okay compromise methinks) - [ ] Tests cover the new/changed behavior (I'm unsure how one would properly test this, sorry!) - [x] Performance impact has been considered and is acceptable Closes #56466 To be completely honest I don't know if this is a good fix or not, it does fix the problem I was running into where opening the large mermaid diagram would blow up VRAM. It doesn't look amazing visually but I would consider this behavior better, if it's not a good fix then that's okay:) I chose 8192 because 8192 only brings VRAM usage up ~100MB in my testing while 16384 brought my VRAM usage up to about 1GB from 150-200MB, for lower end systems this seems unacceptable. Before: I can't take a screenshot of the before at this point because it eats my system VRAM & Memory too fast. As a text description; It would show a large empty rectangle where the mermaid diagram should be and blow up Zed's VRAM usage from ~300MB to ~22GB (all of the available VRAM in my system) After: <img width="1698" height="763" alt="image" src="https://github.com/user-attachments/assets/62eb7c95-cca8-43f9-8257-c7e529f26e8d" /> <img width="1000" height="31" alt="image" src="https://github.com/user-attachments/assets/4315c029-3cdd-44f6-ac78-971d125ab700" /> (Up from ~150MB), the 257MiB figure is the GPU Memory. Release Notes: - N/A? Co-authored-by: Lukas Wirth <lukas@zed.dev> |
||
|
|
3699843254 |
gpui: Refresh mouse position after bounds changes (#60421)
## Summary - Refresh GPUI's cached mouse position when window bounds change so hover hit-testing uses the current cursor position after live resize. - Return X11 mouse positions in window-relative logical pixels to keep `PlatformWindow::mouse_position()` consistent with other backends. Fixes #57354 ## Testing - `cargo fmt -p gpui -p gpui_linux` - `cargo check -p gpui_linux` - `cargo check -p gpui` ## Suggested .rules additions - In GPUI platform backends, `PlatformWindow::mouse_position()` should return window-relative logical pixels; use separate APIs or fields for global/device-pixel coordinates. Release Notes: - Fixed incorrect hover state while resizing GPUI windows. |
||
|
|
a232891710 |
gpui: Fix clear drag overlay when external drag ends outside window (#45759)
Release Notes: - Fixed clear drag overlay when external drag ends outside window When dragging files from macOS Finder over the project panel and then dragging back to Finder, the drag overlay remained visible because the drag state was not properly cleaned up. The root cause was that only `draggingExited:` was handled, but not `draggingEnded:`. On macOS: - `draggingExited:` is called when the drag leaves the window area - `draggingEnded:` is called when the drag operation ends entirely When a user drags a file back to Finder and drops it there, `draggingEnded:` is called but was not being handled. --------- Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com> |
||
|
|
ebb1d87971 |
copilot_ui: Fix Copilot sign-in window focus on Hyprland (#59933)
# Objective
The Copilot sign-in dialog was created without an `app_id` or window
title, resulting in an empty WM class/title on Linux. Tiling window
managers with class-based no-focus rules (like Hyprland's default
configuration in Omarchy) treat such windows as anonymous popups and
refuse to focus them, making the dialog impossible to interact with.
## Solution
Set both `app_id` and window title on the Copilot code verification
window, following the established pattern used in other UI components
like `agent_ui` and `settings_ui`.
Added `release_channel` as a dependency to
`crates/copilot_ui/Cargo.toml` and called
`app_id(ReleaseChannel::app_id(cx))` and `window_title("Use GitHub
Copilot in Zed")` in `open_copilot_code_verification_window`.
## Testing
Verified on Hyprland (Omarchy) by inspecting window properties with
`hyprctl clients`:
**Before (empty class/title):**
```
Window 5606ee1dd280 -> :
class:
title:
acceptsInput: 0
```
**After (with proper class/title):**
```
Window 5606ee22b660 -> Use GitHub Copilot in Zed:
class: dev.zed.Zed-Dev
title: Use GitHub Copilot in Zed
acceptsInput: 1
```
The dialog now receives keyboard focus and mouse input correctly on
Hyprland. I tested on Linux only; this fix lives in the window creation
call so it is a no-op on macOS and Windows where `app_id` is ignored.
## 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 Copilot sign-in window not being focusable on Hyprland and
similar tiling window managers
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
|
||
|
|
ce21c69d30 |
auto_update: Fix installer temp dirs leaking on macOS (#60528)
The unmount of the update disk image was made async-and-detached in #38867, which introduced a race: the installer TempDir was dropped (running remove_dir_all) while the DMG was still mounted inside it. The removal failed silently, leaking a zed-auto-update* dir containing the ~140 MB DMG in /private/var/folders on every update. Now the unmount is awaited before the temp dir is dropped (installation already runs on the background executor since #58767, so this no longer blocks the UI), with the Drop impl kept as a safety net for early exits and cancellation. Additionally, stale installer dirs older than 24 hours are swept from the temp dir when update polling starts, so existing accumulated leaks get reclaimed. Closes FR-104 Closes #58835 Release Notes: - Fixed the macOS auto-updater leaking a copy of the downloaded update in the system temp directory on every update, and added cleanup of previously leaked files. |
||
|
|
114307768e |
opencode: Model updates + fixes (#60526)
**TL;DR**: model updates + reasoning levels + fixes discovered when working on https://github.com/zed-industries/zed/pull/60373 # Objective Since the model auto-discovery PR was [cancelled](https://github.com/zed-industries/zed/pull/60373#issuecomment-4886521448), here is a manual model list update! I also copied the stand-alone bugfixes/enhancements from that PR. ## Solution A lot of manual work 😅 **OpenCode Zen**: - added Fable 5 and Sonnet 5 - added models that were previously only available on OpenCode Go: GLM 5.2, Kimi K2.7 Code, and Minimax M3 - added reasoning levels for all models. I started from the data on [`Models.dev`](https://models.dev) (the `/api.json` raw data), and then I matched that with what is shown in the OpenCode CLI and what I know to be true **OpenCode Go**: - added reasoning levels for GLM 5.2 **OpenCode in general**: - added `protocol` validation for the settings, by moving from a random `String` to an `enum`, for both nicer error messages (random strings or typos will get an error instead of using `openai_chat` by default) and to avoid issues like [folks saying non-existent protocols are a thing](https://github.com/zed-industries/zed/issues/56869#issuecomment-4550154554) - enabled parallel tool calls by default. As per [OpenCode developer on Discord](https://discord.com/channels/1391832426048651334/1471233160993050918/1472020924881702912), _"almost all models worth using support parallel tool calling natively"_. Manual tests confirmed all OpenCode Go models support this correctly (and was enabled by default on the OpenCode side for all but 1 model). I initially wanted to skip this from the release notes, but I added it so folks are aware of it in case any issues are caused by this being enabled for all models - allegedly fixed Google thinking since reasoning levels / thinking effort levels were added for Google models and an auto-checker LLM highlighted that was not properly configured - added support for the new-ish `supports_disabling_thinking` so thinking-only models don't get a no-impact toggle to disable thinking I have no idea if any of the Free models will disappear in 2 days or not, so I did not update those 🤷 (as per decision in https://github.com/zed-industries/zed/issues/56869#issuecomment-4466637648) ## Testing The Zen and Google changes were not tested as I don't have a Zen subscription and I stubbornly refuse to get one. The Free&Go changes were tested by running a "_rename this variable for me. add a function. delete the function_" test with a few different models. ## 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: - Agent: OpenCode settings now validate `protocol` values - Agent: OpenCode only shows the "Disable thinking" toggle if thinking can indeed be disabled/enabled - Agent: OpenCode models now enable parallel tool calls by default - Agent: Updated OpenCode Zen models (added Fable 5, Sonnet 5, GLM 5.2, Kimi K2.7 Code, and Minimax M3) - Agent: Added OpenCode Go GLM 5.2 reasoning effort levels - Agent: Added reasoning effort levels for all OpenCode Zen models - Agent: Fixed thinking for OpenCode Zen Google models |
||
|
|
2b47bfd6b2 |
Change OpenAI compatible URL placeholder in edit prediction settings (#58771)
Fixed my PR #58753. Change the url placeholder from http://localhost:11434 to http://localhost:8080/v1/completions to match the URL endpoint in the [docs](https://zed.dev/docs/ai/edit-prediction) ```json { "edit_predictions": { "provider": "open_ai_compatible_api", "open_ai_compatible_api": { "api_url": "http://localhost:8080/v1/completions", "model": "deepseek-coder-6.7b-base", "prompt_format": "deepseek_coder", "max_output_tokens": 512 } } } ``` Note: http://localhost:8080/v1/completions/ with an extra / does not work. Added the constants OPEN_AI_COMPATIBLE_API_URL_PLACEHOLDER and OPEN_AI_COMPATIBLE_MODEL_PLACEHOLDER. ### Initial Issue I noticed that using http://localhost:8080 doesn't work with llama.cpp. Giving errors like this from (zed: open log): ``` 2026-06-06T17:55:39+01:00 ERROR [crates/edit_prediction/src/edit_prediction.rs:2464] custom server error: 404 Not Found - {"error":{"message":"File Not Found","type":"not_found_error","code":404}} ``` After reading the docs above, I found out that I had to add /v1/completions to the end. 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 Release Notes: - N/A |
||
|
|
65ac02886e |
workspace: Fix missing icons on non-terminal tabs during drag (#53637)
Previously, only terminal tabs displayed their icon while being dragged, all other tab types showed just the label, making the drag preview inconsistent with the actual tab appearance. https://github.com/user-attachments/assets/7c055945-79d6-4f6e-8969-279a4fb1ff58 This PR fixes that by rendering each tab's icon alongside its label, so the dragged preview now accurately reflects the tab regardless of type. https://github.com/user-attachments/assets/3ad5a99b-5ba7-41d2-a6b3-51101b1f9650 Release Notes: - Fixed missing icons on non-terminal tabs when dragging --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> |