Commit Graph
263 Commits
Author SHA1 Message Date
Jack Walters 52e0b848da Add a setting for Threads Sidebar auto-open (#64259)
Closes https://github.com/zed-industries/zed/discussions/64266

Opening a folder in an existing window force-opens the Threads Sidebar,
and there is no way to prevent it. `open_paths` called
`MultiWorkspace::open_sidebar` unconditionally on the reused window, so
the sidebar reopened on every such open regardless of whether the user
had closed it.

This adds `agent.threads_sidebar_auto_open`, defaulting to `true` so
current behavior is unchanged. With `false`, the folder still opens in
the existing window, but the sidebar stays closed.

This path is reached when `default_open_behavior` or
`cli_default_open_behavior` is set to `existing_window`.

`open_sidebar` was doing double duty: besides showing the sidebar, it
pinned the workspace being navigated away from so it survives the
switch. When the setting is disabled, `retain_active_workspace` is
called instead, so only sidebar visibility changes.


https://github.com/user-attachments/assets/fc299df0-27e2-4ac6-98cb-d817d5f71d0e

## Tests

Two tests in `multi_workspace_tests.rs` cover both branches: the sidebar
opens by default, and stays closed when the setting is disabled while
the folder still opens in the same window.

Release Notes:

- Added `agent.threads_sidebar_auto_open` to control whether opening a
folder in an existing window also opens the Threads Sidebar
2026-09-16 16:03:50 +00:00
Kirill Bulatov dc339e4f43 Share application adapter implementations (reduce LLVM IR bloat again) (#64262)
Move settings-update routing, fallible deserialization recovery,
selection effects, context-menu initialization, picker resize handles,
and ACP client setup into shared implementations. Inline the small
button callback adapters.

`cargo llvm-lines --locked -p settings_ui`:
Before (01c555b435): 1571017 lines, 53634 copies
After: 1177376 lines (-25.1%), 43380 copies (-19.1%)

With compiler wrappers disabled, `cargo clean --target-dir
target/binary-size-split-build` and `cargo build --locked -p zed`:
Before: 135.6s wall, 1569.8s CPU, zed binary 1175563800 bytes 
After: 140.9s wall (+3.9%), 1588.8s CPU (+1.2%), zed binary 1157304600
bytes (-1.6%, -18.3MB)

Release Notes:

- N/A
2026-09-16 16:03:09 +00:00
Thibaud Guillaume-Gentil 5f1a6530e9 language_models: Add SuperGrok OAuth provider (#63248)
# Objective

Grok in the agent is BYOK only today (`x_ai` plus an API key from
console.x.ai). SuperGrok is a separate subscription, so you either pay
twice or you skip Grok in Zed. This makes SuperGrok a first-class LLM
provider, same idea as ChatGPT Subscription or GitHub Copilot Chat.

Discussion:
https://github.com/zed-industries/zed/discussions/63114#discussioncomment-18158663

## Solution

Adds a SuperGrok provider next to the API-key one. Sign in / Sign out is
in Settings → AI → LLM Providers, same shape as ChatGPT Subscription.
Tokens go in the OS keychain, not settings.json.

Shipped models: Grok 4.6 (default), Grok 4.5, Grok Build 0.1. Reasoning
effort on 4.5/4.6 matches the BYOK xAI provider (no `none`, default
high, 4.6 has xhigh). Some Grok plans still get HTTP 403 after a
successful login. The error says the account cannot use this API and
points at the API-key provider.

## Testing

I have been running this locally for a few days on macOS 27 (public
beta) with a SuperGrok Heavy subscription. No issues so far.

`cargo test -p x_ai_subscribed --lib` and `cargo test -p language_models
--lib provider::x_ai_subscribed` pass.

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

SuperGrok LLM provider settings:

<img width="956" height="816" alt="Screenshot 2026-08-26 at 13 41 17"
src="https://github.com/user-attachments/assets/ef2d464a-66ad-416a-a924-725a18d41164"
/>

---

Release Notes:

- Added SuperGrok sign-in so a SuperGrok subscription can use Grok
models in the agent
2026-09-16 07:01:45 +00:00
Dom Porada aef893e276 Add a setting for the Threads Sidebar width (#62883)
## Objective

The Threads Sidebar opens at a hard-coded 300px and can be resized only
by dragging. `agent.default_width` controls the Agent Panel rather than
the sidebar, leaving no way to configure the sidebar’s preferred width.

## Solution

Add `agent.threads_sidebar_default_width` for the width used when no
user-chosen sidebar width is stored. The value is clamped to the
existing 200–800px drag range. Existing, unresized sidebars follow
settings changes immediately. Double-clicking the divider resets the
sidebar to the configured width and resumes following subsequent
settings changes.

The sidebar previously saved its width whenever any sidebar state
changed, not only when the divider was dragged. `SerializedSidebar` now
records `width_set_by_user`, so settings-driven widths are no longer
persisted. Manually resized widths take precedence until the divider is
reset.

## Testing

- `test_threads_sidebar_default_width` in
`crates/agent_settings/src/agent_settings.rs` covers the default, a user
override, fallback for `null` and an unset field, and preservation of
the Agent Panel width and sidebar position.
- Five width-focused tests in `crates/sidebar/src/sidebar_tests.rs`
cover reset behavior, live settings updates, clamping, legacy-width
restoration, and persistence. They also check that manually resized
widths resist settings changes and that resetting resumes following the
setting.
- To check by hand: set `"agent": { "threads_sidebar_default_width": 360
}`, reset the divider, and confirm the sidebar is 360px wide. Change the
setting and confirm the width updates immediately. Drag it wider,
restart, and confirm the dragged width is kept. Double-click the divider
and confirm it returns to the configured width. Set the value to `5000`
and confirm the untouched sidebar clamps to 800px.

## 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 `agent.threads_sidebar_default_width` for setting the width of
the Threads Sidebar.
2026-09-15 14:53:12 +00:00
Dom Porada 5151c7953d Clarify how agent.flexible affects agent.default_width (#63020)
## Objective

`agent.default_width` is described as the Agent Panel’s default width,
but panels docked to the left or right use proportional sizing while
`agent.flexible` is enabled. Because flexible sizing is enabled by
default, double-clicking the outer resize handle restores the default
proportion rather than the configured pixel width. This can make
`agent.default_width` appear to be ignored.

## Solution

Clarify that `agent.default_width` controls the fixed width used when
`agent.flexible` is disabled, while resetting a flexibly sized Agent
Panel restores its default proportion.

Update the default settings comments, settings documentation, Settings
UI description, and visual customization guide. Add `agent.flexible` to
the Agent Panel configuration example and explain how it affects reset
behavior. No sizing behavior changes.

## Testing

- `cargo fmt --all -- --check`
- No runtime testing—the change only updates settings descriptions and
documentation.

## 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-09-15 12:45:15 +00:00
Dom PoradaandKirill Bulatov 169a2b11ab Add support for the "..." entry in read_only_files (#64222)
## Objective

Let projects add read-only file patterns without repeating the patterns
inherited from user settings.

## Solution

Extend the `"..."` behavior introduced in #62769 to `read_only_files`. A
`"..."` entry includes the inherited patterns. Omitting it replaces the
list, and `[]` clears it.

## Testing

Tested on macOS with settings merge, VS Code import, and project
integration tests. The project test verifies that user and project
patterns both apply while unrelated files remain editable.

To check manually, configure different user and project patterns,
include `"..."` in the project list, and open matching files. Repeat
without `"..."` after restarting Zed to verify replacement.

Linux, Windows, and manual app testing were not performed.

## 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 `"..."` in `read_only_files` so project settings can
extend inherited read-only patterns.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-15 11:49:56 +00:00
Kirill Bulatov 45ff33717b Refine recent commands' UX (#64181)
Follow-up to https://github.com/zed-industries/zed/pull/63388 


https://github.com/user-attachments/assets/2a855451-141b-4030-8475-92f23c661d51

Release Notes:

- Improved recent commands' UX
2026-09-15 09:58:45 +00:00
Giorgio PoglianiandKirill Bulatov f0261834eb editor: Allow customizing CodeLens text color (#64084)
CodeLens text currently hardcodes `text.muted`, so changing its color
also changes unrelated muted UI text such as the sidebar.

This adds a dedicated `editor.code_lens.foreground` theme color. When
omitted, it falls back to `text.muted`, preserving the existing
appearance of themes while allowing CodeLens text to be customized
independently.

Release Notes:

- Added `editor.code_lens.foreground` for customizing CodeLens text
independently.

---------

Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2026-09-11 15:19:53 +00:00
Xiaobo LiuandKirill Bulatov 450775244f gpui: Prevent idle sleep during AI response streaming (#53130)
Release Notes:

- Added button tu prevent idle sleep during AI response streaming


**Context / Motivation:**
When an AI agent takes a long time to generate a response, the operating
system might enter an idle sleep (or display sleep) state if there is no
user interaction (mouse or keyboard). This can interrupt the workflow.
This PR aims to prevent the system from sleeping during an active AI
turn by invoking native OS APIs, and provides a UI toggle for users to
control this behavior.

**Key Changes:**

1. **Cross-Platform Idle Sleep Prevention in GPUI (`gpui`, `gpui_*`)**
- Added a new `prevent_idle_sleep` method to the `Platform` trait. It
returns a RAII-based `PreventIdleSleepToken`, which automatically
restores the original sleep policy when dropped.
- **macOS**: Utilizes `NSProcessInfo`'s `beginActivityWithOptions` with
`NSActivityIdleDisplaySleepDisabled`.
- **Windows**: Uses `SetThreadExecutionState` to prevent display and
system sleep, incorporating a reference counter to handle concurrent
requests safely.
- **Linux**: Uses `ashpd` to request `org.freedesktop.portal.Inhibit`
(inhibiting `Idle` and `Suspend` states) via D-Bus.

2. **AI Agent State Integration (`crates/acp_thread`)**
- Introduced idle sleep prevention logic in `AcpThread`: Acquires the
token at the beginning of `run_turn`, and automatically releases it when
the turn completes normally, errors out, or is explicitly canceled by
the user.
- Added comprehensive unit tests to ensure the token is correctly
acquired and released under various cancellation and concurrency
scenarios.

3. **Settings and UI (`crates/agent_settings`, `crates/agent_ui`)**
   - Added `AgentOutputIdleSleepControl` to global state.
- Added a new toggle button (screen icon) to the toolbar at the bottom
of the `ThreadView` (AI conversation panel). Users can hover to view the
tooltip and click to toggle the feature on or off.

<img width="419" height="132" alt="截屏2026-04-04 16 09 08"
src="https://github.com/user-attachments/assets/619da9ff-10f7-46e0-b959-d7c74b16b918"
/>

---------

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-09 13:49:13 +00:00
1d25e83fe8 project_panel: Honor preview setting for keyboard opens (#63758)
Closes #63725

Honor `preview_tabs.enable_preview_from_project_panel` when opening
files with `project_panel::Open` (Space), matching the setting-aware
single-click behavior. Add a regression test covering previews disabled.

Testing:

- `cargo test -p project_panel --lib`
- `cargo build -p zed`
- Manually verified with the setting disabled that Space opens two
permanent tabs
- Manually verified with the setting enabled that Space replaces the
previous preview tab
- `./script/clippy -p project_panel --tests` is blocked by an unrelated
existing `clippy::drain_collect` diagnostic in
`crates/rpc/src/proto_client.rs`

Manual verification:

Preview disabled — Space opens both files as permanent tabs:

<img width="1920" height="1032" alt="Preview disabled: Space opens both
files as permanent tabs"
src="https://github.com/user-attachments/assets/4b772aad-031e-401d-ac85-5a7f82a74bc1"
/>

Preview enabled — Space replaces the previous preview tab:

<img width="1920" height="1032" alt="Preview enabled: Space replaces the
previous preview tab"
src="https://github.com/user-attachments/assets/cfef36af-0cd5-4522-99b5-99d3bb2c3f9d"
/>

Release Notes:

- Fixed the project panel preview-tab setting being ignored when opening
files with the keyboard.

---------

Co-authored-by: Chara <249489759+cmdr-chara@users.noreply.github.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-09-07 12:13:53 +00:00
Jake NelsonandKirill Bulatov ba6b83f89d workspace: Add configurable window title formatting (#54379)
## Summary
- Add `window_title_format` and `window_title_separator` settings for
customizing the window title
- Expose `${projectName}`, `${fileName}`, `${filePath}`,
`${relativePath}`, `${fileStem}`, `${remoteName}`, `${remoteHost}`,
`${appName}`, and `${separator}` as the native Zed window-title
variables
- Keep the collab `↗/↙` indicator hard-appended
- Translate VS Code `window.title` / `window.titleSeparator` aliases
into Zed's canonical variables during settings import, including
`${appName}` passthrough support and mapping VS Code's
`${activeEditorMedium}` onto Zed's `${relativePath}`
- Gate path-, remote-, and release-channel-derived lookups on whether
the active template references the corresponding variable, so the
default template avoids the extra work and still uses the existing
`last_window_title` cache to skip redundant platform updates

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

## Implementation reasoning and notes

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

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

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

## Screenshots

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

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

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

Closes #14534

Release Notes:

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

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-04 13:48:58 +00:00
Manoj skandChristopher Biscardi 9c3e2a071f project_panel: Show path tooltip on hover (#63299)
# Objective

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

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

## Testing

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

## Self-Review Checklist:

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

## Showcase

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


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

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

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

My super cool demos here

</details>

---

Release Notes:

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

---------

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

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

## Solution

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

## Testing

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

## Self-Review Checklist:

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

## Recordings


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


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

Release Notes:

- Added a setting to open Markdown files directly in preview mode and
grouped Markdown preview settings together.
2026-09-04 10:54:29 +00:00
CainandChristopher Biscardi 2988a59241 editor: Add optional cursor movement animation (#63195)
# Objective

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

Related to #4991.

## Solution

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

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

### Attribution

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

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

## Testing

Automated checks run on Windows:

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

The tests cover:

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

To test manually:

1. Add the following to the settings file:

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

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

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

Verified that:

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

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

## Self-Review Checklist:

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

## Showcase


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

---

Release Notes:

- Added an optional cursor movement animation setting.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-09-04 07:36:22 +00:00
Smit BarmaseandKirill Bulatov d85eade7ab which_key: Add a pending key binding indicator (#63343)
This PR makes Zed's one-second key binding delay visible.

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

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

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

Release Notes:

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

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-03 09:35:53 +00:00
Albert Bogusz 810c6a04a6 Add on_new_window setting (#63522)
> [!NOTE]
> This is a remake of #63335 as it's unlikely to be reopened just from
my
[mention](https://github.com/zed-industries/zed/pull/63335#issuecomment-5452544138).
Apologies for the noise!

# Objective

Closes #59368, where users (including me) are asking for a way to show
the Launchpad instead of an empty tab when opening a new window. As per
advice from
https://github.com/zed-industries/zed/issues/60720#issuecomment-4936162420,
adding a separate setting from `restore_on_startup` is more ideal.

`on_new_window` allows for two values:
- `empty_tab`
- `launchpad` (default)

## Testing

Added a regression test which opens a new window with `on_new_window`
set to `launchpad` and asserts that no item gets opened in the window's
pane. I've verified it fails without the setting gate, and confirmed
configuring this setting works manually (see Showcase).

## Self-Review Checklist:

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

## Showcase


https://github.com/user-attachments/assets/bf339bd1-8c62-4243-ac9d-1045d1a14865

---

Release Notes:

- Added `on_new_window` setting to configure the opening of new windows.
2026-09-02 18:17:30 +00:00
Matei Oprea 8ce383f221 Improve visibility and wording around close panel on toggle setting (#63548)
# Objective

- Improve documentation for `close_panel_on_toggle` setting. 

## Solution

- Previous docs were a bit ambiguous and since refactoring the setting
name is not possible at the time, I improved the documentation.

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

Release Notes:

- Added the`close_panel_on_toggle` setting to the settings UI and
improved its documentation.
2026-09-01 15:53:33 +00:00
František GažoandKirill Bulatov e8fbacb6d7 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
Dom PoradaandMrSubidubi 9dbc9e76c1 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
669bede5c5 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
Sean WoodandChristopher Biscardi 351899e531 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
DongandKirill Bulatov 8166e3d7b8 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
1e2e422c7b 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
ec312b2701 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
a1cc2548f9 open_router: Support effort-based reasoning (#61308)
# Objective

- This PR adds support for effort-based reasoning for OpenRouter models
- This PR correctly configures whether OpenRouter models support
reasoning or not
- Fixes #58843 (already closed, was converted to #58848 )

## Solution

- The OpenRouter `/v1/models` endpoint includes data about supported
effort levels (see
[docs](https://openrouter.ai/docs/guides/best-practices/reasoning-tokens#discovering-per-model-reasoning-options))
and model capabilities
- This PR uses this data to populate the "effort" dropdown in the agent
panel (compare #56411 which added a similar feature for OpenAI) and to
provide better model metadata (`supports_thinking`,
`supports_disabling_thinking`).
- If a model supports `max_tokens`-based thinking, effort levels will
still be shown. OpenRouter automatically converts effort levels into an
appropriate `max_tokens` budget
([docs](https://openrouter.ai/docs/guides/best-practices/reasoning-tokens#reasoning-effort-level)).
This way users are not limited to a fixed `max_tokens` budget.
- Some models return `"supported_parameters": ["reasoning"]` with
`"reasoning": {"mandatory": false}`. From the docs I am not quite sure
what that's supposed to mean. The PR interprets these models with a
binary thinking on/off switch.

The PR also fixes the inverted logic where
`supports_parallel_tool_calls` would always return `false`, which would
then result in `parallel_tool_calls: None` for the actual API call
(which enables parallel tool calls by default). So the result of
`supports_parallel_tool_calls` was interpreted opposite to what I would
expect. The PR now returns `true` from `supports_parallel_tool_calls`
and adapts the corresponding call. There is no change in behavior
(`parallel_tool_calls` are always enabled in practice), it just fixes
the code logic.

## Testing

I tested the changes manually in an instance started via `cargo run`:
- I tested using GLM 5.2 and GPT 5.5. The reasoning effort is being
shown in the agent panel. Changing the effort level changes the amount
of thinking that the model does (e.g. on "Extra High" I consistently see
thinking blocks, on lower levels I sometimes do. I don't see thinking
blocks when thinking is disabled).
- Some models with `"reasoning": {"mandatory": false}` can be called
with effort levels. I am not sure if it actually makes a difference, but
the API doesn't reject it. Maybe there are configuration options that
are not currently exposed by this PR. I think the approach in this PR is
a safe default though.
- To test this PR:
  1. Build it via `cargo run`
  2. Set an OpenRouter API Key
3. Open the Agent panel and select different models. Notice that the
effort level selector and the thinking toggle is dynamically
shown/hidden/populated based on the model.

## 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 effort-based reasoning when using OpenRouter models

---------

Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-08-26 17:39:50 +00:00
Kirill Bulatov 34241d5fc8 Reduce LLVM IR bloat (#63232)
Cuts serde monomorphization in settings_content: both parse entry points
now share one deserializer instantiation, and the flatten-heavy settings
structs deserialize through a small manual routing macro instead of
serde's Content buffering.
Parsed values seem to be unchanged; JSON schema and serialization
derives are untouched.

`cargo llvm-lines -p settings_content`:
Before (1ff7cb669b): 2716889 lines, 92801 copies
After: 1203744 lines (-55.7%), 47122 copies (-49.2%)

With sccache disabled, `cargo clean` and `cargo build -p zed`:
Before: 132.8s wall, 1440.6s CPU, zed binary 1241791992 bytes
After: 128.8s wall (-3.0%), 1400.0s CPU (-2.8%), zed binary 1204044312
bytes (-3.0%, -37.7MB)

Release Notes:

- N/A
2026-08-26 14:33:14 +00:00
Kirill Bulatov 1475887faf Enable project search on type by default (#62506)
Closes https://github.com/zed-industries/zed/issues/9318

Most of the diff is tests.

Notable behavior changes during this mode, compared to current mode:

* unsaved changes in multi buffer won't spawn any "save or not" pop-ups
during typing — submitting the query still does it, as before.
Unsaved files will stay so after being sorted out on typing: we cannot
save them by default as file-less buffers need a save modal; Zed should
already be able to persist and restore such changes on restart.

* gutter may jump during search, if new excerpts with large line numbers
appear during query input — yet it would not shrink back to avoid
excessive flickering and rewraps

Release Notes:

- Enabled project search on type by default (use `{ "search": {
"search_on_type": false } }` to restore the previous behavior)
2026-08-26 14:33:03 +00:00
Marshall Bowers fd82517a11 git_hosting_providers: Add Tangled support (#63051)
This PR adds support for [Tangled](https://tangled.org/) as a Git
hosting provider.

Release Notes:

- Added support for permalinks to [Tangled](https://tangled.org/)
repositories.
2026-08-21 21:31:55 +00:00
Smit Barmase 54230ad8fd settings_content: Add OpenAI subscription provider autocomplete (#62989)
Release Notes:

- Added settings autocomplete for the OpenAI subscription language model
provider.
2026-08-21 09:48:51 +00:00
DanielandBen Kunkle cb1352a29d Add configurable inline completion debounce timeout (#61568)
# Objective

Add configurable inline completion debounce timeout
Fixes/implements #23159

## Solution

I initially wanted to make a global setting for this, but it would
conflict with hardcoded debounces in codestral (150ms) and copilot
(75ms) which I assume are there for a reason.

So I ended up using the same mechanism used for the hardcoded debounce
in Codestral (`DEBOUNCE_TIMEOUT`) and Copilot
(`COPILOT_DEBOUNCE_TIMEOUT`)
and made it accessible and configurable for all providers.


Also fixed a bug with `DelayMs` `Display` trait adding "ms" into the
input field which then fails to parse something like "150ms" as a `u64`
by implementing `FromStr` which strips the "ms" suffix if present.

So now both "1000" and "1000ms" are parsed correctly and apply.

If the parsing fix is not relevant enough I can open a separate issue +
PR for that (and the inconsistent use and therefore display of
`Option<u64>` vs `Option<DelayMs>` in other ms input fields).

## Testing

#### Did you test these changes? If so, how?

Added a separate test which passes
`test_refresh_prediction_from_buffer_honors_debounce_duration`

Manually tested with openapi compatible prediction

All other tests in affected crates pass (`cargo test -p settings_content
-p settings_ui -p editor -p edit_prediction -p language
`)

#### How can other people (reviewers) test your changes? Is there
anything specific they need to know?

Open provider settings and adjust debounce, then see how long it takes
for a prediction to render.

#### If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

Tested on Fedora 43 KDE, but it shouldn't matter as none of the affected
code is platform specific.

## 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/14efa628-765e-4c2a-ac44-01aaa3657097

---

Release Notes:

- Added configurable inline completion debounce timeout, fixes #23159

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-08-20 16:42:42 +00:00
Vlad Ionescuanddino 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]](https://github.com/anomalyco/models.dev/blob/89183a9646cf2fa30300f7203a5b4f2ca69d1374/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]](https://github.com/anomalyco/models.dev/blob/89183a9646cf2fa30300f7203a5b4f2ca69d1374/providers/opencode-go/models/grok-4.5.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/89183a9646cf2fa30300f7203a5b4f2ca69d1374/models/xai/grok-4.5.toml)
- added **Tencent Hy3** as per
[[1]](https://github.com/anomalyco/models.dev/commit/b013d94872bb5993fad19ad35fadf74cb029516e)
and
[[2]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/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]](https://github.com/anomalyco/models.dev/commit/403a7bdd43ac7daeadc8bb755eccabf66a0afb9d)
and
[[2]](https://github.com/anomalyco/opencode/commit/e9e747245681127c9f3e300aa8c46f2554fdb294)
- added **GLM 5.3** as per
[[1]](https://github.com/anomalyco/models.dev/blob/3876740bf4f0290e014bc85340e1dba34f0e99a7/models/zhipuai/glm-5.3.toml)
and
[[2]](https://github.com/anomalyco/models.dev/commit/94a1629610b579fd80f7c488f5e4e8d78c8b6883)
and [[3]](https://github.com/anomalyco/opencode/pull/42518)

**OpenCode Zen**:
- added **Gemini 3.5 Flash Lite** as per
[[1]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/providers/opencode/models/gemini-3.5-flash-lite.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/models/google/gemini-3.5-flash-lite.toml)
- added **Gemini 3.6 Flash** as per
[[1]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/providers/opencode/models/gemini-3.6-flash.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/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]](https://github.com/anomalyco/models.dev/commit/b1810e30d7abb11af1092b51aa28cbafc2c440b8)
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]](https://github.com/anomalyco/models.dev/commit/e3ae24cdd7fb524d73e1569ed1713991c5ba688c)
and
[[2]](https://github.com/anomalyco/models.dev/commit/342b5572a06735d0efa8c3c419589051199459d8)
- added **Kimi K3** as per
[[1]](https://github.com/anomalyco/opencode/commit/a9bebd36530dbab28c4644eb7b35b2b1460b8b90)
and
[[2]](https://github.com/anomalyco/models.dev/commit/38ccccc20d7d827f99d791d07cc4cedb8b4eec24)
- added **Grok 4.6** as per
[[1]](https://github.com/anomalyco/models.dev/commit/74789f5a02746cf6c40b75c342432a9d525c28b9)
and
[[2]](https://github.com/anomalyco/opencode/commit/d92d1e654bd1aa8ccb972b3059825314c1633eb8)
and [[3]](https://github.com/anomalyco/models.dev/pull/4575)
- added **Muse Spark 1.2** as per
[[1]](https://github.com/anomalyco/models.dev/commit/fa03dca90bad225a09263ad6ad227c7f47d0172d)
and
[[2]](https://github.com/anomalyco/models.dev/blob/3876740bf4f0290e014bc85340e1dba34f0e99a7/models/meta/muse-spark-1.2.toml)
and [[3]](https://github.com/anomalyco/opencode/pull/42508)
- removed **Claude Opus 4.1** as per
[[1]](https://github.com/anomalyco/models.dev/commit/6951484e985fe55646a741ccd3ca1d4b15008e3f)

**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
a7d74150ac Fix the git_gutter_width setting (#62704)
# 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
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
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
Kirill Bulatov 18be72fd68 Make file scanner less eager in non-git-tracked directory trees (#62583)
Fixes https://github.com/zed-industries/zed/issues/35780
Collab schema migration PR:
https://github.com/zed-industries/cloud/pull/3422
The corresponding database schema migration has been created in the
Cloud repo and applied to the production database.

Before, Zed scanned each and every entry in the tree down from the
directory it was opened in, except gitignored files and scan exclusions.
The approach is unchanged, if Zed detects it was open inside a git
repository: e.g. the directory open in Zed contains `.git` directory.

For the rest of the projects, 2 optimizations are made:

* Limit the depth of file scan traversal.
Now, `file_scan_depth` (default `5`) restricts Zed from traversing any
directory that has same number or more segments in its file path.


Such directories behave similar to gitignored directories: their
contents is not available in file finder, project search and project
panel, but can be lazily traversed when the directory is expanded (e.g.
project panel expands it or a nested file is open by path via terminal,
etc.)

To indicate that to the users, a status entry is shown firs time the
limitation is hit in the project:

<img width="858" height="133" alt="image"
src="https://github.com/user-attachments/assets/7da6cfbb-98b4-4cc3-bf2a-8902a9597a15"
/>

* During the scan, any git repositories that are not direct children of
the directory open in Zed (depth >= 2), are traversed and indexed
normally, but their git metadata is never fetched eagerly.

Only when Zed opens a buffer from that repo the git metadata is fetched
and applied.

All that combined now uses a way more moderate amount of CPU and RAM
when opening `~`:

<img width="1717" height="368" alt="Screenshot 2026-08-13 at 17 43 53"
src="https://github.com/user-attachments/assets/ec83e2a9-f7cc-452b-8eb7-af158284ca4e"
/>

File scan inclusions and exclusions are considered still for such
projects.
Set `file_scan_depth` to `0` to enable old behavior.
The setting is supported in the project settings, so custom values can
be set based on the project's structure.

---

Release Notes:

- Fixed Zed using a lot of memory and CPU in large, non-git-tracked,
directory trees
2026-08-13 17:07:06 +00:00
Jake Nelson 08827f9208 Add starts_open setting to terminal panel (#54373)
## Summary

- Add `terminal.starts_open` setting so the terminal panel can open
automatically in new workspaces, like project and git panels already can
- Expose the setting through terminal settings docs, default settings,
Settings Editor metadata, and the terminal panel implementation
- I also added a matching settings page item for the existing
`git_panel.start_open` setting

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behaviour
- I decided not to add tests as the behaviour seems covered by the
existing settings tests, and similar areas don't seem to have their own
explicit tests.
- [x] Performance impact has been considered and is acceptable

Related to #51542 (issue mentions possibly adding for all panels, closed
with implementation for `git_panel`)

Release Notes:

- Added `terminal.starts_open` to control whether the terminal panel
opens automatically in new workspaces
2026-08-08 18:30:33 +00:00
Evan VinciguerraandClaude Opus 4.8 35cb7558a9 editor: Add configurable git gutter width setting (#61304)
## Summary

Adds a `gutter.git_gutter_width` setting that lets users pin the width,
in pixels, of the git diff hunk indicators in the editor gutter.

Previously the width was always derived from the buffer font size
(`floor(0.275 * line_height)`), which can render too thin or too thick
depending on font family and display pixel density. This adds an
optional override:

```json
{
  "gutter": {
    "git_gutter_width": 6
  }
}
```

When the setting is unset (`null`, the default), the width continues to
scale with the buffer font size, so existing behavior is unchanged.

## Motivation

Requested in [discussion
#27799](https://github.com/zed-industries/zed/discussions/27799). Beyond
the width itself, participants noted the git hunk hit target is
extremely narrow and hard to click. Because the hunk hitbox reuses the
painted strip bounds, setting a wider `git_gutter_width` also widens the
clickable area, addressing that complaint with the same setting.

## Changes

- `settings_content`: new `git_gutter_width: Option<f32>` on
`GutterContent`.
- `editor`: mirror field on the resolved `Gutter`; `gutter_strip_width`
now consults the setting, and the value flows through `diff_hunk_bounds`
(including the deleted-hunk marker) and the gutter layout anchors for
line numbers, folds, and expand toggles.
- `settings` (VS Code import): pass through the new field.
- Docs + `default.json`: document the new setting.

## Notes

- `Eq` was dropped from `GutterContent`/`Gutter` because `f32` is not
`Eq`; this matches the existing `EditorSettingsContent` convention for
float-bearing settings.

Release Notes:

- Added a `gutter.git_gutter_width` setting to configure the width of
git diff indicators in the editor gutter

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-03 01:46:00 +00:00
Mikayla MakiandBen Kunkle 5e1fd392f6 git: Add diff_base setting for showing changes since the default branch (#61501)
# Objective

Let git indicators — the editor gutter, file colors, and `git::Diff` —
show all changes on the current branch relative to its merge base with
the default branch, instead of only uncommitted changes.

Supersedes #60398; thanks to @samuelcolvin for the original
implementation and motivation.

Closes FR-135

## Solution

- New `git.diff_base` setting (`"head"` | `"default_branch"`), applied
live and toggleable per session from the editor controls menu ("Diff
Against Default Branch").
- Statuses come from a real merge-base-to-worktree tree diff (`git diff
--merge-base`), so local edits that revert branch changes correctly show
as unchanged.
- `GitStore` shares one `DiffBufferList` per repository with the Branch
Diff view; `repo_snapshots` and `project_path_git_status` keep returning
index/worktree truth, while display surfaces use separate `display_*`
APIs.
- `BufferDiff` now records what its base is (`DiffBaseKind`); hunks
whose base isn't HEAD are read-only in the gutter — stage/restore
buttons and keybindings are inert, so committed work can't be silently
rewritten.
- `git::Diff` follows the setting; new `git::DiffHead` always opens the
HEAD diff; `git::BranchDiff` is renamed `git::DiffBranch` (deprecated
alias kept).

Tradeoffs / known limitations:

- Hunk-level staging is unavailable while in `default_branch` mode
(whole-file staging via the git panel still works). Staging just the
uncommitted sub-ranges of a branch hunk is a follow-up.
- Remote hosts running an older server ignore the new
`GetTreeDiff.includes_worktree` proto field and degrade to
committed-changes-only branch diffs.
- Repositories with no resolvable default branch fall back to
HEAD-relative behavior; a failed first resolution retries on the next
branch-list change.

## Testing

- Real-git-repo tests for the merge-base-to-worktree diff's edge cases:
files recreated after index deletion, committed deletions recreated on
disk, and symlinks.
- GPUI tests for status semantics (a branch change reverted on disk
shows clean), `git::Diff` routing, live setting changes, and read-only
hunk enforcement (restore/stage leave buffer and index untouched).

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

- Git: Added a `git.diff_base` setting (`"head"` or `"default_branch"`)
that makes the editor gutter, file colors, and diff view show all
changes on the current branch since its merge base with the default
branch, instead of only uncommitted changes.

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-07-31 19:57:13 +00:00
AvoidTheKitchenandBen Kunkle 790dcefb01 edit_prediction: Support self-hosted Sweep Next Edit models (#51139)
This adds support for running self-hosted Sweep Next Edit edit
prediction models through Zed's OpenAI-compatible provider. The target
use case is a local deployment based on
[sweepai/sweep-next-edit-1.5B](https://huggingface.co/sweepai/sweep-next-edit-1.5B),
using the rewrite-window prompting approach described in [OSS Next
Edit](https://blog.sweep.dev/posts/oss-next-edit). Personal user testing
shows impressive quality from this small edit prediction model.

This is valuable because it allows more flexibility for Zed users to
self-host state of the art next edit prediction models!

This PR addresses the self-hosted workflow discussed in
https://github.com/zed-industries/zed/discussions/50929.
Note that the self-hosted model path needed more than just a new
dropdown value. Zed has to build the rewrite-window prompt shape the
model expects, map the rewritten window back into anchored edits, and
make `prompt_format: "infer"` work with the filename-style model
identifiers that llama-server local server reports.

The main changes are:
- add a `Sweep` prompt format for OpenAI-compatible edit prediction
providers and route it to a dedicated `SweepPrompt` model path
- build Sweep rewrite-window prompts from the active cursor window,
recent change history, and related file excerpts
- convert rewrite responses back into anchored edits and suppress no-op
rewrites
- add fixed cursor-window extraction used by the Sweep rewrite prompt
path
- recognize `sweep-next-edit` model names during `infer`, including
filename-style identifiers such as
`sweepai_sweep-next-edit-1.5B_sweep-next-edit-1.5b.q8_0.v2.gguf`
- reject reserved Sweep prompt tokens before sending malformed requests
to a self-hosted server
- update the docs to describe the actual Sweep rewrite-window prompt
format

Local setup used for manual verification:

```sh
llama-server \
  --hf-repo sweepai/sweep-next-edit-1.5B \
  --hf-file sweep-next-edit-1.5b.q8_0.v2.gguf \
  --ctx-size 8192 \
  --host 127.0.0.1 \
  --port 8080
```

```json
{
  "edit_predictions": {
    "provider": "open_ai_compatible_api",
    "open_ai_compatible_api": {
      "api_url": "http://127.0.0.1:8080/v1/completions",
      "model": "sweepai_sweep-next-edit-1.5B_sweep-next-edit-1.5b.q8_0.v2.gguf",
      "prompt_format": "infer",
      "max_output_tokens": 512
    }
  }
}
```

The request that produced this PR included screenshots of the
OpenAI-compatible provider configuration and the prompt format dropdown
with `Sweep` selected.

Tests added in this branch:
- `test_sweep_prompt_format_routes_to_sweep_prompt_model`
- `test_fixed_line_window_around_cursor_start_middle_and_end`
-
`test_sweep_prompt_request_prediction_diffs_rewritten_window_into_anchored_edits`
-
`test_sweep_prompt_request_prediction_returns_none_for_identical_rewrite`
-
`test_original_window_for_current_window_uses_latest_pre_edit_snapshot`
-
`test_original_window_for_current_window_returns_none_without_matching_history`
-
`test_recent_change_block_from_event_formats_original_and_updated_sections`

Verification run locally:
- `cargo test -p zed sweep_prompt_format_routes`
- `cargo test -p zed subscribe_uses_stale_provider_config`
- `cargo test -p edit_prediction sweep_prompt`
- `cargo test -p edit_prediction
fixed_line_window_around_cursor_start_middle_and_end`
- `cargo test -p edit_prediction
test_sweep_prompt_request_prediction_diffs_rewritten_window_into_anchored_edits`
- `cargo test -p edit_prediction
test_sweep_prompt_request_prediction_returns_none_for_identical_rewrite`
- `./script/clippy -p zed -p edit_prediction -p settings_content`

Release Notes:

- Added support for self-hosted Sweep Next Edit models in
OpenAI-compatible edit predictions, including the `sweep` prompt format
and `infer` detection for `sweep-next-edit` model names.

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-07-30 18:14:58 +00:00
Kunall Banerjee 36911f8cab docs: Clarify window_decorations currently only works on Linux (#61883)
Also add the setting to our docs at https://zed.dev/docs -- it’s
currently missing. Updated a stale comment as well -- window decorations
were [always supported on
X11](https://github.com/zed-industries/zed/pull/13611)?

Closes #61788.

---

Release Notes:

- N/A
2026-07-29 21:06:03 +00:00
Julien RoncagliaandMrSubidubi 33f1112fc2 theme: Specify color format and pattern in schema (#49136)
## Purpose

While developing a theme for Zed I remarked that the schema available
doesn't mark colors in a way that Zed recognize to display the color
annotations:

```json
{
  "$schema": "https://zed.dev/schema/themes/v0.2.0.json"
}
```
<img width="119" height="190" alt="Screenshot 2026-02-25 at 23 15 10"
src="https://github.com/user-attachments/assets/3f1bb703-cb26-4630-9598-3a7cb8873c20"
/>

But Zed has support for it when colors are marked with `"format":
"color"` in the schema:

<img width="127" height="186" alt="Screenshot 2026-02-25 at 23 14 58"
src="https://github.com/user-attachments/assets/1a9387a4-613a-4cf8-a3af-f6ac201bdf54"
/>

So I searched if the schema file was Open Source somewhere, discovered
it was generated from the codebase and attempted the change.

## Implementation

This is essentially done using a `ThemeColor` wrapper for the color
strings that implements `JsonSchema` with a dedicated regex for
validation and the color format specified. This ends up with a new
`$defs` of `Color` being specified and used:

```json
{
  "$defs": {
    "Color": {
      "type": "string",
      "format": "color",
      "pattern": "^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
    }
  }
}
```

## Other

- There is a small change I made for testing to the schema_generator
that adds an `--output` / `-o` flag. When provided it writes the
generated schema JSON to the specified file path instead of printing to
stdout. This was done to made testing easier but I can remove it or
split it to a separate PR (It's already a separate commit)
- For this PR to do anything a new schema version will need to be
published at something like `https://zed.dev/schema/themes/v0.3.0.json`
and documentation needs to be updated to point to it.

Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing (Manual testing, couldn't find any existing good place to test
it)
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Release Notes:

- N/A

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-07-29 20:59:24 +00:00
12a19dccef agent: Re-enable sandbox (#61711)
Fixes the bug that made us remove the sandbox.

The bug in question was very dumb:
- there is sophisticated machinery for detecting whether a user-granted
writable path is swapped out for a symlink in the timing gap between
approval and sandbox creation
- there was no equivalent machinery to do the same for the (much larger)
gap between a user *persisting an approval* (either for the current
thread or permanently via settings)
- The fix is essentially to store canonical (i.e. absolute and
symlink-free at all depths) paths as the source of truth, but retain the
raw path for display purposes
- On WSL, there is extra care needed becasue of the bidirectional
mounting (i.e. `/mnt/c/...` and `\\wsl.localhost\Ubuntu\...`). In
particular, `/mnt/c/...` paths, since their inodes do not necessarily
pin NTFS file references, weaken the sandbox guarantees, and so we need
some extra UI to call this out and docs etc...

This also does not remove the feature flag, but just toggles it to
"enabled_for_all"

---

Release Notes:

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

---------

Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-07-29 13:03:22 +00:00
Lori HoldenandFinn Evers 1ca8f8396b Add agent panel font family settings (#59629)
Objective:

Allow users to configure the font families used by agent panel content
separately from the main UI and buffer fonts.

Solution:

- Add `agent_ui_font_family` for agent responses in the agent panel.
- Add `agent_buffer_font_family` for the agent panel message editor and
user messages.
- Keep context menus on the primary UI font family.
- Document the new settings and expose them in the settings UI.

Testing:

- Ran `cargo fmt`.
- Ran `cargo check -p settings_content -p theme_settings -p markdown -p
agent_ui -p settings_ui -p ui`.
- Ran `git diff --check`.
- Manually tested the agent panel font behavior in a dev build.

Release Notes:

- Added settings for configuring agent panel UI and buffer font
families.

Co-authored-by: Finn Evers <finn@zed.dev>
2026-07-27 10:34:57 +00:00
9a5344b9eb agent: Add agent.compaction_model setting for context compaction (#60012)
# Objective

Add a new `agent.compaction_model` setting that lets users specify a
separate language model for context compaction (`/compact` and
auto-compaction), independent of the thread's active conversation model.

Compaction is just summarization — there's no reason to pay Opus prices
for it when a cheaper model does the job faster. We've also seen
reasoning models misbehave on this task (empty responses, repetition
loops at high effort), so picking a dedicated non-reasoning model for
compaction is useful.


## Solution

- New `compaction_model: Option<LanguageModelSelection>` field in
`AgentSettingsContent` and `AgentSettings`, mirroring
`thread_summary_model`.
- New `compaction_model: Option<ConfiguredModel>` slot on
`LanguageModelRegistry` with `select_/set_/compaction_model()` trio,
mirroring the existing pattern. The setter deliberately does **not**
emit a registry event in v1; callers read the slot lazily at compaction
time.
- New `Thread::compaction_model(&self, cx: &App)` helper that returns
the configured model or falls back to `self.model()`. Two call sites —
`Thread::compact` and `perform_compaction_if_needed` — now go through
this helper instead of reading `self.model()` directly.
- `build_compaction_telemetry` accepts the compaction model explicitly
so the `model` field reflects the model that actually streamed the
request. `max_tokens` still derives from `thread.model()` (threshold
semantics are unchanged).
- Documentation updated at `docs/src/ai/agent-settings.md` (new
user-facing setting).

**Example:**

```json
{
  "agent": {
    "default_model": {
      "provider": "anthropic",
      "model": "claude-opus-4-6"
    },
    "compaction_model": {
      "provider": "anthropic",
      "model": "claude-sonnet-4-5"
    }
  }
}
```

**Resolution chain:**

```
agent.compaction_model (if set & available)
  → thread.model()  (always available, current behavior)
```

**Behavior change:**

| Trigger | Before | After |
| --- | --- | --- |
| Manual `/compact` | Uses `thread.model()` | Uses
`agent.compaction_model` if set & available; else `thread.model()` |
| Auto-compaction | Uses `thread.model()` | Same as above |
| `/compact` when thread has no model | `NoModelConfiguredError` |
Succeeds if `compaction_model` resolves |
| `compaction_model` configured but provider missing / model id unknown
| n/a | Falls back to `thread.model()` and logs a one-time warning |

**Explicit non-goals:**

- No `Event::CompactionModelChanged`(no consumer; the `_cx` parameter on
`set_compaction_model` is intentionally accepted for future use).
- No GUI selector (consistent with all other feature-specific models).
- No per-profile override.
- No runtime API-error fallback — only config-time failure (provider not
registered, model id not in `provided_models`) triggers fallback. This
matches every other feature-specific model.
- No change to threshold calculation, auto-compact trigger, or
`COMPACTION_PROMPT`.
- No propagation to subagent threads.

## Testing

3 new unit tests in `crates/agent/src/thread.rs::tests`:

- `test_compaction_uses_configured_compaction_model` — manual `/compact`
routes to the configured model; thread's primary model receives no
request; telemetry reflects the configured model.
- `test_compaction_falls_back_when_compaction_model_unavailable` —
configured-but-unresolvable falls back to `thread.model()`; telemetry
reflects the fallback model.
- `test_auto_compaction_uses_compaction_model` — auto-compaction
triggered by threshold honors the same setting.

All 14 existing compaction tests still pass. Test suites in
`crates/agent_settings`, `crates/language_model`,
`crates/settings_content`, `crates/agent_ui` unchanged. `cargo clippy`
clean on the changed crates.

**How reviewers can test:**

1. Add `agent.compaction_model` to `settings.json` with a cheaper model
than the thread's primary model, run `/compact`, observe the cheaper
model receives the request.
2. Set `agent.compaction_model` to a non-existent provider/model id, run
`/compact`, observe fallback to thread model and a `log::warn!` line.
3. Trigger auto-compaction by reaching the threshold, observe it uses
`compaction_model`.

**Platforms tested:** local Linux (cargo check + cargo test on agent /
agent_settings / language_model / settings_content / agent_ui crates).

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — no `unsafe`
blocks introduced
- [x] The content adheres to Zed's UI standards — N/A: settings-only
change, no UI touched
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable — model
resolution is an O(1) registry lookup, not on any hot path; no new work
in the streaming loop


Release Notes:

- agent: Add support for specifying which model is used for compaction
(`agent.compaction_model`)

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
2026-07-24 12:48:58 +00:00
Kirill Bulatov 8276687148 Use proper rules for merging language server settings (#61546)
Closes https://github.com/zed-industries/zed/issues/61524

https://github.com/zed-industries/zed/issues/60763 was a bogus issue:
the semantic of root `language_settings` is the **default settings for
all languages**, not a "magic string that gets applied when an `!x`
exclusion is mentioned there".

Thus, reverts https://github.com/zed-industries/zed/pull/60984 and
redoes https://github.com/zed-industries/zed/pull/60000 in a correct
way: more custom settings replace less custom ones, same applies to the
language server settings.
Instead of doing some odd `!x` manipulations, the right fix is to remove
the old state as

```diff
 impl merge_from::MergeFrom for AllLanguageSettingsContent {
     fn merge_from(&mut self, other: &Self) {
         ...
         self.defaults.merge_from(&other.defaults);
         for language_settings in self.languages.0.values_mut() {
+            let language_servers = language_settings.language_servers.take();
             language_settings.merge_from(&other.defaults);
+            language_settings.language_servers = language_servers;
         }

         for (language_name, user_language_settings) in &other.languages.0 {
             if let Some(existing) = self.languages.0.get_mut(language_name) {
                 existing.merge_from(&user_language_settings);
             } else {
                 let mut new_settings = self.defaults.clone();
+                new_settings.language_servers = None;
                 new_settings.merge_from(&user_language_settings);
```

After the final override is determined, `...` is expanded and `!x`
entries are removed from the final list.

Project settings override user settings, so it's possible that a certain
language server is disabled by the user and re-enabled in the project:
worktree trust mechanism is supposed to mitigate the security issues.

More tests were added to cover all the cases.

Release Notes:

- Fixed project settings not re-enabling language servers
2026-07-24 08:32:03 +00:00
Kirill Bulatov 8c7811ea72 Split VSCode and Zed keymap files (#61532)
Currently, Zed's "VSCode" keymap has certain discrepancies that are not
changed for compatibility reasons, e.g. opening inline assistant is
different in each editor.

To simplify the transition, extract VSCode bindings its own keymap so in
the future it's simpler to accept changes to each keymap separately.

Caveat: people who had ever changed the keymap, will have VSCode keymap
in their settings which will change their bindings slightly after this
commit is released.

I had to introduce more logic to `null` handling as had to somehow
disable `ctrl-enter` on mac from spawning the inline assistant block for
VSCode keymap (it's cmd-i there).

Release Notes:

- Split VSCode and Zed keymap files
2026-07-24 07:54:03 +00:00
Ibrahim KhanandChristopher Biscardi d47347d1aa settings: Fix VS Code import appending duplicate file associations (#61355)
Closes #56536

## What & why

Running `zed: import vs code settings` more than once kept re-adding the
same file extensions to `file_types`, so `files.associations` entries
grew without bound:

```json
"file_types": { "c": ["*.keymap", "*.keymap", "*.keymap"] }
```

The import merges the VS Code-derived settings into the user's existing
settings, and `file_types` values were `ExtendingVec`s, whose
`merge_from` appends every incoming value unconditionally.

Per review feedback, instead of changing `ExtendingVec`'s merge
semantics (it also backs ssh/wsl connections, `private_files`, etc.),
this adds a new `ExtendingSet` type that actually behaves like a set,
and switches `FileTypeMap`'s file associations to it:

- Backed by an insertion-order-preserving `IndexSet`, so users' pattern
order round-trips through the settings file unchanged (the import
machinery diffs serialized old/new content to produce edits; a sorted
set would reorder existing arrays).
- Merging only accumulates new values, so re-importing an
already-present association is a no-op.
- Since it's a real set, deserialization also collapses duplicates that
earlier imports already wrote into the settings file.
- `ExtendingVec` and all its other users are untouched.

## Testing

- Added a `test_vscode_import` case that re-imports an already-present
`files.associations` entry and asserts the extension isn't duplicated.
It fails before the change and passes after.
- `cargo test -p settings -p settings_content -p language` pass.
- `./script/clippy -p settings -p settings_content -p language -p
recent_projects -p json_schema_store` is clean.

Release Notes:

- Fixed importing VS Code settings repeatedly adding duplicate
`file_types` entries for `files.associations`.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-07-24 00:54:58 +00:00
Finn Evers c4c55bade4 Add wrapper type for language servers in settings (#61398)
This is in preparation for making configuration of language servers more
comfortable for users/extensions.

Release Notes:

- N/A
2026-07-22 21:48:46 +00:00
Lukas Wirth 54c5db8346 Disable LSP for files with very long lines (#61447)
Release Notes:

- Fixed ui stutters when opening large single line files like minified
javascript due to running LSP requests against them
2026-07-22 13:25:49 +00:00
saberoueslatiandKirill Bulatov e80cdd2ff7 Autocomplete language names in file_types setting (#58595)
## Context

Closes #58571

When editing `settings.json`, typing a new key under `languages`
triggers language-name autocomplete. The same did not work for
`file_types`, even though both keys map language names to configuration.

The root cause: the JSON schema generator uses `replace_subschema` to
inject installed language names as the allowed properties of a named
type. The `languages` field backed by `LanguageToSettingsMap` (a named
newtype) got this treatment; `file_types` was backed by a raw
`HashMap<Arc<str>, ExtendingVec<String>>` with no named type to target.

The fix introduces a `FileTypeMap` newtype parallel to
`LanguageToSettingsMap` and wires it into the same schema-injection
path.

Video of manual test below :

[Screencast from 2026-06-05
00-04-16.webm](https://github.com/user-attachments/assets/5d8afb60-d566-4c99-ad2a-66ebbb47ed2e)

## How to Review

- `crates/settings_content/src/language.rs` : Adds
`FileTypeMap(HashMap<Arc<str>, ExtendingVec<String>>)` with the full set
of derives (`Debug`, `Clone`, `Default`, `PartialEq`, `Serialize`,
`Deserialize`, `JsonSchema`, `MergeFrom`) and an `IntoIterator for
&FileTypeMap` impl so existing call sites
(`all_languages.file_types.iter().flatten()`) continue to work without
changes. Changes the `file_types` field in `AllLanguageSettingsContent`
from the raw HashMap to `Option<FileTypeMap>`.

- `crates/settings/src/settings_store.rs` : In
`configure_schema_generator`, adds a `replace_subschema::<FileTypeMap>`
call mirroring the existing `LanguageToSettingsMap` one: injects
installed language names as the allowed properties, with
`ExtendingVec<String>` (array of glob patterns) as the value schema.
Adds `test_file_types_schema_generation` to verify the injected
properties.

- `crates/settings/src/vscode_import.rs` : Updates `file_types()` to
return `Option<FileTypeMap>` and wraps the constructed map accordingly.

- `crates/language/src/buffer_tests.rs` : Updates the existing custom
`file_types` test setup to extend the inner map of the new `FileTypeMap`
wrapper explicitly, keeping the language crate test build passing after
the type change.

## 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 language name autocomplete not working in the `file_types`
setting

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-07-21 11:01:05 +00:00