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#54641
Release Notes:
- Fixed creating git worktrees in WSL remote projects from Windows.
## Summary
- Preserve the repository `PathStyle` when constructing git worktree
paths.
- Avoid using local OS path separators when creating worktrees for
remote Posix projects such as WSL.
- Keep worktree archive path checks aligned with the same
path-style-aware worktree directory calculation.
## Root Cause
Remote repository paths are stored as `PathBuf`s, but `PathBuf::join`
and related path operations use the client OS separator. On Windows
clients connected to WSL, this could turn a remote Linux path into a
mixed path like `/home/<user>/\home\<user>\dev\worktrees\...`, causing
worktree creation and opening to fail.
## Validation
- `cargo fmt --all --check`
- `git diff --check`
- `cargo test -p project
test_new_worktree_path_uses_posix_style_for_remote_paths`
- `cargo test -p project test_worktree_directory_uses_remote_path_style`
- `cargo test -p project test_join_path_for_style_uses_remote_separator`
---------
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
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#55022
## Summary
When a task explicitly uses `cmd.exe`, Zed prepares it as a shell
invocation like `cmd.exe /S /C "<command>"`.
If Python virtual environment activation is enabled,
`Project::create_terminal_task` wraps that prepared task in an outer
activation shell so the venv can be activated before the task runs.
Before this change, the activation formatter treated the prepared `/C`
command string as a normal shell argument and quoted it again. On
Windows, that can make cmd receive escaped quotes literally, producing
errors like `'\\"echo Hi there\\"' is not recognized...`.
This preserves the prepared cmd `/C` command string while building the
activation command, and keeps the existing quoting path for ordinary
task arguments.
## Verification
- `cargo test -p project formats_prepared_cmd_task`
- `cargo test -p project formats_non_cmd_task_for_activation`
- `cargo check -p project`
- `cargo fmt --check --package project`
- Manually verified on Windows with a selected Python `.venv` that a
`cmd.exe` task prints `Hi there` and finishes successfully.
Release Notes:
- Fixed Windows `cmd.exe` tasks failing when run with a selected Python
virtual environment.
Follow up: https://github.com/zed-industries/zed/pull/55167,
https://github.com/zed-industries/zed/pull/54468
This is the final PR for adding remote support on the git graph. It uses
the client stream request support added in #55167 to add support for the
initial graph data request. I also fixed a bug where
`GitGraph::FullyLoaded` repository event was never emitted.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes ##53040
Co-authored-by: Remco Smits \<djsmits12@gmail.com\>
Release Notes:
- git_graph: Add remote support
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Lots of people are using `min-release-age` in their .npmrc files these
days.
I saw two options:
1. Force min-release-age=0 so we can always install the latest
2. Be more lenient in what we allow
I opted for 2, which means we convert `package@0.1.2` to
`package@<=0.1.2`. This means npm can find the latest version we can
that meets the user's requirements.
The downside is, the registry args/env may or may not work with the
resolved version, but that should at least surface better thanks to
#55757
There is also the issue that npm will cache package metadata and an
older version it has cached would still resolve. However, once the
metadata is updated, npm does use the newer tarball at least, so it will
update eventually.
It's a tradeoff, but I'd rather start with this until we have a better
solution on the ACP registry, rather than have users be upset becaue we
installed packages in a way they didn't want.
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/agentclientprotocol/claude-agent-acp/issues/516
Release Notes:
- acp: Better support min-release-age settings for npx-based agents from
the registry
* Perform grouping even for repositories that have no main worktree
* Enable grouping for remote projects
* Delete entire project groups when deleting via the recent project
picker
Release Notes:
- Fixed a bug where each linked worktree appeared as its own entry in
recent projects for repositories without main worktrees
- Fixed a bug where deleting projects from the recent projects sometimes
appeared to have no effect.
Use `future::join` when loading index and committed text for buffer diff
bases, while keeping skipped loads as ready None futures.
Release Notes:
- N/A
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
### Motivation
This is the second of three PRs to add remote/collab support for the git
graph and is a follow-up to #54468. I'm adding remote support for the
search because it's not user accessible without the initial graph fetch
having remote support, so it allows us to merge this without having to
add full remote support. Collab guest support will be added in a
follow-up PR.
#### Summary
For large repos, searching can take a while to fully stream in all
matched results. For example, running a basic search on the Linux repo
took over 10s for me. Because of that, we want to stream search results
in chunks to downstream users to keep the time-to-first-match low. After
this change, the first chunk gets sent back after ~50ms on the Linux
repo from receiving the request.
In order to accomplish that, I added a new proto client API that allows
for a request to map to n responses. e.g.
```/dev/null/example.rs#L1-1
client.add_entity_stream_request_handler(Self::handle_search_commits);
```
Note: The proto API isn't supported over collab yet, that will be
another PR
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 #ISSUE
Release Notes:
- N/A
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
## Context
Previously the Run Debugger gutter arrow would fail silently when the
Cargo.toml had garbage lines such as “asdfasdf”. This fix makes it so
that the error is detected and bubbles up to the editor, which will
notify the user with a toast diagnostic.
Closes#46716
## Fix
https://github.com/user-attachments/assets/2e9ac7e9-1306-4607-a762-457131473572
## How to Review
Small PR - focused on four different files:
In - `crates/languages/src/rust.rs`:
- `target_info_from_abs_path()` - The function signature was changed
from `Option<(Option<TargetInfo>, Arc<Path>)>` to
`Result<Option<(Option<TargetInfo>, Arc<Path>)>>`. A condition was added
to ensure that if the Cargo metadata command is unsuccessful, the
function returns an error instead of causing an EOF error while
deserializing the stdout of the command.
- `build_context()` - Added a `?` in `target_info_from_abs_path(path,
project_env.as_ref()).await` in order to return the error.
In - `crates/project/src/task_store.rs`:
- `local_task_context_for_location()` and
`remote_task_context_for_location()` - The functions signatures were
changed from `Task<Option<TaskContext>>` to
`Task<anyhow::Result<Option<TaskContext>>>` for the purpose of
propagating the error.
In - `crates/editor/src/editor_tests.rs`:
- `build_tasks_context()` - The function signature was changed from
`Task<Option<TaskContext>>` to
`Task<anyhow::Result<Option<TaskContext>>>` .
- `toggle_code_actions()` - In case `build_tasks_context()` fails, the
functions notifies the error to the user as a Toast notification.
In - `crates/editor/src/runnables.rs`:
- Since `build_tasks_context()` and
`task_store.task_context_for_location()` now return a Result, the
callers` spawn_nearest_task() `and `task_context()` were modified. The
resulting Result types are transformed to match the expected return
types of `TaskContext` and `Task<Option<TaskContext>>`
Two new tests were added. The first, `target_info_from_abs_path_failed`
in `crates/languages/src/rust.rs`, checks if the system properly catches
the error. The second,
`test_toggle_code_actions_build_tasks_context_error_notifies` in
`crates/editor/src/editor_tests.rs`, confirms that the editor triggers
the expected error notification.
## 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](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [X] Tests cover the new/changed behavior
- [X] Performance impact has been considered and is acceptable
Release Notes:
- Fixed the error: Run Debugger failing silently due to invalid
Cargo.toml content
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
To support branch create with base branch, added extra optional field in
GitCreateBranch proto.
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#43985
Release Notes:
- git: Fixed remote branch creation based on default branch
Fixes https://github.com/zed-industries/zed/issues/54830
This fixes a bugs where
* when there's no main worktree, we treated the first linked worktree as
main
* the titlebar and sidebar showed two different things when opening a
linked wortree directly
When there's no main worktree, our "project group key" will be the bare
repo path. For displaying this to the user, we try to present something
meaningful:
* If the bare repo is `foo.git`, we'll say "foo"
* If the bare repo is "bar/.bare", we'll "bar"
Release Notes:
- Fixed bugs in Zed's sidebar and titlebar when editing in git worktrees
created from bare repositories.
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 #ISSUE
Release Notes:
- N/A
Self-Review Checklist:
- [X] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [X] Performance impact has been considered and is acceptable
Updated `CommitDataReader::read` from single SHA to batched
input/output.
`run_commit_data_reader` is designed to process requests in batches, but
`CommitDataReader::read` previously only sent one SHA per call. So in
practice, commit data was effectively processed one-by-one from the
caller path.
The temporary debug logs show that batching was not performed
previously.
before:
<img width="607" height="154" alt="image"
src="https://github.com/user-attachments/assets/4f9d9041-6209-426f-be44-f28449504c80"
/>
after:
<img width="632" height="121" alt="image"
src="https://github.com/user-attachments/assets/43b349f3-7685-4786-af1e-2a640cdf8ccd"
/>
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>
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#54093 (at least the os error 123 in the comments of that
bug)/#54901 (although the diagnosis in that bug is totally wrong)
Used process monitor to work out what that issue was:
<img width="1573" height="94" alt="image"
src="https://github.com/user-attachments/assets/2f82ad1a-8532-465d-9dcd-ba0bd092e9e7"
/>
There's actually a '\n' after node_modules there so it's an invalid
directory. Add trim() to fix.
After adding that change locally, eslint loaded fine
Release Notes:
- Fixed bug where eslint didn't start on Windows
The DAP TCP transport layer was hardcoded to `Ipv4Addr`, so IPv6
addresses like `fd00::a` in a debug config's `connect.host` always
failed with `hostname must be IPv4: invalid IPv4 address syntax`.
Replaced `Ipv4Addr` with `IpAddr` and `SocketAddrV4` with `SocketAddr`
across the `task`, `dap`, `dap_adapters`, and `project` crates. The WASM
extension API still uses `u32` for the host field to avoid a breaking
WIT interface change; IPv4 round-trips through extensions as before.
Fixes#52237
Release Notes:
- Fixed DAP TCP transport rejecting IPv6 addresses when connecting to
remote debug adapters.
---------
Co-authored-by: moktamd <moktamd@users.noreply.github.com>
Found this bug while investigating why configuring nextest based on the
instructions at
https://github.com/rust-lang/rust-analyzer/issues/21137#issuecomment-4254611341
wasn't working within Zed.
Previously, we'd use `serde(untagged)`, preferring cargo over shell
commands. The problem is that every instance of a shell command is a
valid instance of a cargo command. For example, the shell command:
```json
{
"label": "test my_test",
"kind": "shell",
"args": {
"environment": {"RUSTC_TOOLCHAIN": "/path/to/toolchain"},
"cwd": "/project",
"program": "cargo",
"args": ["nextest", "run", "--package", "my-crate", "--lib", "--", "my_test", "--exact", "--include-ignored"]
}
}
```
would end up getting deserialized as a Cargo command, silently dropping
`program` and `args`.
With this fix, we now use the provided `kind` as a tag. We do have to
introduce a `#[serde(flatten)]` unfortunately, which has a few side
effects due to internal buffering, but `#[serde(untagged)]` also does
internal buffering so this doesn't make things worse.
I've manually tested this by configuring:
```json
{
"lsp": {
"rust-analyzer": {
"initialization_options": {
"runnables": {
"test": {
"overrideCommand": [
"cargo",
"nextest",
"run",
"--package",
"${package}",
"${target_arg}",
"${target}",
"--",
"${test_name}",
"${exact}",
"${include_ignored}"
]
}
}
}
}
}
}
```
and ensuring that nextest is correctly invoked.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed deserialization of rust-analyzer shell runnables.
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
These changes update Zed's Git Panel to be able to detect unsafe git
repositories, where the user running Zed doesn't own the `.git`
directory, and show a dedicated empty view in the Git Panel that not
only explains the situation but also allows the user to choose whether
to trust this directory, which will end up running `git config --global
--add safe.directory <path>`.
While testing those changes, it was noted that attempting to add or
reset files after trusting the directory would fail, as expected, but
the UI wouldn't react to the fact that those operations failed. What
this means is, if the user tried to add a file, the UI would show a
checkmark for that file and, after the operation failed, the checkmark
would remain. We now revert that, for both `git add` and `git reset`.
Some more technical notes on this change:
- Introduce `project::git_store::GitAccess` enum to express whether we
actually have access to the repository, exposed via
`git::Repository::access`, which probes the backend with a `git status`
command and classifies the result.
- On unsafe repositories,
`project::git_store::LocalRepositoryState::new` fails to spawn the git
worker, which now cleanly signals `GitAccess::No` rather than leaving
the panel in a broken state.
- Updated `git_ui::git_panel::GitPanel::render_empty_state` with a third
alternative, when `GitAccess::No`, that basically renders a view
explaining why the repository is considered unsafe, together with
buttons for git's documentation on safe directories and a button to add
the repository's folder as a safe directory
- Updated `project::git_store::GitStore` to now watch `~/.gitconfig` and
`$XDG_CONFIG_HOME/git/config`. Watching this files allows the Git Panel
to react when the git configuration is updated, which will be the case
if the user decides to trust the repository. When either changes, a
`GitStoreEvent::GlobalConfigurationUpdated` event is emitted and the
panel refetches repository state.
- Added `project::git_store::Repository::refetch_repo_state` field,
which stores a closure to allow recreating the
`Repository::repository_state` and the job sender after the repository's
directory is trusted, without requiring a project reload.
- Added a `fs::Fs::git_config` trait method, wrapping a real `git
config` invocation. In order to be able to call this, both
`git_store::GitStore::git_config` and `project::Project::git_config`
wrappers have also been introduced. Worth mentioning that this isn't yet
supported for remote projects or collab guests.
- Updated `fs::Fs::git_clone` argument order to match
`fs::Fs::git_config` and `fs::Fs::git_init`.
- Added a new
`project::git_store::pending_op::PendingOps::last_op_errored` method
that allows determining whether the last pending operation failed. This
now allows us to filter out failed operations when determining whether
`git add` or `git reset` failed, so that we can fall through to the real
git status.
- Updated `git_ui::git_panel::GitPanel::change_file_stage` to now call
`update_counts` in its error branch so the cached staged counters stay
consistent with the reverted per-entry state, seeing as we now handle
reverting the UI state if an operation fails.
- Fixed `fs::RealFs::git_init` to fall back to the provided branch name
when `git config --global --get init.defaultBranch` fails, for example,
when the user hsan't configured one.
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Closes#42286
Release Notes:
- Added a dedicated empty state in the Git Panel for unsafe
repositories, with a "Trust Directory" button that adds the repository
to `safe.directory`
- Fixed stage and unstage checkboxes in the Git Panel not reverting when
a `git add` or `git reset` command failed
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
This change fixes a small bug where we were showing "Loading project..."
even when in fact we had already started the search.
It also refactors three booleans in the `SearchState` enum, so that it's
harder to make similar mistakes in the future.
Release Notes:
- N/A
## Summary
This PR replaces the git file history view with the git graph view that
doesn't render the graph canvas. This has several advantages
1. Benefits from the graphs performance and lazy loading
2. Gets the graph's search for free
3. Resizable columns
4. The commit information panel
5. Is persistent
6. Cleans up a lot of code
The one con of this change is the graph doesn't have support
remote/collab support yet, but that is a WIP and should be merged within
a week.
Also, the git graph now propagates errors to the UI, which is the last
thing on the graph's stable launch todo list!
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
- [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 *or* Added/Fixed/Improved ...
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>
No, sadly, the title is not a typo. See
https://www.githubstatus.com/incidents/zsg1lk7w13cf for the context.
I'll read with joy and popcorn through that root cause analysis.
It makes literally zero sense what happened here, but for some completly
bonkers reason GitHub completely messed up the merge queue with
https://github.com/zed-industries/zed/pull/54632.
I have no idea how it happened. It makes literally zero sense. A PR
going into the merge queue should have the same LoC when getting out of
it. GitHub obviously does not check this. GitHub causes extra work with
a feature that is supposed to save time.
Thanks, I guess.
Release Notes:
- N/A
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This PR brings back the button to filter remote branches when accessing
the title bar's branch picker with the mouse. It was unintentionally
removed when we introduced the new worktree picker.
Release Notes:
- N/A
When starting a search on a project that is in the middle of a scan, we
used to miss results in files that had not yet been scanned.
This change makes the search wait for the scan to complete.
Closes#9858
Release Notes:
- Fixed incomplete search results when the project scan is incomplete
Opening an empty file then writing binary content to it on disk causes a
permanent freeze (not a crash — requires force kill).
`reload_impl` loads raw bytes via `load_bytes` and decodes with
`encoding_rs` but never checks if the content is binary. The existing
binary check in `decode_file_text` only runs on fresh opens, not
reloads. So binary content enters the buffer as lossy UTF-8.
Binary data has almost no newlines, producing a single enormous row. The
wrap map's sync fast path in `flush_edits` checks row count (< 100 rows)
but not line length, so it runs `wrap_line` on a multi-MB single line
synchronously on the main thread via `smol::block_on`. Font shaping
millions of non-ASCII replacement characters blocks the UI thread
indefinitely.
Two fixes, both one-condition guards:
- Null-byte check in `reload_impl` before decoding, same heuristic
(first 8000 bytes) used by `decode_file_text` on fresh opens. Binary
content never enters the buffer.
- Column-length guard (`MAX_SYNC_WRAP_COLUMNS = 10_000`) on the wrap map
sync fast path so absurdly long lines fall through to the async
background path. Defense in depth for any single-line content that's too
long to shape synchronously.
## Test plan
- [ ] Open an empty file in Zed, write binary content to it externally
(e.g. `cp /bin/ls /path/to/open-file`) — should show "Binary files are
not supported" instead of freezing
- [ ] Open a compressed file (zip, gz) that starts empty and gets filled
— same behavior
- [ ] Normal text file reload still works (no regression)
- [ ] Very long single-line text files (>10k columns) don't freeze the
editor
---------
Co-authored-by: deadcode-walker <268043493+deadcode-walker@users.noreply.github.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Some language servers (notably `vtsls` with `completeFunctionCalls`)
update `insertText/textEdit` during `completionItem/resolve` to add
snippet content like function call parentheses. Previously,
`Completion.new_text` was only set from the initial completion response
and never re-derived after resolve, so the snippet text was silently
discarded.
Re-derive `new_text` from the resolved `lsp_completion`. Only the text
content is updated -- replace/insert ranges are left as anchors from the
original response since the LSP ranges in the resolved text_edit are
stale when completions are cached across keystrokes (re: #34094).
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#53275.
Release Notes:
- Fixed the `vtsls` `completeFunctionCalls` setting being ignored
This is reachable when you pass a path to the Zed binary that doesn't
exist, so it feels a bit too aggressive.
Self-Review Checklist:
- [ ] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
This PR adds a "Add to .gitignore" action to the project panel's
right-click context menu. Similar to the "Restore File" action that I
previously added, I frequently find myself wanting this in the project
panel.
<img width="380" height="391" alt="image"
src="https://github.com/user-attachments/assets/e4438fbe-b070-40c8-9e57-84b003fa5c15"
/>
With the restore file option:
<img width="382" height="408" alt="image"
src="https://github.com/user-attachments/assets/84425de8-04e5-4969-8991-edc46e6420dc"
/>
Notes:
- **Implementation**: The `add_to_gitignore` function is essentially
copy-pasted from `git_panel.rs`.
- **Error handling**: Added toast notification on error, which is
consistent with `restore_file` in project_panel and `perform_checkout`
in git_panel.
Note that `add_to_gitignore` in git_panel does NOT show a toast (just
uses `detach_and_log_err`). I don't know if this is on purpose.
To follow up, I can either: match the project_panel implementation to
the git_panel one (no toast), or update the git_panel implementation to
also show a toast on error.
- **Menu grouping**: Previously "Restore File" and "View File History"
were in separate sections, but both relate to git. With this third git
action, I grouped all three together under a single separator (see
screenshot).
We could also keep "View File History" separate and only group "Restore
File" + "Add to .gitignore" together (both modify the working tree state
in some way), if we don't want to alter the existing UI too much.
Release Notes:
- Added "Add to .gitignore" option to the project panel context menu for
files in git repositories.
---------
Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
This sends `branch_list` in live `UpdateRepository` messages so
downstream repository snapshots stay in sync and the remote branch
picker can populate correctly. Collab DB replay for join/reconnect will
follow in a separate change.
This fixes a bug where the branch picker wouldn't show any branches in
remote environments
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#54530
Release Notes:
- git: Fix remote branch picker not showing any branches
### Motivation
To support remote Git graph usage, we need remote support for the Git
APIs that the graph depends on. This PR adds remote support for
`CommitDataHandler` (the `git cat-file --batch` process manager),
allowing remote Git graph consumers to fetch visible commit data without
polling.
#### Summary
The Git graph separates the UI and data layers so the UI can continue
rendering while commit data is fetched in the background. This change
extends that model to remote repositories by allowing
`GitStore::fetch_commit_data(sha: Oid, await_result: bool, cx: &mut
Context) -> &CommitDataState` to await remote commit loading.
For simplicity, the `Starting` variant was removed from
`CommitDataState`. `CommitDataState::Loading(Option<...>)` now stores
`Some(...)` when `await_result == true` is passed to
`fetch_commit_data`. This allows the data layer to await commit loading
without polling, and only when explicitly requested.
I also removed the `Graph` prefix from `CommitData`-related types
because this API is general-purpose and not limited to the graph. Longer
term, I hope to replace `Repository::show` with the commit data
functionality, since it already provides built-in caching.
#### Bug Fixes
- Fix stale `Loading(...)` entries that survive enqueue failure or
handler shutdown.
- Fix commit data handler bookkeeping so `pending_requests`,
`completion_senders`, and `CommitDataState` remain consistent.
- Fix remote commit-data loading so the data layer can await results
instead of polling.
#### Testing
- Add property tests for commit data fetching.
- Add a collab integration test that verifies batched remote commit-data
fetching.
#### Follow Up
In a follow-up, I want to replace the `Repository::show` backend with
the commit data handler and remove `CommitDetails` from the codebase as
a cleanup and maintenance pass. The commit data handler already provides
caching and is a better long-term path for commit metadata access.
I may also want to allow the `CommitData` type to propagate errors to
callers.
For the Git graph, the remaining work is remote search and initial data
fetching.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Remco Smits <djsmits12@gmail.com>
Closes#49581
Adds a `line_ending` language setting that controls how line endings are
handled for new files and during format/save:
- `detect` (default) — detects existing line endings; new files use the
platform default
- `prefer_lf` / `prefer_crlf` — sets LF or CRLF for new files and files
with no existing convention, while preserving existing files
- `enforce_lf` / `enforce_crlf` — normalizes all line endings to LF or
CRLF on every format/save
The setting can be configured globally, per-language, or via
`.editorconfig`'s `end_of_line` property (which maps to `enforce_lf` /
`enforce_crlf`).
Release Notes:
- Added `line_ending` setting to control how line endings are handled
for new files and normalized on save.
- Added support for `.editorconfig` `end_of_line` property to enforce
line endings.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
## Context
Fixes a Windows path handling bug in `crates/util/src/paths.rs` when
computing a relative path via `strip_prefix`. (Closes#51758 )
Previously, Windows prefix matching only handled drive-letter
case-insensitivity. It could still fail when the parent and child paths
referred to the same location but used different separator styles (`\`
vs `/`) or different casing in later path segments. That caused valid
Windows paths to return `None` instead of a relative path, which caused
the diff to break.
This change normalizes Windows paths for prefix comparison by
lowercasing any ASCII characters and converting backslashes to forward
slashes before checking the prefix.
Tests were added for mixed-case and mixed-separator Windows paths to
cover the bug and prevent further regressions.
## How to Review
1. Check the `strip_prefix` Windows branch to confirm the new
normalization logic only affects prefix comparison and still rejects
partial-segment matches.
2. Check the added tests for mixed separator and mixed casing cases on
Windows paths.
## Self-Review Checklist
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fix blank git diff view on Windows when working in a subfolder
---------
Co-authored-by: John Tur <john-tur@outlook.com>
Closes#46551
Zed was using the `terminal.shell` setting for some actions unrelated to
the terminal GUI, like environment capture, ACP agent startup, context
server startup, and vim `:!`, and so if a user set it to `tmux` or
`nushell`, those paths would fail.
This PR ensures paths unrelated to Zed's terminal use the system path
instead.
Manual testing:
Set `terminal.shell` to `tmux` or any another non-bash executable.
Starting an external agent thread shouldn't break.
Release Notes:
- Fixed ACP agent and other breakage when `terminal.shell` was set to a
non-shell program like `tmux`
This PR adds support for rendering **Netpbm** image formats (`.pbm`,
`.ppm`, `.pgm`) within Zed's built-in image viewer.
These formats are particularly useful for projects that want minimal
external dependencies, a common scenario in academic environments and
low-level graphics programming.
Since the underlying `image` crate and `GPUI` already provide support
for these codecs, this change explicitly exposes the `Pnm` variant
within `gpui::ImageFormat` by mapping it to `image::ImageFormat::Pnm`.
## Screenshots/Examples
Below is an example of `.pbm`, `.ppm`, and `.pgm` files being rendered
correctly in the image preview (images taken from
https://filesamples.com):
<img width="1917" height="1012" alt="pnm_example"
src="https://github.com/user-attachments/assets/0056133f-908c-4c91-ba9d-53aef0657b05"
/>
Release Notes:
- Added support for PNM image previews (`.pbm`, `.ppm`, `.pgm`).
Closes#47926
## Summary
When using a uv (or Poetry/PDM) workspace with multiple subprojects,
Python LSP servers (Pyright, Ruff, ty, etc.) are initialized with the
subproject directory as their workspace folder instead of the workspace
root. This happens because `PyprojectTomlManifestProvider::search()`
returns the first (innermost)
`pyproject.toml` found walking up the directory tree.
For example, in a uv workspace like:
main-project/
├── pyproject.toml # workspace root with [tool.uv.workspace]
├── uv.lock
├── packages/
│ └── project-api/
│ └── pyproject.toml # subpackage
└── projects/
└── project-a/
└── pyproject.toml # subpackage
Opening a file in `packages/project-api/` would register
`packages/project-api/` as the LSP workspace folder instead of
`main-project/`.
## Approach
The fix uses lockfile existence as a heuristic to detect workspace
roots. The updated `search()` method walks all ancestors (similar to
`CargoManifestProvider`) and:
- Tracks the **innermost** `pyproject.toml` as a fallback
- Tracks the **outermost** `pyproject.toml` that has a sibling lockfile
(`uv.lock`, `poetry.lock`, `pdm.lock`, or `Pipfile.lock`)
- Returns the outermost workspace root if found, otherwise falls back to
the innermost
This works within the existing `ManifestDelegate` interface (existence
checks only, no file content reading).
| Scenario | Result |
|---|---|
| uv workspace (root `pyproject.toml` + `uv.lock`) | Returns workspace
root |
| Poetry workspace (root `pyproject.toml` + `poetry.lock`) | Returns
workspace root |
| Simple project (single `pyproject.toml`, no lockfile) | Returns
project dir (unchanged) |
| Independent subprojects (no lockfile at any level) | Returns each
project's own dir (unchanged) |
Since the manifest provider is set at the Python **language** level,
this fix applies to all Python LSP servers (Pyright, Ruff, ty, etc.).
## Test plan
- [x] Added unit tests for `PyprojectTomlManifestProvider` covering all
scenarios above
- [x] Existing integration test
`test_running_multiple_instances_of_a_single_server_in_one_worktree`
passes (independent subprojects without lockfiles)
- [x] `cargo check -p languages` compiles cleanly
- [x] Manual testing with a real uv workspace (Pyright and Ruff both
receive correct workspace root)
Release Notes:
- Fixed Python LSP servers (Pyright, Ruff, etc.) using the wrong
workspace folder in uv/Poetry/PDM workspaces with multiple subprojects.
Adds basic bookmark functionality to the editor, allowing users to mark
lines and later navigate between them. This is an MVP and will later be
expanded with a picker, vim marks integration and syntax tree based
bookmark positions. In this MVP bookmarks shift under external edits.
# UI
## Adding/Removing bookmarks
To add a bookmark:
- run the toggle bookmark action
- hold secondary and click in the gutter
- open the context menu by right clicking in the gutter and select add
bookmark To remove a bookmark:
- run the toggle bookmark action
- click on the bookmarks icon in the gutter
- open the context menu by right clicking in the gutter and select
remove bookmark
remove all bookmarks with `workspace: clear bookmarks`
# Implementation
This mirrors the implementation of breakpoints. The rendering of the
gutter was refactored to make place for bookmark icons and buttons:
- Code was extracted to a `Gutter` struct
- Runnables, breakpoints and bookmarks are now collected ahead of
layouting. Just before layouting we remove the items that collide and do
not have priority.
- The `phantom_breakpoint` is replaced by a `gutter_hover_button`
## In depth phantom breakpoint discussion:
This was phantom_breakpoint. It worked as follows:
- A fake breakpoint was added to the list of breakpoints.
- While rendering the breakpoints it a breakpoint turned out to be fake
it would get a different description and look.
- The breakpoint list was edited run_indicators ("play buttons")
rendering to removes the fake breakpoint if it collided.
This would not scale to more functionality. Now we only render
breakpoints, bookmarks and run indicators. Then we render a button if
there is not breakpoint, bookmark or run indicator already present. We
can do so since the rendering of such "gutter indicators" has been
refactored into two phases:
- collect the items.
- render them if no higher priority item collides.
This is far easier and more readable which enabled me to easily take the
phantom_breakpoint system and use it for placing bookmarks as well :)
Note: this was previously merged but it needed a better squashed commit
message. For the actual PR see: 51404. This reverts commit
7e523a2d2b.
Release Notes:
- Added Bookmarks
Co-authored-by: Austin Cummings <me@austincummings.com>
Closes#4526
Adds basic bookmark functionality to the editor, allowing users to mark
lines and later navigate between them.
### What's new
**Toggling bookmarks**
Users can toggle a bookmark on the current line(s) via the `editor:
toggle bookmark` action. A bookmark icon appears in the gutter for each
bookmarked line.
**Navigation**
Two new actions, `editor: go to next bookmark` and `editor: go to
previous bookmark`, navigate between bookmarks in the current buffer,
wrapping around at the ends of the buffer.
**Viewing all bookmarks**
`editor: view bookmarks` opens all bookmarks across the project in a
multibuffer, similar to how references and diagnostics are surfaced.
**Clearing bookmarks**
`workspace: clear bookmarks` removes all bookmarks in the current
project.
**Persistence**
Bookmarks are persisted to the workspace database and restored when the
workspace is reopened. They are stored as `(path, row)` pairs and
resolved back to text anchors. Out of range or unresolvable bookmarks
are skipped with a logged warning.
**Gutter rendering**
Bookmark icons are rendered in the gutter using the existing gutter
button layout system, consistent with breakpoints. They are suppressed
on lines that already show a breakpoint or phantom breakpoint indicator.
A new `gutter.bookmarks` setting (defaulting to `true`) controls their
visibility.
### What's left
- [x] Lazily load buffers that have bookmarks
- [x] Clean up test boilerplate
- [ ] Assign default keybindings
- [ ] Compare line of saved bookmarks with current buffer (gray out the
"stale" bookmarks)
### What's next (and nice to haves)
- [ ] Resilience against external edits
- [ ] Save column position with the bookmark
- [ ] Bookmarks attached to syntactic structures?
- [ ] Labeled bookmarks?
---
Release Notes:
- Added bookmarks: toggle bookmarks on lines with `editor: toggle
bookmark`, navigate with `editor: go to next bookmark` / `editor: go to
previous bookmark`, view all bookmarks with `editor: view bookmarks`,
and clear with `workspace: clear bookmarks`. Bookmarks are shown in the
gutter and persisted across sessions.
---------
Co-authored-by: Yara <git@yara.blue>
### Summary
Follow up to: https://github.com/zed-industries/zed/pull/54001
This PR makes
`agent_ui::thread_worktree_archive::find_or_create_repository` whether
or not the repository it's searching for is on a remote machine. In the
case where it's on a remote machine that has an active connection in
Zed's connection pool, we return the repository; otherwise, we error
out.
I implemented it this way so archiving a thread on a remote machine that
isn't connected deletes the metadata without showing a remote connection
modal to a user. In the future, we can work around this by having better
git worktree garbage collection, where remote machines remove git
worktree's that were created by Zed and have no thread metadata on
connection too.
Finally, this PR gets archive threads working on remotes!
#### Follow Ups
1. Replace instances of `std::fs` with Zed's Fs trait in the archive
thread codepaths
2. Make archive thread work properly for workspace's that are not open
(local and remote)
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Make sure that we never write thread metadata to the DB for a thread
running on a collab project.
When joining a collab project and starting a native thread we would set
all your threads that had no paths associated with to the path of the
collab project (in `move_thread_paths`).
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A