Commit graph

39583 commits

Author SHA1 Message Date
Jakub Konka
c43e2d9734
gpui_linux: Handle XKB context initialization failure (#62868)
Release Notes:

- Added check for XKB context initialization failure
2026-08-19 11:19:10 +00:00
Vlad Ionescu
99f4c21c03
agent: OpenCode model updates (+6 Go, +7/-1 Zen, removed Free) (#61199)
Closes https://github.com/zed-industries/zed/issues/62559
Related discussion:
https://github.com/zed-industries/zed/discussions/61160

# Objective

Adding newly-released OpenCode models. Removing OpenCode Free models
completely.

## Solution

> [!TIP]
> This pull request is **best reviewed commit-by-commit**!

**OpenCode Go**:
- added **Kimi K3** as per
[[1]](89183a9646/providers/opencode-go/models/kimi-k3.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/dev/models/moonshotai/kimi-k3.toml).
Currently, the only supported reasoning level available is `Max` which
was validated both with Models.dev data and OpenCode CLI.
- added **Grok 4.5** as per
[[1]](89183a9646/providers/opencode-go/models/grok-4.5.toml)
and
[[2]](89183a9646/models/xai/grok-4.5.toml)
- added **Tencent Hy3** as per
[[1]](b013d94872)
and
[[2]](f63b5ce78d/models/tencent/hy3.toml)
- added **GPT 5.6 Luna** as per
[[1]](https://github.com/anomalyco/opencode/pull/39812) and
[[2]](https://github.com/anomalyco/models.dev/blob/dev/providers/opencode-go/models/gpt-5.6-luna.toml)
- added **Qwen 3.8 Max** as per
[[1]](403a7bdd43)
and
[[2]](e9e7472456)
- added **GLM 5.3** as per
[[1]](3876740bf4/models/zhipuai/glm-5.3.toml)
and
[[2]](94a1629610)
and [[3]](https://github.com/anomalyco/opencode/pull/42518)

**OpenCode Zen**:
- added **Gemini 3.5 Flash Lite** as per
[[1]](f63b5ce78d/providers/opencode/models/gemini-3.5-flash-lite.toml)
and
[[2]](f63b5ce78d/models/google/gemini-3.5-flash-lite.toml)
- added **Gemini 3.6 Flash** as per
[[1]](f63b5ce78d/providers/opencode/models/gemini-3.6-flash.toml)
and
[[2]](f63b5ce78d/models/google/gemini-3.6-flash.toml)
- added **Gemini 3.7 Flash** as per
[[1]](https://github.com/anomalyco/models.dev/pull/4632) and
[[2]](b1810e30d7)
and [[3]](https://github.com/anomalyco/opencode/pull/42390) and
[[4]](https://github.com/anomalyco/opencode/pull/42393)
- added **Claude Opus 5** as per
[[1]](e3ae24cdd7)
and
[[2]](342b5572a0)
- added **Kimi K3** as per
[[1]](a9bebd3653)
and
[[2]](38ccccc20d)
- added **Grok 4.6** as per
[[1]](74789f5a02)
and
[[2]](d92d1e654b)
and [[3]](https://github.com/anomalyco/models.dev/pull/4575)
- added **Muse Spark 1.2** as per
[[1]](fa03dca90b)
and
[[2]](3876740bf4/models/meta/muse-spark-1.2.toml)
and [[3]](https://github.com/anomalyco/opencode/pull/42508)
- removed **Claude Opus 4.1** as per
[[1]](6951484e98)

**OpenCode Free**: removed all the models and the whole concept of
"OpenCode Free" from Zed. As confirmed [by an Anomaly employee on the
OpenCode
Discord](https://discord.com/channels/1391832426048651334/1394667004979445931/1537530485356363899),
free models are now OpenCode-only since they got abused waaaaay too much
by people. Testing shows that even with an active OpenCode Go
subscription configured, I can't use Free models in Zed — both Big
Pickle and DeepSeek V4 Flash Free failed to reply to a _"hello"_ message
and instead returned a rate-limit error.
A full removal of OpenCode Free from Zed was implemented in
https://github.com/zed-industries/zed/pull/61199/changes/49acbf7c92414c14c453113eb9b886f9bedff7cb
as there was no point in keeping a _"Show free models"_ toggle that
would confuse users.
Users that had `show_free_models` configures in Zed settings will get an
`Property show_free_models is not allowed.` notice. Users that had any
Custom OpenCode models with `"subscription": "free"` configured will get
an `Value is not accepted. Valid values: "zen", "go".` notice. Neither
are blocking errors.

## Testing

 Kimi K3 on OpenCode Go - happily confirmed Kimi K3 works by running a
simple "_rename this variable for me. add a function. delete the
function_" test.

 Grok 4.5 on OpenCode Go - bravely resisted the continuous and
relentless waves of disgust and confirmed Grok 4.5 works by running a
simple "_rename this variable for me. add a function. delete the
function_" test. I was a bit surprised this worked as I was located in
an EU country while testing this.

 Hy3 on OpenCode Go - happily confirmed Hy3 works by running a simple
"_rename this variable for me. add a function. delete the function_"
test.

 GPT 5.6 Luna on OpeCode Go - confirmed GPT 5.6 Luna works on OpenCode
Go by running a simple "_rename this variable for me. add a function.
delete the function_" test.

 Qwen 3.8 Max on OpeCode Go - confirmed Qwen 3.8 Max works on OpenCode
Go by running a simple "_rename this variable for me. add a function.
delete the function_" test.

 GLM 5.3 on OpeCode Go - confirmed GLM 5.3 works on OpenCode Go by
running a simple "_rename this variable for me. add a function. delete
the function_" test.


🤷 I did not test the new OpenCode Zen models (Claude Opus 5, Gemini 3.5
Flash Lite, Gemini 3.6 Flash, Kimi K3, Grok 4.6, Gemini 3.7 Flash, and
Muse Spark 1.2) as I don't have a Zen subscription and I am stubbornly
refusing to get one.

 Confirmed removal of OpenCode Free does not impact the rest of the
OpenCode. Confirmed that any Free-related settings generate notices and
not errors. Confirmed the OpenCode tab in Setting looks good.

## 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

<details>
<summary>Screenshots of the OpenCode Free deprecation warnings</summary>

**Notice shown in the corner of Zed**:
<img width="345" height="90" alt="Notice banner shown in Zed"
src="https://github.com/user-attachments/assets/3e65ba96-582c-424e-9335-1b43d6c632a8"
/>

**Notice shown in Settings -> LLM Providers -> OpenCode**:
<img width="421" height="323" alt="Settings screen showing unexpected
values"
src="https://github.com/user-attachments/assets/a5eb6005-8576-4311-8b23-9c5baf314d8d"
/>

**Notice shown in `settings.json`**:
<img width="569" height="231" alt="Notices shown in settings.json"
src="https://github.com/user-attachments/assets/475375a1-268c-4420-8ef7-a896548e4498"
/>

</details>

---

Release Notes:

- Removed OpenCode Free models from Zed's built-in OpenCode provider
because they are only available through OpenCode surfaces, such as its
external agent through ACP.
- Added Kimi K3, Grok 4.5, Hy3, GPT 5.6 Luna, Qwen 3.8 Max, and GLM 5.3
to OpenCode Go.
- Added Claude Opus 5, Gemini 3.5 Flash Lite, Gemini 3.6 Flash, Gemini
3.7 Flash, Kimi K3, Grok 4.6, and Muse Spark 1.2 to OpenCode Zen.
- Removed the deprecated Claude Opus 4.1 model from OpenCode Zen.

----

> [!TIP]
> This pull request is **best reviewed commit-by-commit**!

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-08-19 11:07:38 +00:00
Dino
28c0f4aef8
git_ui: Refactor git panel entry collapse (#61846)
# Objective

Standardize the behavior of collapsing/expanding entries between Project
Panel and Git Panel. At the time of writing, using `left` or `right` on
the Project Panel would find the nearest parent directory and collapse
it while, on the Git Panel, that will only happen if the directory is
already selected, otherwise it'll select the previous entry instead.

## Solution

Update `git_ui::git_panel::GitPanel::collapse_selected_entry` in order
to always try to find the nearest expanded directory, regardless of the
selected entry, and then collapse it and select it.

The default keymap for Vim/Helix has also been updated to ensure that
`h` and `l` work for collapsing or expanding entries, similar to what
already happens in Project Panel.

## Testing

Tested both manually, as can be seen in the "Showcase" section as well
as added a new test for these changes,
`git_ui::git_panel::tests::test_collapse_selected_entry` .

## 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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
  <summary>Before</summary>


https://github.com/user-attachments/assets/2fd8db03-155a-4406-a190-17a1958dda11
</details>

<details>
  <summary>After</summary>


https://github.com/user-attachments/assets/f64bd584-a3c2-4a33-b95a-2547c8b721d2
</details>

---

Release Notes:

- Improved `git panel: collapse selected entry` in order to find and
collapse the nearest parent directory, similar to the Project Panel.
- Added support for using `h` and `l`, in Vim/Helix mode, to collapse
and expand entries in the Git Panel.
2026-08-19 10:06:46 +00:00
María Craig
1a332533aa
file_finder: Keep filenames visible for long paths (#62839)
# Objective

Prevent long worktree and directory paths from shrinking filenames until
they become difficult to read in file finder results.

## Solution

Give the filename label non-shrinking flex sizing, and let the path
label use the remaining space. When the path does not fit, it truncates
from the beginning so the directories nearest the file remain visible.

## Testing

- Ran `cargo fmt --all --check`.
- Ran `cargo test -p file_finder --lib` — 79 tests passed.
- Ran `./script/clippy -p file_finder`.
- To verify manually, open a project with a long root name, search for
files, and resize the file finder. Confirm that filenames remain visible
while paths truncate from the beginning.

## 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 long project paths obscuring file names in the file finder.
2026-08-19 09:23:57 +00:00
Anthony Eid
7a7c3e1d2f
Restart interrupted update downloads after system wake (#60366)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Follow-up to #60301, which was reverted in #60321.

I removed the reqwest part of the fix because it crashed. reqwest's
`read_timeout` relies on a tokio timer, but Zed polls HTTP responses on
gpui's executor instead of a tokio runtime, so it panicked when the
response body was awaited. I'll follow up later by patching our reqwest
fork to support the poll behavior we wanted.

This fixes the download being stalled since we restart it when the
system wakes.

I also changed `App::on_system_wake` to return a `gpui::Subscription` to
be consistent with gpui's other on-system-event handlers like
`on_keyboard_layout_change` and `on_thermal_state_change`.

Release Notes:

- Fixed Zed update downloads stalling after the system wakes from sleep
2026-08-19 01:38:41 +00:00
Anthony Eid
fa852694f4
Enable CSV preview for all users (#62773)
Closes #58145

Remove the `tabular-data-preview` feature flag and register CSV preview
actions and the quick action bar button for every user. Also remove the
now-unused `feature_flags` dependency from the CSV preview crate.

Release Notes:

- Added CSV preview access for all users
2026-08-19 01:15:44 +00:00
Arnesh
4c7244790a
workspace: Activate the right tab when restoring a workspace (#62844)
@SomeoneToIgnore this is the follow up you asked for in #62692, done as
discussed.

`deserialize_to` keeps a `None` in `items` for every item that failed to
deserialize, and those are never added to the pane. Any later tab
therefore sits at a lower index in the pane than the one it was
serialized with, so activating and previewing by serialized index lands
on the tab that shifted into that slot. When the failing item is the
last one, the index points past the end of the pane and nothing is
activated or previewed.

The serialized index is now mapped to the pane's index by counting the
items before it that actually restored, and an index whose own item
failed to restore is skipped.

Closes #62843

Release Notes:

- Fixed the wrong tab being activated when restoring a workspace
containing items that fail to open

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-18 23:00:25 +00:00
John Yani
3f660a0a60
Remove deprecated std::usize import from uniform_list.rs (#62841)
<img width="993" height="370" alt="image"
src="https://github.com/user-attachments/assets/15e3a185-3328-4069-ad86-21d29f647f83"
/>

# Objective

- using `std::usize` currently is a warning, but it's a hard fairule in
rust nightly
- gpui-web requires rust nightly
- https://doc.rust-lang.org/std/usize/index.html
 
## Solution

- remove std::usize import, it would be used a primitive type

## Testing

-
https://github.com/iamnbutler/gpui-unofficial/actions/runs/32189970651/job/95882109895#step:8:753

## 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: Kirill Bulatov <kirill@zed.dev>
2026-08-18 22:41:54 +00:00
Arnesh
aad75630f9
workspace: Keep pinned tabs correct when restoring a workspace (#62692)
Pinned tabs are the leading tabs of a pane, and that is persisted as a
plain count. Both sides of workspace serialization could leave the count
out of step with the tabs it is meant to describe:

- When serializing, `serialize_pane_handle` drops items that cannot be
serialized (a pinned diagnostics or project search tab, for example)
from the pane's children, but still stored the pane's raw pinned count.
- When restoring, `SerializedPane::deserialize_to` keeps a `None` in
`items` for every item that failed to deserialize. Those are never added
to the pane, but `self.pinned_count.min(items.len())` counted them
anyway.

In both cases the count ends up pointing past the tabs that were
actually pinned, so the tabs that shift into those slots come back
pinned even though they never were. This also explains the `Pinned tab
count (N) exceeds actual tab count (M)` warning from #33342.

Now the serialized count shrinks with each dropped pinned item, and on
restore only the pinned items that were actually restored are counted.

Closes #62003

Release Notes:

- Fixed tabs being wrongly marked as pinned after reloading a workspace
or updating Zed
2026-08-18 21:58:55 +00:00
Ali
00c0e96e76
Make opening large files use less peak memory (#62748)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
# Objective
Opening a file laods it twice. `decode_file_text` builds the whole file
as a `String`, and that `String` stays alive alongside the finished rope
while `text::Buffer::new` copies it in. The `Vec` behind it grows by
doubling, so it also commits up to nearly the file's size again in
capacity it never uses.

Partially addresses #27283.

## Solution

Add `decode_file_text_to_rope`, which streams the file in 1 MB blocks
straight into a `Rope`, validating UTF-8 and normalizing line endings as
it goes. The file is never fully held as a `String`.

`LoadedFile::text` becomes a `Rope` carrying the `LineEnding` detected
before normalizing, so `buffer_store` calls `Buffer::new_normalized`.

## Testing

On a 729 MB SQL dump, peak memory fell 25% and CPU fell around 28%.
tested on 5950x, win11.

Release Notes:

- Improved memory use when opening large files, reducing peak memory
during load by roughly the size of the file itself.
2026-08-18 16:59:08 +00:00
Cameron Mcloughlin
2040e0de59
treesitter: Worker-pinned treesitter parsing (#62784)
Bumps the treesitter version to include
https://github.com/tree-sitter/tree-sitter/pull/5851

Also makes some changes to `cx.spawn_dedicated` to make it work on web:
- remove the blocking `recv` on the main thread
- adds a new variant `TaskState::Rendezvous` to allow this code to
synchronously return a task

`TaskState::Rendezvous` is needed because of how
`spawn_dedicated_thread` works:
- the caller provides a callback that produces a non-`Send` `Future` on
the dedicated thread
- the callback is sent to the dedicated thread, executed, and the
resulting `Task` is sent back to the main thread
- this all happens synchronously, so that `spawn_dedicated_thread`
returns a synchronous `Task`

However, the blocking `recv` on the main thread traps on the main worker
in the browser.

This PR replaces that with a call to `recv_async`, but this requires a
new `Rendezvous` variant on `TaskState` which represents "a task that it
still waiting to receive the underlying handle from the dedicated
thread".

It also enables the `flume/spin` feature on the web, which is needed to
avoid a synchronous lock acquisition in `send` (it's replaced with a
spinlock). Note that `send_async` wouldn't work here because it acquires
the same lock, and it's unnecessary because `send` only blocks when the
channel is full, but it's an unbounded channel.

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-08-18 16:55:09 +00:00
Andrew Mitchell
35f63e406e
markdown: Respect buffer_line_height in code blocks (#62785)
# Objective

- Fixes #62528
- Code blocks in rendered markdown ignored the `buffer_line_height`
setting. With the line height left unset, they fell back to the ambient
default of ~1.618, so the same code was spaced more loosely in markdown
than it was in an editor or the terminal.
- The extra leading is most obvious with box-drawing characters — the
ASCII-art box from the issue renders as disconnected stripes instead of
continuous vertical rules.
- The issue also notes that the preview font "seems bigger". That part
is working as intended and is not changed here: preview code blocks size
from `markdown_preview_font_size`, which falls back to `ui_font_size`
rather than `buffer_font_size` so that temporary UI zoom doesn't resize
the preview. Users who want it to match the editor can set
`markdown_preview_font_size` explicitly.

## Solution

- Set `line_height` on the code block text style in
`MarkdownStyle::themed_with_overrides`, derived from
`theme_settings.buffer_line_height`.
- The value is `relative(...)` rather than absolute pixels so it tracks
the code font size, which some callers override after building the style
(e.g. the agent panel sets `code_block.text.font_size` downstream). An
absolute value computed from the theme's font size would be wrong for
those callers.
- Scope: this applies to every `MarkdownFont` variant — preview, agent
panel, and editor — since the code block style is shared and
`with_preview_overrides` doesn't touch line height.
- Prose leading is deliberately unchanged. It stays a per-element
typographic choice, independent of the buffer setting.

## Testing

- `cargo test -p markdown` — 145 passed, 0 failed.
- Added
`test_code_block_line_height_follows_buffer_line_height_setting`:
renders a paragraph plus a fenced code block at `buffer_line_height` 1.2
and 1.8, asserts the code block's rendered line height tracks the
setting, and asserts prose leading does *not* move.
- Added `test_code_block_line_height_tracks_overridden_code_font_size`:
overrides `code_block.text.font_size` after building the style and
asserts the line height follows the override. This is what pins the
`relative` vs. absolute choice.
- To reproduce manually, set `"buffer_line_height": { "custom": 1.2 }`
and open a markdown preview containing the ASCII-art box from #62528.
The vertical rules should join into continuous lines, matching how the
same block renders in an editor, and should visibly separate again at
`"comfortable"`.

## 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

Before
<img width="927" height="912" alt="Screenshot 2026-08-17 at 5 06 41 PM"
src="https://github.com/user-attachments/assets/be6213bf-f3aa-42fb-8784-1985b5379d74"
/>

After
<img width="915" height="994" alt="Screenshot 2026-08-17 at 5 06 54 PM"
src="https://github.com/user-attachments/assets/c9c7f395-50cb-437b-a423-2030da88e4f4"
/>



---

Release Notes:

- Fixed markdown code blocks not respecting the `buffer_line_height`
setting
2026-08-18 16:33:44 +00:00
Buyun Xu
3624a5bfda
project: Anchor diagnostic related information that points into the buffer (#62805)
Closes #62796. Follow-up to #62110.

# Objective

The range of a diagnostic entry is anchored when it is ingested, so it
follows edits. The ranges in the related information kept on the
diagnostic were the ones the server published. A code action request
carried both and reported the same note at two different lines: the
entry Zed flattened that note into had followed the edit, the related
information had not.

The distance does not correct itself either. When diagnostics are merged
rather than replaced, the existing entries are re-collected from their
anchors while the payload is cloned as it is, so the two positions drift
further apart with every edit that passes.

`mlir-lsp-server` shows what this costs. `MLIRTextFile::getCodeActions`
takes the line number out of `relatedInformation`, and
`getCodeActionForDiagnostic` resolves it against its own current
document, reading that line to copy its indentation before inserting the
`expected-note` check.

## Solution

The related information moves from `Diagnostic` onto
`DiagnosticEntry<T>`, next to the range it belongs with. The locations
of the diagnostic's own file are then in the same coordinate space as
that range: anchors inside the buffer, points in the worktree's store.
`Diagnostic` carries no coordinates again, so nothing that is only
meaningful inside one buffer travels with a payload that outlives it.

Every transition goes through `DiagnosticEntry::map_coordinates`: the
unsaved-edit adjustment and the clipping when diagnostics are ingested,
the anchoring in `DiagnosticSet::new`, and the conversion back to points
in `merge_diagnostic_entries`. Only the diagnostic's own range is
widened when it is empty, since that is for how it is rendered, while
the related locations are reported back as the server framed them.

Locations in another file have nothing here to anchor to and are kept as
published, which is also what `mlir-lsp-server` expects, since it skips
them.

`DiagnosticEntryRef` is left alone. It is what the rendering path
iterates, down to the scrollbar markers that walk every diagnostic of
the buffer on each frame, so nothing there converts or allocates. The
entries are read through `diagnostic_entries_in_range` where the request
is built, and `diagnostics_in_range` is now implemented on top of it.

The field is an `Option`, as an empty `Arc<[_]>` still allocates and
most diagnostics carry no related information.

`data` has the same staleness and cannot be anchored, as it is opaque.

## Commits

The third commit is mechanical: it introduces `DiagnosticEntry::new` and
rewrites the literals at its call sites, so that the last commit holds
only the change of behaviour.

## Testing

Three tests, all failing before this change. The first two are added as
separate commits, so that they can be run against `main`:

- `test_code_actions_related_information_follows_edits` edits above the
note and requests code actions, where the two positions for it used to
disagree.
- `test_code_actions_related_information_drifts_across_merges` edits and
pulls diagnostics twice, where the distance used to be every line
inserted since the diagnostic was published rather than the last edit
alone.
- `test_code_actions_related_information_of_disk_based_diagnostics`
publishes a diagnostic computed against the file on disk while the
buffer holds an unsaved edit, covering the adjustment the two positions
share.

- `cargo test -p project`
- `cargo test -p language -p diagnostics -p editor`
- `cargo fmt --all -- --check`
- `./script/clippy -p project -p language`

## 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 language servers receiving outdated positions for the related
information of a diagnostic when code actions are requested.
2026-08-18 15:06:02 +00:00
Bennet Bo Fenner
87324045be
Switch to async-tar fork (#62821)
This switches to `async-tar` to point to our fork, which has a fix for a
bug that is causing the Cursor ACP agent fail to download in Zed, due to
Pax attributes.

We will switch back as soon as
https://github.com/dignifiedquire/async-tar/pull/73 is merged.

Closes #62655

Release Notes:

- Fixed an issue where the Cursor ACP agent would fail to start
2026-08-18 14:23:30 +00:00
Ben Kunkle
03c9c4e707
gpui: Rasterize parsed SVGs at exact sizes (#62770)
# Objective

Allow callers to rasterize parsed SVGs at exact device-pixel dimensions.

## Solution

Add `SvgSize::ExactSize` and accept `SvgSize` in `render_parsed`.
Existing scale-factor calls retain their 2× rasterization behavior.
`SvgSize::Size` continues to preserve the SVG aspect ratio.

Release Notes:

- N/A
2026-08-18 14:13:27 +00:00
afdul
a7d74150ac
Fix the git_gutter_width setting (#62704)
Some checks are pending
run_tests / check_style (push) Waiting to run
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
# Objective

- Fixes #62645
## Solution
Since the default value isnt constant.It now has two options 1) Default
2) custom where user inputs a value.

## 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
- [ ] Performance impact has been considered and is acceptable

## Showcase
<img width="798" height="361" alt="Screenshot 2026-08-16 at 4 29 54 PM"
src="https://github.com/user-attachments/assets/0af302f6-4733-4a23-9e93-1f9d98dd772f"
/>

<img width="798" height="92" alt="Screenshot 2026-08-16 at 4 30 13 PM"
src="https://github.com/user-attachments/assets/2c87c2a3-2947-45c7-8495-f6a0b36dd793"
/>

Release Notes:

- Added git_gutter_width setting to the Settings UI with default
(font-size-scaled) and custom (fixed pixel width) options

---------

Co-authored-by: Abdul Rafey Ahmed <abdul.r@hyperverge.co>
Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-18 12:40:18 +00:00
Oleksandr Kholiavko
dbc90d18b0
tabular_data_preview: Finish generalizing crate naming (#62807)
# Objective

#62768 renamed `crates/csv_preview` to `crates/tabular_data_preview`,
but left the CSV-specific names inside it untouched (on purpose, to
reduce prev PR scope & git diff noise)

## Solution

Finished the generalization, one mechanical rename per commit for easier
review:

1. `CsvPreviewView` -> `TabularDataPreviewPane`
2. `CsvPreviewSettings` -> `TabularDataPreviewSettings`
3. Methods/vars
4. Test helpers/fn names
5. User-facing strings and element ids: tab title fallback:
    - `"CSV Preview"` -> `"Tabular Data Preview"`,
- empty state `"No CSV content to display"` -> `"No data to display"`,
- dev tooltip, and element ids
`csv-filter-*`/`csv-col-header-*`/`csv-table`/`csv-display-cell-*` ->
`table-*`/`tabular-data-table`
6. Doc comments that implied CSV-only behavior, reworded to be
format-agnostic

> NOTE: PR is split into commits by change type for ease of review)

## Testing

`cargo check -p tabular_data_preview -p zed` builds clean after each
commit; `cargo test -p tabular_data_preview --lib` passes (10/10).

## 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

Release Notes:

- N/A
2026-08-18 12:28:30 +00:00
Oleksandr Kholiavko
05473ed83d
Rename csv_preview crate to tabular_data_preview (#62768)
# Objective

#60768 renamed the feature (action names, icon, TSV/PSV/SSV support)
from CSV-only to generic tabular data preview, but left the crate itself
named `csv_preview` — no longer accurate now that it handles any
delimited format.

## Solution

Renamed `crates/csv_preview` to `crates/tabular_data_preview` and
updated all references (workspace `Cargo.toml` members/dependencies,
`crates/zed/Cargo.toml`, `crates/zed/src/main.rs`,
`crates/zed/src/zed/quick_action_bar/preview.rs`). No behavior change.

> NOTE: Mechanical changes. Internal structs not renamed on purpose to
reduce git diff noise. Follow-up PRs will do the cleanup (also
mechanical changes)

## Testing

`cargo check -p tabular_data_preview` and `cargo check -p zed` build
clean; preview still opens for csv/tsv/psv/ssv files.
Zed still runs, everything still opens.

## 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:

- N/A

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-18 10:10:04 +00:00
tidely
fdad9186b8
git_ui: Dismiss askpass prompts when requests end (#61292)
# Objective

Fixes #47623

- When authenticating git commands using a security key through
`askpass`. The modal which asks for user presence does not get dismissed
even after the git command finishes successfully.

## Solution

Add a cancellation task to the `AskPassModal`, which gets dropped when
the requested operation completes. This cancellation task then dismisses
the modal.

## Testing

- I've tried authentication through `askpass` using my own security key.
Testing both successful and failed authentication.
- I've added tests which confirm that the modal gets dismissed when a
task is cancelled, and that the cancellation is triggered when
`ask_password` Task gets dropped.

Willing to pair on review, message me on Slack. Showcase video left out
because it would leak private information.

## 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 authentication prompts not dismissing automatically when using
security keys with ssh
2026-08-18 10:02:20 +00:00
Qiu shao
fd5cd9398d
Fix markdown task list marker lookup (#60646)
# Objective


Fix Markdown preview task list checkboxes not rendering for task items
in
  loose or nested lists.

For example, this Markdown should render all three items with
checkboxes:

  ```markdown
  - [ ] test
  - [x] test
    - [x] test
```
  Before this change, the items after blank lines could fall back to ordinary
  list bullets instead of task checkboxes.

## Solution

Update Markdown list item rendering to detect task list markers in both tight
  and loose list event shapes emitted by pulldown-cmark.

  The previous renderer only handled:

  Item -> TaskListMarker

  Loose lists can emit:

  Item -> Paragraph -> TaskListMarker

  This PR adds a small helper to find task markers for both forms, then reuses
  the existing checkbox rendering and toggle behavior.

## Testing

  Tested on macOS with:

  rustup run 1.95.0 cargo test -p markdown
  test_task_marker_lookup_handles_loose_and_nested_lists
  rustup run 1.95.0 cargo test -p markdown test_table_checkbox

  The first test covers loose and nested task list items. The table checkbox
  tests verify that [x] and [ ] inside tables still remain text and are not
  treated as task list checkboxes.

## 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
before
<img width="927" height="275" alt="image" src="https://github.com/user-attachments/assets/a36f0b9f-8759-4593-99a9-8a256396e89e" />

after
<img width="963" height="322" alt="Snipaste_2026-07-09_12-27-05" src="https://github.com/user-attachments/assets/972fa7a7-274a-4b0a-a13c-c7e1aec27622" />



---

Release Notes:

- Fixed Markdown Preview for loose list item markers

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-08-18 09:59:35 +00:00
Dom Porada
cf08569e82
Add support for the "..." entry in file_scan_exclusions (#62769)
## Objective

`file_scan_exclusions` replaces the defaults instead of adding to them,
so excluding one extra directory means restating all eleven default
globs and never picking up defaults added in later Zed releases.

## Solution

`file_scan_exclusions` now accepts the `"..."` entry, which expands to
the value it overrides, so `["**/node_modules", "..."]` adds to the
inherited globs instead of replacing them. Entries listed by name keep
their position, and leaving `"..."` out still replaces the list
outright, so existing settings behave exactly as they do today.

## Testing

- Four unit tests in `crates/settings_content/src/project.rs` cover
splicing versus replacing, accumulation across successive layers, and
edge cases: a repeated `"..."`, an empty list clearing the value, and a
bare `["..."]` leaving it unchanged.
- To check by hand: set `"file_scan_exclusions": ["**/node_modules",
"..."]` in user settings and confirm `node_modules` disappears from the
project panel and file finder while `.git` and `.DS_Store` stay
excluded. Remove `"..."` and confirm only `node_modules` is excluded.
Repeat in a project's `.zed/settings.json` to confirm it splices the
resolved user settings rather than the defaults.
- Tested on macOS. This is platform-independent settings-merge logic
with no OS-specific code paths, so I did not test Linux or Windows.

## 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 support for the `"..."` entry in `file_scan_exclusions`. Custom
exclusions can now extend the defaults instead of replacing them.
2026-08-18 09:57:38 +00:00
Levin Rickert
1274a5dc25
task: Support path property on VS Code npm tasks (#62044)
# Objective

npm tasks in VS Code support a `path` property which works like
`options.cwd` but it's always relative to the workspace folder.

## Solution

`cwd` is being set based on `path` of npm tasks. If `options.cwd` is
also set, it wins over the `path` property. This matches the behavior of
VS Code.

## Testing

A new test case has been added, testing deserialization of `path` and
`options.cwd`.

## 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)
- [x] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

---

Release Notes:

- Added support for `path` property on VS Code npm tasks
2026-08-18 07:58:21 +00:00
Remco Smits
2893b86b04
gpui_macos: Add simple fullscreen mode that covers the notch (#60020)
Closes #60013

# Objective

Right now Zed can go full screen but it does not allow you to fix the
hole screen,
by that I mean that Zed can go behind the notch so you don't have extra
useless room left.

## Solution

You can now use the `fullscreen_mode` = `simple` setting to use the new
simple full screen feature, that lives besides the normal full screen
feature. But allows you to have an option to go 100% full screen without
losing any useless space on your macbook screen.
**Note** this is mostly usefull when you have a macbook that has a notch
whitch is kinda in the way of your work flow.

## 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

**Before**
<img width="5712" height="4284" alt="IMG_0339"
src="https://github.com/user-attachments/assets/9f908ffd-7cef-4999-a454-c80f72c40dc8"
/>

**After** (Note now Zed is behind your notch when using the simple full
screen feature)
<img width="5712" height="4284" alt="IMG_0360"
src="https://github.com/user-attachments/assets/5917ed4d-2a64-4464-a794-bc46fd034521"
/>


---

Release Notes:

- Added support for simple fullscreen mode using the `fullscreen_mode`
setting, set it to `simple` to try it out.
2026-08-18 07:00:34 +00:00
Priyadharshan
4bdf188c99
Added Tracked , Staged options to stash (#62254)
# Objective

Closes #62252 

The Git Panel could only stash *everything* — `Stash All` runs
`git stash push --include-untracked`, sweeping tracked edits and
untracked files
into a single entry. There was no way to stash a subset, so the common
workflows
of "park my tracked edits but keep my new scratch files" and "park what
I've
staged and keep working on the rest" required dropping to the terminal.

## Images

<img width="389" height="358" alt="Screenshot 2026-08-10 at 3 10 50 PM"
src="https://github.com/user-attachments/assets/18e4c943-e320-4802-ada8-59e54bf4cefd"
/>

<img width="504" height="462" alt="Screenshot 2026-08-10 at 3 10 37 PM"
src="https://github.com/user-attachments/assets/783237eb-980d-47bc-a0f5-17b03a23a60c"
/>






## Solution

Add two stash variants alongside `Stash All`, surfaced in the Git
Panel's
overflow menu based on how the list is currently grouped, so the menu
mirrors the
sections the user can actually see:

| Group By | Stash entries offered |
| --- | --- |
| None | Stash All |
| Tracked & Untracked | Stash All, **Stash Tracked** |
| Staged & Unstaged | Stash All, **Stash Staged** |

- **`git::StashTracked`** stashes tracked changes and leaves untracked
files in
place. It reuses the existing pathspec plumbing
(`Repository::stash_entries`),
  filtering the status list down to the paths to stash.
- **`git::StashStaged`** stashes the index only, leaving unstaged
changes in
place. This *cannot* be expressed as a pathspec — a partially staged
file would
have its unstaged hunks stashed too — so it needs git's own `--staged`
flag.
  That meant a new `GitRepository::stash_staged` backend method and an
`optional bool staged` field on `proto::Stash` so remote projects work
too.

Both actions are unbound by default and are dispatchable from the
command palette
when the panel is focused.

One subtlety worth calling out for review: `Stash Tracked` filters on
`FileStatus::is_created()`, not `is_untracked()`. Staging a new file
flips it from
`Untracked` to `Tracked { Added }`, but the panel still lists it under
**Untracked** — using `is_untracked()` meant staged-new files were
silently
stashed. `is_created()` is the same predicate the panel uses to build
that section
(`git_panel.rs`), so the menu item and the list can no longer disagree.

This branch also includes a separate commit adding **per-section
staging**
(`git::StageSection` / `git::UnstageSection`) — right-click a file to
stage or
unstage every entry in its section. Happy to split that into its own PR
if
preferred.

## Testing

Manually tested on macOS against a scratch repo with a mix of states:
modified
tracked files, untracked files, and untracked files that had been
staged.

- `Stash Tracked` with tracked edits + untracked files → only tracked
edits
  stashed; untracked files remain.
- `Stash Tracked` with untracked files **staged** → they remain, staged.
This was
  broken in an earlier revision and drove the `is_created()` fix above.
- `Stash Staged` with one file staged and another modified-but-unstaged
→ only the
  staged file is stashed; the unstaged edit and untracked files survive.
- `Stash Pop` round-trips both cases back to the original state, with no
conflicts.
- Menu contents and disabled states verified in all three Group By
modes.
- Per-section staging covered by a new unit test,
  `test_stage_section_scopes_to_selected_section`.

Not covered by automated tests: the stash actions themselves.
`FakeGitRepository`
leaves every stash method `unimplemented!()`, so stash behavior isn't
reachable
from GPUI tests today — consistent with the existing untested
`StashAll`. Adding
fake-repo stash support looks like a worthwhile follow-up but felt out
of scope here.

Reviewers on non-macOS platforms: nothing here is platform-specific.
Note that
`Stash Staged` requires **git 2.35+** (Jan 2022) for `git stash push
--staged`;
older git surfaces a clear error toast rather than failing opaquely. The
remote
path (`proto::Stash.staged`) has not been exercised against a live
collab session.

## 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

Release Notes:

- Added `Stash Tracked` and `Stash Staged` options to the Git Panel,
letting you stash only tracked changes or only staged changes.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-08-18 05:36:16 +00:00
Conrad Irwin
7871260991
Preserve typed errors when listing Anthropic models (#62791)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Anthropic model-list requests currently flatten request, transport,
response, and API failures into `anyhow` strings. Callers therefore
cannot distinguish an invalid API key from connectivity or provider
failures, even though Anthropic returns a structured error payload.

This changes `list_models` to return `AnthropicError`, maps each request
stage to its existing typed variant, and routes unsuccessful responses
through the same structured response handler used by completion
requests. The language model provider converts that error at its
existing `LanguageModelCompletionError` boundary. A regression test
verifies that an authentication response retains both its error category
and Anthropic's human-readable message.

Testing performed:

- `cargo fmt --check`
- `cargo nextest run -p anthropic -p language_models`
- `./script/clippy -p anthropic -p language_models`

Release Notes:

- Fixed Anthropic API key errors being reported as generic model-list
failures.
2026-08-18 03:44:43 +00:00
Conrad Irwin
83f3a8e3e9
open_ai: Classify Responses API send failures as transport errors (#62660)
OpenAI Responses API send failures were being converted into the
catch-all `Other` error before they reached the language model layer. A
DNS failure from the ChatGPT Subscription provider could therefore
appear as an unexpected model error instead of using the existing
transport-aware messaging and retry behavior.

The shared Chat Completions transport already preserves this
distinction. This change applies the same `RequestError::HttpSend`
classification to Responses API streaming and compaction requests,
allowing the existing conversion to produce
`LanguageModelCompletionError::HttpSend` with the provider and
underlying cause intact. Separate regression tests cover send failures
in both request paths.

Testing performed:

- `cargo test -p open_ai reports_http_send_errors -- --nocapture`
- `cargo test -p open_ai`
- `cargo check -p openai_subscribed`
- `cargo fmt --all --check`
- `git diff --check`
- `./script/clippy -p open_ai`

Release Notes:

- Fixed ChatGPT Subscription connection failures showing a generic error
instead of a network-specific message.
2026-08-18 03:20:44 +00:00
Finn Evers
aa3718614b
Ensure that clippy fixes can be disabled for the autofix workflow (#62781)
Also disables them by default because it makes autofixes for the average
case very slow.

Note that this does not yet change anything for the Zippy /autofix
command here.

Release Notes:

- N/A
2026-08-17 22:50:45 +00:00
Xiaobo Liu
fd90c0af7f
project: Deduplicate identical language server hover responses (#62266)
Closes https://github.com/zed-industries/zed/issues/62262

## Solution

Identical hover responses from multiple language servers should be
displayed only once.

Different hover responses should still all be preserved, since multiple
language servers may provide complementary information.


## Showcase



https://github.com/user-attachments/assets/67246d9f-ed1c-4f5a-98f5-f10548b7fc6d



---

Release Notes:

- Deduplicated identical language server hover responses

---------

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-08-17 22:47:34 +00:00
Remco Smits
64d14ea81f
git: Allow using system pinentry in gpg wrapper script (#62357)
Closes https://github.com/zed-industries/zed/issues/61806

Follow-up to #58791 and #61265.

# Objective

Since Zed started injecting its own gpg wrapper for commit signing, the
wrapper's "silent first attempt" used `--pinentry-mode error`, which
forbids gpg-agent from launching *any* pinentry. That was meant to avoid
the `gpg: signing failed: Inappropriate ioctl for device` failure from
TTY-based pinentries, but it also blocked **GUI** pinentries like
pinentry-mac, which need no TTY and can supply the passphrase silently
from the macOS Keychain. For users with that setup (and gpg-agent's
in-memory cache disabled via `default-cache-ttl 0`), the first attempt
always failed and Zed's passphrase modal appeared on **every commit**,
even though terminal git signed silently.

This also makes the setting proposed in #61533 unnecessary: instead of
asking users to choose between Zed's prompt and the system pinentry, the
wrapper now tries the system pinentry automatically and only falls back
to Zed's askpass modal when gpg genuinely cannot obtain the passphrase
on its own.

## Solution

Restructure the wrapper script to sign in three stages, most silent
first, so every pinentry configuration self-selects the right behavior
without any detection or settings:

1. **`--pinentry-mode error`**: succeeds only via gpg-agent's passphrase
cache or an unprotected key; guaranteed to never prompt anywhere. This
keeps the #61265 behavior byte-identical.
2. **Default pinentry mode**: lets the configured pinentry run, exactly
like terminal git. GUI pinentries (e.g. pinentry-mac reading the macOS
Keychain) need no TTY and sign silently or show their native dialog; TTY
pinentries fail fast with `Inappropriate ioctl for device` because git
spawns gpg without a TTY.
3. **Loopback mode**: asks for the passphrase via Zed's askpass modal
and hands it to gpg on fd 3, for setups where gpg cannot prompt at all
(e.g. when gpg-agent's `pinentry-program` is not configured).

## Testing

Initial steps:
1. Run `security delete-generic-password -s GnuPG` to remove the GnuPG
keychain entry, forcing you to re-enter your passphrase (start from the
initial state of issue)
2. (**optional for a few test cases**) Configure your
`~/.gnupg/gpg-agent.conf` with `pinentry-program
/opt/homebrew/bin/pinentry-mac`
3. Run `gpgconf --kill gpg-agent` to force reset/kill the gpg agent
cache

Cases to test:
1. Have no existing gpg key and you can still commit without needing to
enter a passphrase
2. Have a gpg key configured in git but no `~/.gnupg/gpg-agent.conf`
config that configures the `pinentry-program`
This should still request your passphrase via Zed's askpass modal, even
though no `pinentry-program` is configured and committing via the
terminal throws an error `gpg: signing failed: Inappropriate ioctl for
device`
3. Have a gpg key configured in git and a `~/.gnupg/gpg-agent.conf`
config that configures the `pinentry-program`, and cancel the native
pinentry program → Zed should fall back to requesting your passphrase
via the askpass modal
4. Have a gpg key configured in git and a `~/.gnupg/gpg-agent.conf`
config that configures the `pinentry-program`, and fill in your
passphrase via the native pinentry program with storing your passphrase
in the keychain **disabled**
5. Have a gpg key configured in git and a `~/.gnupg/gpg-agent.conf`
config that configures the `pinentry-program`, and fill in your
passphrase via the native pinentry program with storing your passphrase
in the keychain **enabled** → subsequent commits sign silently, matching
terminal git

## 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

**After: (Testing that the system pinentry program is used and works
without needing to reenter your passphrase everytime only when you
remove it from your keychain)**


https://github.com/user-attachments/assets/0c8cdd11-957d-443a-ab10-1579bbf3b49e

---

Release Notes:

- Git: Fixed the GPG passphrase modal appearing on every commit for
users whose configured pinentry (e.g. pinentry-mac with the macOS
Keychain) can supply the passphrase without Zed's help. Zed now only
prompts when gpg cannot obtain the passphrase on its own.

---------

Co-authored-by: Eric Holk <eric@zed.dev>
2026-08-17 22:43:12 +00:00
Austin Cummings
6721ea2e5c
workspace: Reset all configured dock panels (#62552)
Closes #57388.

When a dock is listed in `resize_all_panels_in_dock`, reset its
compatible panels to the active panel's default size. This applies to
the reset actions and resize-handle double-clicks. Docks not listed in
the setting continue to reset only the active panel.

Adds regression coverage for fixed panels with different defaults,
flexible panels, and active-panel-only resets.

Release Notes:

- Fixed dock size reset commands only resetting the active panel when
`resize_all_panels_in_dock` is enabled.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-08-17 22:28:04 +00:00
Cameron Mcloughlin
07a0bd1220
gpui: Frame time debug overlay (#62749)
<img width="372" height="207" alt="image"
src="https://github.com/user-attachments/assets/5e44a121-b6f3-4bb8-9f94-5bb7da1c04d2"
/>

New keybinds:
- `ctrl-alt-shift-p` - cycle debug overlay between "off", "minimal",
"full"
- `ctrl-alt-shift-o` - reset stats

---

Release Notes:

- Added: Frame time debug overlay
2026-08-17 22:17:24 +00:00
goring
7bddd16a09
gpui: Fix TestWindow panicking on window_handle (#62775)
> **AI disclosure:** I used Claude (Anthropic) to diagnose this, write
the fix and its test, and draft this PR description, after every
headless test in my own app started panicking during a gpui upgrade. I
reviewed the diff and the reasoning below, ran the tests myself, and
understand and take responsibility for the change, per Zed's [AI
Policy](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#ai-policy).

# Objective

- `TestWindow` panics instead of returning an error when asked for its
raw window handle. `HasWindowHandle` and `HasDisplayHandle` both return
`Result<_, HandleError>`, so a window with no C-typed handle can report
that — but `TestWindow` calls `unimplemented!()`. Callers who correctly
write `window_handle().ok()?` still crash, and any headless test whose
window reaches code that asks for the platform handle dies on boot.
- This has two halves, and only the second made it reachable:
- `a54eaaece` ("Add raw window handle implementations to GPUI", #7101,
2024-01-30) added both impls for `TestWindow` as `unimplemented!()`
placeholders while the real platforms got real ones. `TestWindow` was
`pub(crate)` then, so nothing outside gpui could hit it.
- `4270f8995` ("gpui: Implement `HasWindowHandle` on `Window`", #24327,
2025-02-06) made `Window` implement both traits by forwarding to
`platform_window`. From then on, any consumer asking a `Window` for its
raw handle reaches `TestWindow` under `TestAppContext`.
- I hit this through
[gpui-component](https://github.com/longbridge/gpui-component), whose
macOS accessibility code calls
`HasWindowHandle::window_handle(window).ok()?` on every window it roots
— correct defensive code that still panics, taking every one of my
headless `#[gpui::test]` tests down at boot.


## Solution

- `TestWindow::window_handle` and `TestWindow::display_handle` now
return `Err(HandleError::NotSupported)` instead of calling
`unimplemented!()`. That variant's documentation describes exactly this
case — "the underlying handle cannot be represented using the types in
this crate".
- Real platform windows are untouched: this only changes what the test
platform reports, so `Ok(...)` on macOS, Linux and Windows is
unaffected. Callers that already handle the error path now get the error
they were written for.

## Testing

- Added `test_window_reports_no_raw_handle_instead_of_panicking` in
`crates/gpui/src/window.rs`, asserting both calls return
`Err(HandleError::NotSupported)`.
- Reverting the fix while keeping the test reproduces the original
panic, so the test pins the behaviour rather than passing vacuously.
- `cargo test -p gpui --lib` from a clean target directory — 220 passed,
0 failed:

```
   Compiling gpui v0.2.2 (/…/zed/crates/gpui)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 5m 25s
     Running unittests src/gpui.rs (target/debug/deps/gpui-463768d254ca0c08)

running 220 tests
...
test window::tests::test_window_reports_no_raw_handle_instead_of_panicking ... ok
...
test result: ok. 220 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.49s
```
- Tested on macOS. The change is confined to
`crates/gpui/src/platform/test/`, which is platform independent, but I
have not built the Linux or Windows platform crates.

## 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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

Before — the new test against the current `unimplemented!()`:

```
thread 'window::tests::test_window_reports_no_raw_handle_instead_of_panicking' panicked at
crates/gpui/src/platform/test/window.rs:57:9:
not implemented: Test Windows are not backed by a real platform window

test result: FAILED. 0 passed; 1 failed
```

After — see the full run above.

Release Notes:

- N/A
2026-08-17 21:50:09 +00:00
David Barsky
8b1497dbd2
gpui: Add spring animations; examples (#62778)
# Objective

I wanted spring animations in GPUI for an application built atop of
GPUI.

## Solution

I texted @mikayla-maki about wanting spring animations; we collaborated
in Delta; this change is the co-authored result. We built atop of GPUI's
existing APIs, but this *is* new API surface. The verbiage is borrowed
from SwiftUI's approach.

First, what _are_ spring animations? If you're unfamiliar, they're the
bouncy, physical animations that you'd often see in mobile applications.
As Claude put it to me, "keyframe animation is a recording; a spring is
a simulation". There's a few consequences:
1. The animation API needs to support interrupts/cancelation, or the
application using spring animations will feel broken. You need to cancel
the momentum in a physically realistic way!
2. The API is more complex! GPUI's existing animations are, roughly,
`Fn(progress: f32) -> eased_progress: f32`, but a spring animation is
closer to `Fn(state: SpringState, target: f32, delta_time: f32) ->
SpringState`. Concretely, GPUI landed on the following:

```
pub fn step(
    &self,
    state: SpringState,
    target: f32,
    delta_time: f32,
) -> SpringState;
```

...where `&self` is:
```
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SpringConfig {
    /// The spring stiffness, conventionally written as $k$.
    pub stiffness: f32,
    /// The viscous damping coefficient, conventionally written as $c$.
    pub damping: f32,
    /// The moving mass, conventionally written as $m$.
    pub mass: f32,
}
```

Conceptually, at each frame, GPUI does `let state = spring.step(state,
target, delta_time);`, or as an other LLM summarized:

```
// Ordinary animation:
progress: f32 -> phase: f32

// GPUI spring:
(state: { position, velocity }, target, dt)
    -> new { position, velocity }
    -> typed presentation value
```

---

Release Notes:

- gpui: Added spring animations
2026-08-17 21:43:46 +00:00
Kirill Bulatov
eb5483528b
Fix overflowing highlights in the markdown blocks (#62714)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
Before:
<img width="1728" height="1084" alt="before"
src="https://github.com/user-attachments/assets/68a33e27-7ee7-42cc-9f1b-53e541ef8d2f"
/>


After:
<img width="1728" height="1084" alt="after"
src="https://github.com/user-attachments/assets/b51df462-6457-44fd-ba83-f13c6129125d"
/>


Release Notes:

- Fixed overflowing highlights in the markdown blocks

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-17 19:07:31 +00:00
Anthony Eid
eb38ea5585
Update community champions list (#62761)
# Objective

@HalavicH Has been responsible for building out our csv preview feature
and producing plenty of high qualtiy PRs to do so. I'm marking him as a
community champion to recgonize that work and give is PRs higher
priority when it comes to review

Release Notes:

- N/A
2026-08-17 19:05:13 +00:00
Ayush
d0bfe0a453
git_ui: Enable navigation for single-hunk diffs (#62615)
## What

Keep the hunk navigation controls available when a diff contains one
hunk, so users can return to it after scrolling away. This applies to
solo, staged, unstaged, and project diff views.

## Why

The controls were only rendered when `hunk_count > 1`, even though the
existing navigation actions already wrap and recenter a single hunk.

## How

Render the previous and next hunk controls whenever `hunk_count > 0`,
reusing the existing navigation actions.

Closes #62469

## Testing

- `cargo +stable-x86_64-pc-windows-gnu test -p git_ui --lib` — 130
passed.
- `cargo +stable-x86_64-pc-windows-gnu build -p zed -j 1` — passed.
- `rustfmt --edition 2024 --check` on the four changed files — passed.
- `git diff --check` — passed.
- Manually verified with the branch-built Zed on Windows: opened a
tracked file with exactly one diff hunk, expanded the context, scrolled
below the hunk, and used **Go to Previous Hunk**. The view returned to
the changed line.

## Showcase


https://github.com/user-attachments/assets/e7b63030-50ad-4536-8266-13987ed85f3d

## 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://zed.dev/docs/development/ux-ui) and [icon
guidelines](https://zed.dev/docs/development/ui-icons))
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Enable "Go to Previous Hunk" and "Go to Next Hunk" buttons even if
there's a single diff hunk.
2026-08-17 18:16:10 +00:00
Buyun Xu
6dee3fc755
project: Send diagnostic related information in code action requests (#62110)
Closes #62560.
Supersedes #62108, which was a subset of this one.
Overlaps #62400, see comments.

# Objective

Zed flattens the `relatedInformation` of a diagnostic into non-primary
entries of the same diagnostic group. Before this change it did not
retain the original related information on the primary diagnostic, so
code action requests were built from the entries intersecting the
requested range, with the primary diagnostic carrying no
`relatedInformation`.

This caused incomplete code actions from servers such as
`mlir-lsp-server`, which generates `expected-note` edits by walking the
related information of an error or warning diagnostic.

## Solution

Keep the related information the server published on the primary
diagnostic when the diagnostic comes in, next to `data`, and pass it
back when building the code action request.

Nothing is removed from `context.diagnostics`: the flattened entries are
still sent as before, so a diagnostic the server published on its own
and that Zed merged into a group as supporting information keeps being
sent with the severity the server gave it. What it does not recover is
that diagnostic's own `relatedInformation`: ingestion keeps only its
severity. Unchanged from `main`.

Reassembling it from the flattened entries instead, which is what the
first revision of this PR did, is neither faithful — ingestion trims
messages and drops entries with an empty message or pointing at another
file — nor cheap: diagnostics are not indexed by group, so every request
would scan all diagnostics of the buffer, once per server, on every
selection change.

One caveat: the stored ranges are the ones the server published rather
than anchors, so they do not follow edits made after the diagnostic
arrived, while the primary's range does. An edit in that window can put
a resolved insertion a few lines off — `mlir-lsp-server` places the
`expected-note` line at the note's own position. `data` has the same
property today. Anchoring them would mean carrying related information
through the anchor conversion, which I would rather do as a follow-up if
you consider it worth it.

The field is not carried over the proto conversion, as LSP requests are
only built by the peer that received the diagnostics from the language
server.

## Testing

New tests for:

- related information sent verbatim, including the cross-file and empty
entries that flattening drops;
- no related information;
- a flattened entry whose primary is outside the requested range;
- a server-published supporting diagnostic;
- two servers on the same buffer.

Verified on the repro from #62560 that `mlir-lsp-server` inserts both
the `expected-error` and the `expected-note` check
([screenshot](https://github.com/zed-industries/zed/issues/62560#issuecomment-5278476460)).

- `cargo test -p project`
- `cargo test -p language -p editor -p diagnostics`
- `cargo fmt --all -- --check`
- `./script/clippy -p project -p language`

## 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 incomplete code actions from language servers that rely on the
related information of a diagnostic.
2026-08-17 16:40:29 +00:00
vinod akshat
dfb696697e
Fix horizontal autoscroll not following cursor on long selections (#62691)
# Objective

Fixes #62524

This bug was introduced in a regression from #61487, which fixed
horizontal autoscroll for multi-row selections (word wrap off) by
computing target_left/target_right from the selection's actual start/end
instead of just head.That fix changed target_left/target_right from
always being a single point (head's column) to spanning the full
selection width. This tripped an existing guard (if target_right -
target_left > viewport_width { return None; }) whenever a selection was
wider than the viewport, previously dead code, since
target_left/target_right were never far apart before #61487. The
function now bails out before adjusting scroll at all in that case.

## Solution

In `autoscroll_horizontally`, compute the selection's span width per
row. If it exceeds the viewport width, fall back to tracking just head
(the pre-#61487 behavior) instead of the full start/end span. If it
fits, keep using the full span so the #61409 fix is unaffected.

## Testing

- Did you test these changes? If so, how?
- Tested manually in-app on macOS: selecting a long line with
cmd+shift+end now scrolls correctly.
(NOTE: I used Claude to write these unit tests for me)
- Added test_autoscroll_horizontally_long_selection_tracks_cursor:
selects a 250-character line in a narrow viewport and asserts the scroll
position moves to follow the cursor, instead of staying frozen at 0.
- Added
test_autoscroll_horizontally_fitting_selection_reveals_full_span:
selects a short span that fits within the viewport and asserts the full
span is revealed, confirming the #61409 fix still holds.
- Ran the full editor test suite locally (cargo test --package editor
--lib), all passing.

## 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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Fixed horizontal scroll not following the cursor when selecting a line
longer than the viewport width

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-17 16:39:45 +00:00
Marshall Bowers
a8b5f6b94f
docs: Fix some links (#62758)
This PR fixes some links in the docs to use relative links instead of
pointing to `docs.zed.dev` (which isn't where the docs actually live).

Release Notes:

- N/A
2026-08-17 13:30:49 +00:00
Xin Zhao
378d6254d5
language: Fix auto-indent overwriting manual indentation when replacing a line's contents (#62644)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
# Objective

Closes #62617

Turns out #62617 is just a special trigger point of a more general
issue: replacing a line's contents can silently rewrite the line's
indentation with the auto-indent suggestion.

Consider the following Rust code, where the line has an extra tab,
making its indent 8 spaces instead of the default 4:
```Rust
fn main() {
        println!("hello world");
}
```
If we select and replace the line's contents (without the indentation):
```Rust
fn main() {
        «println!("hello world");»
}
```
with `let a = 8;`, the result is:
```Rust
fn main() {
    let a = 8;
}
```
The extra indent has been stripped.

Tracing this down to `Buffer::edit_internal()` in
`crates/language/src/buffer.rs`, the code decides whether the edited
line needs an indent update via the `first_line_is_new` flag, which ends
up as the `old_row` of an `AutoindentRequestEntry`. One of these checks
is:


cdc537c690/crates/language/src/buffer.rs (L2913-L2918)

When replacing a line's contents, the edit range ends exactly at the end
of the line, so `old_start.column + (range_len as u32) == old_line_end`.
Because the check uses `<`, this case meets none of the these
conditions, `first_line_is_new` stays `true`, and an indent update is
triggered. If the manual indent differs from the suggested indent, it
gets overwritten — exactly as in the example above.

For IME input, composition updates replace the previously marked preedit
text, which sits at the end of the line — the same geometry as a full
line-content replacement. In some environments (observed on KDE Wayland
with fcitx), a single keystroke delivers the preedit update twice, so
the replacement happens on the very first keystroke, which is what
#62617 reports. On other platforms, the replacement may happens once the
composition changes, i.e. on the second keystroke, so it takes at least
two characters to trigger.

## Solution

Simply change the guard from `(old_start.column + (range_len as u32) <
old_line_end` to `(old_start.column + (range_len as u32) <=
old_line_end`.

## Testing

Two new tests are added: `test_ime_composition_keeps_manual_indent`
covers the IME input path, and
`test_replacing_line_content_keeps_manual_indent` covers a plain
line-content replacement.

## 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 manual indentation being lost when replacing a line's contents
or typing with an input method
2026-08-17 12:58:34 +00:00
Finn Evers
db7c1d38c8
ci: Restore member read permission for community workflows (#62755)
Release Notes:

- N/A
2026-08-17 12:23:47 +00:00
Kirill Bulatov
e0931d5a9d
Reuse char-scan invisibles detection in highlight_invisibles (#62715)
Follow-up to
https://github.com/zed-industries/zed/pull/62478#discussion_r3769810809

New bench results:

| corpus | old | new | speedup |
|---|---|---|---|
| ascii, no invisibles | 83 MB/s | 580 MB/s | **7.0x** |
| unicode, no invisibles | 88 MB/s | 442 MB/s | **5.0x** |
| sparse invisibles | 63 MB/s | 431 MB/s | **6.9x** |
| dense invisibles | 82 MB/s | 109 MB/s | 1.3x |


Release Notes:

- N/A
2026-08-17 09:45:39 +00:00
ADITYA CHAUHAN
bf65fd4d7c
legal: Use absolute URLs for Terms of Service and Privacy Policy links (#62684)
Release Notes:

- Fixed broken links in the installer Terms of Service dialog (#62677).

---

### Description

Closes #62677

In `script/terms/terms.rtf` and `legal/terms.md` (as well as
`legal/privacy-policy.md` and `legal/third-party-terms.md`), relative
URLs like `/privacy-policy` and `/acceptable-use-policies` caused error
-50 ("The application can't be opened") when clicked from installer
dialogs (such as the macOS installer).

This PR updates the relative URLs to absolute `https://zed.dev` URLs so
they open properly in the browser.
2026-08-17 09:35:54 +00:00
Arnesh
30f73707a6
google_ai: Add Gemini 3.7 Flash (#62670)
Follow-up to #62010, which added Gemini 3.6 Flash.

Google released Gemini 3.7 Flash on August 13, 2026. It keeps the 1
million token context window and the 64k output limit, and supports
thinking.

Unlike 3.5 and 3.6 Flash, it does not accept `thinking_level: MINIMAL`
(the API returns a validation error). So it exposes Low, Medium and
High, defaulting to Medium, and `disabled_thinking_level` in
`completion.rs` returns Low for it instead of Minimal when the user
turns thinking off.

The provider builds its model list from `google_ai::Model::iter()`, so
adding the enum variant is enough for it to show up in the model
dropdown.

Release Notes:

- Added Gemini 3.7 Flash to the Google AI models
2026-08-17 08:28:00 +00:00
Anant Goel
dbf7f63875
anthropic: Preserve request context during explicit compaction (#62745)
Explicit compaction currently removes tool definitions before sending
the request. That changes the prompt-cache prefix and can lower the
effective input size below Anthropic's minimum compaction trigger,
causing the request to complete without producing replacement context.

Keep tool definitions in explicit compaction requests while setting
`tool_choice` to `none`, preserving the input context without allowing
tool calls. Also append a user turn when the conversation ends with an
assistant message, since current Anthropic models reject that shape as
unsupported assistant prefill.

Testing:

- `cargo test -p anthropic`
- `cargo fmt --check`
- `./script/clippy -p anthropic`

Release Notes:

- N/A
2026-08-17 08:07:14 +00:00
Akihiro Okuno
90eb566f32
sidebar: Make project reordering key-bindable (#62695)
# Objective

- The sidebar already supports moving project groups through its **Move
Up** and **Move Down** context-menu entries, but those entries use
callbacks that cannot be referenced from `keymap.json`. Moving a project
several positions therefore requires reopening the menu for every step.
- Follow-up to #57448. Related to #61647.

## Solution

- Add `multi_workspace::MoveProjectUp` and
`multi_workspace::MoveProjectDown` actions. The handlers resolve the
active project group and delegate to the existing `MultiWorkspace`
reordering methods, keeping ordering and persistence behavior unchanged.
- Associate the actions with the existing context-menu entries so
configured shortcuts are shown alongside the menu commands. The menu
callbacks still operate on the project that was clicked.

## Testing

- Added a GPUI test that dispatches both actions and verifies that the
active project group moves in the expected direction and remains
unchanged at list boundaries:
- `cargo test -p workspace test_move_active_project_group_actions --
--nocapture`
- Manually verified on macOS with an isolated Zed user-data directory
and three project folders:
  - Assigned custom shortcuts to both actions in `keymap.json`.
  - Confirmed that the active project moves up and down in the sidebar.
- Ran formatting, compilation, and lint checks:
  - `cargo fmt --all -- --check`
  - `cargo check -p sidebar`
- `./script/clippy -p workspace -p sidebar -p gpui_platform --features
gpui_platform/runtime_shaders`

## 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>Move projects with custom keybindings</summary>


https://github.com/user-attachments/assets/09432817-318b-484e-b630-a6012e9599cd

</details>

---

Release Notes:

- Sidebar: Added key-bindable actions for moving projects up and down.
2026-08-17 07:49:57 +00:00
Pavel Olizko
511ac17036
gpui: Make inactive frame throttling configurable (#62628)
# Objective

I am building an [app](https://github.com/nolight132/sonora) with GPUI,
and the current animation throttling implementation does not quite meet
its requirements. I needed the window to stay at a smooth framerate when
unfocused to display lyrics, which was not possible at the time without
modifying GPUI’s frame scheduling behavior. I understand that this is
not a problem for Zed, but I believe making this behavior a field in
`WindowOptions` could be beneficial for other programs going forward.

## Solution

Added a field to `WindowOptions` struct which controls the minimum
interval between animation frames while the window is inactive
(documented). Kept the default value GPUI currently uses.

## Testing

- Ran `gpui/src/examples/animation.rs` with different presets - works as
expected. Zed compiles. One thing worth noting: this setting does not
guarantee the window refreshes at this exact interval, as frames are
still paced by the compositor. For granular FPS control, a helper
function is needed. I have decided to keep it simple and use the
existing logic.
- Tested on NixOS x86_64, Niri.

## 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 (the default didn't change,
tests still pass)
- [x] Performance impact has been considered and is acceptable (no
performance impact unless explicitly set)

## Showcase

Before (unfocused):
<img width="1280" height="802" alt="image"
src="https://github.com/user-attachments/assets/e3302c1d-4f4a-4503-96a2-0bf24e28096c"
/>

After (unfocused with `inactive_frame_interval` set to 16ms):
<img width="1450" height="972" alt="image"
src="https://github.com/user-attachments/assets/1183adf1-2da1-42d5-8e97-f4ad7a31b783"
/>

---

Release Notes:

- Added `WindowOptions::inactive_frame_interval` for configuring
animation frame throttling on inactive GPUI windows.
2026-08-17 07:20:20 +00:00
Darsh Poddar
91a6890df8
sidebar: Wrap import onboarding title when the panel is narrow (#62737)
Narrowing the agent sidebar clips the import-threads banner title
mid-word. The title now wraps instead of overflowing the close button.

<img width="212" height="279" alt="Screenshot 2026-08-16 at 11 25 26 PM"
src="https://github.com/user-attachments/assets/03e20b9d-ea29-4872-a4c1-f364509ddacb"
/>

Release Notes:

- Fixed the agent sidebar import-threads banner clipping its title when
the panel is narrow
2026-08-17 07:08:39 +00:00
Mikhail Butvin
eedd20160f
project_panel: Make the window deactivation test actually deactivate (#62724)
Follow-up to #61852. The regression test I added there passes with or
without the fix.

The test creates the panel with `ProjectPanel::new` but never calls
`workspace.add_panel(...)`, so the panel is never rendered and its
filename editor never holds window focus. Deactivating the window then
blurs nothing, the project panel's `Blurred` handler never runs, and the
assertion holds trivially.

Add the panel to the workspace so it renders and its filename editor
takes focus, and assert that the editor is focused before deactivating,
so the test fails at an explanatory precondition rather than silently
going vacuous again.

Verified by running the new precondition without `add_panel`: it fails,
because the workspace's `on_focus_lost` fallback
(`crates/workspace/src/workspace.rs:1667`) reclaims focus from an editor
that was never rendered into the dispatch tree.

## Suggested .rules additions

> A GPUI test that depends on focus must put the view somewhere it can
actually be focused. Constructing a panel with `ProjectPanel::new` and
friends does not render it, so its editors never hold window focus and
every focus or blur assertion passes vacuously. Add it with
`workspace.add_panel(...)`, and assert the intended editor `is_focused`
before exercising blur.

Release Notes:

- N/A
2026-08-17 07:05:53 +00:00
Eric Holk
984bf4d466
Improve explicit compaction for Anthropic models (#62139)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Explicit compaction (`LanguageModel::compact`) was previously
implemented only for OpenAI-routed cloud models, which use a dedicated
compact operation proxied through `/completions/compact`. Anthropic
models only compacted automatically when a request's `compact_at_tokens`
trigger was crossed, leaving consumers without a provider-backed way to
request compaction immediately.

Anthropic has no compact-on-demand operation, but the `compact_20260112`
context-management edit provides the necessary pieces: the lowest
trigger the API accepts, 50,000 input tokens, combined with
`pause_after_compaction`, which stops the response after the compaction
block. Explicit compaction requests remove tools so the internal
summarizer must produce replacement context while retaining Anthropic's
default summarization prompt. The resulting readable summary, optional
opaque provider state, and usage are collected consistently.

This implements explicit compaction for both direct and hosted Anthropic
models. Hosted requests use the normal `/completions` endpoint; gateway
support for forwarding the compaction fields landed in
zed-industries/cloud#3216. Models expose the 50,000-token minimum so
callers can disable explicit compaction below the provider's floor.
Calls made below that floor still fail if the stream produces no
finalized compaction context.

The existing OpenAI compact operation is moved into a provider-specific
helper without changing its request, endpoint, response handling, or
provider-state ownership.

Testing:

- `cargo nextest run -p anthropic -p language_models_cloud -p
language_models`
- `./script/clippy -p anthropic -p language_model -p
language_models_cloud -p language_models`
- `cargo fmt --all --check`
- `git diff --check`

Release Notes:

- N/A

---------

Co-authored-by: Anant Goel <anant@zed.dev>
2026-08-17 04:27:38 +00:00