The indent guide computation was using visible list indices directly to
access entries, instead of mapping through `logical_indices` first. This
caused incorrect depths to be read from hidden entries when a folder was
collapsed, resulting in stray vertical lines extending to unrelated folders.
Closes#48189
Release Notes:
- Fixed a visual bug in the Git Panel where collapsing a folder in tree
view would cause indent guide lines to incorrectly extend to unrelated
folders below it.
Release Notes:
Refactored:
- Use [flake-parts](https://flake.parts/index.html) modules
- `nix/shell.nix` -> `nix/modules/devshells.nix`
Added:
- Use
[flake-parts.partitions](https://flake.parts/options/flake-parts-partitions.html)
to isolate dev dependencies so that flakes that use `zed-editor` don't
fetch dev-only inputs such as `treefmt-nix`
- [treefmt-nix](https://github.com/numtide/treefmt-nix)
- nixfmt
- rustfmt
Fixed:
- `shell.nix` and `default.nix` fetching `flake-compat` from
`flake.lock` which added an extra and unnecessary input/dependency to
`flake.nix`. Fixed by setting a fixed rev and sha256 instead.
- `nixfmt-rfc-style` is deprecated and is now `nixfmt`
- Fixes#45338 by using rust-overlay toolchain directly
- Previously, the devShell included `rustup` which caused slow startup
times as Nix would build rustup from source (including running its test
suite). Additionally, rust tooling (cargo, rustfmt, clippy,
rust-analyzer) wasn't available in the dev shell.
- cargo, rustc, and rust-toolchain.toml components included in
`rustToolchain`
Chore:
- Update `flake.lock`
- Format Rust code with `rustfmt` via `treefmt-nix`
---------
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Previously, `]m`/`[m` (method) and `]/`/`[/` (comment) motions would
navigate to incorrect positions when diff hunks were expanded. This was
caused by extracting raw `usize` values from `MultiBufferOffset` and
operating directly on the underlying buffer, which doesn't account for
expanded diff hunk content.
The fix properly uses `MultiBufferOffset` throughout and queries
`text_object_ranges` on the `MultiBufferSnapshot` instead of the
underlying buffer, ensuring correct coordinate mapping when diff content
is displayed inline.
Fixes#46612
Release Notes:
- Fixed vim method and comment navigation (`] m`, `[ m`, `] shift-m`, `[
shift-m`, `] /`, `[ /`) incorrectly positioning cursor when diff hunks
are expanded
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
Release Notes:
- Agent: Improved the "Copy Selection" right-click menu item by
disabling it when there are no selections.
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Closes#44420
Added instructions and example keybindings to enable multi-cursor insert
(`shift-i`) and append (`shift-a`) actions in visual mode, making it
easier for users to perform these actions on multiple lines
simultaneously.
Release Notes:
- N/A
---------
Co-authored-by: Kunall Banerjee <hey@kimchiii.space>
Closes ZED-4R9
Introduced in https://github.com/zed-industries/zed/pull/47768
The `insert_context_prefix` function was using byte offsets to check if
the prefix already exists at the cursor. This caused a panic with
multi-byte characters like emojis. Now uses character counts instead.
Release Notes:
- Fixed a crash in the Agent Panel when inserting context mentions with
emojis in the message editor.
Closes#14863
Changes:
- Added `CurrentFileDirectory` variant to the `WorkingDirectory` enum.
- New terminals now open in the directory of the currently active file
when this option is set.
- Falls back to project directory, then first workspace directory if no
file is active.
Release Notes:
- Added `current_file_directory` option for terminal's
`working_directory` setting. Set `"working_directory":
current_file_directory"` to open new terminals in the directory of your
currently open file.
---
Still relatively new to Rust, so happy to receive any feedback! 😁
Closes#46801
When connecting to WSL2 with fish as the default shell, Zed gets stuck
at "Starting proxy". The connection works fine when bash is the default
shell.
In `start_proxy()`, the WSL command was being invoked with:
```rust
let proxy_process = match wsl_command_impl(&self.connection_options, "env", &proxy_args, false)
```
Changing the last argument to true invokes the WSL command with `--exec`
flag which executes the command in the WSL environment without spawning
a new shell.
With above fix I can launch Zed from WSL (Arch) with fish.
The current setup is quite a mess, allocates a ton of unnecessary heap
data when rendering text or querying font info and not really caching
things well, this PR changes that.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Fixes#38709
## Summary
This implements the `extract_pull_request` method for GitLab's
`GitHostingProvider` trait, enabling merge request links to be shown in
the git blame hover popover.
## Implementation
The implementation parses GitLab MR references from commit messages
using a regex that matches two common patterns:
1. **Squash merge pattern**: `message (!123)` - When GitLab
squash-merges, it appends the MR number in parentheses
2. **Standard merge commit**: `See merge request group/project!123` -
The default merge commit message
## Tests Added
- `test_extract_merge_request_from_squash_commit` - Validates the
`(!123)` pattern
- `test_extract_merge_request_from_merge_commit` - Validates the `See
merge request` pattern
- `test_extract_merge_request_self_hosted` - Ensures it works with
self-hosted GitLab instances
- `test_extract_merge_request_no_match` - Confirms None is returned for
non-matching messages
## Related
This follows the same pattern as the GitHub provider implementation.
## Release Notes
- Added support for GitLab merge request links in git blame hover
popover
Git commands can fail when staging or unstaging a very large number of
files because each file path is passed as a separate CLI argument. Once
the argument list grows beyond the OS limit, git errors with Argument
list too long (os error 7).
Since git 2.26, pathspecs can be read from stdin, which lets us avoid
passing thousands of paths as arguments and bypass this limitation.
I looked for existing issues related to this but couldn’t find any.
Repro:
- Clone rust-lang repo
- Delete root tests folder
- Try to stage or unstage (40,000+ files)
- Git fails with Argument list too long (os error 7)
Release Notes:
- Fixed an issue where stage/unstage could fail when operating on a very
large number of files
Fixed git panel not update after commit or switch branch on Linux.
On macOS and Windows, the watcher implementation recursively watches
subdirectories.
On Linux, the watcher is non-recursive.
In Git worktree scenarios, only `<project>/.git` is watched, but the
actual worktree Git directory
`<project>/.git/worktrees/<worktree>` is not.
Therefore, Git operations such as commits or branch switches inside a
worktree do not emit watcher events on Linux, causing the Git panel to
stay out of sync.
Release Notes:
- Fixed git panel not update after commit or switch branch on Linux with
git worktrees.
Closes#15231
changes the priority in the way files are color-labelled..making sure
forcely added files are highlighted appropriately.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
GitHub's commit API endpoint is rate limited to 60 requests/hour for
unauthenticated users. This causes avatar loading to fail after toggling
blame a few times.
This PR uses GitHub's CDN avatar endpoint
`https://avatars.githubusercontent.com/u/e?email={email}&s=128` instead,
which doesn't count against API rate limits. The author email is already
available from local git data (blame output), so
no API calls are needed.
- When author email is available, constructs the CDN URL directly (zero
API calls)
- Falls back to existing API-based behavior when email is unavailable
- Adds unit tests for URL construction
Closes#47590
## Test plan
- [x] `./script/clippy` passes
- [x] `cargo test -p git_hosting_providers` passes (89 tests including 3
new ones i added)
- [ ] Manual test: Open a file, toggle git blame, verify avatars load
without hitting rate limits
Release Notes:
- Fixed GitHub avatar rate limiting in git blame by using CDN endpoint
instead of API calls (#47590)
- Remove old attempt to sync scrolling
- Share a `ScrollAnchor` between the two sides, and be sure to resolve
it against the correct snapshot
- Allow either side to initiate an autoscroll request, and make sure
that request is processed in the same frame by the other side
Release Notes:
- N/A
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Jakub <jakub@zed.dev>
* [x] capture and store teacher model's predicted cursor position
* [x] provide cursor position to student during distillation
* [x] eval cursor positions
* [x] parse and apply cursor position predictions at runtime
Release Notes:
- N/A
The bug occurred because `cx.observe_new::<Workspace>` would pass a
mutable `Window` that was also the new workspace's window. Later,
`fetch_files` would fail to read the newly created workspace from
`WorkspaceStore` because its window already had a mutable reference to
it.
The fix always passes the Settings UI's window handle to the
`fetch_files` function, and uses a `settings_window_handle.defer`
callback to call `fetch_files` after the newly created workspace's
window no longer has any mutable references to it.
Release Notes:
- settings_ui: Fixed editable project settings not being updated when a
new workspace is created
Fixes#8048
## Summary
In vim mode, pressing Escape to dismiss the buffer search now correctly
restores the cursor to its original position, rather than leaving it at
the first match.
## Problem
When using vim's `/` command to search:
1. User positions cursor at line X
2. User presses `/` to open search, types a query
3. Matches are highlighted, cursor may visually jump to first match
4. User presses Escape to dismiss without navigating
5. **Bug:** Cursor ends up at first match instead of line X
This breaks vim parity where Escape should cancel the search and restore
cursor position.
## Solution
The fix leverages the `focused()` callback in `vim.rs`, which is called
when the editor regains focus after the search bar is dismissed.
**Key insight:** When search starts via `/`, the cursor position is
saved in `SearchState.prior_selections`. When search is *submitted* with
Enter, `search_submit()` drains these selections. But when search is
*dismissed* with Escape, they remain.
So in `focused()`, if:
- `prior_selections` is non-empty, AND
- The search bar's `is_dismissed()` returns true
...then we know the user dismissed the search (Escape) rather than
submitted it (Enter), and we restore the cursor.
## Why not handle `buffer_search::Dismiss` directly?
The initial approach tried to register a vim handler for the `Dismiss`
action. This didn't work because when Escape is pressed, the search bar
(which has focus) handles the `Cancel` action internally and calls its
`dismiss()` method directly—it doesn't dispatch `Dismiss` through the
action system. The vim handler registered on the editor was never
invoked.
## Test Plan
- Added `test_search_dismiss_restores_cursor` — verifies cursor
restoration when search is dismissed
- Added `test_search_dismiss_restores_cursor_no_matches` — verifies
behavior when query has no matches
- All 455 vim tests pass
- Manual testing confirms fix works with both `/` and `cmd-f`
## Release Notes
- Fixed vim mode: cursor now returns to original position when
dismissing buffer search with Escape (#8048)
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>