Commit Graph
39774 Commits
Author SHA1 Message Date
František GažoandKirill Bulatov bb501d9221 outline_panel: Add setting to hide symbols in multi-buffer views (#63404)
Closes https://github.com/zed-industries/zed/issues/60242

# Objective

When reviewing a branch diff — or project search results — the outline
panel lists every affected excerpt and symbol beneath each file. On a
diff touching more than a handful of files, this consumes so much
vertical space that you cannot see the list of changed files at all,
which is usually the thing you want the panel for.

Existing settings don't cover this:

- `expand_outlines_with_depth: 0` still renders excerpt rows and
top-level symbol rows.
- Collapsing a file row in the panel is coupled to folding that buffer
in the editor, so it can't be used purely to tidy the panel.

## Solution

A display-only mode that reduces multi-buffer views to just the
directory/file tree.

- New `outline_panel.multi_buffer_hide_symbols` setting (default
`false`). When enabled, multi-buffer views render only directory, file
and folded-directory rows — excerpt, symbol and search-match rows are
hidden.
- New `outline panel: toggle symbols` action, plus a button in the panel
footer, which toggles an in-memory per-panel override of the setting
(the same pattern as `editor: toggle inlay hints`). Changing the setting
clears the override, so the setting wins.
- Single-file views are exempt, and the footer button is not shown there
— the panel contains only symbols in that case, so hiding them would
leave it empty.
- The filter is display-only: `collapsed_entries` and editor buffer
folding are never touched.
- Outline fetching is skipped while the mode is active, so large diffs
don't pay for outlines that will not be rendered. Turning the mode off
re-triggers fetching.

This adds one new icon, `file_code_off`, used by the footer button when
symbols are hidden. cc @zed-industries/design for review per the icon
guidelines — it is `file_code` with the slash and outline gaps from
`file_ignored`, keeping the parts of the chevrons that fall on the near
side of the slash.

## Testing

Three new tests in `crates/outline_panel/src/outline_panel.rs`:

- `test_hide_symbols_in_multibuffer` — outline rows are present by
default; only `Fs`/`FoldedDirs` entries remain once the mode is enabled
via the setting (which also exercises the settings observer) and via the
action; outline rows return when it is toggled off, confirming outlines
are re-fetched; asserts `collapsed_entries` is unchanged at every step,
covering the display-only guarantee.
- `test_hide_symbols_exempts_singleton` — a single-file view still
renders its outline with the setting enabled.
- `test_hide_symbols_hides_search_matches` — project search match rows
are hidden while files and directories still render, and return when
toggled off.

`cargo test -p outline_panel` (15 passing), `cargo test -p icons`,
`cargo test -p settings_ui -p settings_content`, and `./script/clippy`
on the touched crates are all green.

Tested manually on macOS against a branch diff, project search results,
and single-file buffers, checking both the setting and the action (from
the panel footer button and from the command palette with focus outside
the panel), and that expanding/collapsing directories and editor folding
still behave as before.

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

<!-- Screenshots go here: branch-diff before/after, footer button icon
states, search before/after, single-file exemption -->


|  | Symbols shown (default) | Symbols hidden |
| --- | --- | --- |
| **Footer toggle** | <img
src="https://github.com/user-attachments/assets/393f128d-1a7c-43a8-97b8-8176a07b45c7"
width="260"> | <img
src="https://github.com/user-attachments/assets/87c60dd4-d5b7-48f8-9255-226c4a94a586"
width="260"> |
| **Branch diff** | <img
src="https://github.com/user-attachments/assets/79357325-7d7d-40f7-8067-4ae59a824f87"
width="420"> | <img
src="https://github.com/user-attachments/assets/8a3bbc7e-90d4-4638-9f1d-1ba3091eccfd"
width="420"> |
| **Project search** | <img
src="https://github.com/user-attachments/assets/76e3cf18-d624-42f8-8801-f496bf54a552"
width="420"> | <img
src="https://github.com/user-attachments/assets/2a34e899-b9f4-465e-b571-75d3d54d00eb"
width="420"> |

Single-file views are unaffected — symbols still render, and the toggle
is not offered:

<img
src="https://github.com/user-attachments/assets/76c47884-96db-4071-bcc1-931c4283e36f"
width="640">

---

Release Notes:

- Fixed too many outlines shown per excerpt in the outline panel. Added
an `outline_panel.multi_buffer_hide_symbols` setting and an `outline
panel: toggle symbols` action to show only files and directories in the
outline panel for multi-buffer views.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-31 14:36:04 +00:00
tidely fd35a813e9 gpui_macos: Migrate PlatformWindow::prompt to objc2 on MacOS (#59572)
# Objective

Rust 1.96 emits a warning when compiling the `block` crate, that it will
no longer compile past some future version of Rust. The `block` crate
provides `ConcreteBlock` and `RcBlock`, which are stack- and heap-based
functions often passed as callbacks to MacOS. The old `objc` crate
family is deprecated and no longer maintained.

The goal of the PR is to replace one call to `block::ConcreteBlock` by
migrating a standalone portion of code to the objc2 crate family. A full
migration to `objc2` by Zed has been long on the horizon (#22408)

Additional benefits: The new code is completely typed, uses automatic
memory management, and reduces lines of unsafe Rust from 50+ to 1. The
lingering unsafe converts a raw pointer stored by `self` to the
respective `objc2` type, since the rest of the window implementation
does not use the new crates yet.

## Solution

Migrate `PlatformWindow::prompt`'s MacOS implementation to `objc2`.

## Testing

Direct platform code is quite fragile and hard to test, however you can
exercise the codepath by running the following `gpui` example and
clicking on the prompt buttons.

```sh
cargo run -p gpui --example window
```

I've also built Zed with these changes and tried codepaths which
activate prompts, such as deleting a file.

## Self-Review Checklist:

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

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-08-31 14:31:41 +00:00
Lukas Wirth 1344a8a846 gpui: Gate blocking executor APIs on WebAssembly (#63484)
GPUI's scheduler exposed synchronous blocking APIs on WebAssembly even
though the platform implementation could only panic. This became an
implicit crash when cancellation dropped a scoped background operation:
preserving the borrowed task lifetime called `Scheduler::block`, which
panicked with `Cannot block on wasm`.

This change removes blocking scheduler and executor APIs from
WebAssembly builds, including borrowed background scopes and the
separate `pollster::block_on` export. Native behavior remains unchanged.
Application shutdown now runs WebAssembly quit handlers asynchronously
as best-effort cleanup rather than blocking the browser event-loop
thread.


Release Notes:

- Fixed a GPUI Web crash caused by synchronous executor blocking.
2026-08-31 13:35:07 +00:00
Lukas Wirth ab1c37a4ef gpui_web: Let applications provide fonts (#63493)
`gpui_web` currently embeds IBM Plex Sans and Lilex into every browser
application during platform construction. Applications such as Delta
already provide their own fonts, so those binaries contain overlapping
font bundles and register the same faces twice.

This change starts the web platform with an empty font database,
matching the ownership boundary used by native applications: the
application selects and registers its fonts before opening a window.
Delta already follows that sequence. GPUI's browser-capable examples now
load the former eight-face bundle explicitly through shared example
support, while the standalone `hello_web` example demonstrates
registering a minimal application font directly.

Testing performed:

- `cargo check -p gpui --examples --target wasm32-unknown-unknown`
- `cargo check -p gpui --examples`
- `cargo check -p gpui_web --target wasm32-unknown-unknown`
- `cargo check --manifest-path
crates/gpui_web/examples/hello_web/Cargo.toml --target
wasm32-unknown-unknown`
- `./script/clippy -p gpui_web --target wasm32-unknown-unknown`
- `cargo fmt -p gpui -p gpui_web --check`

Release Notes:

- N/A
2026-08-31 13:07:22 +00:00
Kirill Bulatov 7ea8eb3f2e Support CSV preview in project-less set-ups (#63350)
Closes https://github.com/zed-industries/zed/issues/63265

Release Notes:

- Fixed CSV preview not showing in project-less set-ups
2026-08-31 12:04:06 +00:00
Oleksandr KholiavkoandSmit Barmase 75917d2f73 tabular_data_preview: Add shortcut to open tabular data preview (#63369)
## TL;DR

Adds `cmd-shift-v` / `cmd-k v` (ctrl on linux/windows) to open the
tabular data preview for `csv`/`tsv`/`ssv`/`psv` files, mirroring the
existing `markdown::OpenPreview(ToTheSide)` and
`svg::OpenPreview(ToTheSide)` bindings/context pattern already in the
default keymaps.

Extension check kept explicit (not just `"Editor"`) so it doesn't
compete with the `md`/`svg` blocks bound to the same keys on their own
extensions.

## Testing

- Manually verified `cmd-shift-v` / `cmd-k v` open tabular data preview
on `.csv`/`.tsv`/`.ssv`/`.psv` files, no-op on other extensions.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] UI standards followed
- [ ] Tests cover the new/changed behavior
- [x] Performance impact considered, acceptable

Release Notes:

- Added shortcuts to open the tabular data preview for CSV/TSV/SSV/PSV
files (similar to md/svg preview)

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-08-31 11:59:43 +00:00
Kirill Bulatov b6490c5fbd Stop re-resolving editorconfig sections on every language settings lookup (#63323)
Closes https://github.com/zed-industries/zed/issues/59689

Symbolicating the reporter's profile (21s of typing, Windows) showed
`Window::draw` taking 63% of the main thread at ~62 redraws/s (p95 draw
= 40ms), and 30.9% of the *entire* main thread inside
`EditorconfigStore::properties()`:
every `LanguageSettings` lookup — several per frame via
`DisplayMap::tab_size`, `MultiBuffer::language_settings`, indent guides,
and `LspStore::supports_range_formatting` — re-ran the full editorconfig
resolution (ancestor walk plus `ec4rs::Section::apply_to` over every key
of every section) and then cloned the whole `LanguageSettings` struct.
Real-world `.editorconfig` files carry hundreds of irrelevant keys
(`dotnet_*`, `ij_*`, ...), so the per-call map assembly dominated:
`RtlAllocateHeap` 7.3%, `memcmp` 7.0%, `memcpy` 6.6%,
`Properties::find_idx` 5.9% self time.

## Commit 1: resolve only the editorconfig properties Zed reads

- `EditorconfigStore::properties()` now applies only the 7 keys Zed
consumes (`indent_style`, `indent_size`, `tab_width`, `end_of_line`,
`max_line_length`, `insert_final_newline`, `trim_trailing_whitespace`)
instead of materializing every key of every matching section.
- Worktrees with no editorconfig at all now return `None` early instead
of allocating an empty `Properties` and forcing a `LanguageSettings`
clone on every lookup.
- Adds an `editor_render_with_editorconfig` benchmark: maximized window,
file-backed buffer at `src/app/components/editor_pane.ts`, a root
`.editorconfig` shaped after [the second
report](https://github.com/zed-industries/zed/issues/59689#issuecomment-5475124891)
(no `root = true`, a `[*]` section with ~3200 keys, 25 sections with
large `{...}` alternation lists) plus a 4-level nested chain, and a
typing workload (insert/delete + cursor moves).

```
main (f034409b6a):      time: [37.905 ms 38.005 ms 38.107 ms]
                        time: [38.069 ms 38.157 ms 38.248 ms]
this commit:            time: [2.8547 ms 2.8618 ms 2.8702 ms]
                        time: [2.8372 ms 2.8435 ms 2.8510 ms]
```

The candidate is ~13x faster.
GPUI frame report over the same workload: window draw p50 12.71 ms →
0.76 ms, p99 23.38 ms → 1.22 ms; frame budget overruns 556 → 0.

## Commit 2: cache resolved `LanguageSettings` per buffer

- `Buffer` and `BufferSnapshot` now hold `resolved_settings:
Arc<LanguageSettings>`, recomputed by a `SettingsStore` global observer.
- Global methods for retrieving the settings are still there, but buffer
only uses them for multi buffer's `language_settings_at` with an
injected language different from the buffer's primary; cold scopes such
as extension API, LSP workspace configuration, server startup still use
the global resolution

Same benchmark, same method, on top of commit 1 (alternated runs, quiet
machine):

```
commit 1:               time: [2.8547 ms 2.8618 ms 2.8702 ms]
                        time: [2.8372 ms 2.8435 ms 2.8510 ms]
this commit:            time: [1.6256 ms 1.6325 ms 1.6403 ms]
                        change: [-42.685% -42.270% -41.854%] (p = 0.00 < 0.05)
                        time: [1.6221 ms 1.6284 ms 1.6352 ms]
```

Window draw p50 0.76 ms → 0.47 ms, p99 1.22 ms → 0.69 ms, max 1.02 ms;
zero frame-budget overruns on both sides.
Combined, the benchmark's per-keystroke cost drops ~23x vs `main`
(37.9–38.2 ms → 1.62–1.64 ms).


Release Notes:

- Improved typing and rendering performance in projects that use
`.editorconfig` files.
2026-08-31 11:58:50 +00:00
Oleksandr Kholiavko 134e04444c tabular_data_preview: Revive filter funnel icon (#63266)
# Objective

Originally, `IconName::Filter` was a funnel glyph and
`IconName::Sliders` was used for settings/controls.

In #60937 (commit `1a06fd4f2b`), `filter.svg` was replaced with the
sliders glyph, and `sliders.svg` / `Sliders` enum variants were deleted.
Consequently, `IconName::Filter` has become a sliders-shaped icon used
across 8+ surfaces in Zed (git_ui, search, debugger_ui, keymap_editor,
language_tools, quick_action_bar, editor view settings).

When moving tabular data preview settings to follow the editor's
convention (using `IconName::Filter` sliders for table view settings),
column filter buttons in the table header were left using the same
sliders icon instead of a traditional funnel.

Repurposing `IconName::Filter` back to a funnel would break all other UI
surfaces across Zed.

## Solution

- Restored the funnel icon under a new dedicated
`IconName::FilterFunnel` variant (`assets/icons/filter_funnel.svg` and
`crates/icons/src/icons.rs`).
- Updated `tabular_data_preview` column filter trigger buttons
(`table_header.rs`) to use `IconName::FilterFunnel`.
- Left all existing `IconName::Filter` (sliders) usages across the app
untouched.

Before:
<img width="363" height="156" alt="image"
src="https://github.com/user-attachments/assets/84ac5f87-c0f7-4de9-94ea-e4040e3b4a4a"
/>

After:
<img width="361" height="151" alt="image"
src="https://github.com/user-attachments/assets/38514f3a-0710-4273-b227-4623bf78410b"
/>

## Testing

- `cargo check -p icons -p tabular_data_preview` and `./script/clippy`
build clean.
- `cargo test -p tabular_data_preview --lib` passes.
- Verified column filter button renders the funnel icon in tabular data
preview and highlights correctly when filters are active.

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

- Replace column filter icon in tabular data preview with filter funnel
2026-08-31 11:43:50 +00:00
Kirill Bulatov 77d716d5ce Keep first match selecting during type on search (#63375)
Follow-up to https://github.com/zed-industries/zed/pull/62506

Before:


https://github.com/user-attachments/assets/19f6f0df-c5e3-417e-a351-13a09ccb726b

After:


https://github.com/user-attachments/assets/0b302ed7-a98d-4db4-81bc-d67f5cc7db87


* Fixes type on search not selecting the very first result as the
regular search does.
* Unifies the flicker freezing state better in the editor

Release Notes:

- N/A
2026-08-31 11:41:34 +00:00
Kirill Bulatov c99db2149e Fix repo docs (#63486)
* ensures The Rule cannot be accidentall removed
* fixes the perf command example to capture call graphs, to avoid
round-trips like
https://github.com/zed-industries/zed/issues/59689#issuecomment-5453623044
(samples without call graphs are not quite usable for investigating bugs
like these)


Release Notes:

- N/A
2026-08-31 11:00:40 +00:00
那思路(なしろ) a209865454 Recognize .bash_login as shell script (#63466)
Added `.bash_login` to the list of recognized shell script files for
syntax highlighting.

Shoutout: [acidx27x](https://github.com/acidx27x) for #62720

Release Notes:
- Added shell script language detection for `.bash_login` files.
2026-08-31 09:04:16 +00:00
2e1cd0fbb2 project: Underline diagnostics reported past the end of a line (#63125)
Closes #22473.

Some language servers report a syntax error whose range starts at the
end
of one line and ends at the start of the next — e.g.
Pyright/ruff/ty/pyrefly
on a Python function missing its trailing `:`:

```
range: { start: { line: 0, character: 11 }, end: { line: 1, character: 0 } }
```

That range spans nothing but the line terminator, so there's no glyph
left
for the editor to underline. The diagnostic is real (it shows up in the
status bar and the diagnostics panel) but never gets a visible squiggle
in
the buffer, which makes it very easy to miss — especially since a
missing
`:` is one of the most common Python typos.

## Fix

`update_buffer_diagnostics` already collapses *empty* ranges onto an
adjacent character. This adds a sibling case for ranges that are exactly
`line_start..next_line_start` (i.e. cover only the terminator): they're
pulled back onto the last character of the line they actually concern,
the same way empty ranges are. Ranges are only touched when the end
position is precisely the start of the next line, so genuinely
multi-line
diagnostics that happen to *start* at an end-of-line position are left
untouched.

## Testing

Added `test_diagnostic_range_spanning_line_terminator` in
`project_tests.rs`, modeled on the neighboring
`test_empty_diagnostic_ranges`,
asserting the closing `)` of `def main()` gets the error highlight
instead
of the range being invisible.

Verified against real language servers: reproduced the exact same
`start..next_line_start` range on ruff 0.16.4, ty 0.0.74, and pyrefly
1.2.0
for a missing `:`, matching the LSP trace pyright produced in #22473.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


Release Notes:

- Fixed diagnostics not being underlined when their range covers only a
line terminator (e.g. a missing `:` in Python)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2026-08-31 08:11:59 +00:00
Remco Smits f034409b6a cloud_api_client: Add yield point to prevent background task hangs (#63105)
Follow-up: https://github.com/zed-industries/zed/pull/62874

# Objective

After having Zed open for a while I'm getting some foreground and
background hang warnings, like this one.

```
2026-08-19T11:25:45+02:00 INFO [zed::reliability::hang_detection::logging] New foreground hang detected: Tasks(s) that ran too long 215.24375ms          - crates/cloud_api_client/src/websocket/native.rs:34:23
```

## Solution

My solution is to add yield points so a single task doesn't block the
executor thread for too long.

## Self-Review Checklist:

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

Release Notes:

- N/A
2026-08-31 05:45:47 +00:00
Kirill Bulatov c032dcc3bc Enable share-generics in release bundle builds (#63432)
Cargo joins `build.rustflags` across config sources, so the base
`symbol-mangling-version=v0` and `tokio_unstable` flags still apply
after the newly added config.

With sccache disabled, `cargo build --release -p zed` on macOS: 
Before: zed binary 420677880 bytes
After: zed binary 375109048 bytes (-10.8%, -45.6MB)

After `strip -x` of both
(https://github.com/zed-industries/zed/pull/63429):
313879024 -> 307727432 bytes (-2.0%, -6.2MB)
The rest of the delta is the smaller symbol table. `drop_glue`
instantiations: 101778 -> 65041.

Release Notes:

- N/A
2026-08-31 05:42:11 +00:00
Kirill Bulatov 6dc2206180 Reduce LLVM IR bloat in closure funnels (#63426)
Follow-up to https://github.com/zed-industries/zed/pull/63232

Cuts closure monomorphization in settings and editor: settings file
updates now share one boxed write-pipeline instantiation instead of
inlining the `SettingsContent` clone, both `serde_json::to_value` calls,
and the JSON diff at every call site; `Editor::register_action` and the
settings enum dropdown get the same treatment. Behavior and public
signatures are unchanged; thin generic shims remain.

Symbol table of the release binary:
Before: `update_settings_file_inner` 229 instantiations, inlined
`serde_json` `SerializeMap` machinery 6547 copies
After: 3 instantiations, 673 copies (-89.7%); `render_dropdown` is no
longer instantiated at all

With sccache disabled, `cargo clean` and `cargo build --release -p zed`:
Before: zed binary 420677880 bytes
After: zed binary 396999464 bytes (-5.6%, -23.7MB)

Release Notes:

- N/A
2026-08-29 22:51:20 +00:00
Jonathon Anderson fa839e548d context_server: Include requested scopes in OAuth DCR flow (#63370)
# Objective

Fixes https://github.com/zed-industries/zed/issues/63363

The OAuth DCR flow would register an OAuth app with default (unset)
`scope`. This was incompatible with some MCP servers, including GitLab's
Orbit MCP server, which require OAuth scope(s) that are not part of the
default assigned to DCR apps.

## Solution

The OAuth DCR request now registers with the same set of `scope`
selected for the entire flow, matching the authorization prompt used
later. If the server advertises/requests no particular scopes for
authentication, this field is elided to request a default set of scopes
decided by the server.

## Testing

- Successfully logged in via OAuth to the GitLab.com Orbit MCP server
([ref](https://docs.gitlab.com/orbit/remote/access/mcp/#connect-your-mcp-client))
and MCP server
([ref](https://docs.gitlab.com/user/model_context_protocol/mcp_server/#connect-a-client-to-the-gitlab-mcp-server))
on Linux
- Unit tests confirm `scopes` are preserved in the DCR request body

## 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 OAuth authentication failure with MCP servers that require
non-default scopes to access MCP endpoints

Signed-off-by: Jonathon Anderson <anderson.jonathonm@gmail.com>
2026-08-29 22:33:39 +00:00
Dom PoradaandMrSubidubi 7599be8e6b Stop prompting to migrate settings that contain no deprecations (#62818)
## Objective

Zed can report that a settings file uses deprecated settings even when
it contains no deprecations. A context server configured with only a
`url` is enough to trigger the prompt, although the backup Zed offers to
write is identical to the current file.

Fixes #24967.

## Solution

Two text-edit migrations cancel each other on `context_servers` entries:
one adds a `source` key and a later one removes it. The round trip
reindents the entry, and the migrator mistakes the leftover whitespace
for a migration.

Remove `m_2025_06_16` rather than comparing around that whitespace. It
wrote `source` and `settings` into every entry, but
`ContextServerSettingsContent` contains neither field today. `settings`
is worse than inert: an empty entry such as `{ "settings": {} }` matches
neither the `Stdio` nor `Http` variant of the untagged enum.

Update `m_2025_06_27`, the only remaining consumer of the generated
`"source": "custom"`, to detect legacy entries from the shape of
`command` itself. This continues to flatten settings written before
`source` existed. It also deliberately flattens an object `command`
beside `"source": "extension"`, which the old migration skipped. The
command shape is invalid regardless of the declared source, and a test
pins the new behavior. `m_2025_11_25` remains unchanged because it still
removes `source` from settings that genuinely carry it.

This deletes one migration and edits another despite the warning at the
top of `migrator.rs`. That warning protects later migrations that depend
on earlier output, but this output has no remaining consumer. I left the
policy unchanged rather than adding an exception in the same PR that
relies on it, but I can document the exception if preferred.

## Testing

- `cargo test -p migrator` passes, 86 tests. The suite loses the three
tests that only exercised the deleted migration and gains
`test_flatten_context_server_command_alongside_source`, covering a
legacy entry that carries both `source` and an object `command`.
- Restoring the `source` requirement on `m_2025_06_27` with the deletion
in place turns `test_flatten_context_server_command` red. Its input is a
pre-`source` entry, which is what makes the relaxation load-bearing
rather than incidental.
- To check by hand: add `"context_servers": { "grep": { "url":
"https://mcp.grep.app" } }` to user settings and confirm no migration
prompt appears. Add `"show_inline_completions": true` alongside it and
confirm the prompt returns and leaves the context server block
untouched.
- I have not run those steps in a built editor. The tests call
`migrate_settings`, which is all `should_migrate_settings` checks before
raising the prompt, so that call is the whole untested gap. It’s all
platform-independent text processing, 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:

- Fixed the migration prompt appearing for settings that contain no
deprecations. Context servers configured with only a `url` no longer
trigger it.

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-29 22:33:35 +00:00
Petros Amoiridis 2d6911db05 fs: Stop FakeFs deleting files it should leave alone (#63416)
# Objective

`FakeFs::rename` deletes files in two cases where `RealFs` leaves them
alone. Tests written against the fake see a file vanish where the real
filesystem keeps it, so the behavior cannot be tested at all and
anything relying on it drifts unnoticed.

There is already a test for the first case for `RealFs`,
`test_realfs_rename_ignore_if_exists_leaves_source_and_target_unchanged`,
but the fake had no counterpart.

## Solution

Return early in both cases instead of falling through to the removal.

For `ignoreIfExists` onto an existing target, `RealFs` reports success
and does not move anything. The fake kept the target but removed the
source. The fix also stops recording a move that never happened, which
would otherwise leave an open file handle pointing at the wrong path.

For a rename onto itself with `overwrite`, POSIX requires success with
no action. The fake assigned the entry onto itself and then removed it.
I found this while fixing the first one, and included it.

## Testing

I extended an existing test, and added two new ones. Each fails on
`main` and passes here.

I found this issue while working on #5369, where an LSP rename can send
`ignoreIfExists` and the fake made the resulting bug impossible to write
a test for.

Ran the tests only on macOS as the area seems platform agnostic, but
please let me know if I need to run them across all platforms.

## Self-Review Checklist:

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

---

Release Notes:

- N/A
2026-08-29 22:18:44 +00:00
Dipendra Sharma 3ba2bcfd68 theme: Show bundled Docker icon for .dockerignore files (#63398)
## Objective

Fixes #63227 — `.dockerignore` files display a generic icon instead of
the Docker icon.

## Solution

Added `.dockerignore` to the list of filenames mapped to the Docker icon
in `crates/theme/src/icon_theme.rs`.

## Testing

- No automated tests added; the change is a static mapping.
- Manually verified by opening a project with a `.dockerignore` file in
Zed.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments (none)
- [x] The content adheres to Zed's UI standards (single icon mapping)
- [ ] Tests cover the new/changed behavior (not required for static
mapping)
- [x] Performance impact has been considered and is acceptable

## Showcase

> This section is optional. If this PR does not include a visual change
or does not add a new user-facing feature, you can delete this section.

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

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

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

My super cool demos here

</details>

---

- `.dockerignore` now shows the Docker icon for the bundled icon theme.
2026-08-29 22:00:45 +00:00
Albert Bogusz 432c18bcb9 Fix searching for full SHA-256 commit hashes in Git graph (#63371)
# Objective

Search in the Git graph does not support full commit hashes in SHA-256
formatted repos, while SHA-1 formatted repos work fine.

## Solution

Use existing constants in the `git` crate instead of hardcoded values
when checking for a commit hash query.

## Testing

Added a regression test for valid SHA-1 and SHA-256 commit hash lengths,
plus rejection of hashes longer than the max length.

## Self-Review Checklist:

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

## Showcase

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

The screenshots below show the commit that is being searched for open in
the Git graph.

Before:
<img width="1153" height="536" alt="before"
src="https://github.com/user-attachments/assets/e47c4523-a046-4c47-ac75-cd00845b968f"
/>

After:
<img width="1153" height="536" alt="after"
src="https://github.com/user-attachments/assets/72eeaa16-d0ec-48cb-8ca2-c2bb26f02a10"
/>

</details>

---

Release Notes:

- Fixed searching for full SHA-256 commit hashes in the Git graph.
2026-08-29 12:11:25 +00:00
Kirill Bulatov 88483df921 Show last recently used commands on top of the picker's list (#63388)
Closes #8106
Closes #8107


https://github.com/user-attachments/assets/2aba378a-657d-4de9-a45a-6106325281e5

Release Notes:

- Improved command palette ordering: commands are sorted by recency of
use, and previously used commands rank above unused ones while
filtering.
2026-08-28 22:35:33 +00:00
Kirill Bulatov 036af28f9d Restore the rule (#63384)
Release Notes:

- N/A
2026-08-28 20:04:24 +00:00
Miguel Raz Guzmán Macedo 81299967df lints: Add map_lookup_then_insert lint (#62681)
## Objective

Sometimes we can do a hash lookup twice, which is slow and unidiomatic.
We should use the Entry API instead.

## Solution

Add another `dylint` lint called `map_lookup_then_insert` that catches
those cases.

This works with HashMap, BTreeMap, HashSet, BTreeSet and
entry-compatible ADTs.

## What it catches

See the examples in the `tooling/lints/ui/map_lookup_then_insert.rs`.

It's mostly things of the form

```rust
if let Some(value) = map.get(&key) {
    *value
} else {
    map.insert(key, 1);
    1
}
```

which should be 

```rust
*map.entry(key).or_insert(1)
```

The two key expressions are matched up to borrows/derefs,
value-preserving
conversions (`clone`, `to_owned`, `to_string` on string types, `to_vec`
on
slices, `String::from` on `&str` — each resolved by definition, not by
name),
and immutable local aliases. So looking up `&key` and inserting
`key.clone()`
is caught too. When a conversion had to be peeled, the diagnostic
carries a
note that an entry-API rewrite would perform that copy on hits as well
as
misses.

## What it deliberately does not catch

Forms Clippy already catches.

## Findings

A `--workspace` run finds 31 warnings at 30 unique sites in `zed`:
the 16 the plain key matching finds, plus 15 more that require the
conversion/alias matching (e.g. `tiles_by_key.get(key)` followed by
`tiles_by_key.insert(key.clone(), tile)` in `metal_atlas.rs`).

Will post those fixes in a follow up PR.

## Testing

UI tests cover every `Entry` method positively and negatively, BTreeMap
mirrors, set cases, and the Clippy-deferral boundary. The
key-normalization logic is covered by nine positive cases (cloned keys,
UFCS forms, `to_owned`/`to_string`/`to_vec`/`String::from`, deref
layers, local aliases, sets) and six negative cases (inherent methods
merely named `clone`/`to_owned`, mutated aliases, a clone of a different
key, `to_string` on a non-string key, and side-effecting initializers).

## 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
2026-08-28 20:01:28 +00:00
Casey Avila 47df871ecc debugger: Fix breakpoint list not showing breakpoints in single files (#63348)
# Objective

- Currently there is a bug where breakpoints in single files (not in
folder/worktree) are not shown in the debug panel breakpoint list. They
visually make the breakpoint list empty
- This is because we try to create a `RelPath` from `breakpoint.path`,
which is an absolute path

## Solution

- Create the fallback directory string in a valid way
- Because breakpoint directories can now be absolute, the first part of
the path isn't always the worktree root, so we can't blindly skip this
in the UI code anymore
- Instead, only prepend the worktree root if there multiple worktrees,
matching behavior of other UI elements. This simplifies the code overall

## Testing

- Manually tested

## 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="978" height="645" alt="image"
src="https://github.com/user-attachments/assets/334176fd-3ad3-4bc7-b7bc-bf1568be6d76"
/>

After:
<img width="962" height="755" alt="image"
src="https://github.com/user-attachments/assets/e4259c7f-679b-4ac9-807e-d8787d43d067"
/>



---

Release Notes:

- Fixed breakpoint list not showing breakpoints in single files
2026-08-28 18:59:38 +00:00
Cole Miller 9cdbece495 Normalize ranges returned by language servers in more cases (#63372)
Previously, we'd panic when constructing multibuffer excerpts in
response to "find all references" if a language server returned a
reversed range. This PR makes it so we normalize those ranges using the
existing `range_from_lsp` helper before passing them to
`set_excerpts_for_path`. It also replaces several other places where we
were calling `point_from_lsp` on each endpoint of a range separately
with `range_from_lsp`.

Closes ZED-79W

Co-authored-by: Mikayla <mikayla@zed.dev>

Release Notes:
- Fixed a crash with some languages servers when handling
`editor::FindAllReferences`.
2026-08-28 18:06:41 +00:00
f64d69fec6 Ensure that multibuffer anchor ordering is stable over time and consistent with resolution (#62636)
Digging into ZED-7G6 ("buffer snapshot not found for excerpt boundary",
171 events) revealed some bugs in the implementation of multibuffer
anchors that landed in #52364. Specifically:

- In the presence of multibuffer excerpt changes, it was possible for
two anchors to satisfy `a1 < a2` but `a1.to_offset() > a2.to_offset()`.
This happened in particular when a `PathKey` was reused for two
different buffers at different times, and could cause crashes in code
that sorted anchors by `cmp` and expected the resulting offsets to be
sorted.
- Changes of diff base and normal buffer edits could cause two anchors
to sort `a1 < a2` against one snapshot and `a2 < a1` against a later
snapshot. This could also cause crashes in downstream code that
(reasonably) expected anchors to have a stable ordering.

This PR adds a property test asserting that multibuffer anchor ordering
is stable over time and consistent at every moment in time with the
ordering obtained from resolving the anchors, and fixes the bugs in
anchor resolution and comparison that are revealed by that test. It also
includes tests downstream for specific cases that previously crashed.

Closes ZED-7G6
 
Release Notes:

- Fixed a crash that could occur when inlay hints were present while a
multibuffer replaced the contents of a file, such as a diff view whose
base changed.
- Fixed crashes that could occur when a file's contents were replaced in
a multibuffer (such as a diff view refreshing) while highlights, inlay
hints, or other positions still referenced the old contents.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-08-28 18:05:57 +00:00
Miguel Raz Guzmán Macedo 513ad12cef Avoid redundant string allocations (#63377)
Remove unnecessary intermediate `String` allocations when constructing
`Arc<str>` and `SharedString` values. Use static `SharedString` storage
for fixed worktree picker identifiers.

Validation:

- `cargo fmt --all -- --check`
- `tooling/lints/single-lint owned_string_into_shared -p editor -p
git_ui_core -p toolchain_selector`
- `cargo test -p editor -p git_ui_core -p toolchain_selector`

Release Notes:

- N/A
2026-08-28 17:31:36 +00:00
Cameron McloughlinandJakub Konka 50b7479f17 gpui: Touch events (#63373)
Adds support to GPUI for touch events, important for mobile web
browsers, and any potential native ios/android platforms

---

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
2026-08-28 17:22:25 +00:00
María CraigandMrSubidubi 0134fcd23a markdown: Round inline code backgrounds across all markdown surfaces (#63272)
# Objective

Inline code renders as a rounded chip in the Markdown preview (#63118)
but as a square, full-line-height background everywhere else — the agent
panel, editor hover popovers, notifications, and other markdown
surfaces.

## Solution

Inline code with a background color now always renders as a chip with a
4 px corner radius. The radius is fixed at the paint site rather than
exposed through `MarkdownStyle`, so every markdown surface uses the same
rendering without carrying configuration through the element builder and
rendered lines.

Chip backgrounds and text styling remain configurable. Only the corner
radius is fixed, removing the alternative square rendering path and
preventing surfaces from becoming inconsistent.

## Testing

- Updated `test_inline_code_chips_cover_exactly_the_code_span_glyphs` to
cover the fixed chip behavior.
- `cargo test -p markdown
test_inline_code_chips_cover_exactly_the_code_span_glyphs`
- `./script/clippy -p markdown`

## Self-Review Checklist:

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

---

Release Notes:

- Improved inline code to render with rounded backgrounds across all
markdown surfaces, matching the Markdown preview.

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-28 17:13:46 +00:00
Conrad Irwin c67c5c150b Send complete tool JSON schemas to every provider (#63342)
Zed asked each language model which JSON Schema dialect it wanted, and
rewrote every tool's schema into that dialect before sending it.
`LanguageModelToolSchemaFormat` had grown three variants, and providers
picked between them by model name, so Grok and Gemini took a lossy path
while everything else did not.

The subset exists because Google's `FunctionDeclaration.parameters`
field accepts an OpenAPI-flavored schema rather than JSON Schema, and
`adapt_schema_to_format` tried to translate into it. The translation was
best-effort: constructs it could not represent were left in place and
the function still returned `Ok`. The shape schemars produces for a Rust
`String | Vec<String>` union survives as a nested `anyOf` whose outer
node carries no `type`, and Vertex rejects the entire request over it,
taking every other tool down with it. Where the translation did fail,
the caller logged the error and dropped the tool, so the model silently
lost a capability.

Google now offers `parametersJsonSchema` alongside `parameters`, which
takes plain JSON Schema, and every other provider we ship documents JSON
Schema for function parameters. So the first commit switches
`into_google` to `parametersJsonSchema`, and the second deletes the
dialect: `LanguageModelToolSchemaFormat`,
`LanguageModel::tool_input_format`, `adapt_schema_to_format`, and the
per-model branching in every provider go away, along with
`x_ai::Model::requires_json_schema_subset`.

What remains is `normalize_tool_schema`, which every tool now passes
through. It strips `$schema`, `title`, and `description` from the root,
which no provider reads and which cost tokens; gives an object schema an
explicit `"properties": {}`, which OpenAI requires; and inlines
same-document `$ref`s. That last part is carried over from the deleted
code and matters only for context servers: MCP's Python SDK derives
input schemas through pydantic, which emits `$defs` and `$ref` for any
nested model or enum, and `zod-to-json-schema` emits `definitions` for
reused shapes, while Google rejects references outright. Built-in tools
never contain one, because `root_schema_for` inlines subschemas during
generation. A schema whose references cannot all be resolved is passed
through untouched and the reason logged, so a provider explains what is
wrong instead of receiving something half-rewritten.

## Providers whose behavior changes

| Provider | Models affected | Before | After |
|---|---|---|---|
| Google | all | `JsonSchemaSubset` in `parameters` | full JSON Schema
in `parametersJsonSchema` |
| Zed Cloud | Google, xAI | `JsonSchemaSubset` | full JSON Schema |
| Copilot Chat | Google, xAI, unknown vendors | `JsonSchemaSubset` |
full JSON Schema |
| xAI | Grok 4.3, 4.5, 4.6, 4.20 Reasoning, 4.20 Non-Reasoning |
`JsonSchemaSubset` | full JSON Schema |
| OpenRouter | model ids containing `gemini` or `grok` |
`JsonSchemaSubset` | full JSON Schema |
| Vercel AI Gateway | all | `JsonSchemaSubset` | full JSON Schema |
| OpenAI-compatible | all | `JsonSchemaSubset` | full JSON Schema |
| Bedrock Mantle | all | `JsonSchemaSubset` | full JSON Schema |
| Everything else | — | `JsonSchema` | unchanged apart from
normalization |

One deliberate difference for the last row: the old `JsonSchema` path
also injected `additionalProperties: false` into object roots, and
normalization does not. Nothing depends on it. Serde ignores unknown
fields, so a model inventing an argument never broke deserialization,
and OpenAI's strict function calling — the one feature that requires the
flag — is never enabled: every `ToolDefinition::Function` in the tree
passes `strict: None`. It was also only ever applied on the `JsonSchema`
path, so Google, Grok, Vercel and Bedrock Mantle users never received
it. Dropping it makes behavior uniform rather than removing a guarantee.

## Verification

This was checked against live providers rather than by reasoning about
documentation. A harness in the Delta repository dumps all 24 built-in
tool schemas from this branch and submits them with `tool_choice: none`
to each provider, so the only thing under test is whether the provider
accepts the schemas. Anthropic, OpenAI (chat and responses), Gemini,
xAI, Baseten, OpenRouter (Gemini and Grok), Vercel AI Gateway (Gemini
and Grok), Copilot (Gemini and Grok), the ChatGPT subscription, Bedrock
Converse, Bedrock Mantle (GPT and Grok), and Zed Cloud (Anthropic,
OpenAI, and Google) all accepted them. DeepSeek, Mistral, and OpenCode
were not probed for lack of a key.

The failure this fixes is reproducible on the route that broke. Vertex,
not the Gemini Developer API, is what enforces the constraint: the
harness pins the `grep` declaration production generated, replays it to
Vertex through Zed Cloud in the legacy `parameters` field, and gets back
the exact `INVALID_ARGUMENT` naming `parameters.globs`, while the same
route accepts this branch's schemas through `parametersJsonSchema`. The
Gemini Developer API accepts the broken shape on every model tried, so a
direct API key would never have caught it.

Testing:

- `cargo nextest run -p language_model_core -p google_ai -p agent` for
the schema, `into_google`, MCP and built-in tool tests
- New tests cover reference inlining for the shapes pydantic and zod
produce, recursive references, and unresolvable references
- `built_in_tool_schemas_are_normalized` asserts every built-in tool is
present and normalized
- `crates/agent/examples/dump_tool_schemas.rs` prints the definitions
the harness consumes
- 21 live provider probes with the complete tool set

Release Notes:

- Fixed Gemini rejecting requests because Zed translated tool schemas
into a restricted dialect it could not represent
2026-08-28 14:06:27 +00:00
951357a916 editor: Add language detection for untitled buffers (#61412)
# Objective

Closes #4868.

Reintroduce automatic language detection for user-created untitled
buffers without allowing it to override language choices made by users
or owning surfaces.

More details:
+ https://github.com/zed-industries/zed/pull/61201
+ https://github.com/zed-industries/zed/pull/61351

## Solution

VS Code distinguishes between inferred and explicitly selected
languages, and only continues automatic detection in the former state.
This change introduces a buffer-local opt-in flag with the same purpose.
It defaults to disabled and is enabled only for user-created untitled
buffers and restored untitled buffers that did not persist a language.
Choosing a language through the language picker disables detection,
while automatically detected languages remain eligible for later
redetection. Buffers whose language is assigned by their owning surface,
such as Channel Notes, never opt in.

Rather than adding persisted state or changing the database schema,
restoration reuses the existing optional serialized language. An
opted-in buffer that remains Plain Text is serialized without a language
and resumes detection after restoration. Once automatic detection has
selected a language, that language is serialized normally and
restoration leaves detection disabled, effectively treating it as an
explicit selection. This also matches VS Code's effective default after
restoration.

Candidate selection adopts VS Code's confidence-group filtering. Results
below the minimum confidence are discarded, and candidate groups are
accepted only after a clear confidence gap. The detector then selects
the first available Zed language without eagerly loading every
candidate. I then added a separate switching rule: Zed keeps the current
language unless another candidate has a clear confidence advantage,
reducing language changes as model scores fluctuate during editing.
Model inference runs off-thread on a bounded sample, and stale results
are discarded.

I also evaluated penalizing YAML and using stricter global switching
thresholds, but neither reliably resolves the ambiguity between Markdown
and YAML. In the reproduction from #61351, Betlang assigns YAML more
than 80% confidence during editing and peaks around 90%. This is
reasonable from the content alone: `#` denotes a YAML comment, while `-`
denotes a sequence item. Adding ordinary prose or a fenced code block
shifts the model strongly toward Markdown. A fixed penalty would overfit
this example and risk suppressing legitimate YAML detection. Since
known-language buffers do not opt in and manual language selection takes
precedence, I consider this level of ambiguity acceptable and prefer not
to introduce language-specific score tuning.

Model inference itself is fast. As noted in #61201:

> In release builds on Linux with an Intel Core i5-13600KF, the
`betlang::detect` call alone typically completes within 3 ms when
processing the maximum sampled input.

The main concern is the work surrounding inference. Without debouncing,
rapid typing creates a snapshot and launches a background detection task
on every keystroke, while the detected language may change before the
user has finished typing. This change therefore adds a 200 ms debounce
delay, allowing detection to run and update the language only after the
user pauses.

## Testing

Automated coverage verifies that short inputs remain Plain Text,
sufficient Rust content is detected as Rust, replacing it with Go
content triggers redetection, and manually selecting Plain Text prevents
subsequent automatic changes. Restoration coverage verifies that a
stored language keeps detection disabled, while an empty language-less
untitled buffer resumes detection.

Beyond the automated tests, I manually tested automatic language
detection while editing untitled buffers.

## Self-Review Checklist:

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

## Showcase


https://github.com/user-attachments/assets/103fc731-e12e-48d6-ae89-03978f1c9d74




---

Release Notes:

- Added automatic language detection for untitled buffers.

---------

Co-authored-by: Max Stevens <maxstevens2708@gmail.com>
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-08-28 13:19:29 +00:00
Smit Barmase 3122f37ff1 git_ui_core: Fix worktree creation for bare repositories (#63351)
Follow-up https://github.com/zed-industries/zed/pull/55153
Fixes
https://github.com/zed-industries/zed/discussions/54553#discussioncomment-17091833

When a repository stores its Git data in `~/work/zed/.bare`, creating a
linked worktree from Zed is broken in two visible ways:

- Zed creates `random-code` at:
```
~/work/worktrees/.bare/random-code/.bare
```
instead of:
```
~/work/worktrees/zed/random-code/zed
```

- Because the checkout ends in `.bare`, Zed displays `.bare` as its
worktree name in the title bar, worktree picker, and agent thread
sidebar. Every worktree Zed creates from that repository gets the same
`.bare` label instead of its generated name.

This problem is specific to the path Zed creates. Worktrees using either
of these layouts are not malformed:
```
~/work/worktrees/zed/random-code/zed
~/work/zed/some-worktree
```

https://github.com/zed-industries/zed/pull/55153 introduced repository
identities for bare repositories. This PR uses that identity in the
remaining worktree naming and creation paths.

There are three repository layouts to account for:

- In a normal repository, the common Git directory is `~/work/zed/.git`,
so Zed derives the main worktree at `~/work/zed`. Existing behavior
remains unchanged.

- With `~/work/zed/.bare`, Git has no main worktree. A checkout named
main is still a linked worktree. Zed now treats `~/work/zed` as the
repository identity, creates new worktrees under `~/work/worktrees/zed`,
and displays their generated names.

- With a bare repository named `~/work/foo.git`, `foo.git` is the
repository identity. Its worktree path remains
`~/work/worktrees/foo.git/random-code/foo.git`. Zed uses foo.git to
derive the worktree name random-code, while displaying the repository
itself as foo.

Existing malformed worktrees such as
`~/work/worktrees/.bare/random-code/.bare` are not moved and may
continue to display `.bare`.

Broken:

<p>
<img width="238" height="58" alt="image"
src="https://github.com/user-attachments/assets/1504e4d0-c34a-471f-8e76-c5ec062b1d77"
/>
</p>
<p>
<img width="274" height="49" alt="image"
src="https://github.com/user-attachments/assets/13266ca9-4e64-426c-b03c-e23c924a3597"
/>
</p>
<p>
<img width="574" height="85" alt="image"
src="https://github.com/user-attachments/assets/0fca58c7-5be7-4d36-9067-066d0b80caf8"
/>
</p>

Release Notes:

- Fixed linked worktree names and creation paths for bare Git
repositories.
2026-08-28 12:15:55 +00:00
Sean WoodandChristopher Biscardi a0608b889d feat: Add reveal buffer if already open (#63306)
# Objective

Fixes #12572

## Solution

- Adds an opt-in `reveal_if_open` setting which enables searching and
revealing an already open buffer
- Ensures this only happens if there is no pane target for the open
intent

## Testing

- Built for and tested on my Mac
- Tests added covering the scope of the feature

## Self-Review Checklist:

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

## Showcase


https://github.com/user-attachments/assets/cdcc78cd-85fd-4b56-b562-feba375ecd03

---

Release Notes:

- Added configuration to reveal buffers already open in a different pane
instead of the active pane, via `reveal_if_open`

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-08-28 11:51:00 +00:00
VietHannandKunall Banerjee ee83eeca60 docs: Update documentation for YARA (#63340)
## Description
Fixed documentation bug in \docs/src/languages.md\:

- **Issue**: \Yara\ was incorrectly linked to \./languages/yarn.md\ and
there was a duplicate \Yarn\ entry
- **Fix**: Changed \Yara\ link to \./languages/yara.md\ and removed the
duplicate \Yarn\ entry

## Testing
- Verified both \yara.md\ and \yarn.md\ files exist in
\docs/src/languages/\
- Applied Prettier formatting to the file

---

Release Notes:

- N/A

---------

Co-authored-by: Kunall Banerjee <hey@kimchiii.space>
2026-08-28 10:09:06 +00:00
Smit Barmase 26d819a9cf git: Fix remote URL parsing for partial clones (#63331)
Git adds the clone filter after `(fetch)` in `git remote -v` for partial
clones. Zed expected `(fetch)` at the end of the line, so it dropped
these remotes. This fixes that.

**Before:**

Only regular fetch entries were recognized:

```text
origin  https://github.com/zed-industries/zed.git (fetch)
```

**After:**

Fetch entries containing partial-clone filter metadata are also
recognized:
 
```text
origin  https://github.com/zed-industries/zed.git (fetch) [blob:none]
```

Release Notes:

- Fixed Zed failing to recognize Git remotes in partial clones.
2026-08-28 09:04:21 +00:00
Smit Barmase 0403df17a4 which_key: Fix Windows keybinding display in Which Key (#63349)
On Windows, Zed shows some shortcuts using the keys a person presses. 

For example, it displays `ctrl-@` as `Ctrl-Shift-2`. Which Key was
dropping that Windows-specific label and showing `Ctrl-@`, while the
command palette and keymap editor showed `Ctrl-Shift-2`.

This PR makes Which Key use the same shortcut labels as the rest of Zed.

**Before:**

Which Key (Shows `Ctrl-@`):

<p>
<img height="70" alt="image"
src="https://github.com/user-attachments/assets/9272ba29-1ebc-4329-8bd3-ec42937766c8"
/>
</p>

Keymap Editor (Shows `Ctrl-Shift-2` instead of `Ctrl-@`):

<p>
<img height="50" alt="image"
src="https://github.com/user-attachments/assets/3c36d887-2cb8-45fc-9672-6a8ea2ba2f4d"
/>
</p>

Command Palette (Shows `Ctrl-Shift-2` instead of `Ctrl-@`):

<p>
<img height="70" alt="image"
src="https://github.com/user-attachments/assets/2619a84b-341d-4ee4-89fb-4db62c3569dc"
/>
</p>

**After:**

<p>
<img height="70" alt="image"
src="https://github.com/user-attachments/assets/212f4d6e-e07d-4857-a0e7-e526611f2fcb"
/>
<p>

Release Notes:

- Fixed inconsistent shortcut labels in Which Key on Windows.
2026-08-28 09:03:27 +00:00
John Tur 0b1f4f4020 Delay-load ETW profiling DLLs (#62647)
Since we're here, improve the UX by prompting for a path when you save
rather than when recording begins.

Fixes #62334 

Release Notes:

- N/A
2026-08-28 08:13:20 +00:00
Kirill Bulatov 8a54abc4b9 Improve outline fonts and colors (#63325)
Closes https://github.com/zed-industries/zed/issues/58580

* Outline modal and panel now use buffer fonts for the contents:

<img width="1728" height="1117" alt="modal"
src="https://github.com/user-attachments/assets/5e0ef6e3-be39-4949-bc32-7087a51a02ec"
/>
<img width="1728" height="1092" alt="panel"
src="https://github.com/user-attachments/assets/5cf9edbf-5ff3-402d-a2ca-bc915bd10e8e"
/>

* Gutter colors are now fall-backed to tree-sitter better, if no
semantic tokens could be retrieved due to multi buffer shenanigans:

<img width="1728" height="426" alt="gutter"
src="https://github.com/user-attachments/assets/a175b2c8-843e-4632-b030-3edfbd350982"
/>

Release Notes:

- Improved outline fonts and colors
2026-08-28 03:28:04 +00:00
John Tur 2ada348466 Improve Windows shell discovery (#63339)
- Simplify PowerShell discovery, and add support for .NET global tool
installations.
- Fix Git Bash discovery in the case where Zed was launched from within
Git Bash. Git Bash prepends its internal `mingw64\bin` directory to
`PATH`, so `which git` returns a different `bash` executable that causes
the relative path lookup to fail.

Release Notes:

- N/A
2026-08-28 03:21:39 +00:00
Lukas Wirth 9e6bb59956 crashes: Abort after reporting Windows panics (#63157)
On Windows, the panic hook generated a minidump by calling
`simulate_exception`, but that function only invokes the crash callback
and then returns. Rust could therefore unwind a panicking background
thread while leaving the rest of the application running.

Abort unconditionally after minidump generation, matching the existing
Linux and macOS behavior. The Windows-specific simulation still runs
first so the crash sidecar can persist the exception context and panic
metadata before the process terminates.

Testing:

- `cargo fmt -p crashes --check`
- `cargo nextest run -p crashes`

Release Notes:

- Fixed Windows processes remaining alive after a background thread
panic.
2026-08-28 03:20:42 +00:00
Saber OueslatiandKirill Bulatov bb3b7953fe editor: Auto-refresh Bookmarks tab when bookmarks change (#56363)
[## Context

Fixes a bug where the Bookmarks tab, opened via `editor: view
bookmarks`, showed a stale snapshot and had to be reopened to display
bookmarks added or removed while it was open.

Closes #56268

`view_bookmarks` built a one-time multibuffer and never subscribed to
`BookmarkStore`. The store also calls `cx.notify()` while resolving
serialized bookmarks into anchors, even though that bookkeeping does not
represent a user-visible bookmark change. Observing all notifications
would therefore feed resolution notifications back into the refresh
mechanism and cause redundant cancellation and requeue work. The store
now emits a dedicated `BookmarkStoreEvent::BookmarksChanged` from
bookmark mutation paths, while `resolve_all` deliberately does not emit
it.

Refresh state lives on a `BookmarksView` entity that holds the tab's
multibuffer. Split editors already share that multibuffer, so they share
the view as well. Each store event drives one reconciliation regardless
of how many split editors display it. The view remains alive as long as
any split retains it, so closing the original tab does not stop the
remaining split from refreshing.

Each refresh reconciles excerpts per path instead of rebuilding the
multibuffer: `set_excerpts_for_path` updates files that still contain
bookmarks, while `remove_excerpts` removes files whose final bookmark
was deleted. This follows the per-path reconciliation pattern used by
project diff views.

`view_bookmarks` creates the tab synchronously and populates it
asynchronously, following the existing patterns in
`ProjectDiagnosticsEditor::deploy` and
`ProjectSearchView::existing_or_new_search`. Repeated invocations focus
the existing Bookmarks tab instead of opening duplicates.

Video of the manual test:

[Screencast from 2026-05-11
02-03-38.webm](https://github.com/user-attachments/assets/8ac97245-09ff-4a79-9634-20cb8dfbb7eb)

## How to Review

**`crates/project/src/bookmark_store.rs`**

Adds `BookmarkStoreEvent::BookmarksChanged`, emitted from bookmark
mutation paths such as toggle, label edit, file rename or deletion,
clear, and deserialization, but not from anchor resolution. It also adds
`BookmarkStore::is_empty`.

**`crates/editor/src/bookmarks.rs`**

Adds `BookmarksView`, which holds the multibuffer, store subscription,
and in-flight refresh task. It reconciles excerpts and emits
`BookmarksViewEvent::Populated(ranges)` for per-editor highlights and
cursor placement. It also caches the latest populated ranges and replays
them when an editor attaches, allowing a split created after population
to display bookmark highlights immediately.

**`crates/editor/src/editor.rs`**

Adds the shared `bookmark_view`, a per-editor subscription to its
population events, and `bookmark_initial_selection_pending` for initial
cursor placement. `Editor::clone` attaches the split to the shared view
instead of creating another store subscription and refresh task.

**`crates/editor/src/editor_tests.rs`**

Adds five tests covering automatic addition and removal across multiple
files, removal of a file's path after its final bookmark is deleted,
initial cursor placement, a bookmark change racing initial population,
splitting while population is pending, cached highlights in a
late-attaching split, and continued refreshing after the original tab
releases its view handle.

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

Release Notes:

- Fixed Bookmarks tab not updating when bookmarks are added or removed
while the tab is open](https://github.com/zed-industries/zed/pull/56363)

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 23:28:05 +00:00
Mikhail Pertsev 05154a14af helix: Add m i m/m a m and preserve the selection after those actions (#59201)
# Objective

- Preserve Helix mode selections after surround-related commands such as
adding, deleting, and replacing surrounds.
- Add Helix-compatible closest-pair behavior for `m i m` / `m a m` and
surround commands that target `m`.
- Avoid long stalls in Helix text-object boundary scans by removing
repeated syntax-scope classification during textual scans.
- Keep workflows like selecting text with `m i w`, applying `m s`, and
continuing with `i`, `a`, or another surround command aligned with Helix
behavior.

## Solution

- Add selection anchors that preserve each pre-edit selection range and
direction through surround edits.
- Update Helix surround add so the resulting selection includes the
added delimiters, allowing surround commands to compose and
insert/append actions to land outside the pair.
- Apply preserved selections to Helix surround delete and replace so
non-empty selections are not collapsed to the cursor after the edit.
- Add Helix-specific text-object bindings so `m` selects the closest
surrounding pair, `t` selects types/classes, `c` selects comments, and
`x` selects XML/HTML elements in Helix mode.
- Match the current closest pair through language bracket queries, so
delimiters inside strings or comments do not count as surrounding pairs.
- Resolve the textual boundary scanner's `CharClassifier` once per scan
and pass it by reference instead of recomputing the same classifier for
every scanned character. Word and subword boundaries still clone it only
to apply the `ignore_punctuation` flag.

## Performance

The textual boundary scanner previously called
`char_classifier_at(from.0)` inside the per-character comparison
closures for the four `ImmediateBoundary` scan methods and
`FuzzyBoundary::to_boundary`. That lookup resolves the language scope
through the syntax layers, and the value was loop-invariant because
every iteration used the scan's starting offset.

Local debug benchmark, using `] m` in a roughly 540 KB buffer with no
pair characters so the scan runs to EOF across all pair boundaries:

|        | `] m` |
| ------ | -----: |
| Before | 36.3 s |
| After  | 210 ms |

This speeds up the remaining textual scanner paths, including `m i (` /
`m i "`-style pair objects, word/sentence/paragraph objects, `]` / `[`
text-object navigation, and `] m` / `[ m`. The current-pair `m i m`, `m
a m`, `m d m`, and `m r m` paths use the tree-sitter closest-pair path
instead.

## Testing

- Ran `cargo test -p vim test_helix_surround -- --nocapture`.
- The focused Helix surround test filter passed: 10 passed, 0 failed.
- Added coverage for closest-pair selection, Helix-specific text-object
keys, and surround selection preservation.

## 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 Helix mode support for closest-pair text objects with `m i m`
and `m a m`.
- Fixed Helix mode surround commands to preserve selections after edits
and avoid slow textual boundary scans.
2026-08-27 23:24:52 +00:00
DongandKirill Bulatov 7472da6de7 Add folder_indicator setting to show chevron and folder icon together (#62393)
# Objective

- Enable panels to show chevron and icon at the same time.
- Closes #8661

## Solution

- Replaces `folder_icon` with a new `folder_indicator` which converts
from a boolean to enum (`both`, `chevron`, `icon`) for the three display
cases

## Testing

- gpui and migration tests had been applied

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

### project panel

both | chevron | icon
--- | --- | ---
<img width="400" alt="both_project_panel"
src="https://github.com/user-attachments/assets/4c21e1a1-a7a4-4471-b7de-fe867373ddbd"
/> | <img width="400" alt="chevron_project_panel"
src="https://github.com/user-attachments/assets/a626a82e-e5b7-470d-9d93-ed5787dc83d6"
/> | <img width="400" alt="icon_project_panel"
src="https://github.com/user-attachments/assets/20f9c55e-87c4-477a-b4c9-b070d6e5a1db"
/>

### git panel

both | chevron | icon
--- | --- | ---
<img width="400" alt="both_git_panel"
src="https://github.com/user-attachments/assets/3dc166dd-9e63-4943-b803-df3f167876b6"
/> | <img width="400" alt="chevron_git_panel"
src="https://github.com/user-attachments/assets/8dfd2c10-3a68-439a-8019-4951b72e17d1"
/> | <img width="400" alt="icon_git_panel"
src="https://github.com/user-attachments/assets/d78a9938-91e7-4d39-a3c8-04647da67768"
/>

### outline panel

both | chevron | icon
--- | --- | ---
<img width="400" alt="both_outline_panel"
src="https://github.com/user-attachments/assets/1b58c679-0bea-4600-a8ac-e800b0e8d24c"
/> | <img width="400" alt="chevron_outline_panel"
src="https://github.com/user-attachments/assets/0a9358e4-ec89-40d8-8d5e-a53b784ed30a"
/> | <img width="400" alt="icon_outline_panel"
src="https://github.com/user-attachments/assets/d8bf5199-5a8c-4de0-b516-00247e6531a5"
/>



---

Release Notes:

- Added a `folder_indicator` setting that can show the disclosure
chevron and folder icon at the same time in the project, outline, and
git panels.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 20:11:28 +00:00
b421755e5d Fix settings schema missing extension-provided LSP settings on remote (#62355)
## Objective

Fixes an issue where language servers provided by extensions are not
included in the settings schemas served by remote servers. When
connecting to a remote server via the
`open_remote_project_with_existing_connection` flow (dev servers,
multi-workspace reopen, git worktree picker), setup-N servers never
received any extension sync, so their schemas omitted extension-provided
language servers, breaking language support for remote development.

## Solution

Three changes ensure that language servers provided by extensions are
included in the settings schemas served by remote servers:

1. **Register connections opened via
`open_remote_project_with_existing_connection` with the extension
store**: dev servers, multi-workspace reopen, and the git worktree
picker now register their connections with the extension store so that
extensions are synced to those servers. Previously only the
`open_remote_project` flow did this, so setup-N servers never received
any extension sync and their schemas omitted extension language servers.

2. **Emit `ExtensionsInstalledChanged` from `HeadlessExtensionStore`
after sync and install complete**: this allows the remote process to
invalidate its cached settings schemas. The local `ExtensionStore`
already emitted this event; without it, the remote schema cache stayed
stale for the lifetime of the server process.

3. **Include available LSP adapters in the project settings schema**:
this matches the user settings schema (this was fixed for `settings` in
#46766 but never applied to `project_settings`).

## Testing

- Manually verified that after connecting to a remote server via the
`open_remote_project_with_existing_connection` flow (including dev
servers and the git worktree picker), extension language servers appear
in the schema served by the remote server.
- Verified that `ExtensionsInstalledChanged` is emitted after sync and
install complete, and that the remote schema cache is correctly
invalidated and rebuilt.
- Verified that the `project_settings` schema includes the available LSP
adapters, matching the behavior of the user settings schema.
- Reviewers should focus on the multi-workspace reopen and git worktree
picker flows (the two previously unregistered flows) to confirm that
extension language servers are correctly synced and appear in the
schema.

## 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
**Server / Project** — before the fix
<img width="1061" height="749" alt="image"
src="https://github.com/user-attachments/assets/d6c5459f-58fb-4769-a701-f6fb317adc37"
/>
**Local**
<img width="1119" height="449" alt="image"
src="https://github.com/user-attachments/assets/fb30a1e2-74f0-4439-a25f-1022ed164074"
/>

---

Release Notes:

- Fixed an issue where language servers provided by extensions were
missing from settings schemas served by remote servers.

---------

Co-authored-by: vancez <vancez@users.noreply.github.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 17:09:28 +00:00
c684a6a537 Add LSP call hierarchy modal (#53239)
<img width="1128" height="953" alt="image"
src="https://github.com/user-attachments/assets/b2017c0a-e25a-49d7-9342-d074014d085c"
/>

Closes #14203

Release Notes:
- Initial Call Hierarchy support in Zed

---------

Co-authored-by: Alexey Olshanskiy <gh@aohoy.dev>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 16:21:41 +00:00
Cameron Mcloughlin 941bd6fa99 gpui: IME race condition bug (#63311)
When an IME makes a selection, but doesn't modify the text, there was a
race condition, where the GPUI->mirror sync could overwrite the
`selectionchanged` event, causing IME sessions to be discarded.

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-08-27 13:23:18 +00:00
09440c85cb lsp: Add client support for LSP 3.18 markdown diagnostic messages (#61030)
LSP 3.18 allows servers to send [`MarkupContent` diagnostic
messages](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#diagnostic),
guarded by the client capability
`textDocument.diagnostic.markupMessageSupport`.

- Advertise `markup_message_support` only while pull diagnostics are
enabled because `textDocument.diagnostic` is the pull-model capability.
  LSP 3.18 currently has no equivalent capability for push diagnostics:

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#diagnosticClientCapabilities
  https://github.com/microsoft/language-server-protocol/issues/2246
- Handle `string | MarkupContent` messages in both push and pull
diagnostic paths: markdown-kind messages populate the existing
`Diagnostic::markdown` field (rendered in hover popovers and the
diagnostics panel), plaintext-kind markup remains plain text, and plain
string messages keep going through the adapter's
`diagnostic_message_to_markdown`.
- Preserve server-provided markup for code actions sent back to the
originating server, avoid forwarding markup diagnostics to other
servers, and render diagnostic metadata without altering the
server-provided markdown.
- Carry the markup kind over RPC via a new optional
`LspDiagnostic.markup_message_kind` proto field so remote/collab
projects round-trip `MarkupContent` messages.

Depends on the lsp-types change that turns `Diagnostic.message` into a
`DiagnosticMessage` enum (`string | MarkupContent`):
https://github.com/zed-industries/lsp-types/pull/15
Once merged, Cargo.toml can point to the upstream commit.

Note that Zed already rendered some plain-string diagnostics as Markdown
through language-specific adapter hooks, including `rust-analyzer`. This
adds protocol-level support for diagnostics explicitly sent as LSP 3.18
`MarkupContent`, while preserving the existing adapter fallbacks.

As a result, this does not introduce a new diagnostics rendering
pipeline.
Server-provided Markdown is routed through the existing
`Diagnostic::markdown` path, with small fixes to handle Markdown-only
updates and block content correctly.

## Showcase

Example from [JETLS.jl](github.com/aviatesk/JETLS.jl) (a Julia language
server):

> Before
<img width="924" height="160" alt="Screenshot 2026-07-15 at 16 05 40"
src="https://github.com/user-attachments/assets/b19fe9e3-50e3-44e4-9b4d-ac8bd438d3d6"
/>

> After
<img width="924" height="160" alt="Screenshot 2026-07-15 at 14 13 05"
src="https://github.com/user-attachments/assets/359c3382-118d-4fa6-aa91-6bd3661d3d28"
/>

---

Release Notes:

- Added support for rendering LSP 3.18 Markdown diagnostic messages from
language servers.

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2026-08-27 12:55:42 +00:00
Cameron Mcloughlinandzed-zippy[bot] 0854657a2b gpui: Add text_edit_editable_range API (#63294)
When syncing text to the browser IME mirror, we sometimes need to mark a
particular range as "editable". Native clients have a pull-based model,
so don't need this mechanism, but on the web we need to proactively push
content to the IME mirror `textarea`.

---

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-08-27 10:13:49 +00:00
Pranav Bansal b24568132b Add support for Visual Line select in terminal vi mode (#63251)
# Objective

Add support for Visual Line Select in terminal vi mode.

## Solution

Add handling for "V" akin to Visual Line Select mode in vim.

## Testing

manually tested these changes by running locally (`cargo run`)

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


https://github.com/user-attachments/assets/a39636cd-a82e-444d-bdac-8f86d76f03f4



---

Release Notes:

- Added support for Visual Line Select in terminal vi mode
2026-08-27 06:40:50 +00:00
Miguel Raz Guzmán Macedo b90c4869f9 Require clear sections in lint UI fixtures (#62659)
Add `// --- SHOULD FIRE ---- ` and `// ---- SHOULD NOT FIRE ---- ` to
the `/lint-creator` skill.

Release Notes:

- N/A
2026-08-27 05:53:18 +00:00