e8041ccebbd4679bd2a0366eabde8707cbdaba66
3332
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
aec7395e30 |
Fix cargo shear warnings (#64340)
Also updates CI to always run this - that way we ensure that disabling or enabling tests does not become stale at some point and thus can safely add this. Release Notes: - N/A - [GPUI] N/A |
||
|
|
67ebcd9517 |
Fix insertion modes for completions without edit ranges (#64139)
Closes https://github.com/zed-industries/zed/issues/64118 https://github.com/user-attachments/assets/f2152411-6011-4d87-8c8e-d83bed0afbbc `ty` returns completion text without a `textEdit` or a completion-list default edit range: ```json {"label":"value2=","insertText":"value2="} ``` The [LSP specification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionItem) explicitly states: > The `insertText` is subject to interpretation by the client side. For the reported example, `ˇ` marks the cursor: ```py test(value1, ˇvalue2) ``` Previously, Zed inferred only a range covering the existing `value2`. Without an insert range, completion acceptance bypassed `completions.lsp_insert_mode` and replaced that argument with `value2=`, producing: ```py test(value1, value2=) ``` The patch also infers an insert range, ending at the cursor rather than the end of the word. This lets the existing setting choose between inserting before `value2` and replacing it. When a prefix has already been typed, insertion replaces that prefix while preserving the text after the cursor. With the unchanged default, `"replace_suffix"`, Zed replaces text after the cursor only when it is a suffix of the completion’s label. Here, `value2` is not a suffix of `value2=`, so Zed inserts and produces: ```py test(value1, value2=value2) ``` The suffix and subsequence checks now use the raw LSP `label`, not decorated menu text or `filterText`. These checks select the edit range; `insertText` still supplies the inserted text in this example. Release Notes: - Fixed insertion modes for completions without edit ranges |
||
|
|
7cda6f0523 |
acp: Add agent license if available from the registry (#64178)
The JetBrains team started added links to the relevant license terms for each agent. Seems worth linking out to if we have it. Release Notes: - N/A |
||
|
|
1c3d902fbf |
Fix diagnostics batches stopping at paths without a worktree (#64017)
Closes https://github.com/zed-industries/zed/issues/62303 Based on the amazing find in https://github.com/zed-industries/zed/issues/62303#issuecomment-5553387960 Release Notes: - Fixed diagnostics batches stopping at paths without a worktree |
||
|
|
290cbcb9cb |
buffer_store: Fix path_to_buffer_id never update when move action occurs in remote mode (#64005)
# Objective Fix an issue in SSH remote mode where reopening a newly created file at a path that was previously renamed could incorrectly reuse the buffer for the renamed file. ## Solution When handling UpdateBufferFile, remove the buffer's previous path from path_to_buffer_id when the file path changes. ## Testing Tested manually on Linux using SSH remote mode. Reproduction before the fix: touch A Open A from the project panel mv A B touch A Open the new A from the project panel Before the fix, opening A reused the buffer for B. After the fix: B continues to use the original buffer. The recreated A opens as a separate buffer. Renaming an opened remote file still updates the existing buffer to the new path correctly. ## 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 an issue in SSH remote mode where reopening a newly created file at a path that was previously renamed could incorrectly reuse the buffer for the renamed file. --------- Signed-off-by: xiaoff <xiaoff0019@outlook.com> Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
52b2927a1b |
Normalize CRLF line breaks in completion labels too (#63920)
Part of https://github.com/zed-industries/zed/issues/63273#issuecomment-5562451827 https://github.com/user-attachments/assets/ecaa1bd0-672b-4323-a67e-e1a7e3c428fb Release Notes: - Fixed CRLF line breaks not normalized in completion labels |
||
|
|
284c72404a |
lsp: Handle dynamic registration of textDocument/documentHighlight (#63029)
Zed did not advertise document highlight dynamic registration support or handle `textDocument/documentHighlight` registrations. Dynamically registered providers therefore fell through to the unhandled-capability path, while servers with a fallback had to advertise a static provider for every attached document. Advertise dynamic registration support and track document highlight registrations and unregistrations alongside the other selector-aware dynamic text document capabilities. Refresh editors whenever the effective document highlight registration state changes, including selector-only changes that leave the merged provider unchanged, so runtime registrations take effect immediately and unregistrations clear stale or in-flight highlights. Add coverage for the client capability, registration lifecycle with multiple selectors sharing identical provider options, and editor refresh behavior when an applicable selector is added or removed. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed’s UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - N/A --------- Co-authored-by: GPT-5.6 Sol <noreply@openai.com> Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
002161d5ba |
Support commands in inlay hints (#63605)
Closes https://github.com/zed-industries/zed/discussions/51582 During testing, spotted that if I toggle off the hints with the modifier keys, they are resurrected on scrolling — fixed that in a small commit on top. Release Notes: - Supported commands in inlay hints |
||
|
|
0690433b60 |
Support LSP command executions and showDocument requests (#63607)
Closes https://github.com/zed-industries/zed/issues/13756 Closes https://github.com/zed-industries/zed/issues/61572 Last window client capability we were missing! <img width="1557" height="159" alt="image" src="https://github.com/user-attachments/assets/2cca5d92-a28e-4262-8f55-89f582782bbc" /> Two features are connected to each other, as most of the commands result in opening a document: https://github.com/user-attachments/assets/661aae88-7af9-4173-9f6a-2fd11dbec675 Release Notes: - Added support for LSP command executions and showDocument requests |
||
|
|
10676bad1d |
project: Stop sharing private files through project search (#63860)
# Objective Files matching the `private_files` setting are meant not to be shared with collaborators. That is true when a guest asks to open one directly, `respond_to_open_buffer_request` refuses with `ErrorCode::UnsharedItem`. Project search reaches the same `create_buffer_for_peer` without passing through that check. In `handle_search_candidate_buffers`, every matching buffer was shared with the requesting peer unconditionally, so a guest searching for a string that happens to appear in a private file received the buffer containing it. ## Solution Check `is_private` before sharing a matched buffer with a peer ## Testing added new test `test_project_search_excludes_private_files` in the collab integration suite:" The host configures `private_files: ["**/.env"]` and has two files `.env` containing `API_KEY=secret` and `a.txt` containing `the secret is out`. The guest joins the shared project and searches for `secret`. --- Release Notes: - Fixed private files being shared with collaborators through project search. |
||
|
|
490aad88d5 |
debugger: Copy full variable value instead of trimmed preview (#63902)
# Objective Fixes #63869 — "Copy Value" in the debugger panel copied the trimmed display preview instead of the full value. ## Solution Evaluate the variable's `evaluateName` via the DAP `evaluate` request using the `clipboard` context (falling back to `variables`), and copy the returned result. Falls back to the display value if evaluation fails. ## Testing - `cargo test -p debugger_ui --lib` passes. --- Release Notes: - Fixed debugger "Copy Value" copying the truncated preview instead of the full value. |
||
|
|
db10a8dd73 |
fs: Refactor the code around GlobalWatcher to be more testable (#63894)
This is a pure refactoring PR to make our FS watching code more testable. It does two things: 1. Make the `GlobalWatcher` be owned by `RealFs` or `FakeFs` instead of being a process-wide global. 2. Delete `FakeWatcher` and its `Watcher` implementation, and instead mock the notify crate itself in `FakeFs` tests via the existing `WatchBackend` trait. Now all our FS watching code down to the notify boundary runs the same in tests and production. Release Notes: - N/A |
||
|
|
22e9216896 |
Allow concurrent peer LSP requests via collab (#63736)
Before this change, two different guests requesting the same kind of request would cancel each other's requests and only the latest one would have arrived to the latest to query that. Release Notes: - Fixed collab LSP requests cancelling each other sometimes |
||
|
|
3569541038 |
Stop canonicalizing LSP locations before worktree lookup (#63754)
Closes https://github.com/zed-industries/zed/pull/61392#issuecomment-5538772188 Follow-up to https://github.com/zed-industries/zed/pull/61392 https://github.com/user-attachments/assets/6c745474-6b6e-4cfa-b1b6-87e9631973bf Not every language server wants to deal with the canonicalized paths, some (e.g. gopls) can resolve them themselves, and keep sending symlinked paths over the LSP — canonicalizing them means we will break out of the current worktree and open odd singleton files instead. Release Notes: - Fixed goToDefinition opening out-of-worktree entries |
||
|
|
23aca9895c |
lsp: Honor dynamic LSP document selectors (#59243)
Zed previously discarded the documentSelector from dynamically registered textDocument capabilities and treated those capabilities as applicable to every buffer attached to the server. This could route requests for documents outside a registration selector. Track dynamic textDocument registrations by method and registration ID, and use their selectors when routing local requests, checking capabilities, and deriving completion triggers. Static capabilities continue to apply to every attached buffer. Language and URI scheme matching are supported, while unsupported pattern matching remains fail-open. Keep document color, symbol, link, code lens, and folding range caches aligned with the selector-aware server set so incapable or non-matching servers do not leave caches perpetually incomplete. Require an advertised diagnostic provider before sending pull diagnostic requests, and add integration coverage for selector-aware dynamic completion registration and trigger updates. --- Release Notes: - Improved language server request routing to respect dynamically registered document selectors. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
ab7d21d444 |
Fix workspace diagnostics polling (#63336)
Closes https://github.com/zed-industries/zed/issues/62391 Workspace diagnostics were polled incorrectly: * Workspace pulls were cancelled and re-sent every 120s. Pyright-family servers hold the request open forever and re-analyze the whole workspace on every new one, so the retry loop leaked memory; the request is now kept open (long-poll), as the spec recommends. * No re-trigger after a server closed a workspace pull. ty closes the request when diagnostics change and expects the client to re-pull * `ServerCancelled` / `retriggerRequest` was ignored. The spec defaults cancellation data to `{ retriggerRequest: true }`, so these errors now retrigger workspace pulls and retry document pulls instead of failing them. * LSP error codes were erased with `anyhow!(message)` Errors now carry a typed `lsp::ResponseError` through the chain, replacing four copies of `ends_with(...)` matching against rust-analyzer's literal message texts. * Workspace partial results were not tied to their request. Stale or numeric-token `$/progress` reports were applied as current data and could poison `previousResultIds` until a server restart; reports are now matched against the exact in-flight token. * `interFileDependencies` was never read. Every edit re-pulled all other open buffers even for servers declaring no inter-file dependencies (e.g. ruff); cross-buffer pulls are now gated on that capability. * Cross-buffer pulls were unpaced. All open buffers were pulled back-to-back after each edit debounce; they are now paced at one document per 500ms. * The failure valve killed workspace pulls permanently. 51 hard errors over a server's lifetime silently stopped its workspace pulls until restart * Concurrent refresh waiters could be dropped instantly. The capacity-1 refresh channel resolved a second concurrent waiter to `false` immediately, and request errors dropped queued refreshes; waiters now queue and carry over to the retried pull. Release Notes: - Fixed basedpyright memory leak caused by incorrect workspace diagnostics polling |
||
|
|
f8000a30f9 |
Properly clear diagnostics data for stopped servers (#63460)
# Objective Diagnostics published by a language server survive the buffer being detached from that server, so a file keeps showing errors from a server that is no longer reading it. To reproduce: 1. Install the [GitHub Actions extension](https://zed.dev/extensions/github-actions). 2. Open a composite action definition, `.github/actions/<name>/action.yml`. 3. Select the GitHub Actions language for it in the language selector. That server validates the file as a workflow, so it reports `on` and `jobs` as missing and `inputs`, `outputs` and `runs` as unexpected. 4. Select YAML again, since GitHub Actions was not what you wanted here. 5. The errors are still there. `editor: restart language servers` does not clear them either. They go away only once the buffer is dropped, in practice by switching to another project and back. Two things keep them alive: - `LocalLspStore::unregister_buffer_from_language_servers` drops the snapshot bookkeeping and sends `didClose`, but never clears what that server already published. `LspStore::set_language_for_buffer` calls it, so a language change detaches the buffer while leaving the old verdict on it. - Restarting does not reach the server either. `stop_local_language_servers_for_buffers` collects servers through `language_server_ids_for_buffer`, evaluated against the language the buffer has *now*. The old server no longer matches, so it is never stopped, and it is typically still running legitimately for other files in the project. Only `stop_local_language_server` clears diagnostics, and it is never reached for that server. ## Solution The first commit cleared the detached server's diagnostics inside `unregister_buffer_from_language_servers`, on `didClose`. Review pointed out that publishes are applied by path regardless of registration, so a running server can legitimately describe a file that is no longer open in it, and that this clearing also left `diagnostic_summaries` and the worktree's per-path diagnostics stale. The second commit reworks this. Detaching a buffer now only drops the buffer's entry in `buffers_opened_in_servers` and the path's pull-diagnostics result ids for the servers it left, two pieces of per-server state that previously leaked. After the buffer is registered with the servers of its new language, the server tree is rebuilt through `refresh_server_tree`, the same pruning that runs on settings changes: every server no registered buffer maps to any more is stopped through `stop_local_language_server`, whose path already clears buffer diagnostic sets, `diagnostic_summaries` and worktree diagnostics. A detached server that other buffers still map to keeps running and keeps everything it published. An earlier revision judged orphanhood by `buffers_opened_in_servers`, which is only filled in once a server runs, so it stopped servers that were still starting; `test_context_completion_provider_mentions` caught that. ## Testing Added `test_selecting_a_language_clears_the_old_servers_diagnostics`: a Rust buffer gets a diagnostic from a fake server, the buffer is switched to JavaScript, and afterwards both the buffer's diagnostics and the project-level `diagnostic_summary` must be empty. It fails on `main`, where the message survives the switch: ```text < ["unused constant"] > [] ``` The test passes with the rework and fails without it. The `project` test suite, `script/clippy` and style checks ran green on the reworked change in CI. Tested on Linux; the change is platform independent. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase The buffer is back on YAML, as the status bar shows, while the workflow schema's complaints from the GitHub Actions server are still on screen: `on` and `jobs` reported missing, and `inputs`, `outputs` and `runs` reported as unexpected values. <img width="2514" height="2008" alt="Screenshot From 2026-08-30 21-52-12" src="https://github.com/user-attachments/assets/040898a6-cc61-41b6-88c6-f346666e8e13" /> --- Release Notes: - Fixed diagnostics from the previous language server staying on a file after changing its language. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
60bf47b9f2 |
lsp: Scope logs and status updates to their projects (#61221)
The language registry and LSP log store are shared by every workspace in a Zed process. The LSP Logs selector enumerated the shared log store without filtering by project, while each activity indicator consumed global binary status updates. This exposed servers from other windows as "Unknown worktree" entries and surfaced their startup failures or timeouts in unrelated status bars. Key each logged server by its owning project or LSP store together with its process-local language server ID. Use that identity consistently when adding, removing, streaming, selecting, opening, and reselecting log entries so local, remote, SSH, and supplementary servers cannot collide across ownership domains. Model Copilot and other servers outside the project LSP store as project-scoped supplementary servers, while matching SSH servers by their owning LSP store. Tag project-originated binary status updates with the owning LSP store entity ID. Carry that source through extension worktree delegates and every worktree-based WASM language-server call, then let each local LSP store forward only statuses for its project. Activity indicators rely solely on their project LSP store, and remote projects continue to receive host statuses through the existing protocol path instead of subscribing to local registry events. Own each binary-status subscription task in its local LSP store and unregister its broadcaster sender when the store is dropped, so closing windows cannot leave detached status tasks or stale senders behind. Add regression coverage for duplicate process-local server IDs across ownership domains, filtering remote, supplementary, and SSH servers from other projects, retaining servers owned by the current project or LSP store, preserving extension status sources, and unregistering dropped status subscriptions. Release Notes: - Fixed language servers from other projects appearing in the LSP Logs view and their statuses showing in unrelated windows' status bars |
||
|
|
769d0befa7 |
Support Emmet's wrap with abbreviation (#63383)
Closes https://github.com/zed-industries/zed/issues/15588 https://github.com/user-attachments/assets/2813d235-6dac-4fe6-9ae0-2783e16270ac Release Notes: - Added Emmet's wrap with abbreviation support |
||
|
|
229450844d |
git: Move diff hunk operations onto buffer diffs (#63556)
# Objective Keep Git-specific diff-base knowledge in `GitStore`, where Git operations are defined. Related to FR-135. ## Solution Give each `BufferDiff` its supported hunk operations. Keep editor hooks limited to rendering custom controls. ## 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 |
||
|
|
24254879b7 |
Stop re-resolving editorconfig sections on every language settings lookup (#63323)
Closes https://github.com/zed-industries/zed/issues/59689
Symbolicating the reporter's profile (21s of typing, Windows) showed
`Window::draw` taking 63% of the main thread at ~62 redraws/s (p95 draw
= 40ms), and 30.9% of the *entire* main thread inside
`EditorconfigStore::properties()`:
every `LanguageSettings` lookup — several per frame via
`DisplayMap::tab_size`, `MultiBuffer::language_settings`, indent guides,
and `LspStore::supports_range_formatting` — re-ran the full editorconfig
resolution (ancestor walk plus `ec4rs::Section::apply_to` over every key
of every section) and then cloned the whole `LanguageSettings` struct.
Real-world `.editorconfig` files carry hundreds of irrelevant keys
(`dotnet_*`, `ij_*`, ...), so the per-call map assembly dominated:
`RtlAllocateHeap` 7.3%, `memcmp` 7.0%, `memcpy` 6.6%,
`Properties::find_idx` 5.9% self time.
## Commit 1: resolve only the editorconfig properties Zed reads
- `EditorconfigStore::properties()` now applies only the 7 keys Zed
consumes (`indent_style`, `indent_size`, `tab_width`, `end_of_line`,
`max_line_length`, `insert_final_newline`, `trim_trailing_whitespace`)
instead of materializing every key of every matching section.
- Worktrees with no editorconfig at all now return `None` early instead
of allocating an empty `Properties` and forcing a `LanguageSettings`
clone on every lookup.
- Adds an `editor_render_with_editorconfig` benchmark: maximized window,
file-backed buffer at `src/app/components/editor_pane.ts`, a root
`.editorconfig` shaped after [the second
report](https://github.com/zed-industries/zed/issues/59689#issuecomment-5475124891)
(no `root = true`, a `[*]` section with ~3200 keys, 25 sections with
large `{...}` alternation lists) plus a 4-level nested chain, and a
typing workload (insert/delete + cursor moves).
```
main (
|
||
|
|
9a76a39d7d |
project: Underline diagnostics reported past the end of a line (#63125)
Closes #22473. Some language servers report a syntax error whose range starts at the end of one line and ends at the start of the next — e.g. Pyright/ruff/ty/pyrefly on a Python function missing its trailing `:`: ``` range: { start: { line: 0, character: 11 }, end: { line: 1, character: 0 } } ``` That range spans nothing but the line terminator, so there's no glyph left for the editor to underline. The diagnostic is real (it shows up in the status bar and the diagnostics panel) but never gets a visible squiggle in the buffer, which makes it very easy to miss — especially since a missing `:` is one of the most common Python typos. ## Fix `update_buffer_diagnostics` already collapses *empty* ranges onto an adjacent character. This adds a sibling case for ranges that are exactly `line_start..next_line_start` (i.e. cover only the terminator): they're pulled back onto the last character of the line they actually concern, the same way empty ranges are. Ranges are only touched when the end position is precisely the start of the next line, so genuinely multi-line diagnostics that happen to *start* at an end-of-line position are left untouched. ## Testing Added `test_diagnostic_range_spanning_line_terminator` in `project_tests.rs`, modeled on the neighboring `test_empty_diagnostic_ranges`, asserting the closing `)` of `def main()` gets the error highlight instead of the range being invisible. Verified against real language servers: reproduced the exact same `start..next_line_start` range on ruff 0.16.4, ty 0.0.74, and pyrefly 1.2.0 for a missing `:`, matching the LSP trace pyright produced in #22473. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Release Notes: - Fixed diagnostics not being underlined when their range covers only a line terminator (e.g. a missing `:` in Python) --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Kirill Bulatov <kirill@zed.dev> Co-authored-by: Kirill Bulatov <mail4score@gmail.com> |
||
|
|
a61e2609c1 |
Normalize ranges returned by language servers in more cases (#63372)
Previously, we'd panic when constructing multibuffer excerpts in response to "find all references" if a language server returned a reversed range. This PR makes it so we normalize those ranges using the existing `range_from_lsp` helper before passing them to `set_excerpts_for_path`. It also replaces several other places where we were calling `point_from_lsp` on each endpoint of a range separately with `range_from_lsp`. Closes ZED-79W Co-authored-by: Mikayla <mikayla@zed.dev> Release Notes: - Fixed a crash with some languages servers when handling `editor::FindAllReferences`. |
||
|
|
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> |
||
|
|
8ee36b682c |
git_ui_core: Fix worktree creation for bare repositories (#63351)
Follow-up https://github.com/zed-industries/zed/pull/55153 Fixes https://github.com/zed-industries/zed/discussions/54553#discussioncomment-17091833 When a repository stores its Git data in `~/work/zed/.bare`, creating a linked worktree from Zed is broken in two visible ways: - Zed creates `random-code` at: ``` ~/work/worktrees/.bare/random-code/.bare ``` instead of: ``` ~/work/worktrees/zed/random-code/zed ``` - Because the checkout ends in `.bare`, Zed displays `.bare` as its worktree name in the title bar, worktree picker, and agent thread sidebar. Every worktree Zed creates from that repository gets the same `.bare` label instead of its generated name. This problem is specific to the path Zed creates. Worktrees using either of these layouts are not malformed: ``` ~/work/worktrees/zed/random-code/zed ~/work/zed/some-worktree ``` https://github.com/zed-industries/zed/pull/55153 introduced repository identities for bare repositories. This PR uses that identity in the remaining worktree naming and creation paths. There are three repository layouts to account for: - In a normal repository, the common Git directory is `~/work/zed/.git`, so Zed derives the main worktree at `~/work/zed`. Existing behavior remains unchanged. - With `~/work/zed/.bare`, Git has no main worktree. A checkout named main is still a linked worktree. Zed now treats `~/work/zed` as the repository identity, creates new worktrees under `~/work/worktrees/zed`, and displays their generated names. - With a bare repository named `~/work/foo.git`, `foo.git` is the repository identity. Its worktree path remains `~/work/worktrees/foo.git/random-code/foo.git`. Zed uses foo.git to derive the worktree name random-code, while displaying the repository itself as foo. Existing malformed worktrees such as `~/work/worktrees/.bare/random-code/.bare` are not moved and may continue to display `.bare`. Broken: <p> <img width="238" height="58" alt="image" src="https://github.com/user-attachments/assets/1504e4d0-c34a-471f-8e76-c5ec062b1d77" /> </p> <p> <img width="274" height="49" alt="image" src="https://github.com/user-attachments/assets/13266ca9-4e64-426c-b03c-e23c924a3597" /> </p> <p> <img width="574" height="85" alt="image" src="https://github.com/user-attachments/assets/0fca58c7-5be7-4d36-9067-066d0b80caf8" /> </p> Release Notes: - Fixed linked worktree names and creation paths for bare Git repositories. |
||
|
|
797e5dc95c |
editor: Auto-refresh Bookmarks tab when bookmarks change (#56363)
[## Context Fixes a bug where the Bookmarks tab, opened via `editor: view bookmarks`, showed a stale snapshot and had to be reopened to display bookmarks added or removed while it was open. Closes #56268 `view_bookmarks` built a one-time multibuffer and never subscribed to `BookmarkStore`. The store also calls `cx.notify()` while resolving serialized bookmarks into anchors, even though that bookkeeping does not represent a user-visible bookmark change. Observing all notifications would therefore feed resolution notifications back into the refresh mechanism and cause redundant cancellation and requeue work. The store now emits a dedicated `BookmarkStoreEvent::BookmarksChanged` from bookmark mutation paths, while `resolve_all` deliberately does not emit it. Refresh state lives on a `BookmarksView` entity that holds the tab's multibuffer. Split editors already share that multibuffer, so they share the view as well. Each store event drives one reconciliation regardless of how many split editors display it. The view remains alive as long as any split retains it, so closing the original tab does not stop the remaining split from refreshing. Each refresh reconciles excerpts per path instead of rebuilding the multibuffer: `set_excerpts_for_path` updates files that still contain bookmarks, while `remove_excerpts` removes files whose final bookmark was deleted. This follows the per-path reconciliation pattern used by project diff views. `view_bookmarks` creates the tab synchronously and populates it asynchronously, following the existing patterns in `ProjectDiagnosticsEditor::deploy` and `ProjectSearchView::existing_or_new_search`. Repeated invocations focus the existing Bookmarks tab instead of opening duplicates. Video of the manual test: [Screencast from 2026-05-11 02-03-38.webm](https://github.com/user-attachments/assets/8ac97245-09ff-4a79-9634-20cb8dfbb7eb) ## How to Review **`crates/project/src/bookmark_store.rs`** Adds `BookmarkStoreEvent::BookmarksChanged`, emitted from bookmark mutation paths such as toggle, label edit, file rename or deletion, clear, and deserialization, but not from anchor resolution. It also adds `BookmarkStore::is_empty`. **`crates/editor/src/bookmarks.rs`** Adds `BookmarksView`, which holds the multibuffer, store subscription, and in-flight refresh task. It reconciles excerpts and emits `BookmarksViewEvent::Populated(ranges)` for per-editor highlights and cursor placement. It also caches the latest populated ranges and replays them when an editor attaches, allowing a split created after population to display bookmark highlights immediately. **`crates/editor/src/editor.rs`** Adds the shared `bookmark_view`, a per-editor subscription to its population events, and `bookmark_initial_selection_pending` for initial cursor placement. `Editor::clone` attaches the split to the shared view instead of creating another store subscription and refresh task. **`crates/editor/src/editor_tests.rs`** Adds five tests covering automatic addition and removal across multiple files, removal of a file's path after its final bookmark is deleted, initial cursor placement, a bookmark change racing initial population, splitting while population is pending, cached highlights in a late-attaching split, and continued refreshing after the original tab releases its view handle. ## Self-Review Checklist - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the UI/UX checklist - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed Bookmarks tab not updating when bookmarks are added or removed while the tab is open](https://github.com/zed-industries/zed/pull/56363) --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
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> |
||
|
|
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> |
||
|
|
12ef40c316 |
lsp: Add client support for LSP 3.18 markdown diagnostic messages (#61030)
LSP 3.18 allows servers to send [`MarkupContent` diagnostic messages](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#diagnostic), guarded by the client capability `textDocument.diagnostic.markupMessageSupport`. - Advertise `markup_message_support` only while pull diagnostics are enabled because `textDocument.diagnostic` is the pull-model capability. LSP 3.18 currently has no equivalent capability for push diagnostics: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#diagnosticClientCapabilities https://github.com/microsoft/language-server-protocol/issues/2246 - Handle `string | MarkupContent` messages in both push and pull diagnostic paths: markdown-kind messages populate the existing `Diagnostic::markdown` field (rendered in hover popovers and the diagnostics panel), plaintext-kind markup remains plain text, and plain string messages keep going through the adapter's `diagnostic_message_to_markdown`. - Preserve server-provided markup for code actions sent back to the originating server, avoid forwarding markup diagnostics to other servers, and render diagnostic metadata without altering the server-provided markdown. - Carry the markup kind over RPC via a new optional `LspDiagnostic.markup_message_kind` proto field so remote/collab projects round-trip `MarkupContent` messages. Depends on the lsp-types change that turns `Diagnostic.message` into a `DiagnosticMessage` enum (`string | MarkupContent`): https://github.com/zed-industries/lsp-types/pull/15 Once merged, Cargo.toml can point to the upstream commit. Note that Zed already rendered some plain-string diagnostics as Markdown through language-specific adapter hooks, including `rust-analyzer`. This adds protocol-level support for diagnostics explicitly sent as LSP 3.18 `MarkupContent`, while preserving the existing adapter fallbacks. As a result, this does not introduce a new diagnostics rendering pipeline. Server-provided Markdown is routed through the existing `Diagnostic::markdown` path, with small fixes to handle Markdown-only updates and block content correctly. ## Showcase Example from [JETLS.jl](github.com/aviatesk/JETLS.jl) (a Julia language server): > Before <img width="924" height="160" alt="Screenshot 2026-07-15 at 16 05 40" src="https://github.com/user-attachments/assets/b19fe9e3-50e3-44e4-9b4d-ac8bd438d3d6" /> > After <img width="924" height="160" alt="Screenshot 2026-07-15 at 14 13 05" src="https://github.com/user-attachments/assets/359c3382-118d-4fa6-aa91-6bd3661d3d28" /> --- Release Notes: - Added support for rendering LSP 3.18 Markdown diagnostic messages from language servers. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Kirill Bulatov <mail4score@gmail.com> |
||
|
|
fe5b7cedc4 |
Remove wasted clones of loop-invariant values (#62763)
# Objective Remove avoidable clones of loop-invariant values that pay a copy on every loop iteration. These were found by running a prototype `deep_clone_in_loop` dylint (modeled on the accidentally quadratic project-search fix in #62658) across the workspace. None of these sites are quadratic in practice — the loops are bounded — but each one does strictly wasted work that a one-line change removes. ## Solution - `collab/src/api/extensions.rs`: use `next_marker.take()` instead of `next_marker.clone()` for the S3 pagination marker. The marker is either overwritten via `clone_from` at the end of the iteration or the loop breaks, so it is never read after the `take`. - `project/src/manifest_tree/path_trie.rs`: build the trie key with `Arc::from(path_so_far.as_rel_path())` instead of `path_so_far.clone().into()`. The `From<RelPathBuf> for Arc<RelPath>` impl copies the bytes into the `Arc` anyway, so the intermediate `RelPathBuf` clone was a second, redundant copy. - `context_server/src/client.rs`: in `notify`, split off the last handler and move the `serde_json::Value` payload into it, cloning only for the preceding handlers. Previously every handler received a clone and the final one was always wasted. - `editor/src/rewrap.rs`: use `std::mem::replace` to move the comment-delimiter and rewrap-prefix accumulators into the pushed range instead of cloning them and immediately reassigning. ## Testing - `cargo check -p collab -p project -p context_server -p editor` — clean. - `cargo test -p editor rewrap` — 7/7 pass, including the boundary-sensitive `test_rewrap*` editor tests. - `cargo test -p context_server` — 97/97 pass. - `cargo test -p project path_trie` — 2/2 pass. - Re-ran the `deep_clone_in_loop` lint on the four crates: the `extensions.rs`, `path_trie.rs`, and `rewrap.rs` hits are gone; `client.rs` still (correctly) reports the remaining required per-handler clone. - Not tested platform-specifically; the changes are platform-independent. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - N/A |
||
|
|
fc9258b463 |
editor: Add file permalink support to tabs and the Project Panel (#62177)
# Objective - Add file-level hyperlink support for opening and copying hyperlinks for Git remote source control to project panel and tabs - Unify the language for Git remote hyperlinks across blame, project panels, and tabs to be similar to GitLens' definitions (which are commonly used in VS Code) ## Solution - Updated the Git crate to expose relevant metadata to surface new options within the editor - Added new options for `Open File on Remote` and `Copy Remote File URL` to project panel/file explorer and file tabs - Altered the blame UI options to be consistent with new labels / more clear ## Testing - Ran `cargo run` to boot app and manually smoke test (see proof below) - Added unit tests for this change ## 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/d600ca4f-47e7-438c-90e1-f40124a606b4 --- Release Notes: - Added options to open or copy whole-file permalinks from file tabs and the Project Panel. --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> |
||
|
|
3b90a96830 |
agent: Release completed terminal PTY resources (#62978)
Closes #62972 Completed Agent terminal cards remain alive so conversation history can render their output. Each retained terminal also kept its Alacritty PTY sender alive, which retained a poller and one kqueue descriptor after the command exited. Terminal lifecycle state is now more strongly typed to prevent this class of regression. Task terminals are created through a sealed `TerminalMode` API that pairs their running state with the correct completion channel, while PTY resources use explicit active and released states. This makes invalid lifecycle combinations unrepresentable instead of relying on callers to coordinate independent `Option` values correctly. - Release the live PTY sender after final terminal output is captured. - Preserve PTY process metadata and working-directory behavior for historical terminal cards. - Represent PTY resources as explicit active or released lifecycle states. - Construct interactive and task terminals through typed modes so a task cannot omit its running state or use a mismatched completion channel. - Keep resource release idempotent for later ACP release and entity destruction. - Add a macOS regression test that retains the historical terminal entity while exercising the complete sandboxed terminal tool path. Release Notes: - Fixed Agent terminal tool calls leaking file descriptors on macOS. Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
7ecab315fb |
Fix project search holding a reference to closed unsaved files (#61677)
# Objective Fixes #28398 ## Solution This issue was occurring because `ProjectSearch` stored `Entity<MultiBuffer>` with has reference counted pointers to underlying buffers The function `remove_deleted_buffers` is renamed to `remove_stale_buffers` and it now also checks for buffers which do not have a file associated with them and are closed. Then, it removes them from `Entity<MultiBuffer>` stored in ProjectSearch. This function is also called in again when workspace is upgraded. ## Testing Bug being fixed was manually verified. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed project search retaining results from closed untitled buffers. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
c595091b0a |
Bump dependencies to dedupe the crate graph (#63231)
Deduplicates crates with different versions from the graph, drops unused features. `cargo tree -d duplicate` listing: 160 -> 112 lines. <details> <summary>Deduplicated list</summary> ``` base64 (v0.22.1, v0.21.7 -> v0.22.1) convert_case (v0.11.0, v0.10.0, v0.8.0 -> v0.11.0, v0.10.0) core-foundation (v0.10.0, v0.9.4 -> v0.10.0) cssparser (v0.36.0, v0.35.0 -> v0.37.0, v0.36.0) fancy-regex (v0.18.0, v0.16.2 -> v0.19.0) fixedbitset (v0.5.7, v0.4.2 -> v0.5.7) h2 (v0.4.12, v0.3.27 -> v0.4.12) heck (v0.5.0, v0.4.1, v0.3.3 -> v0.5.0, v0.4.1) html5ever (v0.39.0, v0.35.0 -> v0.39.0) hyper (v1.7.0, v0.14.32 -> v1.7.0) hyper-rustls (v0.27.9, v0.24.2 -> v0.27.9) mach2 (v0.6.0, v0.5.0, v0.4.3 -> v0.6.0, v0.5.0) markup5ever (v0.39.0, v0.35.0 -> v0.39.0) phf (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3) phf_codegen (v0.13.1, v0.11.3 -> v0.13.1) phf_generator (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3) phf_macros (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3) phf_shared (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3) prost (v0.12.6, v0.9.0 -> v0.14.4) prost-build (v0.12.6, v0.9.0 -> v0.14.4) prost-derive (v0.12.6, v0.9.0 -> v0.14.4) prost-types (v0.12.6, v0.9.0 -> v0.14.4) rustix (v1.1.4, v0.38.44 -> v1.1.4) rustls (v0.23.40, v0.21.12 -> v0.23.40) rustls-native-certs (v0.8.3, v0.6.3 -> v0.8.3) rustls-pemfile (v2.2.0, v1.0.4 -> v2.2.0) rustls-webpki (v0.103.13, v0.101.7 -> v0.103.13) security-framework (v3.5.1, v2.11.1 -> v3.5.1) socket2 (v0.6.3, v0.5.10 -> v0.6.3) string_cache (v0.9.0, v0.8.9 -> v0.9.0) string_cache_codegen (v0.6.1, v0.5.4 -> v0.6.1) strum (v0.28.0, v0.27.2 -> v0.28.0) strum_macros (v0.28.0, v0.27.2 -> v0.28.0) tendril (v0.5.1, v0.4.3 -> v0.5.1) tokio-rustls (v0.26.4, v0.24.1 -> v0.26.4) tungstenite (v0.28.0, v0.27.0 -> v0.28.0) web_atoms (v0.2.6, v0.1.3 -> v0.2.6) which (v6.0.3, v4.4.2 -> v8.0.5) ``` </details> Release Notes: - N/A |
||
|
|
839ab7a9f7 |
Fix shallow diffs causing a lot of computations (#63024)
For repositories with shallow mode enabled, before, Zed instantly loaded diff changes which could be very large and CPU-demanding: https://github.com/user-attachments/assets/5577730a-efef-424f-b749-501394a8b51f Now, we show the following state instead of loading: <img width="1728" height="1084" alt="after" src="https://github.com/user-attachments/assets/03cc47fe-7074-4e8b-ba12-2fefa101377d" /> (the button allows to move on and do the load nonetheless) Release Notes: - Fixed shallow diffs causing a lot of computations --------- Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de> |
||
|
|
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) |
||
|
|
391a66a5ad |
debugger: Separate Continue Program and Continue Thread actions (#63135)
Fixes #63091 Continue Program was sending `singleThread: true` whenever the adapter supported it, which caused some adapters to resume only the selected thread. It now leaves `singleThread` unset and resumes all threads. Adapters that support single-thread execution now show separate Continue Program and Continue Thread buttons. Other adapters still show only Continue Program. <img width="247" height="108" alt="image" src="https://github.com/user-attachments/assets/5059d291-4809-488b-9169-e4817852fb07" /> This change also: - Updates thread states from the continue response instead of waiting for a [continued event, which adapters are not expected to send](https://github.com/microsoft/debug-adapter-protocol/blob/bf8a5d27e8040044b84b863f90916e08925ee811/debugAdapterProtocol.json#L243-L246). - Treats an omitted allThreadsContinued in a continued event as true, as required by the [DAP specification](https://github.com/microsoft/debug-adapter-protocol/blob/main/debugAdapterProtocol.json#L260-L263). Release Notes: - Added a Continue Thread action and fixed Continue Program to resume all threads. |
||
|
|
49a841c7ad |
Fix PythonLocator to pass through env variables from the task template (#63154)
This matches `GoLocator` and `NodeLocator`
# Objective
The problem: `env` variables defined in `tasks.json` aren't used when
the task runs in debug mode.
Example:
```json
[
{
"label": "pytest (custom)",
"env": {
"DATABASE_URL": "...",
},
"command": "$ZED_CUSTOM_PYTHON_ACTIVE_ZED_TOOLCHAIN",
"args": [
"-m",
"pytest",
"$ZED_CUSTOM_PYTHON_TEST_TARGET",
],
"tags": ["python-pytest-class", "python-pytest-method"],
"cwd": "$ZED_WORKTREE_ROOT",
},
]
```
When a test runs normally, the `DATABASE_URL` variable is set correctly.
When the test runs in debug mode, the variable is not set.
## Solution
`PythonLocator` copies the `env` value from the `TaskTemplate`. This
matches other locators, such as `GoLocator` and `NodeLocator`
## Testing
- Did you test these changes? If so, how?
- The existing integration test is updated to verify the change
- Are there any parts that need more testing?
- No
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- Run `cargo test -p project --test integration
debugger::python_locator::test_python_locator`
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
- Linux (NixOS), the change is platform-agnostic.
## 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
N/A
---
Release Notes:
- Fix `PythonLocator` to pass through `env` variables from the task
template
|
||
|
|
5b70f793d3 |
Use Duration to improve type safety and unit correctness (#62969)
# Objective - Prefer using `Duration` instead of integers when dealing with spans of time. This prevents confusing different units of time and comparing arbitrary integers with durations. - Remove `_ms`/`_secs` suffixes from variables which are `Duration`, since their unit is inside of the type. - Initialize large integer constants using `Duration`, which has more descriptive constructors, while maintaining the resulting integer type. Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
deb194b49b |
Properly deduplicate overlapping range formatting results (#62935)
Fixes https://github.com/zed-industries/zed/issues/62780 When formatting changed-only regions, we have received formatting changes that are larger than the regions submitted. Previous code merged only adjacent hunks in a single response, without merging anything else, e.g. multiple responses' ranges that overlapped. Release Notes: - Fixed overlapping range format results duplicating the text |
||
|
|
09adbb01f6 |
workspace: Persist recent navigation history across sessions (#55034)
Saves the recent navigation history (up to 20 entries) to the workspace DB so it survives restarts. When reopening a workspace, persisted paths that resolve to the current project are merged into the file finder's history, deduplicated against files already opened in the session. https://github.com/user-attachments/assets/3d8934e1-0da6-4445-8f3d-acc5597d7ac8 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: https://github.com/zed-industries/zed/issues/56271 Release Notes: - Improved file finder history to include recently opened files from previous sessions. |
||
|
|
3ea4d186a1 |
Deduplicate worktree entries from LSP paths with mismatched casing (#61392)
# Objective On case-insensitive volumes (the macOS default), language servers may return `Location` URIs whose path casing differs from the worktree's stored casing - e.g. `Utils/helpers.py` when the on-disk (and worktree) path is `utils/helpers.py`. `LspStore::open_local_buffer_via_lsp` used the LSP path verbatim, and worktree selection (`WorktreeStore::find_worktree`) does a case-sensitive prefix match, so the existing worktree was either missed (creating a duplicate invisible worktree) or matched but with a relative path that retained the LSP's intermediate-component casing. That relative path was then used to `load_file`, which inserted a brand-new `Entry` keyed by the differently-cased path alongside the existing one - producing duplicate file entries in the project panel. This was most visible when navigating Python imports (Go to Definition) where the LSP returned differently-cased paths. https://github.com/user-attachments/assets/e36930b5-8dfd-4b43-8fe4-5317d401e198 ## Solution Canonicalize the LSP-provided absolute path via `fs.canonicalize` before the worktree lookup in `LspStore::open_local_buffer_via_lsp`, so the path casing matches the filesystem and the existing worktree/entry is reused. Canonicalization failures (e.g. a path that doesn't exist on disk yet) fall back to the original path to preserve prior behavior. To enable testing this on a fake filesystem, `FakeFs` now supports `set_case_sensitive(false)` and its `canonicalize` resolves names case-insensitively, returning the stored (canonical) casing. ## Testing Added `test_open_buffer_via_lsp_case_variant_no_duplicate` in `crates/project/tests/integration/lsp_store.rs`. It opens a buffer via an LSP URI with differently-cased intermediate component (`/root/SRC/main.rs` vs `/root/src/main.rs`) on a case-insensitive FakeFs and asserts that no differently-cased entry is created and the canonical entry is preserved. Verified the test fails without the fix (`SRC/main.rs` duplicate appears) and passes with it. Existing worktree, fs, and project_panel test suites remain green. ## 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/f052cf10-8b45-4547-8425-00ce4050ee7c --- Release Notes: - Fixed duplicate file entries in the project panel on macOS when navigating to definitions via the language server returned paths with different casing than the worktree root. --------- Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com> |
||
|
|
828544342d |
search: Fix regex replace with lookahead and lookbehind (#61900)
# Objective - Fixes #25905 - Regex search-and-replace silently does nothing when a same-line pattern contains a lookahead or lookbehind. Searching highlights the correct hits, but Replace All or `:s` in Vim mode leaves the buffer untouched. Reproduce with `316227766016837933199`, search `(\d)(?=(\d{4})+$)` in regex mode, and replace with `$1,`. Expected: `3,1622,7766,0168,3793,3199`. Actual before this change: nothing changes. The same problem affects `(?<=foo: )bar` replaced with `BAZ`. `SearchQuery::replacement_for` expanded the replacement by re-running the whole pattern against the matched text alone. Lookaround assertions inspect text outside the match, so the isolated hit no longer matched and the edit replaced the hit with itself. ## Solution - `replacement_for` now expands from captures located at the exact hit range within its source context. - Single-line regex hits use the complete source line, so lookahead, lookbehind, and line anchors see the same surrounding text used by search. - Literal and escaped-regex searches bypass context reconstruction because their replacements do not use captures. - Multi-line hits retain the exact matched text, preserving the prior cross-line behavior. - If selection boundaries prevent the pattern from matching the reconstructed line, replacement falls back to the isolated hit, preserving prior behavior. - Replace All caches the source line across hits on the same line. Cross-line lookaround remains unchanged: assertions that need text outside a multi-line hit still produce a no-op replacement. Search-within-selection can also retain the prior no-op behavior when the selection boundary changes assertion context. ## Testing - `cargo test -p search test_replace_with_lookaround` (2 passed) - `cargo fmt --all -- --check` - `./script/clippy -p editor -p project -p search` - Tested on Linux arm64. The change is platform independent. ## Self-Review Checklist: - [x] I have reviewed the diff for quality, security, and reliability - [x] Unsafe blocks, if any, have justifying comments - [x] The content adheres to Zed UI standards - [x] Tests cover the changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed same-line regex replacements that use lookahead or lookbehind |
||
|
|
fa00dccc42 |
Fix project path handling when connecting from Unix to Windows remotes (#62038)
# Objective Follow-up of #61374. Zed now supports Windows as a remote target, but when connecting from a Unix platform to Windows, some path handling still uses the native client's path style (Unix) to construct paths, which causes weird path displays in different areas. One of them is the project path stored in the `settings.json` file, which is related to the open path picker in the codebase: https://github.com/zed-industries/zed/blob/5e1fd392f67e27fa1da91bad43eef7db1a5dec23/crates/open_path_prompt/src/open_path_prompt.rs#L668-L679 For example, if I have a remote project at `D:\code\test_python` and want to open it in remote development, I usually use path completions, with `D:\code\` as the parent path and `test_python` as the selected candidate. Zed directly joins them using `Path::join` on the Unix platform, which results in `D:\code\/test_python`. A second thing I found is the displayed name for the git repo. The related source code is: https://github.com/zed-industries/zed/blob/5e1fd392f67e27fa1da91bad43eef7db1a5dec23/crates/title_bar/src/title_bar.rs#L262-L268 Also taking `D:\code\test_python` as an example: the passed-in `common_dir_abs_path` is `D:\code\test_python\.git`, and `repo_identity_path()` directly uses `Path::file_name()` and `Path::parent()` from the standard library to handle this: https://github.com/zed-industries/zed/blob/5e1fd392f67e27fa1da91bad43eef7db1a5dec23/crates/project/src/git_store.rs#L9956-L9965 Ideally, this function should return `D:\code\test_python`. But due to the platform mismatch, `D:\code\test_python\.git` is returned; after further processing in the title bar, we get `D:\code\test_python\` as the displayed name, while the expected display name is `test_python`. In the past, only Unix-like systems could serve as remote servers, and their path separator (`/`) is valid on Windows, so everything looked fine. But Unix does not support `\` as a valid separator — that's the root cause. We need to use `PathStyle`, which is designed for processing paths across platforms, to deal with these cases. ## Solution - Added new APIs `PathStyle::parent()` and `PathStyle::file_name()`, which serve as replacements for `Path::parent()` and `Path::file_name()` to process paths cross-platform. - Adopted the new APIs in `repo_identity_path()`, and updated the relevant call sites. - For the open path picker, use `PathStyle::join_path()` instead of `Path::join`. ## Testing The added `PathStyle::parent()` and `PathStyle::file_name()` are covered by detailed unit tests. These tests verify that the behavior matches the corresponding methods in `Path`, just independent of the host platform. For the path display issues, I built and tested manually; a comparison is attached in the Showcase section. ## 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>Click to view showcase</summary> | Content | Before | After | |:--:|:--:|:--:| |title bar|<img width="486" height="272" alt="title_bar_before" src="https://github.com/user-attachments/assets/d14d0e37-a1b8-43ab-b51b-fe9dd1b977eb" /> | <img width="406" height="274" alt="title_bar_after" src="https://github.com/user-attachments/assets/fc9193f4-d42c-47a8-a254-4ed08c806a11" /> | |path storage| <img width="337" height="264" alt="project_path_before" src="https://github.com/user-attachments/assets/3352add3-20df-43b9-8a20-10ee7d96e703" />| <img width="319" height="262" alt="project_path_after" src="https://github.com/user-attachments/assets/fa3d7feb-f393-416a-868d-85eb0af5cfb8" />| |open remote| <img width="554" height="135" alt="open_remote_before" src="https://github.com/user-attachments/assets/62983eca-22ad-472f-8333-8561cfc17357" />|<img width="562" height="176" alt="open_remote_after" src="https://github.com/user-attachments/assets/22528a6b-0e73-4a12-a825-673ba57a63da" /> | </details> ## Other things to note This PR also did a little refactoring: it moved the `PathStyle`-related tests from the `util` crate to the `path` crate, and updated the documentation to reflect that Windows can serve as a remote platform. The recent project picker also suffers from the same cross-platform bug, but it is not fixed here, because a clean fix requires dealing with database storage, unlike the direct API changes made here. I will address it in a follow-up PR. This PR looks very large, but most of the changes are the test migration and the new API implementation. I hope the unit tests and comments can offload some of the burden for reviewers. --- Release Notes: - Fixed project paths being built incorrectly when connecting from Unix machines to Windows remote servers. |
||
|
|
3f660a0a60 |
Remove deprecated std::usize import from uniform_list.rs (#62841)
<img width="993" height="370" alt="image" src="https://github.com/user-attachments/assets/15e3a185-3328-4069-ad86-21d29f647f83" /> # Objective - using `std::usize` currently is a warning, but it's a hard fairule in rust nightly - gpui-web requires rust nightly - https://doc.rust-lang.org/std/usize/index.html ## Solution - remove std::usize import, it would be used a primitive type ## Testing - https://github.com/iamnbutler/gpui-unofficial/actions/runs/32189970651/job/95882109895#step:8:753 ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - N/A --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
00c0e96e76 |
Make opening large files use less peak memory (#62748)
# Objective Opening a file laods it twice. `decode_file_text` builds the whole file as a `String`, and that `String` stays alive alongside the finished rope while `text::Buffer::new` copies it in. The `Vec` behind it grows by doubling, so it also commits up to nearly the file's size again in capacity it never uses. Partially addresses #27283. ## Solution Add `decode_file_text_to_rope`, which streams the file in 1 MB blocks straight into a `Rope`, validating UTF-8 and normalizing line endings as it goes. The file is never fully held as a `String`. `LoadedFile::text` becomes a `Rope` carrying the `LineEnding` detected before normalizing, so `buffer_store` calls `Buffer::new_normalized`. ## Testing On a 729 MB SQL dump, peak memory fell 25% and CPU fell around 28%. tested on 5950x, win11. Release Notes: - Improved memory use when opening large files, reducing peak memory during load by roughly the size of the file itself. |
||
|
|
3624a5bfda |
project: Anchor diagnostic related information that points into the buffer (#62805)
Closes #62796. Follow-up to #62110. # Objective The range of a diagnostic entry is anchored when it is ingested, so it follows edits. The ranges in the related information kept on the diagnostic were the ones the server published. A code action request carried both and reported the same note at two different lines: the entry Zed flattened that note into had followed the edit, the related information had not. The distance does not correct itself either. When diagnostics are merged rather than replaced, the existing entries are re-collected from their anchors while the payload is cloned as it is, so the two positions drift further apart with every edit that passes. `mlir-lsp-server` shows what this costs. `MLIRTextFile::getCodeActions` takes the line number out of `relatedInformation`, and `getCodeActionForDiagnostic` resolves it against its own current document, reading that line to copy its indentation before inserting the `expected-note` check. ## Solution The related information moves from `Diagnostic` onto `DiagnosticEntry<T>`, next to the range it belongs with. The locations of the diagnostic's own file are then in the same coordinate space as that range: anchors inside the buffer, points in the worktree's store. `Diagnostic` carries no coordinates again, so nothing that is only meaningful inside one buffer travels with a payload that outlives it. Every transition goes through `DiagnosticEntry::map_coordinates`: the unsaved-edit adjustment and the clipping when diagnostics are ingested, the anchoring in `DiagnosticSet::new`, and the conversion back to points in `merge_diagnostic_entries`. Only the diagnostic's own range is widened when it is empty, since that is for how it is rendered, while the related locations are reported back as the server framed them. Locations in another file have nothing here to anchor to and are kept as published, which is also what `mlir-lsp-server` expects, since it skips them. `DiagnosticEntryRef` is left alone. It is what the rendering path iterates, down to the scrollbar markers that walk every diagnostic of the buffer on each frame, so nothing there converts or allocates. The entries are read through `diagnostic_entries_in_range` where the request is built, and `diagnostics_in_range` is now implemented on top of it. The field is an `Option`, as an empty `Arc<[_]>` still allocates and most diagnostics carry no related information. `data` has the same staleness and cannot be anchored, as it is opaque. ## Commits The third commit is mechanical: it introduces `DiagnosticEntry::new` and rewrites the literals at its call sites, so that the last commit holds only the change of behaviour. ## Testing Three tests, all failing before this change. The first two are added as separate commits, so that they can be run against `main`: - `test_code_actions_related_information_follows_edits` edits above the note and requests code actions, where the two positions for it used to disagree. - `test_code_actions_related_information_drifts_across_merges` edits and pulls diagnostics twice, where the distance used to be every line inserted since the diagnostic was published rather than the last edit alone. - `test_code_actions_related_information_of_disk_based_diagnostics` publishes a diagnostic computed against the file on disk while the buffer holds an unsaved edit, covering the adjustment the two positions share. - `cargo test -p project` - `cargo test -p language -p diagnostics -p editor` - `cargo fmt --all -- --check` - `./script/clippy -p project -p language` ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed language servers receiving outdated positions for the related information of a diagnostic when code actions are requested. |
||
|
|
fdad9186b8 |
git_ui: Dismiss askpass prompts when requests end (#61292)
# Objective Fixes #47623 - When authenticating git commands using a security key through `askpass`. The modal which asks for user presence does not get dismissed even after the git command finishes successfully. ## Solution Add a cancellation task to the `AskPassModal`, which gets dropped when the requested operation completes. This cancellation task then dismisses the modal. ## Testing - I've tried authentication through `askpass` using my own security key. Testing both successful and failed authentication. - I've added tests which confirm that the modal gets dismissed when a task is cancelled, and that the cancellation is triggered when `ask_password` Task gets dropped. Willing to pair on review, message me on Slack. Showcase video left out because it would leak private information. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed authentication prompts not dismissing automatically when using security keys with ssh |
||
|
|
4bdf188c99 |
Added Tracked , Staged options to stash (#62254)
# Objective Closes #62252 The Git Panel could only stash *everything* — `Stash All` runs `git stash push --include-untracked`, sweeping tracked edits and untracked files into a single entry. There was no way to stash a subset, so the common workflows of "park my tracked edits but keep my new scratch files" and "park what I've staged and keep working on the rest" required dropping to the terminal. ## Images <img width="389" height="358" alt="Screenshot 2026-08-10 at 3 10 50 PM" src="https://github.com/user-attachments/assets/18e4c943-e320-4802-ada8-59e54bf4cefd" /> <img width="504" height="462" alt="Screenshot 2026-08-10 at 3 10 37 PM" src="https://github.com/user-attachments/assets/783237eb-980d-47bc-a0f5-17b03a23a60c" /> ## Solution Add two stash variants alongside `Stash All`, surfaced in the Git Panel's overflow menu based on how the list is currently grouped, so the menu mirrors the sections the user can actually see: | Group By | Stash entries offered | | --- | --- | | None | Stash All | | Tracked & Untracked | Stash All, **Stash Tracked** | | Staged & Unstaged | Stash All, **Stash Staged** | - **`git::StashTracked`** stashes tracked changes and leaves untracked files in place. It reuses the existing pathspec plumbing (`Repository::stash_entries`), filtering the status list down to the paths to stash. - **`git::StashStaged`** stashes the index only, leaving unstaged changes in place. This *cannot* be expressed as a pathspec — a partially staged file would have its unstaged hunks stashed too — so it needs git's own `--staged` flag. That meant a new `GitRepository::stash_staged` backend method and an `optional bool staged` field on `proto::Stash` so remote projects work too. Both actions are unbound by default and are dispatchable from the command palette when the panel is focused. One subtlety worth calling out for review: `Stash Tracked` filters on `FileStatus::is_created()`, not `is_untracked()`. Staging a new file flips it from `Untracked` to `Tracked { Added }`, but the panel still lists it under **Untracked** — using `is_untracked()` meant staged-new files were silently stashed. `is_created()` is the same predicate the panel uses to build that section (`git_panel.rs`), so the menu item and the list can no longer disagree. This branch also includes a separate commit adding **per-section staging** (`git::StageSection` / `git::UnstageSection`) — right-click a file to stage or unstage every entry in its section. Happy to split that into its own PR if preferred. ## Testing Manually tested on macOS against a scratch repo with a mix of states: modified tracked files, untracked files, and untracked files that had been staged. - `Stash Tracked` with tracked edits + untracked files → only tracked edits stashed; untracked files remain. - `Stash Tracked` with untracked files **staged** → they remain, staged. This was broken in an earlier revision and drove the `is_created()` fix above. - `Stash Staged` with one file staged and another modified-but-unstaged → only the staged file is stashed; the unstaged edit and untracked files survive. - `Stash Pop` round-trips both cases back to the original state, with no conflicts. - Menu contents and disabled states verified in all three Group By modes. - Per-section staging covered by a new unit test, `test_stage_section_scopes_to_selected_section`. Not covered by automated tests: the stash actions themselves. `FakeGitRepository` leaves every stash method `unimplemented!()`, so stash behavior isn't reachable from GPUI tests today — consistent with the existing untested `StashAll`. Adding fake-repo stash support looks like a worthwhile follow-up but felt out of scope here. Reviewers on non-macOS platforms: nothing here is platform-specific. Note that `Stash Staged` requires **git 2.35+** (Jan 2022) for `git stash push --staged`; older git surfaces a clear error toast rather than failing opaquely. The remote path (`proto::Stash.staged`) has not been exercised against a live collab session. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Added `Stash Tracked` and `Stash Staged` options to the Git Panel, letting you stash only tracked changes or only staged changes. --------- Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com> |
||
|
|
fd90c0af7f |
project: Deduplicate identical language server hover responses (#62266)
Closes https://github.com/zed-industries/zed/issues/62262 ## Solution Identical hover responses from multiple language servers should be displayed only once. Different hover responses should still all be preserved, since multiple language servers may provide complementary information. ## Showcase https://github.com/user-attachments/assets/67246d9f-ed1c-4f5a-98f5-f10548b7fc6d --- Release Notes: - Deduplicated identical language server hover responses --------- Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com> Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |