https://github.com/zed-industries/zed/issues/30972 brought up another
case where our context is not enough to track the actual source of the
issue: we get a general top-level error without inner error.
The reason for this was `.ok_or_else(|| anyhow!("failed to read HEAD
SHA"))?; ` on the top level.
The PR finally reworks the way we use anyhow to reduce such issues (or
at least make it simpler to bubble them up later in a fix).
On top of that, uses a few more anyhow methods for better readability.
* `.ok_or_else(|| anyhow!("..."))`, `map_err` and other similar error
conversion/option reporting cases are replaced with `context` and
`with_context` calls
* in addition to that, various `anyhow!("failed to do ...")` are
stripped with `.context("Doing ...")` messages instead to remove the
parasitic `failed to` text
* `anyhow::ensure!` is used instead of `if ... { return Err(...); }`
calls
* `anyhow::bail!` is used instead of `return Err(anyhow!(...));`
Release Notes:
- N/A
## Description
This PR implements basic support for Japanese Input Method Editors
(IMEs) in the Zed terminal on macOS, addressing issue #9900. Previously,
users had to switch input modes to confirm Japanese text, and pre-edit
(marked) text was not displayed.
With these changes:
- **Marked Text Display:** Pre-edit text (e.g., underlined characters
during Japanese composition) is now rendered directly in the terminal at
the cursor's current position.
- **Composition Confirmation:** Pressing Enter correctly finalizes the
IME composition, clears the marked text, and sends the confirmed string
to the underlying PTY process. This allows for a more natural input flow
similar to other macOS applications like iTerm2.
- **State Management:** IME state (marked text and its selected range
within the marked text) is now managed within the `TerminalView` struct.
- **Input Handling:** `TerminalInputHandler` has been updated to
correctly process IME callbacks (`replace_and_mark_text_in_range`,
`replace_text_in_range`, `unmark_text`, `marked_text_range`) by
interacting with `TerminalView`.
- **Painting Logic:** `TerminalElement::paint` now fetches the marked
text and its range from `TerminalView` and renders it with an underline.
The standard terminal cursor is hidden when marked text is present to
avoid visual clutter.
- **Candidate Window Positioning:**
`TerminalInputHandler::bounds_for_range` now attempts to provide more
accurate bounds for the IME candidate window by using the actual painted
bounds of the pre-edit text, falling back to a cursor-based
approximation if necessary.
This significantly improves the usability of the Zed terminal for users
who need to input Japanese characters, bringing the experience closer to
system-standard IME behavior.
## Movies
https://github.com/user-attachments/assets/be6c7597-7b65-49a6-b376-e1adff6da974
---
Closes#9900
Release Notes:
- **Terminal:** Implemented basic support for Japanese Input Method
Editors (IMEs) on macOS. Users can now see pre-edit (marked) text as
they type Japanese and confirm their input with the Enter key directly
in the terminal. This provides a more natural and efficient experience
for Japanese language input. (Fixes#9900)
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Bounded this action to the same defaults `task::Rerun` is bound to.
Unlike the `task::Rerun` which will always rerun the latest task, this
command reruns the current task tab, if focused.
The task is not in scope when the terminal pane is not focused, and
falls back to the regular rerun if invoked on a task-less terminal tab.
This way, we can add a proper tooltip to the terminal tab reruns:
<img width="231" alt="image"
src="https://github.com/user-attachments/assets/2cdd7458-5ba2-4cc7-a10b-3e2db059f1ca"
/>
Release Notes:
- Added `terminal::RerunTask` task action
Closes https://github.com/zed-industries/zed/issues/25110https://github.com/user-attachments/assets/4624c256-8dfb-48eb-a726-6cf130d946da
Terminal may update its hovered word way before reporting it to the
terminal view, and that processing the file check later.
Hence, store the terminal hover data in the terminal view and avoid
highlights when it's different from what the terminal has (as the source
of truth here).
In addition, now only does hover refreshes when the terminal hover
actually changes, not on every event report.
Release Notes:
- Fixed underline flicker when switching cmd-hovered words in terminal
To-dos:
- [x] Expose the command to defend against cases where that's just super
long
- [x] Tackle the vertical scroll conflict with panel scroll
- [x] Reduce default font-size
Release Notes:
- N/A
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Co-authored-by: Agus Zubiaga <hi@aguz.me>
resolves#24655resolves#23945
I haven't yet added a default binding for the new command. #27797 added `:ls` and
`:buffers` which in my opinion should use the global searchable version
given that that matches the vim semantics of those commands better than
just showing the tabs in the local pane.
There's also a question of what to do when you select a tab from another
pane, should the focus jump to that pane or should that tab move to the
currently focused pane? For now I've implemented the former.
Release Notes:
- Added `tab_switcher::ToggleAll` to search open tabs from all panes and focus the selected one.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Part of https://github.com/zed-industries/zed/issues/16472
* Adds debug logging to everywhere near INSERT/UPDATEs in the DB
So something like
`env RUST_LOG=debug,wasmtime_cranelift=off,cranelift_codegen=off,vte=off
cargo run` could be used to view these (current zlog seems to process
the exclusions odd, so not sure this is the optimal RUST_LOG line) can
be used to debug any further writes.
* Removes excessive window stack serialization
Previously, it serialized unconditionally every 100ms.
Now, only if the stack had changed, which is now check every 500ms.
* Removes excessive terminal serialization
Previously, it serialized its `cwd` on every `ItemEvent::UpdateTab`
which was caused by e.g. any character output.
Now, only if the `cwd` has changed at the next event processing time.
Release Notes:
- Fixed more excessive DB writes
Attempt to lookup exact relative paths before full worktree traversal,
only do the full traversal if all other methods fail.
Closes https://github.com/zed-industries/zed/issues/28407
Release Notes:
- Fixed wrong paths opening when cmd-clicking in the terminal
Split `locator` out of DebugTaskDefinition to make it clearer when
location needs to happen.
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Anthony <anthony@zed.dev>
Co-authored-by: Cole Miller <m@cole-miller.net>
This PR adds functionality to right click in terminal create new
selection if none present. The selection is identical with double click
a text in terminal, plus the logic is moved from the double-click in the
terminal::mouse_down.
Closes#28237
Release Notes:
- Adds functionality to right click in terminal create new selection if
none present
This PR renames the `regex_search` tool to `grep` because I think it
conveys more meaning to the model, the idea of searching the filesystem
with a regular expression. It's also one word and the model seems to be
using it effectively after some additional prompt tuning.
It also takes an include pattern to filter on the specific files we try
to search. I'd like to encourage the model to scope its searches more
aggressively, as in my testing, I'm only seeing it filter on file
extension.
Release Notes:
- N/A
Release Notes:
- Added the ability to copy external files into remote projects by
dragging them onto the project panel.
---------
Co-authored-by: Peter Tripp <petertripp@gmail.com>
## Summary
This PR starts the process of adding debug task locators to Zed's
debugger system. A task locator is a secondary resolution phase that
allows a debug task to run a command before starting a debug session and
then uses the output of the run command to configure itself.
Locators are most applicable when debugging a compiled language but will
be helpful for any language as well.
## Architecture
At a high level, this works by adding a debug task queue to `Workspace`.
Which add's a debug configuration associated with a `TaskId` whenever a
resolved task with a debug config is added to `TaskInventory`'s queue.
Then, when the `SpawnInTerminal` task finishes running, it emits its
task_id and the result of the ran task.
When a ran task exits successfully, `Workspace` tells `Project` to start
a debug session using its stored debug config, then `DapStore` queries
the `LocatorStore` to configure the debug configuration if it has a
valid locator argument.
Release Notes:
- N/A
This is the core change:
https://github.com/zed-industries/zed/pull/26758/files#diff-044302c0d57147af17e68a0009fee3e8dcdfb4f32c27a915e70cfa80e987f765R1052
TODO:
- [x] Use AsyncFn instead of Fn() -> Future in GPUI spawn methods
- [x] Implement it in the whole app
- [x] Implement it in the debugger
- [x] Glance at the RPC crate, and see if those box future methods can
be switched over. Answer: It can't directly, as you can't make an
AsyncFn* into a trait object. There's ways around that, but they're all
more complex than just keeping the code as is.
- [ ] Fix platform specific code
Release Notes:
- N/A
### DISCLAIMER
> As of 6th March 2025, debugger is still in development. We plan to
merge it behind a staff-only feature flag for staff use only, followed
by non-public release and then finally a public one (akin to how Git
panel release was handled). This is done to ensure the best experience
when it gets released.
### END OF DISCLAIMER
**The current state of the debugger implementation:**
https://github.com/user-attachments/assets/c4deff07-80dd-4dc6-ad2e-0c252a478fe9https://github.com/user-attachments/assets/e1ed2345-b750-4bb6-9c97-50961b76904f
----
All the todo's are in the following channel, so it's easier to work on
this together:
https://zed.dev/channel/zed-debugger-11370
If you are on Linux, you can use the following command to join the
channel:
```cli
zed https://zed.dev/channel/zed-debugger-11370
```
## Current Features
- Collab
- Breakpoints
- Sync when you (re)join a project
- Sync when you add/remove a breakpoint
- Sync active debug line
- Stack frames
- Click on stack frame
- View variables that belong to the stack frame
- Visit the source file
- Restart stack frame (if adapter supports this)
- Variables
- Loaded sources
- Modules
- Controls
- Continue
- Step back
- Stepping granularity (configurable)
- Step into
- Stepping granularity (configurable)
- Step over
- Stepping granularity (configurable)
- Step out
- Stepping granularity (configurable)
- Debug console
- Breakpoints
- Log breakpoints
- line breakpoints
- Persistent between zed sessions (configurable)
- Multi buffer support
- Toggle disable/enable all breakpoints
- Stack frames
- Click on stack frame
- View variables that belong to the stack frame
- Visit the source file
- Show collapsed stack frames
- Restart stack frame (if adapter supports this)
- Loaded sources
- View all used loaded sources if supported by adapter.
- Modules
- View all used modules (if adapter supports this)
- Variables
- Copy value
- Copy name
- Copy memory reference
- Set value (if adapter supports this)
- keyboard navigation
- Debug Console
- See logs
- View output that was sent from debug adapter
- Output grouping
- Evaluate code
- Updates the variable list
- Auto completion
- If not supported by adapter, we will show auto-completion for existing
variables
- Debug Terminal
- Run custom commands and change env values right inside your Zed
terminal
- Attach to process (if adapter supports this)
- Process picker
- Controls
- Continue
- Step back
- Stepping granularity (configurable)
- Step into
- Stepping granularity (configurable)
- Step over
- Stepping granularity (configurable)
- Step out
- Stepping granularity (configurable)
- Disconnect
- Restart
- Stop
- Warning when a debug session exited without hitting any breakpoint
- Debug view to see Adapter/RPC log messages
- Testing
- Fake debug adapter
- Fake requests & events
---
Release Notes:
- N/A
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Anthony <anthony@zed.dev>
Co-authored-by: Piotr Osiewicz <peterosiewicz@gmail.com>
Co-authored-by: Piotr <piotr@zed.dev>
Closes https://github.com/zed-industries/zed/issues/26431
Follow-up of https://github.com/zed-industries/zed/pull/26174
`path_with_position.path.strip_prefix(&worktree_root)` used in the PR is
wrong for cases of single-file worktrees, where it will return empty
paths that will result in incorrect project and FS entries accessed.
Release Notes:
- Fixed goto single file worktrees during terminal cmd-clicks
Modified version of #25950. We still use worktree paths, but repo paths
with a status that lie outside the worktree are not excluded; instead,
we relativize them by adding `..`. This makes the list in the git panel
match what you'd get from running `git status` (with the repo's worktree
root as the working directory).
- [x] Implement + test new unrelativization logic
- [x] ~~When collecting repositories, dedup by .git abs path, so
worktrees can share a repo at the project level~~ dedup repos at the
repository selector layer, with repos coming from larger worktrees being
preferred
- [x] Open single-file worktree with diff when activating a path not in
the worktree
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/25701
Reworks the way cmd-click is handled:
* first, all worktree entries are checked for existence
This allows more fine-grained lookup of entries that are in the
worktree, but their path in the terminal is not "full": in case neither
`cwd` no worktree's root + that temrinal paths form a valid path
(https://github.com/zed-industries/zed/issues/25701)
The worktrees are sorted by "the most close to cwd first" so such files
are attempted to resolved in the most specific worktree.
This also fixes no cmd-click working in the remote ssh.
* second, only if the client is local, do the FS checks to find
non-indexed files
Release Notes:
- Improved cmd-click in terminal to find more paths
These changes tackle two issues with running terminal commands via vim
mode:
- When using `!!` the tab's title was set to `!!` instead of the
previous command that was run and these changes fix that in order to
always display the previous command in the tab's title when re-running
the command with `!!`
- For a terminal command, pressing the rerun button would actually bring
up the task palette, so this has been updated in order to disable the
rerun button when the terminal tab was spawned via a vim command
Closes#25800
Release Notes:
- Fixed the terminal tab title when using `!!` to rerun the last command
- Improved the terminal tab for when command is run via vim mode, in
order to disable the rerun button, seeing as Zed does not support it
This solves a couple of issues with Vim search by making the search
buffer and `SearchableItem` aware of the direction of the search. If
`SearchOptions::BACKWARDS` is set, all operations will be reversed. By
making `SearchableItem` aware of the direction, the correct active match
can be selected when searching backward.
Fixes#22506. This PR does not fix the last problem in that issue, but
that one is also tracked in #8049.
Release Notes:
- Fixes incorrect behavior of backward search in Vim mode
Done automatically with
> ast-grep -p '$A.background_executor().spawn($B)' -r
'$A.background_spawn($B)' --update-all --globs "\!crates/gpui"
Followed by:
* `cargo fmt`
* Unexpected need to remove some trailing whitespace.
* Manually adding imports of `gpui::{AppContext as _}` which provides
`background_spawn`
* Added `AppContext as _` to existing use of `AppContext`
Release Notes:
- N/A
Super subtle, but when I initially saw just "Close", I got weirded out
asking myself "why there's a menu item to close the context menu?", to
only then realize that it didn't close the menu, but the terminal _tab_.
Might be obvious, because that's how buffer tabs are labled, but I don't
know, it feels like the redundancy here is overall positive.
Release Notes:
- N/A
When saving an item, some logic is done to determine whether one can
save it. In the special case where the intent is to `SaveAs`, it was
previously allowed to proceed as long as the buffer was a singleton
(presumably since it only makes sense to provide a save path for a
single file). However, we need to _also_ check that this item can be
"saved as" at all.
For this, we resurrect the `ItemHandle`/`Item` trait method
`can_save_as`. We have given it the default implementation of returning
`false`, and then overridden this in the implementation for
`TerminalView`.
Closes#25023
Release Notes:
- Fixed crash when trying to save terminal buffer
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#22247
- [x] Do not close pinned tab on keyboard shortcuts like `ctrl+w` or
`alt+f4`
- [x] Close pinned tab on context menu action, menu bar action, or vim
bang
- [x] While closing pinned tab via shortcut (where it won't close),
instead activate any other non-pinned tab in same pane
- [x] Else, if any other pane contains non-pinned tab, activate that
- [x] Tests
Co-authored-by: uncenter <47499684+uncenter@users.noreply.github.com>
Release Notes:
- Pinned tab now stay open when using close shortcuts, auto focuses to
any other non-pinned tab instead.
There's still a bit more work to do on this, but this PR is compiling
(with warnings) after eliminating the key types. When the tasks below
are complete, this will be the new narrative for GPUI:
- `Entity<T>` - This replaces `View<T>`/`Model<T>`. It represents a unit
of state, and if `T` implements `Render`, then `Entity<T>` implements
`Element`.
- `&mut App` This replaces `AppContext` and represents the app.
- `&mut Context<T>` This replaces `ModelContext` and derefs to `App`. It
is provided by the framework when updating an entity.
- `&mut Window` Broken out of `&mut WindowContext` which no longer
exists. Every method that once took `&mut WindowContext` now takes `&mut
Window, &mut App` and every method that took `&mut ViewContext<T>` now
takes `&mut Window, &mut Context<T>`
Not pictured here are the two other failed attempts. It's been quite a
month!
Tasks:
- [x] Remove `View`, `ViewContext`, `WindowContext` and thread through
`Window`
- [x] [@cole-miller @mikayla-maki] Redraw window when entities change
- [x] [@cole-miller @mikayla-maki] Get examples and Zed running
- [x] [@cole-miller @mikayla-maki] Fix Zed rendering
- [x] [@mikayla-maki] Fix todo! macros and comments
- [x] Fix a bug where the editor would not be redrawn because of view
caching
- [x] remove publicness window.notify() and replace with
`AppContext::notify`
- [x] remove `observe_new_window_models`, replace with
`observe_new_models` with an optional window
- [x] Fix a bug where the project panel would not be redrawn because of
the wrong refresh() call being used
- [x] Fix the tests
- [x] Fix warnings by eliminating `Window` params or using `_`
- [x] Fix conflicts
- [x] Simplify generic code where possible
- [x] Rename types
- [ ] Update docs
### issues post merge
- [x] Issues switching between normal and insert mode
- [x] Assistant re-rendering failure
- [x] Vim test failures
- [x] Mac build issue
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Joseph <joseph@zed.dev>
Co-authored-by: max <max@zed.dev>
Co-authored-by: Michael Sloan <michael@zed.dev>
Co-authored-by: Mikayla Maki <mikaylamaki@Mikaylas-MacBook-Pro.local>
Co-authored-by: Mikayla <mikayla.c.maki@gmail.com>
Co-authored-by: joão <joao@zed.dev>
Closes#12553
* [x] Fix `diff_hunk_before`
* [x] Fix failure to show deleted text when expanding hunk w/ cursor on
second line of the hunk
* [x] Failure to expand diff hunk below the cursor.
* [x] Delete the whole file, and expand the diff. Backspace over the
deleted hunk, panic!
* [x] Go-to-line now counts the diff hunks, but it should not
* [x] backspace at the beginning of a deleted hunk deletes too much text
* [x] Indent guides are rendered incorrectly
* [ ] Fix randomized multi buffer tests
Maybe:
* [ ] Buffer search should include deleted text (in vim mode it turns
out I use `/x` all the time to jump to the next x I can see).
* [ ] vim: should refuse to switch into insert mode if selection is
fully within a diff.
* [ ] vim `o` command when cursor is on last line of deleted hunk.
* [ ] vim `shift-o` on first line of deleted hunk moves cursor but
doesn't insert line
* [x] `enter` at end of diff hunk inserts a new line but doesn't move
cursor
* [x] (`shift-enter` at start of diff hunk does nothing)
* [ ] Inserting a line just before an expanded hunk collapses it
Release Notes:
- Improved diff rendering, allowing you to navigate with your cursor
inside of deleted text in diff hunks.
---------
Co-authored-by: Conrad <conrad@zed.dev>
Co-authored-by: Cole <cole@zed.dev>
Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Michael <michael@zed.dev>
Co-authored-by: Agus <agus@zed.dev>
Co-authored-by: João <joao@zed.dev>
This PR consolidates the two Assistant panels into one for users in the
`assistant2` feature flag.
Now that the Assistant1 prompt editor is accessible through the
Assistant2 panel, we no longer have a need to show both panels.
Release Notes:
- N/A
Closes#4798
This PR implements a scrollbar for the terminal by turning
`ScrollableHandle` into a trait, allowing us to implement a custom
scroll handle, `TerminalScrollHandle`. It works by converting terminal
lines into pixels that `ScrollableHandle` understands. When
`ScrollableHandle` provides a changed offset (e.g., when you drag the
scrollbar), we convert this pixel offset back into the number of lines
to scroll and update the terminal content accordingly.
While the current version works as expected, I believe the scrollbar's
offset updates could potentially be turned into an event. This event
could then be subscribed to in `TerminalView`, not needing to update the
terminal's offset in the `render` method as it might have performance
implications. Further ideas on this are welcome.
Preview:
https://github.com/user-attachments/assets/560f0aac-4544-4007-8f0b-8833386f608f
Todo:
- [x] Experiment with custom scrollbar responding to terminal mouse
scroll
- [x] Refactor existing scrollbar handle into a trait
- [x] Update terminal to use the scrollbar trait instead of a custom
scrollbar implementation
- [x] Figure out how scrollbar events like mouse drag should notify the
terminal to update its state
- [x] Code clean up
- [x] Scrollbar hide setting for terminal
Release Notes:
- Added scrollbar to the terminal
Also:
* Adds `impl_internal_actions!` for deriving the `Action` trait without
registering.
* Removes some deserializers that immediately fail in favor of
`#[serde(skip)]` on fields where they were used. This also omits them
from the schema.
Release Notes:
- Keymap settings file now has more JSON schema information to inform
`json-language-server` completions and info, particularly for actions
that take input.
Closes#15705
When opening a file from the terminal, if the file path is relative, we
attempt to guess all possible paths where the file could be. This
involves generating paths for each worktree, the current terminal
directory, etc. For example, if we have two worktrees, `dotfiles` and
`example`, and `foo.txt` in `example/a`, the generated paths might look
like this:
- `/home/tims/dotfiles/../example/a/foo.txt` from the `dotfiles`
worktree
- `/home/tims/example/../example/a/foo.txt` from the `example` worktree
- `/home/tims/example/a/foo.txt` from the current terminal directory
(This is already canonicalized)
Note that there should only be a single path, but multiple paths are
created due to missing canonicalization.
Later, when opening these paths, the worktree prefix is stripped, and
the remaining path is used to open the file in its respective worktree.
As a result, the above three paths would resolve like this:
- `../example/a/foo.txt` as the filename in the `dotfiles` worktree
(Ghost file)
- `../example/a/foo.txt` as the filename in the `example` worktree
(Ghost file)
- `foo.txt` as the filename in the `a` directory of the `example`
worktree (This opens the file)
This PR fixes the issue by canonicalizing these paths before adding them
to the HashSet.
Before:

After:

Release Notes:
- Fixed ghost files appearing in the project panel when clicking
relative paths in the terminal.
* Remove unnecessary WindowContext and ViewContext '_ lifetimes
* Removed some cases where WindowContext has a different name than `cx`.
Release Notes:
- N/A